plib-1.8.5/0000777000175000001440000000000010765365517007473 500000000000000plib-1.8.5/configure0000755000175000001440000106134010765365025011315 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.60. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 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 Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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 BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # PATH needs CR # 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 # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. 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 echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. 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 # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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 BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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 BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 fi echo >conf$$.file 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # Find out whether ``test -x'' works. Don't use a zero-byte file, as # systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then as_executable_p="test -x" else as_executable_p=: fi rm -f conf$$.file # 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 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, 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= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="src/js/js.h" ac_default_prefix=/usr # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #endif #if HAVE_STDINT_H # include #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP RANLIB BUILD_FNT_TRUE BUILD_FNT_FALSE BUILD_JS_TRUE BUILD_JS_FALSE BUILD_PW_TRUE BUILD_PW_FALSE BUILD_NET_TRUE BUILD_NET_FALSE BUILD_PUI_TRUE BUILD_PUI_FALSE BUILD_PUAUX_TRUE BUILD_PUAUX_FALSE BUILD_SG_TRUE BUILD_SG_FALSE BUILD_PSL_TRUE BUILD_PSL_FALSE BUILD_SL_TRUE BUILD_SL_FALSE BUILD_SSG_TRUE BUILD_SSG_FALSE BUILD_SSGAUX_TRUE BUILD_SSGAUX_FALSE BUILD_UL_TRUE BUILD_UL_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os XMKMF X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS GREP EGREP LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS CPPFLAGS CPP CXX CXXFLAGS CCC CXXCPP XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false # 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}' 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=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_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval enable_$ac_feature=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_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval enable_$ac_feature=\$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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval with_$ac_package=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 ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && 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'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. 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 case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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 echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 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 .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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 -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | 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 .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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 this package 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/PACKAGE] --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 cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-fnt build FNT library (OpenGL needed) default: yes --enable-js build JS library default: yes --enable-pw build PW library default: yes --enable-net build NET library default: yes --enable-pui build PUI library (OpenGL needed) default: yes --enable-sg build SG library default: yes --enable-psl build PSL library default: yes --enable-sl build SL library default: yes --enable-ssg build SSG library (OpenGL needed) default: yes --enable-puaux build puAux library (OpenGL needed) default: yes --enable-ssgaux build ssgAux library (OpenGL needed) default: yes --enable-ul build UTIL library default: yes Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-GL=DIR set the prefix directory where GL resides --with-x use the X Window System Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _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" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`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 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 configure generated by GNU Autoconf 2.60 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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 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 $as_me, which was generated by GNU Autoconf 2.60. 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=. 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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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 cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_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 cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" 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'; { (exit 1); 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 # 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 # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" 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. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # 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,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 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 { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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 # **WARNING**WARNING**WARNING**WARNING**WARNING**WARNING** # # When you make a new release, there are TWO places where you # have to change the version number: # 1) Right below this comment. # 2) In 'ul.h' where PLIB_VERSION is created. # # **WARNING**WARNING**WARNING**WARNING**WARNING**WARNING** am__api_version="1.9" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; 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 { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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. # 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. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_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 ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS 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 { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$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' { echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } # Just in case sleep 1 echo timestamp > conftest.file # 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 ( 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 rm -f conftest.file 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". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } 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 $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm -f conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&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 { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } 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=plib VERSION=1.8.5 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"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' # This AC_PREFIX_DEFAULT will place the library files # into /usr/lib - but will put the include files into # /usr/include - when /usr/include/plib would be less # polluting to the filename space. # # There is probably a better way to do this. if echo $includedir | egrep "plib$" > /dev/null; then echo "includedir is" $includedir "libdir is" $libdir else includedir="${includedir}/plib" echo "includedir changed to" $includedir "libdir is" $libdir 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 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_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" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out 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. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 | *.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 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$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 { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* 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" 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac 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 done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_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='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} 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 { echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$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 { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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 { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } 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=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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$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 depcc="$CXX" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} 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 { echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 echo "${ECHO_T}$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 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 { echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { echo "$as_me:$LINENO: result: $CXXCPP" >&5 echo "${ECHO_T}$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } 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 # 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. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_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 ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS 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 { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$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' 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi # Check whether --with-GL was given. if test "${with_GL+set}" = set; then withval=$with_GL; GL_PREFIX=$withval else GL_PREFIX=auto fi # Check whether --enable-fnt was given. if test "${enable_fnt+set}" = set; then enableval=$enable_fnt; else enable_fnt=yes fi # Check whether --enable-js was given. if test "${enable_js+set}" = set; then enableval=$enable_js; else enable_js=yes fi # Check whether --enable-pw was given. if test "${enable_pw+set}" = set; then enableval=$enable_pw; else enable_pw=yes fi # Check whether --enable-net was given. if test "${enable_net+set}" = set; then enableval=$enable_net; else enable_net=yes fi # Check whether --enable-pui was given. if test "${enable_pui+set}" = set; then enableval=$enable_pui; else enable_pui=yes fi # Check whether --enable-sg was given. if test "${enable_sg+set}" = set; then enableval=$enable_sg; else enable_sg=yes fi # Check whether --enable-psl was given. if test "${enable_psl+set}" = set; then enableval=$enable_psl; else enable_psl=yes fi # Check whether --enable-sl was given. if test "${enable_sl+set}" = set; then enableval=$enable_sl; else enable_sl=yes fi # Check whether --enable-ssg was given. if test "${enable_ssg+set}" = set; then enableval=$enable_ssg; else enable_ssg=yes fi # Check whether --enable-puaux was given. if test "${enable_puaux+set}" = set; then enableval=$enable_puaux; else enable_puaux=yes fi # Check whether --enable-ssgaux was given. if test "${enable_ssgaux+set}" = set; then enableval=$enable_ssgaux; else enable_ssgaux=yes fi # Check whether --enable-ul was given. if test "${enable_ul+set}" = set; then enableval=$enable_ul; else enable_ul=yes fi if test "x$enable_fnt" = "xyes"; then need_opengl=yes if test "x$enable_sg" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build FNT library without SG library enabled" >&5 echo "$as_me: WARNING: cannot build FNT library without SG library enabled" >&2;} dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build FNT library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build FNT library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_pw" = "xyes"; then if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build PW library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build PW library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_js" = "xyes"; then if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build JS library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build JS library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_net" = "xyes"; then if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build NET library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build NET library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_pui" = "xyes"; then need_opengl=yes if test "x$enable_fnt" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build PUI library without FNT library enabled" >&5 echo "$as_me: WARNING: cannot build PUI library without FNT library enabled" >&2;} dependancy_problem=yes fi if test "x$enable_sg" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build PUI library without SG library enabled" >&5 echo "$as_me: WARNING: cannot build PUI library without SG library enabled" >&2;} dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build PUI library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build PUI library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_sg" = "xyes"; then if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build SG library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build SG library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_psl" = "xyes"; then if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build PSL library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build PSL library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_sl" = "xyes"; then if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build SL library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build SL library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_ssg" = "xyes"; then need_opengl=yes if test "x$enable_sg" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build SSG library without SG library enabled" >&5 echo "$as_me: WARNING: cannot build SSG library without SG library enabled" >&2;} dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build SSG library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build SSG library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_puaux" = "xyes"; then need_opengl=yes if test "x$enable_pui" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build puAux library without PUI library enabled" >&5 echo "$as_me: WARNING: cannot build puAux library without PUI library enabled" >&2;} dependancy_problem=yes fi if test "x$enable_sg" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build puAux library without SG library enabled" >&5 echo "$as_me: WARNING: cannot build puAux library without SG library enabled" >&2;} dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build puAux library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build puAux library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$enable_ssgaux" = "xyes"; then need_opengl=yes if test "x$enable_ssg" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build ssgAux library without SSG library enabled" >&5 echo "$as_me: WARNING: cannot build ssgAux library without SSG library enabled" >&2;} dependancy_problem=yes fi if test "x$enable_sg" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build ssgAux library without SG library enabled" >&5 echo "$as_me: WARNING: cannot build ssgAux library without SG library enabled" >&2;} dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then { echo "$as_me:$LINENO: WARNING: cannot build ssgAux library without UL library enabled" >&5 echo "$as_me: WARNING: cannot build ssgAux library without UL library enabled" >&2;} dependancy_problem=yes fi fi if test "x$dependancy_problem" = "xyes"; then { { echo "$as_me:$LINENO: error: dependancy problems detected" >&5 echo "$as_me: error: dependancy problems detected" >&2;} { (exit 1); exit 1; }; } fi if test "x$enable_fnt" = "xyes"; then BUILD_FNT_TRUE= BUILD_FNT_FALSE='#' else BUILD_FNT_TRUE='#' BUILD_FNT_FALSE= fi if test "x$enable_js" = "xyes"; then BUILD_JS_TRUE= BUILD_JS_FALSE='#' else BUILD_JS_TRUE='#' BUILD_JS_FALSE= fi if test "x$enable_pw" = "xyes"; then BUILD_PW_TRUE= BUILD_PW_FALSE='#' else BUILD_PW_TRUE='#' BUILD_PW_FALSE= fi if test "x$enable_net" = "xyes"; then BUILD_NET_TRUE= BUILD_NET_FALSE='#' else BUILD_NET_TRUE='#' BUILD_NET_FALSE= fi if test "x$enable_pui" = "xyes"; then BUILD_PUI_TRUE= BUILD_PUI_FALSE='#' else BUILD_PUI_TRUE='#' BUILD_PUI_FALSE= fi if test "x$enable_puaux" = "xyes"; then BUILD_PUAUX_TRUE= BUILD_PUAUX_FALSE='#' else BUILD_PUAUX_TRUE='#' BUILD_PUAUX_FALSE= fi if test "x$enable_sg" = "xyes"; then BUILD_SG_TRUE= BUILD_SG_FALSE='#' else BUILD_SG_TRUE='#' BUILD_SG_FALSE= fi if test "x$enable_psl" = "xyes"; then BUILD_PSL_TRUE= BUILD_PSL_FALSE='#' else BUILD_PSL_TRUE='#' BUILD_PSL_FALSE= fi if test "x$enable_sl" = "xyes"; then BUILD_SL_TRUE= BUILD_SL_FALSE='#' else BUILD_SL_TRUE='#' BUILD_SL_FALSE= fi if test "x$enable_ssg" = "xyes"; then BUILD_SSG_TRUE= BUILD_SSG_FALSE='#' else BUILD_SSG_TRUE='#' BUILD_SSG_FALSE= fi if test "x$enable_ssgaux" = "xyes"; then BUILD_SSGAUX_TRUE= BUILD_SSGAUX_FALSE='#' else BUILD_SSGAUX_TRUE='#' BUILD_SSGAUX_FALSE= fi if test "x$enable_ul" = "xyes"; then BUILD_UL_TRUE= BUILD_UL_FALSE='#' else BUILD_UL_TRUE='#' BUILD_UL_FALSE= fi if test "x$need_opengl" = "xyes" && test "x$GL_PREFIX" != "xauto"; then LDFLAGS="$LDFLAGS -L$GL_PREFIX/lib" CPPFLAGS="$CPPFLAGS -I$GL_PREFIX/include" fi # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; 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 { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; 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 case "${host}" in *-*-cygwin* | *-*-mingw32*) LIBS="$LIBS -lwinmm" if test "x$need_opengl" = "xyes"; then LIBS="$LIBS -lopengl32" fi ;; *-apple-darwin*) if test "x$need_opengl" = "xyes"; then LIBS="$LIBS -framework OpenGL" fi LIBS="$LIBS -framework Carbon" ;; *) if test "x$need_opengl" = "xyes"; then { echo "$as_me:$LINENO: checking for X" >&5 echo $ECHO_N "checking for X... $ECHO_C" >&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 #( *\'*) { { echo "$as_me:$LINENO: error: Cannot use X directory names containing '" >&5 echo "$as_me: error: Cannot use X directory names containing '" >&2;} { (exit 1); exit 1; }; };; #( *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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; 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 | /lib) ;; *) 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/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # We can compile using X headers with no special include directory. ac_x_includes= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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.$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="-lXt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS=$ac_save_LIBS for ac_dir in `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; do if test -r "$ac_dir/libXt.$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 { echo "$as_me:$LINENO: result: $have_x" >&5 echo "${ECHO_T}$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'" { echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6; } fi if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. cat >>confdefs.h <<\_ACEOF #define X_DISPLAY_MISSING 1 _ACEOF X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else if test -n "$x_includes"; then X_CFLAGS="$X_CFLAGS -I$x_includes" fi # It would also be nice to do this for all -L options, not just this one. if test -n "$x_libraries"; then X_LIBS="$X_LIBS -L$x_libraries" # For Solaris; some versions of Sun CC require a space after -R and # others require no space. Words are not sufficient . . . . case `(uname -sr) 2>/dev/null` in "SunOS 5"*) { echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5 echo $ECHO_N "checking whether -R must be followed by a space... $ECHO_C" >&6; } ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_R_nospace=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_R_nospace=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test $ac_R_nospace = yes; then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } X_LIBS="$X_LIBS -R$x_libraries" else LIBS="$ac_xsave_LIBS -R $x_libraries" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_R_space=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_R_space=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test $ac_R_space = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } X_LIBS="$X_LIBS -R $x_libraries" else { echo "$as_me:$LINENO: result: neither works" >&5 echo "${ECHO_T}neither works" >&6; } fi fi LIBS=$ac_xsave_LIBS esac fi # Check for system-dependent libraries X programs must link with. # Do this before checking for the system-independent R6 libraries # (-lICE), since we may need -lsocket or whatever for X linking. if test "$ISC" = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" else # Martyn Johnson says this is needed for Ultrix, if the X # libraries were built with DECnet support. And Karl Berry says # the Alpha needs dnet_stub (dnet does not exist). ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 XOpenDisplay (); int main () { return XOpenDisplay (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5 echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6; } if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dnet_dnet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dnet_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6; } if test $ac_cv_lib_dnet_dnet_ntoa = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5 echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6; } if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet_stub $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dnet_stub_dnet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dnet_stub_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_xsave_LIBS" # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, # to get the SysV transport functions. # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) # needs -lnsl. # The nsl library prevents programs from opening the X display # on Irix 5.2, according to T.E. Dickey. # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. { echo "$as_me:$LINENO: checking for gethostbyname" >&5 echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6; } if test "${ac_cv_func_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define gethostbyname to an innocuous variant, in case declares gethostbyname. For example, HP-UX 11i declares gettimeofday. */ #define gethostbyname innocuous_gethostbyname /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef gethostbyname /* 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 gethostbyname (); /* 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_gethostbyname || defined __stub___gethostbyname choke me #endif int main () { return gethostbyname (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6; } if test $ac_cv_func_gethostbyname = no; then { echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6; } if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6; } if test $ac_cv_lib_nsl_gethostbyname = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5 echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6; } if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_bsd_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6; } if test $ac_cv_lib_bsd_gethostbyname = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi fi fi # lieder@skyler.mavd.honeywell.com says without -lsocket, # socket/setsockopt and other routines are undefined under SCO ODT # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary # on later versions), says Simon Leinen: it contains gethostby* # variants that don't use the name server (or something). -lsocket # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. { echo "$as_me:$LINENO: checking for connect" >&5 echo $ECHO_N "checking for connect... $ECHO_C" >&6; } if test "${ac_cv_func_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define connect to an innocuous variant, in case declares connect. For example, HP-UX 11i declares gettimeofday. */ #define connect innocuous_connect /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef connect /* 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 connect (); /* 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_connect || defined __stub___connect choke me #endif int main () { return connect (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 echo "${ECHO_T}$ac_cv_func_connect" >&6; } if test $ac_cv_func_connect = no; then { echo "$as_me:$LINENO: checking for connect in -lsocket" >&5 echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6; } if test "${ac_cv_lib_socket_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 connect (); int main () { return connect (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5 echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6; } if test $ac_cv_lib_socket_connect = yes; then X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi fi # Guillermo Gomez says -lposix is necessary on A/UX. { echo "$as_me:$LINENO: checking for remove" >&5 echo $ECHO_N "checking for remove... $ECHO_C" >&6; } if test "${ac_cv_func_remove+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define remove to an innocuous variant, in case declares remove. For example, HP-UX 11i declares gettimeofday. */ #define remove innocuous_remove /* System header to define __stub macros and hopefully few prototypes, which can conflict with char remove (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef remove /* 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 remove (); /* 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_remove || defined __stub___remove choke me #endif int main () { return remove (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_remove=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_remove=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5 echo "${ECHO_T}$ac_cv_func_remove" >&6; } if test $ac_cv_func_remove = no; then { echo "$as_me:$LINENO: checking for remove in -lposix" >&5 echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6; } if test "${ac_cv_lib_posix_remove+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 remove (); int main () { return remove (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_posix_remove=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_posix_remove=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5 echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6; } if test $ac_cv_lib_posix_remove = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. { echo "$as_me:$LINENO: checking for shmat" >&5 echo $ECHO_N "checking for shmat... $ECHO_C" >&6; } if test "${ac_cv_func_shmat+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shmat to an innocuous variant, in case declares shmat. For example, HP-UX 11i declares gettimeofday. */ #define shmat innocuous_shmat /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shmat (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shmat /* 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 shmat (); /* 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_shmat || defined __stub___shmat choke me #endif int main () { return shmat (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_shmat=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shmat=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5 echo "${ECHO_T}$ac_cv_func_shmat" >&6; } if test $ac_cv_func_shmat = no; then { echo "$as_me:$LINENO: checking for shmat in -lipc" >&5 echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6; } if test "${ac_cv_lib_ipc_shmat+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 shmat (); int main () { return shmat (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ipc_shmat=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ipc_shmat=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5 echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6; } if test $ac_cv_lib_ipc_shmat = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi fi fi # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS=$LDFLAGS test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # John Interrante, Karl Berry { echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5 echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6; } if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 IceConnectionNumber (); int main () { return IceConnectionNumber (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ICE_IceConnectionNumber=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ICE_IceConnectionNumber=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6; } if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi LDFLAGS=$ac_save_LDFLAGS fi LDFLAGS="$LDFLAGS $X_LIBS" LIBS="$LIBS $X_PRE_LIBS -lXi -lXmu -lXext -lX11 $X_EXTRA_LIBS -lm" { echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6; } if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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_create (); int main () { return pthread_create (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_create=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6; } if test $ac_cv_lib_pthread_pthread_create = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" fi { echo "$as_me:$LINENO: checking for glNewList in -lGL" >&5 echo $ECHO_N "checking for glNewList in -lGL... $ECHO_C" >&6; } if test "${ac_cv_lib_GL_glNewList+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lGL $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 glNewList (); int main () { return glNewList (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_GL_glNewList=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_GL_glNewList=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_GL_glNewList" >&5 echo "${ECHO_T}$ac_cv_lib_GL_glNewList" >&6; } if test $ac_cv_lib_GL_glNewList = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBGL 1 _ACEOF LIBS="-lGL $LIBS" fi if test "x$ac_cv_lib_GL_glNewList" = "xno" ; then { echo "$as_me:$LINENO: checking for glNewList in -lMesaGL" >&5 echo $ECHO_N "checking for glNewList in -lMesaGL... $ECHO_C" >&6; } if test "${ac_cv_lib_MesaGL_glNewList+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lMesaGL $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 glNewList (); int main () { return glNewList (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_MesaGL_glNewList=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_MesaGL_glNewList=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_MesaGL_glNewList" >&5 echo "${ECHO_T}$ac_cv_lib_MesaGL_glNewList" >&6; } if test $ac_cv_lib_MesaGL_glNewList = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBMESAGL 1 _ACEOF LIBS="-lMesaGL $LIBS" else { { echo "$as_me:$LINENO: error: could not find working GL library" >&5 echo "$as_me: error: could not find working GL library" >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: checking for dlclose in -ldl" >&5 echo $ECHO_N "checking for dlclose in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlclose+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 dlclose (); int main () { return dlclose (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlclose=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlclose=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlclose" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlclose" >&6; } if test $ac_cv_lib_dl_dlclose = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { echo "$as_me:$LINENO: checking for ALopenport in -laudio" >&5 echo $ECHO_N "checking for ALopenport in -laudio... $ECHO_C" >&6; } if test "${ac_cv_lib_audio_ALopenport+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-laudio $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 ALopenport (); int main () { return ALopenport (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_audio_ALopenport=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_audio_ALopenport=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_audio_ALopenport" >&5 echo "${ECHO_T}$ac_cv_lib_audio_ALopenport" >&6; } if test $ac_cv_lib_audio_ALopenport = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBAUDIO 1 _ACEOF LIBS="-laudio $LIBS" fi ;; esac { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else 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" { test -f "$ac_path_GREP" && $as_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 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" 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 ac_count=`expr $ac_count + 1` 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 fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else 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" { test -f "$ac_path_EGREP" && $as_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 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" 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 ac_count=`expr $ac_count + 1` 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 fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "${ac_cv_header_windows_h+set}" = set; then { echo "$as_me:$LINENO: checking for windows.h" >&5 echo $ECHO_N "checking for windows.h... $ECHO_C" >&6; } if test "${ac_cv_header_windows_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_windows_h" >&5 echo "${ECHO_T}$ac_cv_header_windows_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking windows.h usability" >&5 echo $ECHO_N "checking windows.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking windows.h presence" >&5 echo $ECHO_N "checking windows.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: windows.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: windows.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: windows.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: windows.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: windows.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: windows.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: windows.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: windows.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: windows.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: windows.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: windows.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: windows.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: windows.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: windows.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: windows.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: windows.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for windows.h" >&5 echo $ECHO_N "checking for windows.h... $ECHO_C" >&6; } if test "${ac_cv_header_windows_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_windows_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_windows_h" >&5 echo "${ECHO_T}$ac_cv_header_windows_h" >&6; } fi if test $ac_cv_header_windows_h = yes; then cat >>confdefs.h <<\_ACEOF #define WIN32 1 _ACEOF fi if test "x$need_opengl" = "xyes"; then case "${host}" in *-*-cygwin* | *-*-mingw32*) if test "${ac_cv_header_GL_gl_h+set}" = set; then { echo "$as_me:$LINENO: checking for GL/gl.h" >&5 echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6; } if test "${ac_cv_header_GL_gl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_GL_gl_h" >&5 echo "${ECHO_T}$ac_cv_header_GL_gl_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking GL/gl.h usability" >&5 echo $ECHO_N "checking GL/gl.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking GL/gl.h presence" >&5 echo $ECHO_N "checking GL/gl.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: GL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: GL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: GL/gl.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: GL/gl.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: GL/gl.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: GL/gl.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: GL/gl.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: GL/gl.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: GL/gl.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: GL/gl.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for GL/gl.h" >&5 echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6; } if test "${ac_cv_header_GL_gl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_GL_gl_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_GL_gl_h" >&5 echo "${ECHO_T}$ac_cv_header_GL_gl_h" >&6; } fi if test $ac_cv_header_GL_gl_h = yes; then : else { { echo "$as_me:$LINENO: error: OpenGL header file not found" >&5 echo "$as_me: error: OpenGL header file not found" >&2;} { (exit 1); exit 1; }; } fi ;; *-apple-darwin*) if test "${ac_cv_header_OpenGL_gl_h+set}" = set; then { echo "$as_me:$LINENO: checking for OpenGL/gl.h" >&5 echo $ECHO_N "checking for OpenGL/gl.h... $ECHO_C" >&6; } if test "${ac_cv_header_OpenGL_gl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_OpenGL_gl_h" >&5 echo "${ECHO_T}$ac_cv_header_OpenGL_gl_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking OpenGL/gl.h usability" >&5 echo $ECHO_N "checking OpenGL/gl.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking OpenGL/gl.h presence" >&5 echo $ECHO_N "checking OpenGL/gl.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: OpenGL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: OpenGL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: OpenGL/gl.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: OpenGL/gl.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: OpenGL/gl.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: OpenGL/gl.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: OpenGL/gl.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: OpenGL/gl.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: OpenGL/gl.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: OpenGL/gl.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: OpenGL/gl.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: OpenGL/gl.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: OpenGL/gl.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: OpenGL/gl.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: OpenGL/gl.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: OpenGL/gl.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for OpenGL/gl.h" >&5 echo $ECHO_N "checking for OpenGL/gl.h... $ECHO_C" >&6; } if test "${ac_cv_header_OpenGL_gl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_OpenGL_gl_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_OpenGL_gl_h" >&5 echo "${ECHO_T}$ac_cv_header_OpenGL_gl_h" >&6; } fi if test $ac_cv_header_OpenGL_gl_h = yes; then : else { { echo "$as_me:$LINENO: error: OpenGL header file not found" >&5 echo "$as_me: error: OpenGL header file not found" >&2;} { (exit 1); exit 1; }; } fi ;; *) if test "${ac_cv_header_GL_gl_h+set}" = set; then { echo "$as_me:$LINENO: checking for GL/gl.h" >&5 echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6; } if test "${ac_cv_header_GL_gl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_GL_gl_h" >&5 echo "${ECHO_T}$ac_cv_header_GL_gl_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking GL/gl.h usability" >&5 echo $ECHO_N "checking GL/gl.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking GL/gl.h presence" >&5 echo $ECHO_N "checking GL/gl.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: GL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: GL/gl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: GL/gl.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: GL/gl.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: GL/gl.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: GL/gl.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: GL/gl.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: GL/gl.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: GL/gl.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: GL/gl.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: GL/gl.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for GL/gl.h" >&5 echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6; } if test "${ac_cv_header_GL_gl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_GL_gl_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_GL_gl_h" >&5 echo "${ECHO_T}$ac_cv_header_GL_gl_h" >&6; } fi if test $ac_cv_header_GL_gl_h = yes; then : else { { echo "$as_me:$LINENO: error: OpenGL header file not found" >&5 echo "$as_me: error: OpenGL header file not found" >&2;} { (exit 1); exit 1; }; } fi ;; esac fi WFLAG="-Wall" case "$host" in mips-sgi-irix*) if test "x$CXX" = "xCC"; then WFLAG="-fullwarn"; fi ;; *) if test "x$CXX" = "xicpc" || test "x$CXX" = "xicc"; then WFLAG="-w1" fi if test "x$GCC" != xyes; then # if the compiler is not GCC we reset WFLAG to null for safety WFLAG="" fi ;; esac CFLAGS="$CFLAGS $WFLAG" CXXFLAGS="$CXXFLAGS $WFLAG" save_CXXFLAGS="$CXXFLAGS" save_CFLAGS="$CFLAGS" save_LIBS=$LIBS CXXFLAGS="-pthread $CXXFLAGS" CFLAGS="-pthread $CFLAGS" { echo "$as_me:$LINENO: checking for pthread_exit in -lc_r" >&5 echo $ECHO_N "checking for pthread_exit in -lc_r... $ECHO_C" >&6; } if test "${ac_cv_lib_c_r_pthread_exit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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_exit (); int main () { return pthread_exit (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_r_pthread_exit=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_r_pthread_exit=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_exit" >&5 echo "${ECHO_T}$ac_cv_lib_c_r_pthread_exit" >&6; } if test $ac_cv_lib_c_r_pthread_exit = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBC_R 1 _ACEOF LIBS="-lc_r $LIBS" fi if test "x$ac_cv_lib_c_r_pthread_exit" != "xyes"; then CFLAGS=$save_CFLAGS CXXFLAGS=$save_CXXFLAGS fi LIBS=$save_LIBS { echo "$as_me:$LINENO: checking for socklen_t" >&5 echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include socklen_t apa; int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int accept (int, struct sockaddr *, size_t *); int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: size_t" >&5 echo "${ECHO_T}size_t" >&6; } cat >>confdefs.h <<\_ACEOF #define socklen_t size_t _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: int" >&5 echo "${ECHO_T}int" >&6; } cat >>confdefs.h <<\_ACEOF #define socklen_t int _ACEOF 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_config_files="$ac_config_files Makefile src/Makefile src/js/Makefile src/util/Makefile src/sg/Makefile src/sl/Makefile src/psl/Makefile src/ssg/Makefile src/ssgAux/Makefile src/fnt/Makefile src/pui/Makefile src/puAux/Makefile src/pw/Makefile src/net/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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_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 test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 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}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= 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=`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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_FNT_TRUE}" && test -z "${BUILD_FNT_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_FNT\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_FNT\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_JS_TRUE}" && test -z "${BUILD_JS_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_JS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_JS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_PW_TRUE}" && test -z "${BUILD_PW_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_PW\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_PW\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_NET_TRUE}" && test -z "${BUILD_NET_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_NET\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_NET\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_PUI_TRUE}" && test -z "${BUILD_PUI_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_PUI\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_PUI\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_PUAUX_TRUE}" && test -z "${BUILD_PUAUX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_PUAUX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_PUAUX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_SG_TRUE}" && test -z "${BUILD_SG_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_SG\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_SG\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_PSL_TRUE}" && test -z "${BUILD_PSL_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_PSL\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_PSL\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_SL_TRUE}" && test -z "${BUILD_SL_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_SL\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_SL\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_SSG_TRUE}" && test -z "${BUILD_SSG_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_SSG\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_SSG\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_SSGAUX_TRUE}" && test -z "${BUILD_SSGAUX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_SSGAUX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_SSGAUX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BUILD_UL_TRUE}" && test -z "${BUILD_UL_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BUILD_UL\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BUILD_UL\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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 BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # PATH needs CR # 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 # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. 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 echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. 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 # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 fi echo >conf$$.file 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # Find out whether ``test -x'' works. Don't use a zero-byte file, as # systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then as_executable_p="test -x" else as_executable_p=: fi rm -f conf$$.file # 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 # 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 $as_me, which was generated by GNU Autoconf 2.60. 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 cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet 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 Configuration files: $config_files Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.60, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 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' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. 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=$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 ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) 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. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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 if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/js/Makefile") CONFIG_FILES="$CONFIG_FILES src/js/Makefile" ;; "src/util/Makefile") CONFIG_FILES="$CONFIG_FILES src/util/Makefile" ;; "src/sg/Makefile") CONFIG_FILES="$CONFIG_FILES src/sg/Makefile" ;; "src/sl/Makefile") CONFIG_FILES="$CONFIG_FILES src/sl/Makefile" ;; "src/psl/Makefile") CONFIG_FILES="$CONFIG_FILES src/psl/Makefile" ;; "src/ssg/Makefile") CONFIG_FILES="$CONFIG_FILES src/ssg/Makefile" ;; "src/ssgAux/Makefile") CONFIG_FILES="$CONFIG_FILES src/ssgAux/Makefile" ;; "src/fnt/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnt/Makefile" ;; "src/pui/Makefile") CONFIG_FILES="$CONFIG_FILES src/pui/Makefile" ;; "src/puAux/Makefile") CONFIG_FILES="$CONFIG_FILES src/puAux/Makefile" ;; "src/pw/Makefile") CONFIG_FILES="$CONFIG_FILES src/pw/Makefile" ;; "src/net/Makefile") CONFIG_FILES="$CONFIG_FILES src/net/Makefile" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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_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= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim CYGPATH_W!$CYGPATH_W$ac_delim PACKAGE!$PACKAGE$ac_delim VERSION!$VERSION$ac_delim ACLOCAL!$ACLOCAL$ac_delim AUTOCONF!$AUTOCONF$ac_delim AUTOMAKE!$AUTOMAKE$ac_delim AUTOHEADER!$AUTOHEADER$ac_delim MAKEINFO!$MAKEINFO$ac_delim install_sh!$install_sh$ac_delim STRIP!$STRIP$ac_delim INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim mkdir_p!$mkdir_p$ac_delim AWK!$AWK$ac_delim SET_MAKE!$SET_MAKE$ac_delim am__leading_dot!$am__leading_dot$ac_delim AMTAR!$AMTAR$ac_delim am__tar!$am__tar$ac_delim am__untar!$am__untar$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim DEPDIR!$DEPDIR$ac_delim am__include!$am__include$ac_delim am__quote!$am__quote$ac_delim AMDEP_TRUE!$AMDEP_TRUE$ac_delim AMDEP_FALSE!$AMDEP_FALSE$ac_delim AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim CCDEPMODE!$CCDEPMODE$ac_delim am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim CPP!$CPP$ac_delim CXX!$CXX$ac_delim CXXFLAGS!$CXXFLAGS$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim CXXDEPMODE!$CXXDEPMODE$ac_delim am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim CXXCPP!$CXXCPP$ac_delim RANLIB!$RANLIB$ac_delim BUILD_FNT_TRUE!$BUILD_FNT_TRUE$ac_delim BUILD_FNT_FALSE!$BUILD_FNT_FALSE$ac_delim BUILD_JS_TRUE!$BUILD_JS_TRUE$ac_delim BUILD_JS_FALSE!$BUILD_JS_FALSE$ac_delim BUILD_PW_TRUE!$BUILD_PW_TRUE$ac_delim BUILD_PW_FALSE!$BUILD_PW_FALSE$ac_delim BUILD_NET_TRUE!$BUILD_NET_TRUE$ac_delim BUILD_NET_FALSE!$BUILD_NET_FALSE$ac_delim BUILD_PUI_TRUE!$BUILD_PUI_TRUE$ac_delim BUILD_PUI_FALSE!$BUILD_PUI_FALSE$ac_delim BUILD_PUAUX_TRUE!$BUILD_PUAUX_TRUE$ac_delim BUILD_PUAUX_FALSE!$BUILD_PUAUX_FALSE$ac_delim BUILD_SG_TRUE!$BUILD_SG_TRUE$ac_delim BUILD_SG_FALSE!$BUILD_SG_FALSE$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF BUILD_PSL_TRUE!$BUILD_PSL_TRUE$ac_delim BUILD_PSL_FALSE!$BUILD_PSL_FALSE$ac_delim BUILD_SL_TRUE!$BUILD_SL_TRUE$ac_delim BUILD_SL_FALSE!$BUILD_SL_FALSE$ac_delim BUILD_SSG_TRUE!$BUILD_SSG_TRUE$ac_delim BUILD_SSG_FALSE!$BUILD_SSG_FALSE$ac_delim BUILD_SSGAUX_TRUE!$BUILD_SSGAUX_TRUE$ac_delim BUILD_SSGAUX_FALSE!$BUILD_SSGAUX_FALSE$ac_delim BUILD_UL_TRUE!$BUILD_UL_TRUE$ac_delim BUILD_UL_FALSE!$BUILD_UL_FALSE$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim XMKMF!$XMKMF$ac_delim X_CFLAGS!$X_CFLAGS$ac_delim X_PRE_LIBS!$X_PRE_LIBS$ac_delim X_LIBS!$X_LIBS$ac_delim X_EXTRA_LIBS!$X_EXTRA_LIBS$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 27; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ 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[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :C $CONFIG_COMMANDS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[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="$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 || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$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 "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; 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 || 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`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 || 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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`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 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # 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= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF 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 sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;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 $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 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 "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; 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. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /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 || 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"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //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' -e 's/\$U/'"$U"'/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 || 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 case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`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 || 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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # 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 || { (exit 1); exit 1; } fi { echo "$as_me:$LINENO: result: PLIB configuration information: Building FNT library: $enable_fnt Building JS library: $enable_js Building NET library: $enable_net Building PUI library: $enable_pui Building puAux library: $enable_puaux Building SG library: $enable_sg Building PSL library: $enable_psl Building SL library: $enable_sl Building SSG library: $enable_ssg Building ssgAux library: $enable_ssgaux Building PW library: $enable_pw Building UTIL library: $enable_ul " >&5 echo "${ECHO_T}PLIB configuration information: Building FNT library: $enable_fnt Building JS library: $enable_js Building NET library: $enable_net Building PUI library: $enable_pui Building puAux library: $enable_puaux Building SG library: $enable_sg Building PSL library: $enable_psl Building SL library: $enable_sl Building SSG library: $enable_ssg Building ssgAux library: $enable_ssgaux Building PW library: $enable_pw Building UTIL library: $enable_ul " >&6; } plib-1.8.5/NEWS0000644000175000001440000000023210765364452010100 00000000000000Fri Oct 13 16:54:04 CEST 2006 Moved from SF CVS to SF SVN. To grab a copy from svn, use this command: $ svn co https://svn.sf.net/svnroot/plib/trunk plib plib-1.8.5/KNOWN_BUGS0000644000175000001440000000174410765364452011051 00000000000000Known bugs and limitations in PLIB version 1.8.x More in depth stuff can be found in TODO_AFTER135. * ssgLOS is really broken. * ssgStripify and ssgFlatten might well have bugs in them. A known bug of ssgStripify is that : since it rearranges and merges leaf nodes, ssgSelectors are messed up * Sometimes cr*p values appear in 3D files, for example .ac files. The reason seems to be that sometimes the loader handles colours differently than the writer. * Several, general smalish .MDL loader bugs are known; Look in TODO_AFTER135 * Scaling does not work (intentionally). Uniform scaling may be enabled by uncommenting "radius *= sgLengthVec3(m[0])" in sgSphere::orthoXform. It is currently disabled because that extra calculation would degrade performance on non-scaled matrices. Scaling really makes a mess of SSG bounding sphere tests * .ssg files should not be used for long term storage. It will probably change in incompatible ways. plib-1.8.5/missing0000755000175000001440000002540610532024455010776 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2005-06-08.21 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # Originally 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, 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. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] 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 # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case "$1" in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: plib-1.8.5/plib.dsp0000644000175000001440000000331110765364452011040 00000000000000# Microsoft Developer Studio Project File - Name="plib" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Generic Project" 0x010a CFG=plib - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "plib.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "plib.mak" CFG="plib - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "plib - Win32 Release" (based on "Win32 (x86) Generic Project") !MESSAGE "plib - Win32 Debug" (based on "Win32 (x86) Generic Project") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 MTL=midl.exe !IF "$(CFG)" == "plib - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" !ELSEIF "$(CFG)" == "plib - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "plib___Win32_Debug" # PROP BASE Intermediate_Dir "plib___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" !ENDIF # Begin Target # Name "plib - Win32 Release" # Name "plib - Win32 Debug" # End Target # End Project plib-1.8.5/autogen.sh0000755000175000001440000000061610765364452011410 00000000000000#!/bin/sh OSTYPE=`uname -s` AMFLAGS="--add-missing" if test "$OSTYPE" = "IRIX" -o "$OSTYPE" = "IRIX64"; then AMFLAGS=$AMFLAGS" --include-deps"; fi echo "Running aclocal" aclocal echo "Running automake" automake $AMFLAGS echo "Running autoconf" autoconf echo "======================================" echo "Now you are ready to run './configure'" echo "======================================" plib-1.8.5/README.GLUT0000644000175000001440000000005510765364452011036 00000000000000 PUI no longer depends on GLUT or freeglut. plib-1.8.5/NOTICE0000644000175000001440000000207510765364452010314 00000000000000NOTICE: The PLIB Portable Interactive Applications Library distribution contains source code that is released as OpenSource under the GNU Library Public License. These programs are thus freely distributable without licensing fees. These programs are provided without guarantee or warrantee expressed or implied. If you use PLIB in a commercial or shareware product, it would be nice if you gave credit where it is due. If you make any neat modifications or improvements to PLIB, I would greatly appreciate a copy of the improved code or at least a source patch. Note that PLIB uses an addition to the LGPL: As a special exception Steve Baker gives permission to link these libraries with proprietary software and distribute the resulting executable without including that proprietary code in any distribution as the LGPL would normally dictate. This exception is ONLY granted in the case of an embedded system in which there is no possibility of an end user re-linking or recompiling against new versions of this library that may appear in the future." plib-1.8.5/README0000644000175000001440000001157410765364452010274 00000000000000 Portability Libraries. ====================== by Steve Baker. All the documentation and installation instructions are now online at: http://plib.sourceforge.net They are also downloadable - along with example programs and demos from the same site. SUPPORT: Please don't email me (Steve Baker) directly - I get *WAY* too much mail as it is! Instead, please sign up to the PLIB user's mailing list. Instructions can be found here: http://plib.sourceforge.net LICENSING: These libraries are offered as OpenSource freeware under the provisions of the GNU Library Public License (LGPL). Those terms and conditions are detailed in the file 'LICENSE' in this directory. I have added a short preamble to LGPL that removes no rights from ordinary users but offers special dispensation to allow PLIB to be used under certain commercial conditions (such as Games Consoles) where the constraints of LGPL are impossible to meet. | As a special exception Steve Baker gives permission to link these | libraries with proprietary software and distribute the resulting | executable without including that proprietary code in any distribution | as the LGPL would normally dictate. | | This exception is ONLY granted in the case of an embedded system in | which there is no possibility of an end user re-linking or recompiling | against new versions of this library that may appear in the future. REQUIREMENTS: In addition to the libraries that I provide, you will also need OpenGL (OpenGL 1.1 or later - Mesa 3.0 or later) and GLUT (The OpenGL utilities toolkit - version 3.7 or later) and a hardware 3D graphics accellerator that supports OpenGL. WHAT DO YOU GET? The following libraries are provided: JS -- A Joystick interface. PUI -- A simple GUI built on top of OpenGL. SG -- Some Standard Geometry functions (vector and matrix math, spheres, boxes, frustra, etc) SL -- A Games-oriented Sound Library. FNT -- OpenGL texture-mapped font Library. PW -- A minimalist windowing library. PSL -- A C-like scripting language. SSG -- A Simple Scene Graph API built on top of OpenGL. NET -- Some Networking functions for games. UTIL-- Utilities - things that your OS would normally handle - but these functions are portable. SSGAUX -- Some optional additional high level features for SSG PUIAUX -- Some optional additional high level features for PUI DIRECTORY STRUCTURE: PLIB expects to be installed in one standard place: /usr/lib ...with header files at: /usr/include/plib PORTABILITY and DEPENDANCIES: Although all these libraries are designed to be easily portable (and more importantly so that programs using them can be UTTERLY portable), some of them have not yet been ported to all operating systems. JS -- Currently Linux/Windows/BSD only. UL -- Should be portable to POSIX-compliant OS's ... and Windows. SG -- Totally portable, no dependancies. PUI -- Requires OpenGL also FNT and SG. PUI also requires some kind of windowing library - which could be PW - or GLUT, freeglut, SDL, FLTK - or others. PSL -- Requires UL. PW -- Requires UL. NET -- Should be portable to POSIX-compliant OS's. FNT and SSG -- Require OpenGL, SG and UL. SSGAUX -- Requires SSG - and hence OpenGL, SG and UL. PUIAUX -- Requires PUI - and hence FNT and SG. SL -- This has now been ported onto: Linux FreeBSD OpenBSD M$ Windows (NT,95,98 - so far) MacOS SGI IRIX Sun Solaris Any operating system that supports OSS (The Open Sound System). NOTE: SL has a subsidiary library 'SM' that can be used to control the audio mixer - but that is not portable beyond Linux. You might get it to work under OSS-based sound systems too. Don't use SM if you want to write portable code. No other requirements. AUX LIBRARIES AND TOOLS: The 'tools' directory contains a number of useful tools and utility programs that are either built using PLIB or which are specifically useful when writing PLIB programs. COMPILING/LINKING WITH PLIB In your source code, add any combination of: #include #include #include #include #include #include #include #include #include #include #include #include Add any of these to your link line: -lplibjs -lplibssgaux -lplibssg -lplibsl -lplibpu -lplibpuaux -lplibpw -lplibpsl -lplibfnt -lplibnet -lplibsg -lplibul Under UNIX/Linux, you'll also need: -lGLU -lGL -L/usr/X11/lib -lX11 -lXext -lXmu -lm ...and perhaps a -l for whatever windowing library you're using - unless it's the built-in PW library. Steve Baker. http://www.sjbaker.org plib-1.8.5/COPYING0000644000175000001440000006245710765364452010455 00000000000000 SPECIAL NOTICE: As a special exception Steve Baker gives permission to link these libraries with proprietary software and distribute the resulting executable without including that proprietary code in any distribution as the LGPL would normally dictate. This exception is ONLY granted in the case of an embedded system in which there is no possibility of an end user re-linking or recompiling against new versions of this library that may appear in the future. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, 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 library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, 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 companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Library 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! plib-1.8.5/config.sub0000755000175000001440000007724210532024455011367 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. timestamp='2006-05-13' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # 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 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. # # 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. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # 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. # 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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 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-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) 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) os= basic_machine=$1 ;; -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*) 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 \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[24]a | 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 | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-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-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | 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-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; # 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 ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; 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 ;; cr16c) basic_machine=cr16c-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 ;; 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'm not sure what "Sysv32" means. Should this be sysv3.2? 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 ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; 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-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; 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 ;; 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 ;; 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) basic_machine=powerpc-unknown ;; ppc-*) 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) 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 ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; 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 ;; 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 ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; 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 ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-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[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. -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* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -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* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -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*) # 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 ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -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 spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) 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 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) 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 ;; -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: plib-1.8.5/Makefile.am0000644000175000001440000000034010765364452011435 00000000000000SUBDIRS = src EXTRA_DIST = KNOWN_BUGS NOTICE README README.GLUT \ README.win32 README.mac TODO-1.6 TODO-2.0 \ TODO_AFTER135 autogen.sh missing \ plib.dsp plib.dsw transferCvs2WebSite plib-1.8.5/TODO_AFTER1350000644000175000001440000001111010765364452011240 00000000000000 +============+ | TO BE DONE | +============+ A tasks and bugs are now being tracked by sourceforge. Please goto: http://sourceforge.net/projects/plib/ * Have a look into known_bugs and fix them. * Lines in ASCII files are terminated... With '\n' under UNIX/Linux With '\r' under MacOS With BOTH under Windoze. Hence, UNIX/Linux does no conversions of either '\r' or '\n'. and MAC swaps '\r' and '\n' on input. and Windoze dumps '\r' if it follows a '\n'. This is a mess - so I'm changing all the ASCII I/O code to allow either or both '\n' or '\r' and I'm reading the ASCII files in BINARY mode. * Array deletion requires '[]' after 'delete' on Mac. * Some of the MSVC-project files for plib_examples seem to be broken, for example some miss a "winmm.lib". * Check whether the new ssgStripify works with TuxKart See Steves post from 11.12.2000 15:12 for a problem description The abbreviation NIV14 means not in Version 1.4. Bugs: ===== - When creating fgfsTux, sometimes .ac, .dxf, .ase and .obj saved zero objects, although there were objects. For example, PLIB created this .ac file: ----------- snip ------------ AC3Db OBJECT world kids 0 OBJECT group kids 0 ----------- snip ------------ This seems to happen after ssgFlatten. - WK: Create a sphere in ppe. Save it as .ASE. See that values like diffuse colour are cr*p. Try to load it. It crashes. This could be one or - probably - two bugs. I don't think this is a ppe problem. The loader complains that number of faces is -2. The problem seems to be the writer. *new remark*: About the diffuse values: I think it has to do with colour material, a loader (.ASE?) loading colours into a colour list and writing colours from the ssgSimpleState where they are undefined. I think the same bug is in .AC - WK: I have a crash in ssgFlatten if I load .ac files with unused materials (not reproducable?) - Loading and saving lines in .OBJ doesn't work. Maybe NIV14. - Sam wrote: Has anyone here debugged with plib under Windoze 2000 and MSVC++? I get a whole bunch of "Free Heap block modifed after it was free" warnings with the ssgFlatten and ssgStripify. I'll try and hunt this one down. ... I think it may be because I'm using MFC which (if I remember correctly) enables a bunch more memory checks. Also I'm doing #ifdef _WIN32 #ifdef _DEBUG #define new DEBUG_NEW #endif #endif - Not all loaders use ssgLoaderOptions::begin. Don't all have to? - Search for todo, fix, fixme, kludge. Misc: ===== - Look whether scaling works. [see current discussion] If not and if we can't/don't want to make it work, for example because of performance issues we need a warning in the docs and IMHO PLIB should "write out" a warning if an unallowed matrix is sent to it. Update: Scaling does not work (intentionally). Uniform scaling may be enabled by uncommenting "radius *= sgLengthVec3(m[0])" in sgSphere::orthoXform. It is currently disabled because that extra calculation would degrade performance on non-scaled matrices. - Reduce lint warnings. Lint is an error checking tool that gives warnings where things *could be* wrong as opposed to the compiler that tells you where they are wrong. - It would be great if we had one or even two working native .ssg file formats. Currently (16.12.2001) the format work most of the time, but not all entities are implemented. - We should write the GetWrapU/GetWrapV function, since loading /writing .ssg files can't work 100% without it. - When saving, there is often a warning that "ref count doesn't tally with parent count" - Go through the mailing list for unfinished business. - Someone, preferably a native english speaker with ssg-knowledge, should go through the new ssg-doc and fix any mistakes. It should be fairly complete by now. - Add Per's new Formats to the doc? - For the other parts of plib, people should bring the doc up to date. - There is a bug in the 3Dfx driver for Linux (tdfx_dri-4.0.1-1) that causes the "complex" example program to crash in "fxSetupBlend". This is fixed in more recent DRI snapshots (requires kernel 2.4.x). Probably after 1.4.0: ===================== - In fgfsTux, not a large object, you get a DList overflow with the standard values for its size. Can we make its size dynamic? - Look at handling of normals. For example, loaders, stripify etc should only recalculate missing normals. Have *one* function that recalculates normals. It would be nice if people would volunteer for tasks. plib-1.8.5/config.guess0000755000175000001440000012655110532024455011722 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. timestamp='2006-05-13' # 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 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. # # 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 Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. 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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 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_MACHINE}" in i?86) test -z "$VENDOR" && VENDOR=pc ;; *) test -z "$VENDOR" && VENDOR=unknown ;; esac test -f /etc/SuSE-release -o -f /.buildenv && VENDOR=suse # 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 tupples: *-*-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 ;; *) 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 __ELF__ >/dev/null 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 ;; *: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 powerppc-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'` exit ;; 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 ;; 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:SunOS:5.*:*) echo i386-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:*:[45]) 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 __LP64__ >/dev/null 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:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[345]*) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T:Interix*:[345]*) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-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-gnu`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/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-${VENDOR}-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-${VENDOR}-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-${VENDOR}-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-${VENDOR}-linux-gnu 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 ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu${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-${VENDOR}-linux-gnu ;; PA8*) echo hppa2.0-${VENDOR}-linux-gnu ;; *) echo hppa-${VENDOR}-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-${VENDOR}-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-${VENDOR}-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-${VENDOR}-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-${VENDOR}-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-${VENDOR}-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-${VENDOR}-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; 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.0*:*) 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 i386. echo i386-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; } ;; 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.0*:*) 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 ;; 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 ;; 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 case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac 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 ;; 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 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 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: plib-1.8.5/configure.in0000644000175000001440000002603310765364747011730 00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT(src/js/js.h) # **WARNING**WARNING**WARNING**WARNING**WARNING**WARNING** # # When you make a new release, there are TWO places where you # have to change the version number: # 1) Right below this comment. # 2) In 'ul.h' where PLIB_VERSION is created. # # **WARNING**WARNING**WARNING**WARNING**WARNING**WARNING** AM_INIT_AUTOMAKE(plib, 1.8.5) # This AC_PREFIX_DEFAULT will place the library files # into /usr/lib - but will put the include files into # /usr/include - when /usr/include/plib would be less # polluting to the filename space. # # There is probably a better way to do this. AC_PREFIX_DEFAULT(/usr) if echo $includedir | egrep "plib$" > /dev/null; then echo "includedir is" $includedir "libdir is" $libdir else includedir="${includedir}/plib" echo "includedir changed to" $includedir "libdir is" $libdir fi dnl Checks for programs. AC_PROG_CC AC_PROG_CPP AC_PROG_CXX AC_PROG_CXXCPP AC_PROG_INSTALL AC_PROG_RANLIB dnl Command line arguments dnl Don't use AC_HELP_STRING here as old versions of autoconf do not dnl understand it. AC_ARG_WITH(GL, [ --with-GL=DIR set the prefix directory where GL resides], GL_PREFIX=$withval, GL_PREFIX=auto) AC_ARG_ENABLE(fnt, [ --enable-fnt build FNT library (OpenGL needed) default: yes],, enable_fnt=yes) AC_ARG_ENABLE(js, [ --enable-js build JS library default: yes],, enable_js=yes) AC_ARG_ENABLE(pw, [ --enable-pw build PW library default: yes],, enable_pw=yes) AC_ARG_ENABLE(net, [ --enable-net build NET library default: yes],, enable_net=yes) AC_ARG_ENABLE(pui, [ --enable-pui build PUI library (OpenGL needed) default: yes],, enable_pui=yes) AC_ARG_ENABLE(sg, [ --enable-sg build SG library default: yes],, enable_sg=yes) AC_ARG_ENABLE(psl, [ --enable-psl build PSL library default: yes],, enable_psl=yes) AC_ARG_ENABLE(sl, [ --enable-sl build SL library default: yes],, enable_sl=yes) AC_ARG_ENABLE(ssg, [ --enable-ssg build SSG library (OpenGL needed) default: yes],, enable_ssg=yes) AC_ARG_ENABLE(puaux, [ --enable-puaux build puAux library (OpenGL needed) default: yes],, enable_puaux=yes) AC_ARG_ENABLE(ssgaux, [ --enable-ssgaux build ssgAux library (OpenGL needed) default: yes],, enable_ssgaux=yes) AC_ARG_ENABLE(ul, [ --enable-ul build UTIL library default: yes],, enable_ul=yes) dnl Dependancy checking if test "x$enable_fnt" = "xyes"; then need_opengl=yes if test "x$enable_sg" = "xno"; then AC_MSG_WARN([cannot build FNT library without SG library enabled]) dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build FNT library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_pw" = "xyes"; then if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build PW library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_js" = "xyes"; then if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build JS library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_net" = "xyes"; then if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build NET library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_pui" = "xyes"; then need_opengl=yes if test "x$enable_fnt" = "xno"; then AC_MSG_WARN([cannot build PUI library without FNT library enabled]) dependancy_problem=yes fi if test "x$enable_sg" = "xno"; then AC_MSG_WARN([cannot build PUI library without SG library enabled]) dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build PUI library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_sg" = "xyes"; then if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build SG library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_psl" = "xyes"; then if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build PSL library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_sl" = "xyes"; then if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build SL library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_ssg" = "xyes"; then need_opengl=yes if test "x$enable_sg" = "xno"; then AC_MSG_WARN([cannot build SSG library without SG library enabled]) dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build SSG library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_puaux" = "xyes"; then need_opengl=yes if test "x$enable_pui" = "xno"; then AC_MSG_WARN([cannot build puAux library without PUI library enabled]) dependancy_problem=yes fi if test "x$enable_sg" = "xno"; then AC_MSG_WARN([cannot build puAux library without SG library enabled]) dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build puAux library without UL library enabled]) dependancy_problem=yes fi fi if test "x$enable_ssgaux" = "xyes"; then need_opengl=yes if test "x$enable_ssg" = "xno"; then AC_MSG_WARN([cannot build ssgAux library without SSG library enabled]) dependancy_problem=yes fi if test "x$enable_sg" = "xno"; then AC_MSG_WARN([cannot build ssgAux library without SG library enabled]) dependancy_problem=yes fi if test "x$enable_ul" = "xno"; then AC_MSG_WARN([cannot build ssgAux library without UL library enabled]) dependancy_problem=yes fi fi if test "x$dependancy_problem" = "xyes"; then AC_MSG_ERROR([dependancy problems detected]) fi AM_CONDITIONAL(BUILD_FNT, test "x$enable_fnt" = "xyes") AM_CONDITIONAL(BUILD_JS, test "x$enable_js" = "xyes") AM_CONDITIONAL(BUILD_PW, test "x$enable_pw" = "xyes") AM_CONDITIONAL(BUILD_NET, test "x$enable_net" = "xyes") AM_CONDITIONAL(BUILD_PUI, test "x$enable_pui" = "xyes") AM_CONDITIONAL(BUILD_PUAUX, test "x$enable_puaux" = "xyes") AM_CONDITIONAL(BUILD_SG, test "x$enable_sg" = "xyes") AM_CONDITIONAL(BUILD_PSL, test "x$enable_psl" = "xyes") AM_CONDITIONAL(BUILD_SL, test "x$enable_sl" = "xyes") AM_CONDITIONAL(BUILD_SSG, test "x$enable_ssg" = "xyes") AM_CONDITIONAL(BUILD_SSGAUX, test "x$enable_ssgaux" = "xyes") AM_CONDITIONAL(BUILD_UL, test "x$enable_ul" = "xyes") if test "x$need_opengl" = "xyes" && test "x$GL_PREFIX" != "xauto"; then LDFLAGS="$LDFLAGS -L$GL_PREFIX/lib" CPPFLAGS="$CPPFLAGS -I$GL_PREFIX/include" fi dnl Checks for library functions. dnl check for OpenGL related libraries AC_CANONICAL_HOST case "${host}" in *-*-cygwin* | *-*-mingw32*) dnl CygWin under Windoze. dnl Multimedia library LIBS="$LIBS -lwinmm" if test "x$need_opengl" = "xyes"; then dnl OpenGL libraries LIBS="$LIBS -lopengl32" fi ;; *-apple-darwin*) dnl Mac OS X if test "x$need_opengl" = "xyes"; then dnl OpenGL libraries LIBS="$LIBS -framework OpenGL" fi dnl Sound libraries LIBS="$LIBS -framework Carbon" ;; *) if test "x$need_opengl" = "xyes"; then dnl Check for X11 AC_PATH_XTRA LDFLAGS="$LDFLAGS $X_LIBS" LIBS="$LIBS $X_PRE_LIBS -lXi -lXmu -lXext -lX11 $X_EXTRA_LIBS -lm" dnl ========================================================= dnl if test "x$x_includes" != "x"; then dnl CPPFLAGS="$CPPFLAGS -I$x_includes" dnl fi dnl ========================================================= dnl Reasonable stuff non-windoze variants ... :-) AC_CHECK_LIB(pthread, pthread_create) AC_CHECK_LIB(GL, glNewList) if test "x$ac_cv_lib_GL_glNewList" = "xno" ; then dnl if no GL, check for MesaGL AC_CHECK_LIB(MesaGL, glNewList,, AC_MSG_ERROR([could not find working GL library])) fi fi AC_CHECK_LIB(dl, dlclose) dnl Check SGI audio library AC_CHECK_LIB(audio, ALopenport) ;; esac dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADER(windows.h, AC_DEFINE(WIN32)) if test "x$need_opengl" = "xyes"; then dnl Check for OpenGl header files case "${host}" in *-*-cygwin* | *-*-mingw32*) dnl CygWin under Windoze. AC_CHECK_HEADER(GL/gl.h,, AC_MSG_ERROR([OpenGL header file not found])) ;; *-apple-darwin*) dnl Mac OS X AC_CHECK_HEADER(OpenGL/gl.h,, AC_MSG_ERROR([OpenGL header file not found])) ;; *) AC_CHECK_HEADER(GL/gl.h,, AC_MSG_ERROR([OpenGL header file not found])) ;; esac fi dnl Warning flags WFLAG="-Wall" case "$host" in mips-sgi-irix*) if test "x$CXX" = "xCC"; then WFLAG="-fullwarn"; fi ;; *) if test "x$CXX" = "xicpc" || test "x$CXX" = "xicc"; then WFLAG="-w1" fi if test "x$GCC" != xyes; then # if the compiler is not GCC we reset WFLAG to null for safety WFLAG="" fi ;; esac CFLAGS="$CFLAGS $WFLAG" CXXFLAGS="$CXXFLAGS $WFLAG" dnl FreeBSD requires the -pthread switch to enable pthreads. Look for this dnl weirdness. save_CXXFLAGS="$CXXFLAGS" save_CFLAGS="$CFLAGS" save_LIBS=$LIBS CXXFLAGS="-pthread $CXXFLAGS" CFLAGS="-pthread $CFLAGS" AC_CHECK_LIB(c_r, pthread_exit) if test "x$ac_cv_lib_c_r_pthread_exit" != "xyes"; then CFLAGS=$save_CFLAGS CXXFLAGS=$save_CXXFLAGS fi LIBS=$save_LIBS dnl Checks for typedefs, structures, and compiler characteristics. dnl check for socklen_t (in Unix98) AC_MSG_CHECKING(for socklen_t) AC_TRY_COMPILE([ #include #include socklen_t apa; ],[],[ AC_MSG_RESULT(yes)],[ AC_TRY_COMPILE([ #include #include int accept (int, struct sockaddr *, size_t *); ],[],[ AC_MSG_RESULT(size_t) AC_DEFINE(socklen_t,size_t)], [ AC_MSG_RESULT(int) AC_DEFINE(socklen_t,int)])]) AC_OUTPUT( \ Makefile \ src/Makefile \ src/js/Makefile \ src/util/Makefile \ src/sg/Makefile \ src/sl/Makefile \ src/psl/Makefile \ src/ssg/Makefile \ src/ssgAux/Makefile \ src/fnt/Makefile \ src/pui/Makefile \ src/puAux/Makefile \ src/pw/Makefile \ src/net/Makefile ) AC_MSG_RESULT( [PLIB configuration information: Building FNT library: $enable_fnt Building JS library: $enable_js Building NET library: $enable_net Building PUI library: $enable_pui Building puAux library: $enable_puaux Building SG library: $enable_sg Building PSL library: $enable_psl Building SL library: $enable_sl Building SSG library: $enable_ssg Building ssgAux library: $enable_ssgaux Building PW library: $enable_pw Building UTIL library: $enable_ul ]) plib-1.8.5/aclocal.m40000644000175000001440000007462010765365020011245 00000000000000# generated automatically by aclocal 1.9.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005 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. # Copyright (C) 2002, 2003, 2005 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. AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.9.6])]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 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_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 # 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. # serial 7 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) 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, 2000, 2001, 2002, 2003, 2004, 2005 # 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. # serial 8 # 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", "GCJ", or "OBJC". # 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 ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} 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, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # 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. #serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; 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. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /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"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //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' -e 's/\$U/'"$U"'/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, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # 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. # serial 12 # 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. # 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.58])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 # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) 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], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])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) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # 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)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # 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_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 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 install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 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. # serial 2 # 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])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 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. # serial 3 # 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 done .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 # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi 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, 1999, 2000, 2001, 2003, 2005 # 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. # serial 4 # 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 supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005 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_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. # # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). # This was a mistake. There are at least two reasons why we must not # use `-m 0755': # - it causes special bits like SGID to be ignored, # - it may be too restrictive (some setups expect 775 directories). # # Do not use -m 0755 and let people choose whatever they expect by # setting umask. # # We cannot accept any implementation of `mkdir' that recognizes `-p'. # Some implementations (such as Solaris 8's) are not thread-safe: if a # parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' # concurrently, both version can detect that a/ is missing, but only # one can create it and the other will error out. Consequently we # restrict ourselves to GNU make (using the --version option ensures # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi AC_SUBST([mkdir_p])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 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. # serial 3 # _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], [AC_FOREACH([_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])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # 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. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # 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 ( 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 rm -f conftest.file 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 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)]) # Copyright (C) 2001, 2003, 2005 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="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 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. # serial 2 # _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. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. 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 plib-1.8.5/README.mac0000644000175000001440000000105110765364452011020 00000000000000 PLIB Project files for CodeWarrior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NOTE from Steve: It seems that the CodeWarrior project files for PLIB are considerably larger than the entire source distribution (450Kb!) Hence, since Mac/CodeWarrior users are not exactly commonplace, I'm not going to include the project files into the distro and cause everyone else prolonged download times. I suggest you contact Darrell Walisser should you need to build PLIB in this setting. Sorry! plib-1.8.5/ChangeLog0000644000175000001440000010404110765364452011156 00000000000000 PLIB Change Log. ================ PLIB v1.8.5 (Oct 2006) ~~~~~~~~~~~~~~~~~~~~~~ * removed several widgets from pui/, which were declared obsolete since a long time. Most of them are now available in puAux/ * several fixes and improvements to puAuxList * puInputText scrolling fixed. * Improved DirectX loader. * Check ownership before deleting in ssgSimpleList. * Fixed netSocket. * Fixed mem leak in ssgVertSplitter. * Fixed pw window sizes on win32. * Added pview ssg-example. * Fix clock delta in first call. * Made colour of listbox changable. * Fixed text with negative coordinates * Fixed misc bugs in puAuxLargeInput * Allow the user to activate a widget with custom mouse button. * Made material loading from wavefront models more robust. * Handle linux joysticks with a lot of axes. * Avoid specular anomalies in 3ds files. * Added a demo for ssgaShapes. * Fixed the diameter of ssgaSphere. * Fixed inability to add colour to the ssgaTeapot. * Remove scale dep in ssgaFire PLIB v1.8.4 (Jan 2005) ~~~~~~~~~~~~~~~~~ * Added a way to get SSG intersection tests to work with backfacing polygons. * Added ssgaScreenDepthDump into ssgAux. * Several fixes for FreeBSD included. * Added exporter for OpenInventor. * Implemented im- and exporter for ASC files. * Optimisations. * Various (minor) improvements to ASE, MDL, PCX and X loading and ASE saving. * Implemented ssgAnimTransforms. * AC loader now reads "crease" lines and creates much smaller and cleaner scene graphs. * Joystick code adapted to current OS versions (especially Linux). PLIB v1.8.3 (April 8th 2004) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * NET now allows a NULL argument to netSocket::accept * Added #include to all top level header files in order to ensure that NULL is defined. * Added ssgaScreenDump into ssgAux.dsp * Cleaned up some warnings from MSVC. * Added Christos Dimitrakakis' fixes to SL to prevent crackling in certain envelope conditions. * Added pwAutoRepeatKey to control keyboard auto-repeat. * Fixed a horrific bug in the sgDistToLineSegment routines. PLIB v1.8.2 (March 26th 2004) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * PW now runs on Mac and MacOSX. * Uppercase keystrokes now work in PW for Windows. * Version number in ul.h now set correctly. * Package now builds correctly under MSVC. PLIB v1.8.1 (March 21th 2004) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * puAux library wouldn't build without GLUT being installed...that's fixed. * the NET library examples needed some love and attention. They are much more useful now! PLIB v1.8.0 (March 19th 2004) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * puAux library added to provide a place for the more obscure PUI widgets. * PW (PLIB Windowing) library added to provide a built-in alternative to windowing libraries such as GLUT and SDL. Applications that only need a single window, mouse and keyboard (and no other features of GLUT) can now have no dependencies whatever outside of PLIB and OpenGL. * PLIB is now completely independent of GLUT. You can even build it without GLUT being installed. Modules to allow PUI to work with GLUT, freeglut, SDL, FLTK and our own PW windowing library are provided. * ssgAux now includes a relatively simple sky model kindly donated by the SimGear project. Now you can have sun, moon, stars and clouds with just a handful of function calls. * PSL - a C-like interpreted scripting language is now bundled into PLIB. It's a byte-code interpreter - and it has some useful properties for games and other interactive packages in that it allows the application much finer control over the running of the script(s) than traditional scripting engines. * In the demos area, we added the 'simon' package which provides a simple framework for PSL scripts to be loaded - and they may in turn load 3D models, move them around, etc. Astropong.psl (a simple 3D 'Pong' game in PSL) is provided as a demo. And of course, many bugs have been slain and numerous other smaller features have been added. PLIB v1.6.0 (Sept 2nd 2002) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's been over a year since the last PLIB release and we have been somewhat lax about maintaining a list of changes. Some highlights are: * Significant improvements and cleanup throughout PLIB, especially in PUI. * ssgAux library added - includes handy classes for more sophisticated effects layered on top of SSG. + Standard shapes like cubes, spheres, cylinders and teapots. + Water waves. + Fire. + Particle Systems + Lens Flare. * More example programs. * P-Guide GUI builder for PUI. * JS promoted to a full library. PLIB v1.5.1 (July 21st 2001) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added ssgTween and ssgTweenController * Added puFileSelector - henceforth puFilePicker is deprecated. * Added ulList * Added VRML loader (this one works!) * Numerous bug fixes in other loaders. * Added TopHat support to JS * Added support for >3 simultaneous sounds in SL. (You have to explicitly enable that though - it's not the default) * Fixed bugs in util's directory handling. * puInput and puListBox now cope better with text that is too big for the widget * puListBox (and hence puFileSelector and puFilePicker) works with both large and small font sizes. * puDial changed to be derived from puSlider - many consequences of that change will be visible in the application. (eg output range is 0..1 and not 0..360) * PUI widgets are now 'sticky' so that if you are dragging a slider along a puSlider and your mouse slips off the edge of it, it'll still have "focus". * Added sgLerpAnglesVec3 to linearly interpolate angles allowing for the nasty wrap-around-360 problem. * Added sgLineSegment3ToLine3, sgDistSquaredToLineVec3 sgDistSquaredToLineSegmentVec3, sgDistToLineVec3 and sgDistToLineSegmentVec3. Also sgLine3 and sgLineSegment3 structures. * Added a 'Gallery' page to the documentation to show potential developers the range of applications that use PLIB - and also to promote things our developers have done. To save download time and CVS space, the actual images are not in the PLIB tarball. PLIB v1.4.2 (July 21st 2001) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Changes in NET to allow compilation under RedHat 7.1 * Fixed a small bug in ssgaSphere * Fixes a small bug in puFilePicker PLIB v1.4.1 (June 25th 2001) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Converted MSVC project files to 'BINARY' in the CVS archive because some versions of MSVC don't line UNIX-style line endings. * Many improvements and bug fixes to puFileSelector and puListBox. * Minor fix to NET to accomodate Solaris users. * Fixed puMenuBar so it highlights as you drag the mouse across it. * Fixed ulOpenDir so it returns NULL on error on non-MSVC systems * Changed colour of text on buttons in documentation to make them easier to read by colour-blind users. PLIB v1.5.0 (June 20th 2001) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Just a 'place holder' - actually identical to 1.4.0. PLIB v1.4.0 (June 20th 2001) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed example programs so they don't use the obsolete _SSG_TYPE tags. * Removed multiplie tags on web pages. * Updated 'AUTHORS' file. * Added 'demos' to the CVS repository. PLIB v1.3.3 (June 18th 2001) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Various warnings cleaned up under MSVC. * Fixed function prototypes for the Quaternion functions in SG * Fixed bug in sgEulerToQuat where the angles were not being converted from degrees to radians. * Changed PUI to make sliders and dial widgets grab a hold of the mouse focus and not release it until the button is released. This is a subtle but important behavioural change. * puDial's are now derived from puSlider's - one side-effect of that is that they now return 0..1 rather than 0..360 and no longer support the maximum and minimum range functions. PLIB v1.3.2 (June 13th 2001) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * This CHANGES file has regrettably not been well maintained, hence there a numerous changes not listed here. * File loaders now require app to pass 'ssgLoaderOptions' rather than other ad-hoc callback function hooks. * Added Active Widget Implementation (pui) * Added puFilePicker * Added Ref Counting to ssgState * Added puBiSlider and puTriSlider * Added some missing 'AUTHORS' entries. * puDial widget (was actually in 1.3.1 but got missed in the 'CHANGES' file) * Fixed a problem in the configure.in that prevented ssgAux from building. * Moved the 'name' and 'user_data' (with associated set/get member functions) from ssgEntity down into ssgBase so that these functions will work with ssgState and ssgTexture objects. This is needed for PrettyPoly. PLIB v1.3.1 (Sept 15th 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Changed License conditions to specifically permit use of PLIB outside of LGPL for embedded applications. * There is now a task and bug tracking system for PLIB on Sourceforge. * Configuration/Install tool changed to support CygWin better than in the past. * PLIB examples' data files consolidated into a single 'examples/data' directory. * PLIB's documentation is now under CVS. * Added 'SSGAUX' library - include and link to /usr/lib/libplibssgaux.a * Aux library has 'ssga' classes to add high level shapes such as cylinders, cubes and spheres (two different kinds). * Lots of new example programs. + New PUI 'complex' uses multiple windows. + Cute 'waving flag' demo + Working Quaternions versus Eulers demo + Model viewer (this is actually a useful program - as well as a demo). * More const-correctness throughout library. * OPTIONAL support for PNG image loading (you have to compile PLIB specially to get this because it introduces an additional dependancy). * PLIB now checks that a valid OpenGL rendering context exists when the various ssgInit/puInit/etc routines are called. * PUI hasi: + better support for multiple windows, + a new function to allow the deletion of an object within one of it's own callbacks. + the ability to operate in a separate OpenGL coordinate space. + puFilePicker and puListBox + enhancements to puSlider * SL has a completely new audio driver for SGI's IRIX. Unfortunately, we don't think it fixes the long-standing timing problems for audio under IRIX. * SSG's ssgVtxArray and ssgIndexArray now use 'short's for indices - which is more efficient on most OpenGL's. * Several bugs fixed in SSG - also some changes to make it more suited to embedded use in game consoles and such. * Many improvements to SSG's post-processing tools that are typically applied to scene graph fragments after loading from disk. * SSG now permits you to disable MIPmapping for selected textures. * SSG's print() functions now work for more classes and produce more useful output. * Code for ssgVtxArray streamlined. * Added a 'Lookat' function for SSG's camera model. * ssgSelectors can now have more than 32 kids. * ssgContext had incorrect defaults for the camera orientation. * Some loaders were not sharing ssgState's between polygons - that's fixed. * 3DS loader has had numerous improvements...but the limitations of this format are becoming evident. * All error/warning handling is now done through a centralized handler that can be redirected (eg to send errors to a popup window or something) * Some bugs fixed in ASE loader. It now uses ssgVtxArray primitives. * Added a loader for the Quake 'MD2' format. It seems to work amazingly well. * Added 'UL' library. Applications MUST link to -lplibul (/usr/lib/libplibul.a) - and should include and call ulInit() before making UL calls. If you use automake/autoconf, then it's easy to make applications that will compile and link under both PLIB 1.2 and 1.3/1.4, just add this: AC_CHECK_LIB(plibul, ulInit,,,) libplibul currently contains: + Fast, portable clock/timer routines. + Low level networking code. + Some directory searching routines. * Documents and Examples are now under CVS. * Added Tools and Auxlibs folders for future work. PLIB v1.3.0 (July 1st 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Unstable version of 1.2.0, no significant code changes. PLIB v1.2.0 (July 1st 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Stable version of 1.1.12, no significant code changes. PLIB v1.1.12 (June 24th 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed some compilation problems for Macintosh/Codewarrior which treats 'xor' and 'or' as reserved words!! Yikes! Thanks to Darrell Walisser for that piece of nasty news. * Fixed some problems in slMODinst.cxx that were causing compilation warnings under windoze (thanks to Bram Stolk) * Changed SL to open audio devices with O_NONBLOCK - thanks to Trent Gamblin for spotting this one. * Added configure.in check for libdl to cover bug in ld.so under Linux. Application programs under Linux need to link to libdl.so in order to work around this. Ben Woodhead added this. * Added Borland project files, thanks to Dave Heil for contributing these. * Swapped order of multiplication in sgMultMat4. Thanks to Lucas Ackerman for spotting this one. * Added a unique ID field to every node in the scene graph. This helps out some picking algorithms in PPE. * Added some more ifdefs to make PLIB Audio/JS components to make them work under NetBSD. (They already work with FreeBSD and OpenBSD). Many thanks to Rene Hexel! * Fixed a ref() problem with ssgVtxTable::clone - thanks to Will Weisser for catching that one! * Added checks to ensure that a valid OpenGL rendering context exists before ssgInit/puiInit/fnt-loaders are called. * Added Dave McClurg's ASE loader and matching writer. If you use the new 'ssgLoad()/ssgSave()' functions, it'll "just work" - if you prefer you can call ssgLoadASE/ssgSaveASE analogously to all the other loaders. * Several fixes to the quaternion code in SG were contributed by "Negative0" (Who was that masked man?) PLIB v1.1.11 (Feb 9th 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed a tiny problem with double-sided polygons. PLIB v1.1.10 (Feb 9th 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added ssgLoad and ssgSave that look at the filename extension and call the appropriate lower level load/save routine. * Added a 'clone' function for all SSG classes. * PLIB now managed under CVS at SourceForge. http://sourceforge.net/project/?group_id=382 * Added a collection of line/plane, plane/plane and line/line intersection routines to SG. Thanks to Norman Vine for most of them. * Fixed a bug in SSG file loader that would prevent recognition of obsolete SSG file types. PLIB v1.1.9 (Jan 28th 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed bug that caused the ref counts of the various vertex arrays in an ssgVtxTable to be incorrectly set to zero when that VtxTable is loaded from an '.ssg' format file. This tended to crash SSG with an assertion failure whenever you deleted an object loaded from a '.ssg' file. * Added the current texture map filename to ssgSimpleState and ssgStateSelector - which means that... * The SSG file format finally works correctly. Note that any SSG files you might have created before this release won't work anymore...but then they didn't work correctly before. PLIB v1.1.8 (Jan 23rd 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added ssgContext. This makes it a lot easier to write programs that need to render multiple eyepoints in quick succession. * Added functionality to ssgVtxTable to enable applications to construct a vertex table and then add the vertex arrays instead of doing it all in one step. PLIB v1.1.7 (Jan 20th 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Ooops! 1.1.6 accidentally went out set up to REQUIRE the 'freeglut' library instead of the original GLUT. That's fixed now - it'll pick up on whichever you have installed and use freeglut if you have both. (This only really selects which header PLIB will use - you can still link your application against either GLUT) freeglut is here: http://freeglut.sourceforge.net PLIB v1.1.6 (Jan 19th 2000) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Changed ssgSaveSSG and ssgSaveAC to return TRUE on success, FALSE otherwise. Neither function is really working well enough for 'primetime' use. * Added an optimisation to sgInvertMat4 (thanks to Norman Vine). * Changed all Makefile.am's to refer to top_srcdir rather than top_builddir - I have no idea why that matters - but Steve Lamont says it matters - so I fixed it! * Fixed a bug in PUI's default colour scheme picker that caused text on dark coloured backgrounds to be black instead of white. PLIB v1.1.5 (Dec 20th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Optimised sgMakeNormal (thanks to Klaus Hartmann!) * Added 'Orthographic' rendering modes to SSG...this is a work in progress - so no documentation yet - sorry! PLIB v1.1.4 (Dec 3rd 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Moved pre- and post-draw callbacks from ssgLeaf to all ssgEntities. * Changed user-data - all userdata must be derived from ssgBase so that it can be ref-counted and automatically deleted when no longer referenced. * Added some specialised highlighting code for the PPE tool. PLIB v1.1.3 (Nov 28th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added some missing 'get' functions to SSG. * Added a way to load the current view frustum and modelview matrices into OpenGL. * Removed dependancy of SSG on GLUT. * Added ssgVtxTable - which will ultimately replace ssgVTable. The main difference is that ssgVtxTables don't support indexing and add reference counted vertex data tables. * ssgLoadAC changed to use the new ssgVtxTable. * Added pre- and post-draw callbacks to ssgLeaf. PLIB v1.1.2 (Nov 8th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed double declaration of sgdTransposeNegateMat4 that prevented SG from compiling under Windoze. * Split examples and documentation off into a separate tarball. PLIB v1.1.1 (Nov 6th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added routines to SG to interconvert sgd and sg data types. * Matrix inversion routines added to SG. * Attempt to work around possible compiler error in ssgLoad3Ds - this shows up in some versions of CygWin under Windoze and exhibits itself as an out-of-memory error when loading 3DStudio models. PLIB v1.1.0 (Oct 29th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * This is actually identical to 1.0.20 except that it installs its headers in /usr/include/plib and its libraries in /usr/lib. To avoid name-space pollution in /usr/lib, the libraries are renamed as follows: libssg.a --> libplibssg.a libsg.a --> libplibsg.a libfnt.a --> libplibfnt.a ...you get the idea I'm sure. * With this release, I'm going to the even-number-stable, odd-number-experimental numbering scheme. Hence, I'll be adding bug fixes only to the 1.0.xx series. When 1.1.xx has been enhanced - and is again stable, it'll become 1.2.0 and 1.3.0 will be the experimental version. PLIB v1.0.20 (Oct 29th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed problem with memory leakage in SSG, the ref count of branch nodes was including the parent nodes as well as the children. Revised instructions on deleting nodes added to manual. * Added sgDistanceSquaredVec2/3/4 to SG. (Christian Mayer asked *so* nicely). * Added Per Liedman's latest 3D studio file loader. This is a truly awesomely useful thing. Thanks Per! * This will be the last version to install in /usr/local/plib. PLIB v1.0.19 (Oct 16th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added bunches of missing 'const' directives to SG and parts of SSG. Thanks to Christian Mayer for this one. * Fixed a bug in FNT that should allow more than two lines of text to be output with a single call to puFont::drawString. Thanks to Sylvan Clebsch for this one. * Added a 'saturation' limit to js.h - intended for those joysticks that don't generate a full range of output. Thanks again to Sylvan Clebsch! * Keiji Kato provided a patch to SL for the Windoze platform that fixes some kind of a slowdown problem when playing sounds on WinNT-4 machines. PLIB v1.0.18 (Oct 3rd 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Removed GIF files from all the Web pages. Rassin-frassin Unisys...grumble >:-( * Fixed a problem that caused too many joystick axes to be reported by JS. Thanks to Paolo Leoncini - good catch! * Added new Quaternion interpolation routines and reduced complexity of quaternion multiplication routines. Thanks to Sylvan Clebsch. * ssgEntity (and hence most SSG classes) didn't make a copy of strings passed to setName() - hence there was a tendancy to leak name memory as objects were deleted. That's fixed but be aware that 'name' is now copied. * As requested by Christian Mayer, sgAddScaleVec functions have been added into SG. * Fixed up some compilation warnings in ssgStateSelector.cxx, fnt.cxx and ssgSaveAC.cxx. (Thanks to Sylvan Clebsch for those) * Fixed a potential problem in ssgModelPath/ssgTexturePath that would blow up if you ever passed a local string variable to them. Be sure not to call either function before ssgInit() - OK! PLIB v1.0.17 (Aug 23rd 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added new ssgState derivitive "ssgStateSelector". Check out SSG documents for details. * Stopped warning about unused variable 'ww' in FNT and SSG. * Fixed bug in puValue::setValue(char*) that prevented empty strings from changing the current string state for the puValue. (Thanks to Sylvan Clebsch for finding that one) * Removed the 'test' program for PUI (it was never meant to be in the release). * Added error return to Font loaders (Thanks to Norman Vine). PLIB v1.0.16 (Aug 13th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed compiler warning in slMODfile.cxx * Fixed a bunch of compile errors in slScheduler.cxx due to some default arguments that got left in place by mistake. PLIB v1.0.15 (Aug 12th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Minor fix to SL to make it compile under CygWin. Thanks to Norman Vine for that one. * MacOS port of SL is now complete! Many thanks to Darrell Walisser * Fixed a problem with const correctness when compiling with gcc 2.95. * Moved a lot of SL functions from inline to non-inline... they had grown over time from one liners into 10 liners. * In SM, changed 'not_working' to 'notWorking' to make it look more like SL. * Fixed bug that caused SL to crash if you played MOD music without a sound card (Thanks to Daryll Strauss for finding that one). * Fixed bug in puButton constructor that makes menus come out with irregular height. * Fixed recurrent crashing problem with the PUI 'complex' demo program. PLIB v1.0.14 (Aug 4th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The use of PROXY textures seems to break both nVidia and G200 Mesa ports for Linux - so I have temporarily commented out that code. If you need it, find the code in src/ssg/ssgImageLoader.cxx and src/fnt/fntTXF.cxx and re-instate the code that's ifdef'ed out using #ifdef PROXY_TEXTURES_ARE_NOT_BROKEN * Significant fixes to SL to make it work with /dev/audio under SOLARIS. Thanks to Steve Brown for his patch. * Somehow the FNT documentation became corrupted in 1.0.13, it's fixed now though. * FNT and PUI now allow '\n' characters inside strings to signify carriage-return + line-feed. Thanks to Shane Arnott for this one. * Added parameters to FNT routines to allow the application to pick which OpenGL texture filtering to apply. * Fixed some minor name-space pollution in PUI. * Fixed a bug in ssgBaseTransform that causes ssgGetLastTransform to mess up on the first call. * Fixed a bug in measuring the bounding box of text containing space characters in the FNT component. Thanks to Alexander A. Babichev for this one. * Lots of minor syntax changes for MSVC, PLIB v1.0.13 (July 8th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Included a JS patch from Karl Heinz Kremer that adds support for the latest Linux joystick driver. For those who have the latest driver, this will increase the number of joystick axes from 2 to 6.Beware though that the detection of which kind of driver is present is currently done at compile time which could be a problem for binary distributed code. * Added a simple terrain demo (examples/ssg/majik)- originally put together to give the good people in the Majik group something to play with. Check out *their* good stuff at: http://majik.netti.fi * Improved state handling in SSG. Also added ssgForceBasicState(). * JS library should work with FreeBSD. (Thanks to Stephen Montgomery-Smith) * Texture loaders in SSG and FNT changed to use GL_PROXY texture tests instead of being hard-coded to crappy 256x256 limits. * Since puiAlone is sadly outdated, I have ceased to distribute it. If you need it, the last version is with plib-1.0.12 on the PLIB homepage. * Changed definition of SG_PI to be a 'float', fixed the precision of SGD_PI to be double. * Removed strncasecmp - because it's not universally implemented. * Changed an ifdef in SL to allow it to compile under FreeBSD. * Added an 'puArrowButton' call - just like a puButton - but shaped like an arrow. * Added an 'ssgGetVersion' call. * Deleted ssgAnimation class (it was never completely implemented anyway). * Added ssgTimedSelector (which takes over the functions I'd planned to add to ssgAnimation). * I didn't rename the file ssgAnimation.cxx to ssgTimedSelector.cxx because I couldn't stand to change all the MSVC project thingies. * Numerous fixes for the Mac: * Fixed a byte-swapping problem with the BMP texture loader. * Changed some arrays from local to 'new/delete' because the Mac CodeWarrior compiler can't cope with more than 32Kb of local memory in a single function or class. * Provided conditional compilation for Mac file naming conventions in a couple of places. It's not enough though. PLIB v1.0.12 (June 3rd 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added a set of MSVC project files. * More portability issues resolved. * Lots more actually. * Official Acronym "IBFITNR" (It'll Be Fixed In The Next Release) now adopted. PLIB v1.0.11 (May 30th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed a problem with LoadAC creating 2-point tstrips. * Fixed an assert in SSG's deRef. * The tables inside an ssgVTable are now 'protected' rather than 'private'. * Added new code to slScheduler to allow applications to replay MOD files. * Reorganized slSamplePlayer to be derived from a new abstract base class slPlayer. Added new private class slMODPlayer for replaying MOD files. * Added a demo program for the new SL MOD player. * Added ssgRangeSelector class to allow level-of-detail management. This isn't well tested yet - but it's really simple code - so it should be OK. PLIB v1.0.10 (May 10th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Ooops! A fatal error in my strcasecmp code. 1.0.9 and 1.0.10 should have *died* on most machines! PLIB v1.0.9 (May 9th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~ * Error in SGI version of slSample.cxx cleared up (Thanks Devrim!) * Made some changes for MSVC. PLIB v1.0.8 (May 3rd 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~ * A couple of warnings eliminated from SL when compiled under CygWin. * Added a contribution from Simon Britnell to allow programs to search the SSG scene graph by name or path. (Thanks Simon!) * Fixed a bug in sgIdentityQuat (Thanks Kevin!) * Following the first release of Tux-aqfh, I was snowed under with little fixes. + strcasecmp should be stricmp on some machines...but alas, not on others. The heck with it - I'll just write my own! + fntFont wasn't pushing/popping GL state correctly. + More minor hacks to make for clean compiles under IRIX. + puInterface's destructor was only deleting half of it's child node. + Missing contructor functions for various SG classes. + SSG culling functions were not testing for empty bounding spheres. + Minor compilation warnings for slSample.cxx + example/sl/example.cxx used M_PI - which is a no-no under Windoze. PLIB v1.0.7 (May 3rd 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~ * Removed a bunch of redundant NOTICE, CHANGES and REAME files. All that stuff is now maintained in the top level directory. * SG used to be set up so you could compile it in double precision with the drop of an option. However, some applications need both float and double support - so SG now has duplicate functions for double-precision that start 'sgd'. * Changed the structure of the FNT library to move font sizes from the fntFont/fntTexFont class into the fntRenderer class. This corrects a poor design decision because it was hard to create fonts in multiple point sizes and slants without using multiple identical texture maps (BAD!). RTFM. * Added a bunch of TXF fonts into examples/fnt/data and changed the fnt_test program to cycle through them whenever you press a key. * PUI can now use FNT fonts - which is good news because now you can use TXF fonts for better variety and speed compared to GLUT fonts. This means that PUI programs now need to link with -lpui -lfnt -lsg * The PUI 'complex' example program now uses the sorority font. * I added a 'rendering callback' to some PUI widgets as suggested by Eero Pajarre. The idea is to allow you to do arbitary OpenGL rendering onto a PUI widget...however, I'm not convinced that this is a good idea. In any case, you can put icons on widgets more easily by defining custom fonts using FNT. PLIB v1.0.6 (May 1st 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added a complete new component library called FNT that allows texturemapped fonts to be loaded and rendered nicely. * More small configure/compile problems fixed. * Added Quaternions to the SG library thanks to a fine contribution from Kevin Thompson * Fixed a bug in JS under Windoze that made three axis sticks return garbage in the third axis and swapped the order of the third and fourth axes for >3 axis sticks. PLIB v1.0.5 (April 21st 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed another IRIX compile problem in pu.h * Found that configure script was not enabling full warning levels...as a result, fixed a dozen minor warnings in SSG. * SSG's image loader now loads 8 bit and 24 bit uncompressed BMP files. This seems to work for RGB images - but I can't seem to build BMP images with Alpha planes using any of the tools I have. PLIB v1.0.4 (April 20th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Restructured SSG texture image loader to permit use of other file formats than SGI. * In the event that a texture doesn't load, SSG will now insert a red and white chequerboard. * Another round of changes to configure.in should solve the CygWin issues. * Added in some *ancient* fixes to PUI - that kind people donated and I somehow forgot all about (oops!) PLIB v1.0.3 (April 18th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Fixed to compile cleanly under IRIX 6.2 using the official SGI C++ compiler. * More fixes for MSVC under Windoze. * OpenGL logo added to HTML documents following request from opengl.org PLIB v1.0.2 (April 14th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Yet more minor build tweaks - CygWin wasn't defining WIN32, that should work now. * JS should now work with Windoze - and with sticks with up to 6 axes. Under Linux, the presence of the joystick driver (or at least it's header files) is now mandatory, PLIB won't build without it. * The JS demo program has been fixed to display all of the axes of all of the joysticks. * PUI now supports valuators - this is where the value of a widget is set using the address of one of the application's variables. Once the valuator is set, the PUI widget's display will always the same as the valuator - and any changes to the widget will also change the value stored at that address. This saves you from creating a bunch of callbacks when buttons and sliders have no side-effects apart from changing some global variable. PLIB v1.0.1 (April 11th 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Some minor portability issues cleared up. * More minor build process errors corrected. PLIB v1.0 (April 1st 1999) ~~~~~~~~~~~~~~~~~~~~~~~~~~ * All the separate libraries that I support in the public domain are now rolled into a single tarball under the new name 'PLIB'. * Although this is the first release of PLIB. The sub- libraries: SL, JS and PUI had previous releases - this is the first Beta of SG and SSG. * Directory layouts for all of the component libraries have been somewhat rationalized. * I have shifted from a completely open license to LGPL on the advice of several OpenSource authors. Any earlier releases of these libraries that you may happen to have remain free of LGPL restrictions. If any contributors to the earlier code have objections to this arrangement, please let me know and I'll arrange to remove their code from subsequent copies. * With help from Curtis Olson, we now have proper 'configure' scripts to streamline the build process. plib-1.8.5/INSTALL0000644000175000001440000002171310765364452010441 00000000000000Basic Installation ================== These are generic installation instructions. 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, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). 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 at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' 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. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. 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. 4. Type `make install' to install the programs and any data files and documentation. 5. 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. OpenGL Configure ================ Configure is not able to find the OpenGL headers and libraries. In this case please add ./configure --with-GL=PREFIX Examples ./configure --with-GL=/usr/local This will look in the /usr/local/include for headers (GL/ is not needed) and /usr/local/lib for the libraries. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure 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 must use a version of `make' that supports the `VPATH' variable, such as 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 `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have 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. Compiling for Windows with MSVC =============================== You can easily compile plib with MSVC 6. First, you have to set some paths in tools\options\directories. In "include" set the plib path itself (and, if needed the parent). Then, in "library paths" add the plib path itself again so that packages that use plib will find it. The building process will copy the finished *.lib files and any header files that are visible to projects using plib into the plib path. There is a workspace (*.dsw file) for plib, for examples, for tools (including only af2rgb) and for each of the demos: exposer, p-guide and ttt3d. Simply open one of them (starting with plib itself, of course) in MSVC, choose what you want to compile (build/set active configuration) and then compile (F7). if you want to compile or even create a project that uses plib, please note that the plib workspaces have "multi threading" enabled. Either enable this as well in your project or disable it for plib. A missmatch leads to errors. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' 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. 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'. Optional Features ================= 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. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM 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 host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. 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. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--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. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. plib-1.8.5/AUTHORS0000644000175000001440000000334610765364452010462 00000000000000PLIB was originally written by Steve Baker as a solo project - but has subsequently been greatly enhanced and expanded by a 'cast of thousands'. Most important of all - the 'official' PLIB developers: Alex Perry Curtis Olson Ben Woodhead Dave McClurg Gerard Decatrel Gil Carter Giancarlo Niccolai James Jones John Fay ("Mr. PUI") Juergen Marquardt Mark Vallevand Marten Stromberg Nathan Matias Norman Vine Per Liedman Sam Stickland Sebastian Ude Steve Baker <--- Hmmm - must sort this list by SECOND name! Will Lachance Wolfram Kuss Then, the non-registered contributors: (Apologies to anyone I've left out - please let me know who you are and I'll add you in.) Andrew Ross Christopher St.John Christian Mayer Darrell Walisser Dave Heil Erik Hofman Kevin Thompson Karl Kremer Negative0 <---- Who? Some kind of 1's complement arithmetic fanatic? Mark Danks Michael Kurth Sean Palmer Simon Britnell Themie Gouthas Tony Knienieder Trent Gamblin Special mention must go to: Daryll Strauss (GLIDE port to Linux) David Bucciarelli (Mesa -> GLIDE interface) Brian Paul (Mesa) Curtis Olson (FlightGear guru and all-round "Mr Nice Guy", who nagged me into writing most of this stuff!) Vasily Lewis (Tireless maintainer and sysadmin at Woodsoup where PLIB was first hosted) Toru Egashira (Who wrote a program called 'NSPmod' which was the original basis of the SL 'MOD' player - although the original code has been almost entirely rewritten in the process of merging it with SL. Everyone at OPENGL-GAMEDEV-L plib-1.8.5/src/0000777000175000001440000000000010765365521010255 500000000000000plib-1.8.5/src/ssg/0000777000175000001440000000000010765365520011050 500000000000000plib-1.8.5/src/ssg/ssgSave3ds.cxx0000644000175000001440000003411010765364437013542 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSave3ds.cxx 2108 2006-12-11 20:42:05Z fayjf $ */ /******************************************************* ** ssgSave3ds.cxx ** ** Written by Per Liedman (liedman@home.se) ** Last updated: 2001-02-25 ** ** This was written to be a part of Stephen J Bakers ** PLIB (http://plib.sourceforge.net) *******************************************************/ /* This writer is highly experimental. It has *not* been tested with 3D Studio. Please note that this writer does not save hierarchal information */ #include #include "ssgLocal.h" #include "ssg3ds.h" static FILE* save_fd; static const int MAX_MATERIALS = 128; static ssgSimpleState* mat[MAX_MATERIALS]; static int mat_count; static void writeChunkHeader( unsigned short id, unsigned int length ) { ulEndianWriteLittle16( save_fd, id ); ulEndianWriteLittle32( save_fd, length ); } class _ssgSave3dsData { public: _ssgSave3dsData( void* ptr, size_t memb_size, size_t nmemb ) : swabbed(false), memb_size(memb_size), nmemb(nmemb), ptr(ptr), next(NULL) { } ~_ssgSave3dsData() { if (next != NULL) { delete next; } free(ptr); } unsigned int size() { unsigned int s = memb_size*nmemb; if (next != NULL) { s += next->size(); } return s; } void write() { if (!swabbed) { switch (memb_size) { case 2: ulEndianLittleArray16( (unsigned short*)ptr, nmemb ); break; case 4: ulEndianLittleArray32( (unsigned int*)ptr, nmemb ); break; default: break; } swabbed = true; } fwrite( ptr, memb_size, nmemb, save_fd ); if (next != NULL) { next->write(); } } void append( _ssgSave3dsData* next ) { this->next = next; } protected: bool swabbed; size_t memb_size, nmemb; void* ptr; _ssgSave3dsData* next; }; class _ssgSave3dsChunk { public: _ssgSave3dsChunk( unsigned short id ) : id(id), first_data(NULL), last_data(NULL), next_sibling(NULL), first_kid(NULL), last_kid(NULL) {} ~_ssgSave3dsChunk() { if (first_data != NULL) delete first_data; if (next_sibling != NULL) delete next_sibling; if (first_kid != NULL) delete first_kid; } void addData( _ssgSave3dsData* data ) { if (first_data == NULL) { first_data = last_data = data; } else { last_data->append(data); last_data = data; } } void addKid( _ssgSave3dsChunk* kid ) { if (first_kid == NULL) { first_kid = last_kid = kid; } else { last_kid->next_sibling = kid; last_kid = kid; } } void addSibling( _ssgSave3dsChunk* sibling ) { sibling->next_sibling = next_sibling; next_sibling = sibling; } unsigned int size() { unsigned int s = 6; if (first_data != NULL) s += first_data->size(); _ssgSave3dsChunk* kid = first_kid; while (kid != NULL) { s += kid->size(); kid = kid->next_sibling; } return s; } void write() { unsigned int s = size(); writeChunkHeader(id, s); if (first_data != NULL) { first_data->write(); } _ssgSave3dsChunk* kid = first_kid; while (kid != NULL) { kid->write(); kid = kid->next_sibling; } } protected: unsigned short id; _ssgSave3dsData *first_data, *last_data; _ssgSave3dsChunk *next_sibling; _ssgSave3dsChunk *first_kid, *last_kid; }; static char* get_material_name( ssgSimpleState *state ) { static char matnamebuff[16]; if (state->getName() != NULL) { return state->getName(); } else { for (int i = 0; i < mat_count; i++) { if (state == mat[i]) { sprintf(matnamebuff, "Material #%d", i+1); return matnamebuff; } } ulSetError(UL_WARNING, "ssgSave3ds: Material not found."); return NULL; } } static _ssgSave3dsChunk* create_vertex_chunk( ssgLeaf* leaf, sgMat4 transform ) { _ssgSave3dsChunk* vertexlist = new _ssgSave3dsChunk( CHUNK_VERTLIST ); unsigned short *num_verts; _ssgSave3dsData *nverts; float* vdata; num_verts = new unsigned short; *num_verts = leaf->getNumVertices(); nverts = new _ssgSave3dsData(num_verts, 2, 1); vdata = new float[ *num_verts * 3]; for (int i = 0; i < *num_verts; i++) { sgXformPnt3(&vdata[i*3], leaf->getVertex(i), transform); } _ssgSave3dsData *vertices = new _ssgSave3dsData(vdata, 4, *num_verts * 3); vertexlist->addData(nverts); vertexlist->addData(vertices); return vertexlist; } static _ssgSave3dsChunk* create_maplist_chunk( ssgLeaf* leaf ) { _ssgSave3dsChunk* maplist = new _ssgSave3dsChunk( CHUNK_MAPLIST ); unsigned short *num_verts; _ssgSave3dsData *nverts; float* vdata; num_verts = new unsigned short; *num_verts = leaf->getNumTexCoords(); nverts = new _ssgSave3dsData(num_verts, 2, 1); vdata = new float[ *num_verts * 2]; for (int i = 0; i < *num_verts; i++) { sgCopyVec2(&vdata[i*2], leaf->getTexCoord(i)); } _ssgSave3dsData *mapdata = new _ssgSave3dsData(vdata, 4, *num_verts * 2); maplist->addData(nverts); maplist->addData(mapdata); return maplist; } static _ssgSave3dsChunk* create_facemat_chunk( ssgLeaf* leaf ) { char* matname = get_material_name( (ssgSimpleState*)leaf->getState() ); char* namecopy = ulStrDup ( matname ) ; _ssgSave3dsData* namedata = new _ssgSave3dsData(namecopy, 1, strlen(matname) + 1); unsigned short *fmdata = new unsigned short[ leaf->getNumTriangles() + 1 ]; fmdata[0] = leaf->getNumTriangles(); for (int i = 0; i < leaf->getNumTriangles(); i++) { fmdata[i+1] = i; } _ssgSave3dsData* fmlist = new _ssgSave3dsData(fmdata, 2, leaf->getNumTriangles() + 1); _ssgSave3dsChunk* facemat = new _ssgSave3dsChunk( CHUNK_FACEMAT ); facemat->addData(namedata); facemat->addData(fmlist ); return facemat; } static _ssgSave3dsChunk* create_facelist_chunk( ssgLeaf* leaf ) { _ssgSave3dsChunk* facelist = new _ssgSave3dsChunk( CHUNK_FACELIST ); short* fdata = new short[leaf->getNumTriangles() * 4 + 1]; fdata[0] = leaf->getNumTriangles(); for (int i = 0; i < leaf->getNumTriangles(); i++) { leaf->getTriangle(i, &fdata[i * 4 + 1], &fdata[i * 4 + 2], &fdata[i * 4 + 3]); fdata[i * 4 + 4] = 7; // flag indicating anti-clockwise ordering (?) } _ssgSave3dsData *facedata = new _ssgSave3dsData(fdata, 2, leaf->getNumTriangles()*4 + 1); facelist->addData(facedata); facelist->addKid( create_facemat_chunk(leaf) ); return facelist; } static _ssgSave3dsChunk* create_transform_chunk() { // creates an identity transform _ssgSave3dsChunk* transform = new _ssgSave3dsChunk( CHUNK_TRMATRIX ); float* matrix = new float[12]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { matrix[i * 3 + j] = (i == j) ? 1.0f : 0.0f; } } _ssgSave3dsData* matdata = new _ssgSave3dsData( matrix, 4, 12 ); transform->addData(matdata); return transform; } static void traverse_objects( ssgEntity* node, _ssgSave3dsChunk *parent, sgMat4 transform ) { if ( node->isAKindOf( ssgTypeTransform() ) ) { sgMat4 local_transform; ssgTransform *t_node = (ssgTransform*)node; t_node->getTransform(local_transform); sgPostMultMat4( local_transform, transform ); for (ssgEntity* kid = t_node->getKid(0); kid != NULL; kid = t_node->getNextKid()) { traverse_objects( kid, parent, local_transform ); } } else if ( node->isAKindOf( ssgTypeBranch() ) ) { ssgBranch *b_node = (ssgBranch*)node; for (ssgEntity* kid = b_node->getKid(0); kid != NULL; kid = b_node->getNextKid()) { traverse_objects( kid, parent, transform ); } } else if ( node->isAKindOf( ssgTypeLeaf() ) ) { ssgLeaf* l_node = (ssgLeaf*)node; _ssgSave3dsChunk *mesh = new _ssgSave3dsChunk(CHUNK_TRIMESH ); mesh -> addKid( create_vertex_chunk (l_node, transform) ); mesh -> addKid( create_facelist_chunk(l_node) ); mesh -> addKid( create_transform_chunk() ); if (l_node->getNumTexCoords() > 0) { mesh -> addKid( create_maplist_chunk(l_node) ); } parent->addKid(mesh); } } static void create_objects_chunk( ssgEntity* ent, _ssgSave3dsChunk* parent ) { _ssgSave3dsChunk* objs = new _ssgSave3dsChunk(CHUNK_OBJBLOCK); static const char const_objname[] = "Object written by ssgSave3ds"; char *objname = ulStrDup ( const_objname ) ; objs->addData( new _ssgSave3dsData(objname, 1, strlen(objname)+1) ); parent->addKid(objs); sgMat4 ident; sgMakeIdentMat4( ident ); traverse_objects( ent, objs, ident ); } static _ssgSave3dsChunk *create_colour_chunk( unsigned short id, float* colour ) { _ssgSave3dsChunk *chunk = new _ssgSave3dsChunk(id); _ssgSave3dsChunk *rgbchunk = new _ssgSave3dsChunk(CHUNK_RGB1); float *colvec = new sgVec3; sgCopyVec3(colvec, colour); _ssgSave3dsData *coldata = new _ssgSave3dsData(colvec, 4, 3); rgbchunk->addData(coldata); chunk->addKid(rgbchunk); return chunk; } static _ssgSave3dsChunk *create_shininess_chunk( float shininess ) { _ssgSave3dsChunk *chunk = new _ssgSave3dsChunk(CHUNK_SHINE_STRENGTH); _ssgSave3dsChunk *percent = new _ssgSave3dsChunk(CHUNK_AMOUNT); unsigned short *amount = new unsigned short; *amount = (unsigned short)(shininess * 100.0f / 128.0f); _ssgSave3dsData *sdata = new _ssgSave3dsData(amount, 2, 1); percent->addData(sdata); chunk->addKid(percent); return chunk; } static _ssgSave3dsChunk *create_mapparam_chunk( unsigned short id, float val ) { _ssgSave3dsChunk *chunk = new _ssgSave3dsChunk( id ); float *f = new float; *f = val; chunk -> addData( new _ssgSave3dsData(f, 4, 1) ); return chunk; } static _ssgSave3dsChunk *create_map_chunk( ssgSimpleState *state ) { _ssgSave3dsChunk *map_chunk = new _ssgSave3dsChunk(CHUNK_TEXTURE); _ssgSave3dsChunk *mapname_chunk = new _ssgSave3dsChunk(CHUNK_MAPFILENAME); char *mapname = ulStrDup(state->getTextureFilename()); mapname_chunk -> addData( new _ssgSave3dsData(mapname, 1, strlen(mapname) + 1) ); map_chunk -> addKid(mapname_chunk); map_chunk -> addKid( create_mapparam_chunk( CHUNK_MAP_USCALE, 1.0f ) ); map_chunk -> addKid( create_mapparam_chunk( CHUNK_MAP_VSCALE, 1.0f ) ); map_chunk -> addKid( create_mapparam_chunk( CHUNK_MAP_UOFFST, 0.0f ) ); map_chunk -> addKid( create_mapparam_chunk( CHUNK_MAP_VOFFST, 0.0f ) ); return map_chunk; } static _ssgSave3dsChunk *create_material_chunk( ssgSimpleState *state ) { _ssgSave3dsChunk *mat = new _ssgSave3dsChunk(CHUNK_MATERIAL); _ssgSave3dsChunk *matname_chunk = new _ssgSave3dsChunk(CHUNK_MATNAME); char *matname; if (state->getName() != NULL) matname = ulStrDup(state->getName()); else { matname = new char[16]; sprintf(matname, "Material #%d", mat_count); } _ssgSave3dsData *matname_data = new _ssgSave3dsData(matname, 1, strlen(matname) + 1); matname_chunk->addData(matname_data); mat->addKid(matname_chunk); mat->addKid( create_colour_chunk( CHUNK_AMBIENT, state->getMaterial(GL_AMBIENT) ) ); mat->addKid( create_colour_chunk( CHUNK_DIFFUSE, state->getMaterial(GL_DIFFUSE) ) ); mat->addKid( create_colour_chunk( CHUNK_SPECULAR, state->getMaterial(GL_SPECULAR) ) ); mat->addKid( create_shininess_chunk( state->getShininess() ) ); if (state->isEnabled(GL_COLOR_MATERIAL)) { ulSetError(UL_WARNING, "State \"%s\" has GL_COLOR_MATERIAL enabled, which " \ "is not supported by 3DS format. Data will be lost.", matname); } if (state->getTextureFilename() != NULL) { mat->addKid( create_map_chunk(state) ); } return mat; } static void traverse_materials( ssgEntity* node, _ssgSave3dsChunk* parent ) { if ( node->isAKindOf( ssgTypeBranch() ) ) { ssgBranch *b_node = (ssgBranch*)node; for (ssgEntity* kid = b_node->getKid(0); kid != NULL; kid = b_node->getNextKid()) { traverse_materials( kid, parent ); } } else if ( node->isAKindOf( ssgTypeLeaf() ) ) { ssgLeaf* l_node = (ssgLeaf*)node; ssgSimpleState *state = (ssgSimpleState*)l_node->getState(); for (int i = 0; i < mat_count; i++) { if (state == mat[i]) return; } assert(mat_count < MAX_MATERIALS); mat[mat_count++] = state; parent->addKid( create_material_chunk(state) ); } } static void create_materials_chunk( ssgEntity* ent, _ssgSave3dsChunk* parent ) { mat_count = 0; for (int i = 0; i < MAX_MATERIALS; i++) { mat[i] = NULL; } traverse_materials( ent, parent ); } int ssgSave3ds( const char* filename, ssgEntity* ent ) { save_fd = fopen( filename, "wb" ); if (save_fd == NULL) { ulSetError( UL_WARNING, "ssgSave3ds: Failed to open '%s' for writing", filename ); return FALSE; } _ssgSave3dsChunk *top_chunk = new _ssgSave3dsChunk( CHUNK_MAIN ); _ssgSave3dsChunk *main_chunk = new _ssgSave3dsChunk( CHUNK_OBJMESH ); _ssgSave3dsChunk *version_chunk = new _ssgSave3dsChunk( CHUNK_VERSION ); unsigned int *version = new unsigned int; *version = 3; _ssgSave3dsData *versiondata = new _ssgSave3dsData(version, 4, 1); version_chunk -> addData(versiondata); top_chunk -> addKid( main_chunk ); top_chunk -> addKid( version_chunk ); create_materials_chunk (ent, main_chunk); create_objects_chunk (ent, main_chunk); top_chunk->write(); delete top_chunk; fclose(save_fd); return TRUE; } plib-1.8.5/src/ssg/ssgSaveATG.cxx0000644000175000001440000001127410765364437013472 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveATG.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ /* .scenery writer for SSG/PLIB ATG = ascii Terra Gear Written by Wolfram Kuss (Wolfram.Kuss@t-online.de) in May 2001 */ #include #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" int ssgSaveATG( const char* fname, ssgEntity *ent ) { FILE *fd = fopen ( fname, "w" ) ; int i; if ( fd == NULL ) { ulSetError ( UL_WARNING, "ssgSaveATG: Failed to open '%s' for writing", fname ); return FALSE ; } ssgVertexArray* vertices = new ssgVertexArray(); ssgIndexArray* indices = new ssgIndexArray (); fprintf(fd, "# Created by ssgSaveATG. Original graph structure was:\n"); ent->print(fd, "#", 0); sgMat4 ident; sgMakeIdentMat4( ident ); ssgSimpleStateArray ssa; // = new ssgSimpleStateArray(); ssgIndexArray* materialIndices = new ssgIndexArray(); ssgTexCoordArray * texCoordArray = new ssgTexCoordArray(); ssgAccumVerticesAndFaces( ent, ident, vertices, indices, /* epsilon = */ -1, &ssa, materialIndices, texCoordArray); assert ( vertices->getNum() == texCoordArray->getNum() ); for (i = 0; i < vertices->getNum(); i++) { fprintf(fd, "v %f %f %f\n", vertices->get(i)[0], vertices->get(i)[1], vertices->get(i)[2]); } // hack calc normal ssgNormalArray *na=new ssgNormalArray (vertices->getNum()); sgVec3 myVec3; myVec3[0]=0.0; myVec3[1]=0.0; myVec3[2]=1.0; sgVec3 n; int ind1, ind2, ind3; for (i = 0; i < vertices->getNum(); i++) na->add(myVec3); for (i = 0; i < indices->getNum(); i += 3) { ind1 = *indices->get(i); ind2 = *indices->get(i + 1); ind3 = *indices->get(i + 2); if ((vertices->get(ind1)!=NULL) && (vertices->get(ind2)!=NULL) && (vertices->get(ind3)!=NULL)) // wk: kludge: why can it be NULL? { sgMakeNormal( n, vertices->get(ind1), vertices->get(ind2), vertices->get(ind3) ); sgCopyVec3( na->get(ind1), n ); sgCopyVec3( na->get(ind2), n ); sgCopyVec3( na->get(ind3), n ); } } for (i = 0; i < vertices->getNum(); i++) { float *f = na->get(i); fprintf(fd, "vn %f %f %f\n", f[0], f[1], f[2]); } for (i = 0; i < texCoordArray->getNum(); i++) fprintf(fd, "vt %f %f\n", texCoordArray->get(i)[0], texCoordArray->get(i)[1]); // output all faces int runningIndex=0, lastIndex = -1; for (i = 0; i < indices->getNum(); i += 3) { // output material int matIndex = *(materialIndices->get(runningIndex++)); if (( matIndex >= 0 ) && ( lastIndex != matIndex )) { ssgSimpleState * ss = ssa.get( matIndex ); if ( ss->getTextureFilename() != NULL) { // remove .rgb char *s1, *s2, * s = new char [ strlen(ss->getTextureFilename()) +1 ]; assert ( s != NULL ); strcpy(s, ss->getTextureFilename()); char *p = strrchr(s, '.'); if ( p != NULL ) { if (((p[2]=='a') || (p[2]=='A')) && ((p[3]=='f') || (p[3]=='F'))) // *.?af textures are special: // the name before the ':' is not unique, you have to use the first character of the extension as // well. The tool af2rgb, which converts *.?af into rgb-files, also appends this char to the filename. { p[0]=p[1]; p[1]=0; } else *p = 0; } s2 = s; s1 = strrchr(s, '/'); if ( s1 != NULL ) s2 = ++s1; s1 = strrchr(s2, '\\'); if ( s1 != NULL ) s2 = ++s1; fprintf(fd, "# usemtl %s\n", s2); delete [] s; } lastIndex = matIndex; } // output face fprintf(fd, "f %d/%d %d/%d %d/%d\n", *indices->get(i), *indices->get(i), *indices->get(i + 1), *indices->get(i + 1), *indices->get(i + 2), *indices->get(i + 2) ); } assert ( runningIndex == materialIndices->getNum() ); delete materialIndices; fclose( fd ) ; delete vertices; delete indices ; return TRUE; } plib-1.8.5/src/ssg/ssgSaveQHI.cxx0000644000175000001440000000341110765364437013472 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveQHI.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" int ssgSaveQHI( const char* fname, ssgEntity *ent ) { FILE *fd = fopen ( fname, "w" ) ; int i; if ( fd == NULL ) { ulSetError ( UL_WARNING, "ssgSaveQHI: Failed to open '%s' for writing", fname ); return FALSE ; } ssgVertexArray* vertices = new ssgVertexArray(); sgMat4 ident; sgMakeIdentMat4( ident ); ssgAccumVerticesAndFaces( ent, ident, vertices, NULL, 0.0001f ); fprintf(fd, "3\n"); // Dimension fprintf(fd, "%d\n", vertices->getNum()); // No of points // Points: for (i = 0; i < vertices->getNum(); i++) { fprintf(fd, "%f %f %f\n", vertices->get(i)[0], vertices->get(i)[1], vertices->get(i)[2]); } fclose( fd ) ; delete vertices; return TRUE; } plib-1.8.5/src/ssg/ssgLoadSSG.cxx0000644000175000001440000001520510765364437013472 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadSSG.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ // code for loading and writing .ssg files #include "ssgLocal.h" // used for reading only: int _ssgFileVersionNumber = 0 ; // simple list of ssgBase derived objects: class _ssgBaseList : public ssgSimpleList { public: _ssgBaseList() : ssgSimpleList( sizeof(ssgBase *), 16 ) {} ~_ssgBaseList() {} ssgBase *get ( unsigned n ) { return n < total ? ((ssgBase **) list) [ n ] : NULL; } void add ( ssgBase *obj ) { sizeChk ( 1 ) ; ((ssgBase **) list) [ total++ ] = obj ; } int find ( ssgBase *obj ) { for ( unsigned i = 0 ; i < total ; i++ ) if ( ((ssgBase **) list) [ i ] == obj ) return i ; return -1 ; } }; // list of ssgBase objects for instance referencing: static _ssgBaseList *_ssgInstanceList ; int _ssgLoadObject ( FILE *f, ssgBase **objp, int type_mask ) { int type = 0, key = 0; ssgBase *obj; _ssgReadInt ( f, &type ) ; if ( type == _SSG_BACKWARDS_REFERENCE ) { _ssgReadInt ( f, &key ) ; obj = _ssgInstanceList -> get ( key ) ; if ( obj == NULL ) { if ( key != 0 ) { ulSetError ( UL_WARNING, "ssgLoadObject: Unexpected null object for key %d.", key ) ; return FALSE ; } } else if ( ! obj -> isAKindOf ( type_mask ) ) { ulSetError ( UL_WARNING, "ssgLoadObject: Bad type %#x (%s), expected %#x.", obj -> getType (), obj -> getTypeName (), type_mask ) ; return FALSE ; } } else { if ( ( type & type_mask ) != type_mask ) { ulSetError ( UL_WARNING, "ssgLoadObject: Bad type %#x, expected %#x.", type, type_mask ) ; return FALSE ; } obj = ssgCreateOfType ( type ) ; if ( obj == NULL ) return FALSE ; _ssgInstanceList -> add ( obj ) ; if ( ! obj -> load ( f ) ) { ulSetError ( UL_DEBUG, "ssgLoadObject: Failed to load object of type %s.", obj -> getTypeName () ) ; return FALSE ; } if ( obj -> isAKindOf ( ssgTypeEntity () ) ) { ((ssgEntity *) obj) -> recalcBSphere () ; } } if ( _ssgReadError () ) { ulSetError ( UL_WARNING, "ssgLoadObject: Read error." ) ; return FALSE ; } *objp = obj ; return TRUE ; } int _ssgSaveObject ( FILE *f, ssgBase *obj ) { int key = _ssgInstanceList -> find ( obj ) ; if ( key >= 0 ) { _ssgWriteInt ( f, _SSG_BACKWARDS_REFERENCE ) ; _ssgWriteInt ( f, key ) ; } else { _ssgWriteInt ( f, obj -> getType () ) ; _ssgInstanceList -> add ( obj ) ; if ( ! obj -> save ( f ) ) { ulSetError ( UL_DEBUG, "ssgSaveObject: Failed to save object of type %s.", obj -> getTypeName () ) ; return FALSE ; } } if ( _ssgWriteError () ) { ulSetError ( UL_WARNING, "ssgSaveObject: Write error." ) ; return FALSE ; } return TRUE ; } ssgEntity *ssgLoadSSG ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; const ssgLoaderOptions* current_options = ssgGetCurrentOptions () ; char filename [ 1024 ] ; current_options -> makeModelPath ( filename, fname ) ; FILE *fd = fopen ( filename, "rb" ) ; if ( fd == NULL ) { perror ( filename ) ; ulSetError ( UL_WARNING, "ssgLoadSSG: Failed to open '%s' for reading.", filename ) ; return NULL ; } int magic ; ssgEntity *kid ; _ssgReadInt ( fd, & magic ) ; if ( ( magic & 0xFFFFFF00 ) != ( SSG_FILE_MAGIC_NUMBER & 0xFFFFFF00 ) ) { if (((magic & 0x0000FF)>> 0)==((SSG_FILE_MAGIC_NUMBER & 0xFF000000)>>24) && ((magic & 0x00FF00)>> 8)==((SSG_FILE_MAGIC_NUMBER & 0x00FF0000)>>16) && ((magic & 0xFF0000)>>16)==((SSG_FILE_MAGIC_NUMBER & 0x0000FF00)>> 8) ) ulSetError ( UL_WARNING, "ssgLoadSSG: File appears to be byte swapped!" ) ; else ulSetError ( UL_WARNING, "ssgLoadSSG: File has incorrect magic number!" ) ; return NULL ; } /* Save the old version number so we can do recursive loads */ int oldFileVersion = _ssgFileVersionNumber ; _ssgFileVersionNumber = ( magic & 0xFF ) ; if ( _ssgFileVersionNumber == 0 ) { ulSetError ( UL_WARNING, "ssgLoadSSG: SSG file format version zero is no longer supported, sorry! For more, see the docs." ) ; _ssgFileVersionNumber = oldFileVersion ; return NULL ; } if ( _ssgFileVersionNumber > SSG_FILE_VERSION ) { ulSetError ( UL_WARNING, "ssgLoadSSG: This version of SSG is too old to load this file!" ) ; _ssgFileVersionNumber = oldFileVersion ; return NULL ; } _ssgBaseList *oldInstanceList = _ssgInstanceList ; // in case of recursive loads _ssgInstanceList = new _ssgBaseList ; _ssgInstanceList -> add ( NULL ) ; // index 0 --> NULL int success = _ssgLoadObject ( fd, (ssgBase **) &kid, ssgTypeEntity () ) ; if ( ! success ) { ulSetError ( UL_WARNING, "ssgLoadSSG: Failed to load object." ) ; kid = NULL ; } delete _ssgInstanceList ; _ssgInstanceList = oldInstanceList ; _ssgFileVersionNumber = oldFileVersion ; fclose ( fd ) ; return kid ; } int ssgSaveSSG ( const char *filename, ssgEntity *ent ) { FILE *fd = fopen ( filename, "wb" ) ; if ( fd == NULL ) { perror ( filename ) ; ulSetError ( UL_WARNING, "ssgSaveSSG: Failed to open '%s' for writing.", filename ) ; return FALSE ; } _ssgBaseList *oldInstanceList = _ssgInstanceList ; // for recursive saves _ssgInstanceList = new _ssgBaseList ; _ssgInstanceList -> add ( NULL ) ; // index 0 --> NULL _ssgWriteInt ( fd, SSG_FILE_MAGIC_NUMBER ) ; int success = _ssgSaveObject ( fd, ent ) ; if ( ! success ) ulSetError ( UL_WARNING, "ssgSaveSSG: Failed to write object." ) ; delete _ssgInstanceList ; _ssgInstanceList = oldInstanceList ; fclose ( fd ) ; return success ; } plib-1.8.5/src/ssg/ssgLoadX.cxx0000644000175000001440000005166210765364437013254 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadX.cxx 2065 2006-01-05 21:38:31Z fayjf $ */ // // .X loader for SSG/PLIB // .X is the 3D file format for Micro$ofts directX. // Written by Wolfram Kuss (Wolfram.Kuss@t-online.de) in Oct/Nov of 2000 // #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" #include "ssgParser.h" #define u32 unsigned int // These functions return TRUE on success typedef int HandlerFunctionType(const char *sName, const char *firstToken); static char *globEmpty=""; static ssgBranch *curr_branch_; struct EntityType { const char * sName; HandlerFunctionType *HandleEntity; int bMayBeIgnored; } ; static /* const */ ssgLoaderOptions* current_options = NULL ; static _ssgParserSpec parser_spec = { "\r\n\t ", // delim_chars_skipable ",;", // delim_chars_non_skipable NULL, // pre_processor "{", // open_brace_chars "}", // close_brace_chars '"', // quote_char '#', // comment_char "//" // comment_string } ; static _ssgParser parser; static ssgBranch* top_branch; static int Ascii2Int(int &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = int(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } static int Ascii2UInt(unsigned int &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = (unsigned int)(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } static int Ascii2Float(SGfloat &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = SGfloat(strtod( token, &endptr)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } static int HandleHeader(const char * /* sName */, const char *firstToken) { //parser.expectNextToken("{"); int Dummy; if (! Ascii2Int(Dummy, firstToken, "Header.major")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextInt(Dummy, "Header.minor")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextInt(Dummy, "Header.flags")) return FALSE; parser.expectNextToken(";"); parser.expectNextToken("}"); return TRUE; } static void IgnoreEntity(int startLevel) // startLevel should be 0 when you are "in front of the {" (normally) // or 1 when you have already parsed the "{" { int Level = startLevel; char *token; while ( TRUE) { token = parser.getNextToken(0); if ( parser.eof ) { parser.error("unexpected end of file\n"); return ; //FALSE; } assert(token!=NULL); if ( ulStrEqual (token,"{") ) Level++; else if ( ulStrEqual (token,"}") ) { assert(Level>0); // Fixme, NIV14: Handle this gracefully. if (Level==1) return; // found THE closing brace of entitiy Level--; // Found A closing brace } } } static int HandleMesh(const char *sName, const char *firstToken); static int HandleMeshMaterialList(const char *sName, const char *firstToken); static int HandleTextureCoords(const char *sName, const char *firstToken); static int HandleMaterial(const char *sName, const char *firstToken); static int HandleTextureFileName(const char *sName, const char *firstToken); static EntityType aEntities[] = { { "Header", HandleHeader, FALSE}, { "Vector", NULL, FALSE}, { "Coords2d", NULL, FALSE}, { "Quaternion", NULL, FALSE}, { "Matrix4x4", NULL, FALSE}, { "ColorRGBA", NULL, FALSE}, { "ColorRGB", NULL, FALSE}, { "Indexed Color", NULL, FALSE}, { "Boolean", NULL, FALSE}, { "Boolean2d", NULL, FALSE}, { "Material", HandleMaterial, FALSE}, { "TextureFilename", HandleTextureFileName, FALSE}, { "MeshFace", NULL, FALSE}, { "MeshFaceWraps", NULL, FALSE}, { "MeshTextureCoords", HandleTextureCoords, FALSE}, { "MeshNormals", NULL, TRUE}, { "MeshVertexColors", NULL, FALSE}, { "MeshMaterialList", HandleMeshMaterialList, FALSE}, { "Mesh", HandleMesh, FALSE}, { "FrameTransformMatrix", NULL, FALSE}, { "Frame", NULL, FALSE}, { "FloatKeys", NULL, FALSE}, { "TimedFloatKeys", NULL, FALSE}, { "AnimationKey", NULL, FALSE}, { "AnimationOptions", NULL, FALSE}, { "Animation", NULL, FALSE}, { "AnimationSet", NULL, FALSE}, { "template", NULL, TRUE}, { NULL, NULL, FALSE} }; static int ParseEntity(char *token) // called recursively { int i=0; while(aEntities[i].sName!=NULL) { if (ulStrEqual (token,aEntities[i].sName)) { if (aEntities[i].HandleEntity) { char *sNextToken, *sName=globEmpty; sNextToken=parser.getNextToken(0); if ( parser.eof ) { parser.error("unexpected end of file\n"); return FALSE; } // if entity is named, read the name. skip "{": sName = NULL; if (0 != strcmp(sNextToken, "{")) { sName = new char[ strlen(sNextToken) + 1 ]; assert ( sName ); strcpy(sName, sNextToken); sNextToken = parser.getNextToken(0); if (0 != strcmp(sNextToken, "{")) parser.error("\"{\" expected\n"); } sNextToken = parser.getNextToken(0); if(sNextToken[0] == '<') // UUID sNextToken = parser.getNextToken(0); if ( parser.eof ) { parser.error("unexpected end of file\n"); return FALSE; } if (!aEntities[i].HandleEntity(sName, sNextToken)) return FALSE; if ( sName ) delete [] sName; } else if (aEntities[i].bMayBeIgnored) IgnoreEntity ( 0 ); else { parser.error("I am sorry, but Entity-type '%s' is not yet implemented.", aEntities[i].sName); return FALSE ; } break; } i++; } if (aEntities[i].sName==NULL) { parser.error("unexpected token %s", token); return FALSE ; } return TRUE; } #define MAX_NO_VERTICES_PER_FACE 1000 static class ssgLoaderWriterMesh currentMesh; static ssgSimpleState *currentState; extern sgVec4 currentDiffuse; static int HandleTextureFileName(const char * /*sName*/, const char *firstToken) {/* TextureFilename { "../image/box_top.gif"; } #TextureFilename */ char *filename_ptr, *filename = new char [ strlen(firstToken)+1 ] ; assert(filename!=NULL); strcpy ( filename, firstToken ) ; filename_ptr = filename ; if ( filename_ptr[0] == '"' ) filename_ptr++; if (filename_ptr[strlen(filename_ptr)-1] == '"') filename_ptr[strlen(filename_ptr)-1] = 0; currentState -> setTexture( current_options -> createTexture( filename_ptr ) ); currentState -> enable( GL_TEXTURE_2D ); parser.expectNextToken(";"); parser.expectNextToken("}"); delete [] filename; return TRUE; } static class ssgSimpleStateList *globalMaterialList; static int HandleMaterial(const char * /*sName*/, const char *firstToken) // return TRUE on success { SGfloat power; int bFoundTextureFileName = FALSE; sgVec4 specularColour, EmissiveColour; // read body if (! Ascii2Float(currentDiffuse[0], firstToken, "Facecolour R")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(currentDiffuse[1], "Facecolour G")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(currentDiffuse[2], "Facecolour B")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(currentDiffuse[3], "Facecolour A")) return FALSE; parser.expectNextToken(";"); parser.expectNextToken(";"); if (!parser.getNextFloat(power, "power")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(specularColour[0], "Specular R")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(specularColour[1], "Specular G")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(specularColour[2], "Specular B")) return FALSE; specularColour[3] = 0.0; parser.expectNextToken(";"); parser.expectNextToken(";"); if (!parser.getNextFloat(EmissiveColour[0], "Emissive R")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(EmissiveColour[1], "Emissive G")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(EmissiveColour[2], "Emissive B")) return FALSE; EmissiveColour[3] = 0.0; parser.expectNextToken(";"); parser.expectNextToken(";"); // create SimpleState currentState = new ssgSimpleState () ; // currentState -> setMaterial ( GL_AMBIENT, mat -> amb ) ; currentState -> setMaterial ( GL_DIFFUSE, currentDiffuse) ; currentState -> setMaterial ( GL_SPECULAR, specularColour) ; currentState -> setMaterial ( GL_SPECULAR, specularColour[0], specularColour[1], specularColour[2], currentDiffuse[3] ) ; currentState -> setMaterial ( GL_EMISSION, EmissiveColour[0], EmissiveColour[1], EmissiveColour[2], currentDiffuse[3] ) ; currentState -> setShininess ( power ) ; // Fixme, NIV14: Is that correct? currentState -> enable ( GL_COLOR_MATERIAL ) ; currentState -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; currentState -> enable ( GL_LIGHTING ) ; currentState -> setShadeModel ( GL_SMOOTH ) ; if ( currentDiffuse[3] > 0.0f ) { currentState -> disable ( GL_ALPHA_TEST ) ; currentState -> enable ( GL_BLEND ) ; currentState -> setTranslucent () ; } else { currentState -> disable ( GL_BLEND ) ; currentState -> setOpaque () ; } currentState -> disable( GL_TEXTURE_2D ); while(TRUE) { char *nextToken =parser.getNextToken(0); if (0==strcmp("}", nextToken)) { /*if(currentMesh.theMaterialsExists()) currentMesh.addMaterial( ¤tState ); else*/ { if(!globalMaterialList) globalMaterialList = new ssgSimpleStateList(3); globalMaterialList->add(¤tState); } return TRUE; // Material is finished. success } if (! ulStrEqual ( "TextureFilename", nextToken) ) { parser.error("TextureFilename expected!\n"); return FALSE; } if ( bFoundTextureFileName ) { parser.error("Only one TextureFileName per Material please!\n"); return FALSE; } if (!ParseEntity(nextToken)) // read "TextureFileName" return FALSE; bFoundTextureFileName = TRUE; } return TRUE; //lint !e527 } static int HandleTextureCoords(const char * /* sName */, const char *firstToken) { u32 nNoOfVertices, i; if (! Ascii2UInt(nNoOfVertices, firstToken, "nNoOfVertices")) return FALSE; if ( nNoOfVertices != currentMesh.getNumVertices()) { parser.error("No of vertices of mesh (%d) and no " "of texture coordinates (%d) do not match!\n" "Therefore the texture coordinates are ignored!", ( int ) currentMesh.getNumVertices(), ( int ) nNoOfVertices ); IgnoreEntity ( 1 ); // ignores TC. return FALSE; } currentMesh.createPerVertexTextureCoordinates2( nNoOfVertices ) ; parser.expectNextToken(";"); for(i=0;i currentMesh.getNumFaces()) { parser.error("No of face indexes of materiallist (%d) is greater than then no " "of faces (%d)!\n" "Therefore the material list is ignored!", ( int ) nFaceIndexes, ( int ) currentMesh.getNumFaces()); IgnoreEntity ( 1 ); // ignores TC. return TRUE; // go on parsing } if ( nFaceIndexes > currentMesh.getNumFaces()) parser.message("Informational: No of face indexes of materiallist (%d) is less than then no " "of faces (%d)\n" , ( int ) nFaceIndexes, ( int ) currentMesh.getNumFaces()); for ( i=0 ; igetNum(); i++) { currentMesh.addMaterial(globalMaterialList->get(i)); } return TRUE; // Mesh is finished. success } if(ulStrEqual ("{", nextToken) ) { // reference to global material nextToken =parser.getNextToken(0); // name of material parser.expectNextToken("}"); // search for "name" in global list if(globalMaterialList == NULL) { parser.error("No global materials defined, but used!\n"); return FALSE; } for(int i=0; igetNum(); i++) { ssgSimpleState * ss = *(globalMaterialList->get(i)); if(ulStrEqual(nextToken, ss->getName())) break; } } else { if ( !ulStrEqual ("Material", nextToken) ) { parser.error("Material expected!\n"); return FALSE; } if ( nMaterialsRead >= nMaterials ) { parser.error("Too many Materials!\n"); return FALSE; } if (!ParseEntity(nextToken)) // read "Material" return FALSE; } nMaterialsRead++; } return TRUE; //lint !e527 } static int HandleMesh(const char * sName, const char *firstToken) { u32 i, j, nNoOfVertices, nNoOfVerticesForThisFace, nNoOfFaces; int iVertex, aiVertices[MAX_NO_VERTICES_PER_FACE]; //char *sMeshName = parser.getNextToken("Mesh name"); //parser.expectNextToken("{"); if (! Ascii2UInt(nNoOfVertices, firstToken, "nNoOfVertices")) return FALSE; //parser.getNextInt("number of vertices"); currentMesh.reInit (); currentMesh.setName( sName ); currentMesh.createVertices( nNoOfVertices ); parser.expectNextToken(";"); for(i=0;isetOpaque(); currentState->disable(GL_BLEND); currentState->disable(GL_ALPHA_TEST); currentState->disable(GL_TEXTURE_2D); currentState->enable(GL_COLOR_MATERIAL); currentState->enable(GL_LIGHTING); currentState->setShadeModel(GL_SMOOTH); currentState->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.7f, 1.0f); currentState->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.7f, 1.0f); currentState->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f); currentState->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f); currentState->setShininess(50); /* currentState -> setMaterial ( GL_AMBIENT, 0.5, 0.5, 0.5); currentState -> setMaterial ( GL_DIFFUSE, 0.7, 0.7, 0.7); // light grey currentState -> setMaterial ( GL_SPECULAR, 1.0, 1.0, 1.0); currentState -> setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0); currentState -> setShininess ( 3 ) ; //currentState -> enable ( GL_COLOR_MATERIAL ) ; //currentState -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; currentState -> enable ( GL_LIGHTING ) ; currentState -> setShadeModel ( GL_SMOOTH ) ; currentState -> disable ( GL_BLEND ) ; currentState -> setOpaque () ; currentState -> disable( GL_TEXTURE_2D ); */ } currentMesh.addToSSG( currentState // Pfusch, kludge. NIV135 , current_options, curr_branch_); return TRUE; } inline int TwoCharsToInt(char char1, char char2) { return ((int)(char1-'0'))*256+char2-'0'; } static int HeaderIsValid(char *firstToken) { // xof 0302txt 0064 if (!ulStrEqual (firstToken,"xof")) { parser.error("not X format, invalid Header"); return FALSE ; } char* token = parser.getNextToken("2nd Header field"); if (strlen(token)!=7) { parser.error("not X format, invalid Header"); return FALSE ; } char *sp=&(token[4]); if (!ulStrEqual (sp,"txt")) { if (!ulStrEqual (sp,"bin")) parser.error("not X format, invalid Header"); else parser.error("Binary X format files are not supported. If you have access to Windows, " "please use Microsofts conversion-utility convx from the directX-SDK " "to convert to ascii."); return FALSE ; } if (strncmp(token, "0302", 4)) parser.message("This loader is written for X-file-format version 3.2.\n" "AFAIK this is the only documented version.\n" "Your file has version %d.%d\n" "Use the file at your own risk\n", TwoCharsToInt(token[0], token[1]), TwoCharsToInt(token[2], token[3])); token = parser.getNextToken("3rd Header field"); if (!ulStrEqual(token,"0032") && !ulStrEqual (token,"0064")) { parser.error("not X format, invalid Header"); return FALSE ; } return TRUE; } static int parse() { int firsttime = TRUE; char* token; //int startLevel = parser.level; token = parser.getNextToken(0); while (! parser.eof ) { if (firsttime) { if(!HeaderIsValid(token)) return FALSE; firsttime = FALSE; } else { if (!ParseEntity(token)) return FALSE; } token = parser.getNextToken(0); } return TRUE ; } ssgEntity *ssgLoadX ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; currentState = NULL; globalMaterialList = NULL; top_branch = new ssgBranch ; curr_branch_ = top_branch; if ( !parser.openFile( fname, &parser_spec )) { delete top_branch ; return 0; } if ( !parse() ) { delete top_branch ; top_branch = 0 ; } // parse_free(); parser.closeFile(); delete globalMaterialList; return top_branch ; } plib-1.8.5/src/ssg/ssgLoadTexture.cxx0000644000175000001440000002336110765364437014500 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadTexture.cxx 2128 2007-10-03 02:42:32Z fayjf $ */ #include "ssgLocal.h" #include struct _ssgTextureFormat { const char *extension ; bool (*loadfunc) ( const char *, ssgTextureInfo* info ) ; } ; enum { MAX_FORMATS = 100 } ; static _ssgTextureFormat formats [ MAX_FORMATS ] ; static int num_formats = 0 ; static int total_texels_loaded = 0 ; int ssgGetNumTexelsLoaded () { return total_texels_loaded ; } bool ssgMakeMipMaps ( GLubyte *image, int xsize, int ysize, int zsize, bool freeData ) { bool non_power_of_two_tex_supported = ssgIsExtensionSupported( "GL_ARB_texture_non_power_of_two" ); if ( !non_power_of_two_tex_supported && ( ! ((xsize & (xsize-1))==0) || ! ((ysize & (ysize-1))==0) ) ) { ulSetError ( UL_WARNING, "Map is not a power-of-two in size!" ) ; return false ; } GLubyte *texels [ 20 ] ; /* One element per level of MIPmap */ for ( int l = 0 ; l < 20 ; l++ ) texels [ l ] = NULL ; texels [ 0 ] = image ; int lev ; for ( lev = 0 ; (( xsize >> (lev+1) ) != 0 || ( ysize >> (lev+1) ) != 0 ) ; lev++ ) { /* Suffix '1' is the higher level map, suffix '2' is the lower level. */ int l1 = lev ; int l2 = lev+1 ; int w1 = xsize >> l1 ; int h1 = ysize >> l1 ; int w2 = xsize >> l2 ; int h2 = ysize >> l2 ; if ( w1 <= 0 ) w1 = 1 ; if ( h1 <= 0 ) h1 = 1 ; if ( w2 <= 0 ) w2 = 1 ; if ( h2 <= 0 ) h2 = 1 ; texels [ l2 ] = new GLubyte [ w2 * h2 * zsize ] ; for ( int x2 = 0 ; x2 < w2 ; x2++ ) for ( int y2 = 0 ; y2 < h2 ; y2++ ) for ( int c = 0 ; c < zsize ; c++ ) { int x1 = x2 + x2 ; int x1_1 = ( x1 + 1 ) % w1 ; int y1 = y2 + y2 ; int y1_1 = ( y1 + 1 ) % h1 ; int t1 = texels [ l1 ] [ (y1 * w1 + x1 ) * zsize + c ] ; int t2 = texels [ l1 ] [ (y1_1 * w1 + x1 ) * zsize + c ] ; int t3 = texels [ l1 ] [ (y1 * w1 + x1_1) * zsize + c ] ; int t4 = texels [ l1 ] [ (y1_1 * w1 + x1_1) * zsize + c ] ; if ( c == 3 ) /* Alpha */ { int a = t1 ; if ( t2 > a ) a = t2 ; if ( t3 > a ) a = t3 ; if ( t4 > a ) a = t4 ; texels [ l2 ] [ (y2 * w2 + x2) * zsize + c ] = a ; } else texels [ l2 ] [ (y2 * w2 + x2) * zsize + c ] = ( t1 + t2 + t3 + t4 ) / 4 ; } } texels [ lev+1 ] = NULL ; glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ) ; int map_level = 0 ; #ifndef PROXY_TEXTURES_ARE_BROKEN GLint ww ; do { glTexImage2D ( GL_PROXY_TEXTURE_2D, map_level, zsize, xsize, ysize, FALSE /* Border */, (zsize==1)?GL_LUMINANCE: (zsize==2)?GL_LUMINANCE_ALPHA: (zsize==3)?GL_RGB: GL_RGBA, GL_UNSIGNED_BYTE, NULL ) ; glGetTexLevelParameteriv ( GL_PROXY_TEXTURE_2D, 0,GL_TEXTURE_WIDTH, &ww ) ; if ( ww == 0 ) { if ( freeData ) delete [] texels [ 0 ] ; else delete [] texels [ 1 ] ; /* User does not want input image freed, but we need to free all the rest of them */ xsize >>= 1 ; ysize >>= 1 ; for ( int l = 0 ; texels [ l ] != NULL ; l++ ) texels [ l ] = texels [ l+1 ] ; if ( xsize < 64 && ysize < 64 ) { ulSetError ( UL_FATAL, "SSG: OpenGL will not accept a downsized version ?!?" ) ; } } } while ( ww == 0 ) ; #endif for ( int i = 0 ; texels [ i ] != NULL ; i++ ) { int w = xsize>>i ; int h = ysize>>i ; if ( w <= 0 ) w = 1 ; if ( h <= 0 ) h = 1 ; total_texels_loaded += w * h ; glTexImage2D ( GL_TEXTURE_2D, map_level, zsize, w, h, FALSE /* Border */, (zsize==1)?GL_LUMINANCE: (zsize==2)?GL_LUMINANCE_ALPHA: (zsize==3)?GL_RGB: GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) texels[i] ) ; map_level++ ; if ( freeData || ( i > 0 ) ) delete [] texels [ i ] ; } return true ; } static void ssgLoadDummyTexture ( ssgTextureInfo* info ) { GLubyte *image = new GLubyte [ 2 * 2 * 3 ] ; /* Red and white chequerboard */ image [ 0 ] = 255 ; image [ 1 ] = 0 ; image [ 2 ] = 0 ; image [ 3 ] = 255 ; image [ 4 ] = 255 ; image [ 5 ] = 255 ; image [ 6 ] = 255 ; image [ 7 ] = 255 ; image [ 8 ] = 255 ; image [ 9 ] = 255 ; image [ 10] = 0 ; image [ 11] = 0 ; if ( info != NULL ) { info -> width = 2 ; info -> height = 2 ; info -> depth = 3 ; info -> alpha = 0 ; } ssgMakeMipMaps ( image, 2, 2, 3 ) ; } void ssgAddTextureFormat ( const char* extension, bool (*loadfunc) (const char*, ssgTextureInfo* info) ) { for ( int i = 0 ; i < num_formats ; i++ ) { if ( ulStrEqual ( formats [ i ] . extension, extension ) ) { formats [ i ] . extension = extension ; formats [ i ] . loadfunc = loadfunc ; return ; } } if ( num_formats < MAX_FORMATS ) { formats [ num_formats ] . extension = extension ; formats [ num_formats ] . loadfunc = loadfunc ; num_formats ++ ; } else { ulSetError ( UL_WARNING, "ssgAddTextureFormat: too many formats" ); } } static int fileMTimeCmp( const char *fname_input, const char *fname_output ) // Compare the two input file names against their modification time // -1: fname_input newer than fname_output // 1: fname_input older than fname_output // 0: stat error { #ifdef UL_WIN32 #define stat _stat #endif struct stat buffer_in, buffer_out; if ( stat( fname_input, &buffer_in ) == 0 && stat( fname_output, &buffer_out ) == 0 ) return buffer_in.st_mtime > buffer_out.st_mtime ? -1 : 1; else return 0; } bool ssgConvertTexture( char * fname_output, const char * fname_input ) // converts file to .rgb (Silicon Graphics) format // returns true if the file has been converted to rgb, or already exists as rgb // if it returns false, then it has already output an error message { char *extension ; strcpy( fname_output, fname_input); // copy so that a) there is enough room for .rgb and b) we don't change the buffer of fname_input extension = strrchr(fname_output, '.'); if ( extension == NULL ) { ulSetError(UL_WARNING, "There is no extension in the texture '%s'.", fname_input); return false; // no extension -> give up } extension[1] = 'r'; extension[2] = 'g'; extension[3] = 'b'; extension[4] = 0; if ( ulFileExists ( fname_output ) ) return true; // found *.rgb-file // look for original, non-rgb - file if ( !ulFileExists ( fname_input ) ) { ulSetError(UL_WARNING, "Can't find the texture file '%s'.", fname_input); return false; // no input file => we can't convert it } if ( ulFileExists ( fname_output ) && fileMTimeCmp( fname_input, fname_output ) != -1 ) return true; // found *.rgb-file, and it's newer than fname_input, so no conversion is needed // ****** found original file. convert it. ****** char command [ 1024 ] ; char *conv_cmd = #ifdef UL_WIN32 "imconvert"; #else "convert"; #endif sprintf(command, "%s -verbose %s sgi:%s", conv_cmd, fname_input, fname_output); if ( system( command ) < 0 || !ulFileExists ( fname_output ) ) { ulSetError(UL_WARNING, "Couldn't convert texture '%s'. Did you install ImageMagick?" " You may also convert it manually to '%s' and reload the model.", fname_input, fname_output); return false; } return true; } bool ssgLoadTexture ( const char * filename, ssgTextureInfo* info ) { if ( info != NULL ) { info -> width = 0 ; info -> height = 0 ; info -> depth = 0 ; info -> alpha = 0 ; } if ( filename == NULL || *filename == '\0' ) return false ; //find extension const char *extn = & ( filename [ strlen(filename) ] ) ; while ( extn != filename && *extn != '/' && *extn != '.' ) extn-- ; if ( *extn != '.' ) { ulSetError ( UL_WARNING, "ssgLoadTexture: Cannot determine file type for '%s'", filename ); ssgLoadDummyTexture ( info ) ; return false ; } _ssgTextureFormat *f = formats ; for ( int i=0; iloadfunc != NULL && ulStrNEqual ( extn, f->extension, strlen(f->extension) ) ) { if ( f->loadfunc( filename, info ) ) return true ; ssgLoadDummyTexture ( info ) ; /* fail */ return false ; } } #ifdef SSG_LOAD_SGI_SUPPORTED char * fname_output = new char [ strlen(filename) + 4 ]; // +4 as reserve for .rgb if ( ssgConvertTexture( fname_output, filename) ) if ( ssgLoadSGI ( fname_output, info ) ) { delete [] fname_output; return true; } delete [] fname_output; #else ulSetError ( UL_WARNING, "ssgLoadTexture: Unrecognised file type '%s'", extn ) ; #endif ssgLoadDummyTexture ( info ) ; return false ; } plib-1.8.5/src/ssg/ssgSaveAC.cxx0000644000175000001440000001532010765364437013336 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveAC.cxx 2117 2007-09-13 23:21:09Z fayjf $ */ #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" static ssgSimpleStateArray gSSL ; static const int writeTextureWithoutPath = TRUE ; struct saveTriangle { int v [ 3 ] ; sgVec2 t [ 3 ] ; } ; static FILE *save_fd ; static sgVec3 *vlist ; static saveTriangle *tlist ; static int ssgSaveLeaf ( ssgEntity *ent ) { int i; assert ( ent -> isAKindOf ( ssgTypeLeaf() ) ) ; ssgLeaf *vt = (ssgLeaf *) ent ; int num_verts = vt -> getNumVertices () ; int num_tris = vt -> getNumTriangles () ; vlist = new sgVec3 [ num_verts ] ; tlist = new saveTriangle [ num_tris ] ; for ( i = 0 ; i < num_verts; i++ ) sgCopyVec3 ( vlist[i], vt->getVertex ( i ) ) ; for ( i = 0 ; i < num_tris ; i++ ) { short vv0, vv1, vv2 ; vt -> getTriangle ( i, &vv0, &vv1, &vv2 ) ; tlist[i].v[0] = vv0 ; tlist[i].v[1] = vv1 ; tlist[i].v[2] = vv2 ; sgCopyVec2 ( tlist[i].t[0], vt->getTexCoord ( vv0 ) ) ; sgCopyVec2 ( tlist[i].t[1], vt->getTexCoord ( vv1 ) ) ; sgCopyVec2 ( tlist[i].t[2], vt->getTexCoord ( vv2 ) ) ; } fprintf ( save_fd, "OBJECT poly\n" ) ; fprintf ( save_fd, "name \"%s\"\n", ent->getPrintableName() ) ; ssgState* st = vt -> getState () ; if ( st && st -> isAKindOf ( ssgTypeSimpleState() ) ) { ssgSimpleState* ss = (ssgSimpleState*) vt -> getState () ; if ( ss -> isEnabled ( GL_TEXTURE_2D ) ) { const char* tfname = ss -> getTextureFilename () ; if (( tfname != NULL ) && ( tfname[0] != 0 )) { if ( writeTextureWithoutPath ) { const char *s = strrchr ( tfname, '\\' ) ; if ( s == NULL ) s = strrchr ( tfname, '/' ) ; if ( s == NULL ) fprintf ( save_fd, "texture \"%s\"\n", tfname ) ; else fprintf ( save_fd, "texture \"%s\"\n", ++s ) ; } else fprintf ( save_fd, "texture \"%s\"\n", tfname ) ; } } } fprintf ( save_fd, "numvert %d\n", num_verts ) ; for ( i = 0 ; i < num_verts ; i++ ) fprintf ( save_fd, "%g %g %g\n", vlist[i][0],vlist[i][2],-vlist[i][1] ) ; fprintf ( save_fd, "numsurf %d\n", num_tris ) ; for ( i = 0 ; i < num_tris ; i++ ) { fprintf ( save_fd, "SURF 0x0%x\n", (! vt -> getCullFace () ) << 5 ) ; ssgState *s = vt->getState (); int istate = 0; if ( s != NULL ) if ( s -> isAKindOf ( ssgTypeSimpleState() ) ) { istate = gSSL.findIndex ( (ssgSimpleState *) s ) ; assert ( istate >= 0 ) ; } fprintf ( save_fd, "mat %d\n", istate ) ; fprintf ( save_fd, "refs 3\n" ) ; fprintf ( save_fd, "%d %g %g\n", tlist[i].v[0],tlist[i].t[0][0],tlist[i].t[0][1] ) ; fprintf ( save_fd, "%d %g %g\n", tlist[i].v[1],tlist[i].t[1][0],tlist[i].t[1][1] ) ; fprintf ( save_fd, "%d %g %g\n", tlist[i].v[2],tlist[i].t[2][0],tlist[i].t[2][1] ) ; } fprintf ( save_fd, "kids 0\n" ) ; delete [] vlist ; delete [] tlist ; return TRUE ; } static int ssgSaveACInner ( ssgEntity *ent ) { /* WARNING - RECURSIVE! */ if ( ent -> isAKindOf ( ssgTypeBranch() ) ) { ssgBranch *br = (ssgBranch *) ent ; fprintf ( save_fd, "OBJECT group\n" ) ; fprintf ( save_fd, "kids %d\n", ent->getNumKids() ) ; for ( int i = 0 ; i < br -> getNumKids () ; i++ ) if ( ! ssgSaveACInner( br -> getKid ( i ) ) ) return FALSE ; return TRUE ; } return ssgSaveLeaf ( ent ) ; } int ssgSaveAC ( const char *filename, ssgEntity *ent ) { int i ; save_fd = fopen ( filename, "wa" ) ; if ( save_fd == NULL ) { ulSetError ( UL_WARNING, "ssgSaveAC: Failed to open '%s' for writing", filename ) ; return FALSE ; } fprintf ( save_fd, "AC3Db\n" ) ; gSSL.collect( ent ); /* There is a *huge* problem here. The AC3D format doesn't support per-vertex or even per-polygon colours. You *must* use materials. Hence what we really should do is to collect together all the per-vertex colours in the SSG model and make a material from each one (possibly more if that colour is on many polygons which have different ssgSimpleState's. For now, I'll cheat and set the GL_COLORMATERIAL colours to white - which works *reasonably* well for most heavily textured models...well, at least you don't get uninitialised colours coming from SSG. */ for (i = 0 ; i < gSSL.getNum(); i++) { sgVec4 white = { 1, 1, 1, 1 } ; ssgSimpleState * ss = gSSL.get(i); float *em = ss->getMaterial (GL_EMISSION ); float *sp = ss->getMaterial (GL_SPECULAR ); float *am = ss->getMaterial (GL_AMBIENT ); float *di = ss->getMaterial (GL_DIFFUSE ); if ( ss->isEnabled ( GL_COLOR_MATERIAL ) ) { switch ( ss->getColourMaterial () ) { case GL_AMBIENT_AND_DIFFUSE : am = di = white ; break ; case GL_EMISSION : em = white ; break ; case GL_SPECULAR : sp = white ; break ; case GL_AMBIENT : am = white ; break ; case GL_DIFFUSE : di = white ; break ; } } int shiny = (int) ss->getShininess (); fprintf ( save_fd, "MATERIAL \"%s\"" " rgb %f %f %f" " amb %f %f %f" " emis %f %f %f" " spec %f %f %f" " shi %d trans %f\n", ss->getPrintableName(), di[0], di[1], di[2], am[0], am[1], am[2], em[0], em[1], em[2], sp[0], sp[1], sp[2], shiny, 1.0-di[3] ) ; } fprintf ( save_fd, "OBJECT world\n" ) ; fprintf ( save_fd, "kids 1\n" ) ; int bReturn = ssgSaveACInner ( ent ) ; gSSL.removeAll () ; fclose ( save_fd ) ; return bReturn ; } plib-1.8.5/src/ssg/ssgLoadMDL_BGLTexture.cxx0000644000175000001440000002442710765364437015525 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadMDL_BGLTexture.cxx 2117 2007-09-13 23:21:09Z fayjf $ */ //=========================================================================== // // File: ssgLoadMDL_BGLTexture.cxx // // Created: Jun 1 22:20:31 2002 // // Author: Thomas Engh Sevaldrud // Juergen Marquardt // // Revision: $Id: ssgLoadMDL_BGLTexture.cxx 2117 2007-09-13 23:21:09Z fayjf $ // // Description: // // Changes: by Juergen Marquardt // - separated from ssgLoadMDL // it's now used by ssgLoadMDL and ssgLoadBGL // - added support for translucatant textures // - rindex replaced by strrchr // //=========================================================================== #include "ssgLocal.h" #include "ssgMSFSPalette.h" //=========================================================================== // Texture palette values (from fs5.pal) // Alpha channel added for more efficient // rendering on 3dfx hardware. unsigned const char ssgFsTexPalette[1024] = { 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08, 0xff, 0x10, 0x10, 0x10, 0xff, 0x18, 0x18, 0x18, 0xff, 0x20, 0x20, 0x20, 0xff, 0x28, 0x28, 0x28, 0xff, 0x30, 0x30, 0x30, 0xff, 0x38, 0x38, 0x38, 0xff, 0x41, 0x41, 0x41, 0xff, 0x49, 0x49, 0x49, 0xff, 0x51, 0x51, 0x51, 0xff, 0x59, 0x59, 0x59, 0xff, 0x61, 0x61, 0x61, 0xff, 0x69, 0x69, 0x69, 0xff, 0x71, 0x71, 0x71, 0xff, 0x79, 0x79, 0x79, 0xff, 0x82, 0x82, 0x82, 0xff, 0x8a, 0x8a, 0x8a, 0xff, 0x92, 0x92, 0x92, 0xff, 0x9a, 0x9a, 0x9a, 0xff, 0xa2, 0xa2, 0xa2, 0xff, 0xaa, 0xaa, 0xaa, 0xff, 0xb2, 0xb2, 0xb2, 0xff, 0xba, 0xba, 0xba, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xcb, 0xcb, 0xcb, 0xff, 0xd3, 0xd3, 0xd3, 0xff, 0xdb, 0xdb, 0xdb, 0xff, 0xe3, 0xe3, 0xe3, 0xff, 0xeb, 0xeb, 0xeb, 0xff, 0xf7, 0xf7, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x05, 0x05, 0xff, 0x2a, 0x0a, 0x0a, 0xff, 0x3f, 0x0f, 0x0f, 0xff, 0x54, 0x14, 0x14, 0xff, 0x69, 0x19, 0x19, 0xff, 0x7e, 0x1e, 0x1e, 0xff, 0x93, 0x23, 0x23, 0xff, 0xa8, 0x28, 0x28, 0xff, 0xbd, 0x2d, 0x2d, 0xff, 0xd2, 0x32, 0x32, 0xff, 0xe7, 0x37, 0x37, 0xff, 0xfc, 0x3c, 0x3c, 0xff, 0x05, 0x15, 0x05, 0xff, 0x0a, 0x2a, 0x0a, 0xff, 0x0f, 0x3f, 0x0f, 0xff, 0x14, 0x54, 0x14, 0xff, 0x19, 0x69, 0x19, 0xff, 0x1e, 0x7e, 0x1e, 0xff, 0x23, 0x93, 0x23, 0xff, 0x28, 0xa8, 0x28, 0xff, 0x2d, 0xbd, 0x2d, 0xff, 0x32, 0xd2, 0x32, 0xff, 0x37, 0xe7, 0x37, 0xff, 0x3c, 0xfc, 0x3c, 0xff, 0x00, 0x07, 0x17, 0xff, 0x00, 0x0f, 0x28, 0xff, 0x00, 0x17, 0x3a, 0xff, 0x00, 0x28, 0x54, 0xff, 0x00, 0x40, 0x68, 0xff, 0x00, 0x47, 0x7a, 0xff, 0x00, 0x57, 0x8f, 0xff, 0x00, 0x63, 0x9c, 0xff, 0x00, 0x70, 0xb3, 0xff, 0x00, 0x80, 0xc7, 0xff, 0x00, 0x8f, 0xd7, 0xff, 0x00, 0x99, 0xe6, 0xff, 0x1c, 0x0e, 0x00, 0xff, 0x38, 0x1c, 0x00, 0xff, 0x54, 0x2a, 0x00, 0xff, 0x70, 0x38, 0x00, 0xff, 0x8c, 0x46, 0x00, 0xff, 0xa8, 0x54, 0x00, 0xff, 0xc4, 0x62, 0x00, 0xff, 0xe0, 0x70, 0x00, 0xff, 0xfc, 0x7e, 0x00, 0xff, 0x1c, 0x1c, 0x00, 0xff, 0x38, 0x38, 0x00, 0xff, 0x54, 0x54, 0x00, 0xff, 0x70, 0x70, 0x00, 0xff, 0x8c, 0x8c, 0x00, 0xff, 0xa8, 0xa8, 0x00, 0xff, 0xc4, 0xc4, 0x00, 0xff, 0xe0, 0xe0, 0x00, 0xff, 0xfc, 0xfc, 0x00, 0xff, 0x19, 0x15, 0x10, 0xff, 0x32, 0x2a, 0x20, 0xff, 0x4b, 0x3f, 0x30, 0xff, 0x64, 0x54, 0x40, 0xff, 0x7d, 0x69, 0x50, 0xff, 0x96, 0x7e, 0x60, 0xff, 0xaf, 0x93, 0x70, 0xff, 0xc8, 0xa8, 0x80, 0xff, 0xe1, 0xbd, 0x90, 0xff, 0x1c, 0x0b, 0x07, 0xff, 0x38, 0x16, 0x0e, 0xff, 0x54, 0x21, 0x15, 0xff, 0x70, 0x2c, 0x1c, 0xff, 0x8c, 0x37, 0x23, 0xff, 0xa8, 0x42, 0x2a, 0xff, 0xc4, 0x4d, 0x31, 0xff, 0xe0, 0x58, 0x38, 0xff, 0xfc, 0x63, 0x3f, 0xff, 0x11, 0x16, 0x09, 0xff, 0x22, 0x2c, 0x12, 0xff, 0x33, 0x42, 0x1b, 0xff, 0x44, 0x58, 0x24, 0xff, 0x55, 0x6e, 0x2d, 0xff, 0x66, 0x84, 0x36, 0xff, 0x77, 0x9a, 0x3f, 0xff, 0x88, 0xb0, 0x48, 0xff, 0x99, 0xc6, 0x51, 0xff, 0x00, 0x3a, 0x68, 0xff, 0x00, 0x57, 0x70, 0xff, 0x2b, 0x70, 0x80, 0xff, 0xff, 0x00, 0x00, 0xff, 0x40, 0xff, 0x40, 0xff, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x69, 0x69, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x51, 0x51, 0x51, 0xff, 0x79, 0x79, 0x79, 0xff, 0x92, 0x92, 0x92, 0xff, 0xaa, 0xaa, 0xaa, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xe3, 0xe3, 0xe3, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xc0, 0xc0, 0xff, 0xff, 0xc8, 0xc8, 0xff, 0xff, 0xd0, 0xd0, 0xff, 0xff, 0xd8, 0xd8, 0xff, 0xff, 0xe0, 0xe0, 0xff, 0xff, 0xe8, 0xe8, 0xff, 0xff, 0xf0, 0xf0, 0xff, 0xff, 0xf8, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x48, 0x10, 0xff, 0x20, 0x50, 0x20, 0xff, 0x30, 0x58, 0x30, 0xff, 0x40, 0x60, 0x40, 0xff, 0x50, 0x68, 0x50, 0xff, 0x60, 0x70, 0x60, 0xff, 0x70, 0x78, 0x70, 0xff, 0x78, 0x7c, 0x78, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x21, 0x8c, 0xbd, 0xff, 0x39, 0x84, 0xa5, 0xff, 0xbd, 0x42, 0x42, 0xff, 0x9c, 0x42, 0x42, 0xff, 0x84, 0x4a, 0x4a, 0xff, 0x21, 0x52, 0x6b, 0xff, 0xd6, 0x5a, 0x52, 0xff, 0xbd, 0x5a, 0x52, 0xff, 0xa5, 0x5a, 0x52, 0xff, 0x7b, 0x39, 0x31, 0xff, 0x63, 0x39, 0x31, 0xff, 0x6b, 0x4a, 0x42, 0xff, 0x7b, 0x5a, 0x52, 0xff, 0xb5, 0x5a, 0x42, 0xff, 0x4a, 0x31, 0x29, 0xff, 0xbd, 0x73, 0x5a, 0xff, 0x8c, 0x5a, 0x31, 0xff, 0x21, 0x31, 0x4a, 0xff, 0xb5, 0x73, 0x31, 0xff, 0x63, 0x42, 0x21, 0xff, 0xa5, 0x73, 0x42, 0xff, 0x31, 0x29, 0x21, 0xff, 0xa5, 0x8c, 0x73, 0xff, 0xbd, 0xa5, 0x8c, 0xff, 0x39, 0x63, 0x7b, 0xff, 0xb5, 0x6b, 0x18, 0xff, 0xce, 0x7b, 0x21, 0xff, 0x9c, 0x63, 0x21, 0xff, 0x94, 0x6b, 0x31, 0xff, 0x6b, 0x52, 0x31, 0xff, 0x21, 0x21, 0x39, 0xff, 0x21, 0x73, 0xa5, 0xff, 0xd6, 0xd6, 0x21, 0xff, 0xad, 0xad, 0x21, 0xff, 0xc6, 0xc6, 0x29, 0xff, 0x8c, 0x8c, 0x21, 0xff, 0x73, 0x73, 0x21, 0xff, 0xbd, 0xbd, 0x39, 0xff, 0x9c, 0x9c, 0x31, 0xff, 0xad, 0xad, 0x39, 0xff, 0x7b, 0x7b, 0x31, 0xff, 0x7b, 0x7b, 0x42, 0xff, 0x4a, 0x4a, 0x31, 0xff, 0x7b, 0x7b, 0x5a, 0xff, 0x29, 0x29, 0x21, 0xff, 0x5a, 0x63, 0x39, 0xff, 0x6b, 0x73, 0x4a, 0xff, 0x7b, 0x94, 0x52, 0xff, 0x8c, 0xad, 0x63, 0xff, 0x84, 0x9c, 0x63, 0xff, 0x31, 0x42, 0x29, 0xff, 0x63, 0xa5, 0x5a, 0xff, 0x4a, 0xd6, 0x4a, 0xff, 0x39, 0x8c, 0x39, 0xff, 0x4a, 0xb5, 0x4a, 0xff, 0x5a, 0xc6, 0x5a, 0xff, 0x39, 0x7b, 0x39, 0xff, 0x31, 0x63, 0x31, 0xff, 0x5a, 0xa5, 0x5a, 0xff, 0x52, 0x94, 0x52, 0xff, 0x4a, 0x63, 0x4a, 0xff, 0x39, 0x73, 0x84, 0xff, 0x21, 0x63, 0x7b, 0xff, 0x4a, 0x73, 0x84, 0xff }; #ifdef SSG_LOAD_MDL_BGL_TEXTURE_SUPPORTED // This really simple (raw paletted) format is used by older MSFS for textures bool ssgLoadMDLTexture ( const char *fname, ssgTextureInfo* info ) { FILE *tfile; int index = 0; if ( (tfile = fopen(fname, "rb")) == NULL) { char *dupfname = strdup( fname); char *p = strrchr( dupfname,'_'); if (p != 0) { *p = '\0'; p++; index = atoi (p); if ( (tfile = fopen(dupfname, "rb")) == NULL) { ulSetError( UL_WARNING, "ssgLoadTexture: Failed to load '%s'.", dupfname ); free( dupfname); return false ; } free( dupfname); } else { ulSetError( UL_WARNING, "ssgLoadTexture: Failed to load '%s'.", fname ); free( dupfname); return false ; } } fseek(tfile, 0, SEEK_END); unsigned long file_length = ftell(tfile); if (file_length != 65536) { // this is not a MSFS-formatted texture, so it's probably a BMP fclose(tfile); return ssgLoadBMP( fname, info ); } else { fseek(tfile, 0, SEEK_SET); unsigned char *texels = new unsigned char[256 * 256 * 4]; int c = 0; for (int y = 0; y < 256; y++) { for (int x = 0; x < 256; x++) { unsigned char b; fread(&b, 1, 1, tfile); texels[c++] = ssgFsTexPalette[b*4 ]; texels[c++] = ssgFsTexPalette[b*4 + 1]; texels[c++] = ssgFsTexPalette[b*4 + 2]; texels[c++] = (b width = 256 ; info -> height = 256 ; info -> depth = 4 ; info -> alpha = TRUE ; //?? } return ssgMakeMipMaps ( texels, 256, 256, 4 ) ; } } #else bool ssgLoadMDLTexture ( const char *fname, ssgTextureInfo* info ) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - MDL/BGL Texture support not configured", fname ) ; return false ; } #endif plib-1.8.5/src/ssg/ssgSaveASC.cxx0000644000175000001440000001352310765364437013464 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ // // ASC (ascii files, used for example by 3DS R4 (the DOS version)) export for SSG/PLIB // Written by Wolfram Kuss in Mar-2003 // #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" static FILE *save_fd ; static ssgSimpleStateArray gSSL; float save_scale = 1.0f; int calledByTheHuman = TRUE; static void save_vtx_table ( ssgVtxTable *vt ) { GLenum mode = vt -> getPrimitiveType () ; if ( mode != GL_TRIANGLES && mode != GL_TRIANGLE_FAN && mode != GL_TRIANGLE_STRIP ) { //only triangle export return; } /* Named object: */ int j ; int istate = gSSL.findIndex ( (ssgSimpleState*)vt->getState () ) ; int num_vert = vt -> getNumVertices () ; int num_face = vt -> getNumTriangles () ; ssgSimpleState* st = ( istate != -1 )? gSSL.get( istate ): 0; bool mapped = ( st && st -> isEnabled ( GL_TEXTURE_2D ) && vt -> getNumTexCoords () == num_vert ); fprintf ( save_fd, "Named object: \"%s\"\n", vt->getPrintableName()); fprintf ( save_fd, "Tri-mesh, Vertices: %d Faces: %d\n", num_vert, num_face ); if(mapped) fprintf ( save_fd, "Mapped\n"); /* Vertex list: */ fprintf ( save_fd, "Vertex list:\n"); const char *material = "PALGREY27"; ssgState *s = vt->getState(); if (s) if(s->isAKindOf(ssgTypeSimpleState())) { ssgTexture * t = ((ssgSimpleState *)s)->getTexture(); if(t) { char *fn = t->getFilename(); if (fn) { char *tsA = new char [strlen(fn)+1]; // kludge: mem leak! strcpy(tsA, fn); char *t = strrchr(tsA, '\\'); if (!t) t = tsA; else t++; char *t1 = strrchr(t, '/'); if (!t1) t1 = t; else t1++; char *t2 = strrchr(t1, '.'); if (t2) { // special handling for *.0af .. *.9af to be able to differntiate between them: if((t2[2]=='a') && (t2[3]=='f')) *t2='_'; else *t2=0; } material = t1; } } } for ( j = 0; j < num_vert; j++ ) { sgVec3 v; sgCopyVec3 ( v, vt->getVertex ( j ) ) ; fprintf ( save_fd, "Vertex %d: X:%f Y:%f Z:%f", j, save_scale*v[0], save_scale*v[1], save_scale*v[2] ); if(mapped) { sgVec2 tv ; sgCopyVec2 ( tv, vt->getTexCoord ( j ) ) ; // *************************************************** // WK: Originally I did not have the "U:" and "V:" !!! // Strange !! Maybe there are two formats?? // *************************************************** fprintf ( save_fd, " U:%f V:%f\n", tv[0], tv[1]); // 1.0f - tv[1]); } else fprintf ( save_fd, "\n"); } /* Face list: */ if(num_face > 0) fprintf ( save_fd, "Face list:\n"); for ( j = 0; j < num_face; j++ ) { short i1,i2,i3; vt -> getTriangle ( j, &i1, &i2, &i3 ) ; fprintf ( save_fd, "Face %d: A:%d B:%d C:%d AB:1 BC:1 CA:1\n", j, i1, i2, i3 ); fprintf ( save_fd, "Material:\"%s\"\n", material ); } fprintf ( save_fd, "\n"); // empty line after the named object /* Item MESH_NUMTVERTEX. */ fflush ( save_fd ) ; /* Item NUMCVERTEX. */ //fprintf ( save_fd, " *MESH_NUMCVERTEX 0\n" ); //if ( st ) fprintf ( save_fd, " *MATERIAL_REF %d\n", gSSL.findIndex ( st ) ); } // wk: Kludge !!! // if the "calling app" like PPE sets this, then only nodes with spare ==1 are saved !! int bUseSpare=FALSE; static void save_geom ( ssgEntity *e ) { if ( e -> isAKindOf ( ssgTypeBranch() ) ) { ssgBranch *br = (ssgBranch *) e ; for (int i = 0 ; i < br -> getNumKids () ; i++ ) save_geom ( br -> getKid ( i ) ) ; } else if ( e -> isAKindOf ( ssgTypeVtxTable() ) ) { int bSaveIt = TRUE; if(bUseSpare) if( 1 != e->getSpare() ) bSaveIt = FALSE; if ( bSaveIt ) { ssgVtxTable *vt = (ssgVtxTable *) e ; save_vtx_table ( vt ) ; } } } int ssgSaveASC ( FILE* fileout, ssgEntity *ent ) { save_fd = fileout ; /* Write the header. */ fprintf ( save_fd, "Ambient light color: Red=0.039216 Green=0.039216 Blue=0.039216\n" ); fprintf ( save_fd, "Solid background color: Red=0.372549 Green=0.454902 Blue=0.639216\n" ); gSSL.collect ( ent ) ; //save_states () ; save_geom ( ent ) ; gSSL.removeAll(); fflush ( save_fd ) ; return TRUE ; } int ssgSaveASC ( const char *filename, ssgEntity *ent ) { save_fd = fopen ( filename, "wa" ) ; if ( save_fd == NULL ) { ulSetError ( UL_WARNING, "ssgSaveASC: Failed to open '%s' for writing", filename ) ; return FALSE ; } if(calledByTheHuman) if(save_scale!=1.0f) { #ifdef WIN32 char temp[999]; sprintf(temp, "Applying a scale factor of %f", save_scale); ::MessageBox(0, temp, "For your info:", 0); #else printf("Applying a scale factor of %f", save_scale); #endif } int result = ssgSaveASC ( save_fd, ent ) ; fclose ( save_fd ) ; return result ; } plib-1.8.5/src/ssg/ssgSaveOBJ.cxx0000644000175000001440000001165110765364437013470 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveOBJ.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ // // Wavefront OBJ export for SSG/PLIB // Ported from IVCON by Dave McClurg (dpm@efn.org) in March-2000 // #include "ssgLocal.h" static FILE *fileout ; static int total_vert ; static int total_normal ; static void save_vtx_table ( ssgVtxTable *vt ) { float w = 1.0f ; short iv1, iv2; GLenum mode = vt -> getPrimitiveType () ; //fprintf ( fileout, "g test\n" ); wk: Pfusch fixme: is this necessary? NIV135 if (( mode == GL_LINES ) || ( mode == GL_LINE_LOOP) || ( mode == GL_LINE_STRIP)) { int num_vert = vt -> getNumVertices () ; // V: vertex coordinates. for ( int i = 0; i < num_vert; i++ ) { sgVec3 vert ; sgCopyVec3 ( vert, vt -> getVertex ( i ) ) ; fprintf ( fileout, "v %f %f %f %f\n", vert[0], vert[1], vert[2], w ); } // L: lines. fprintf ( fileout, "\n" ); int num_lines = vt -> getNumLines () ; for ( int j = 0; j < num_lines; j ++ ) { vt -> getLine ( j, &iv1, &iv2 ) ; fprintf ( fileout, "l %d %d\n", total_vert + j + 1, total_vert + j + 2 ); } total_vert += num_vert ; } else if ( mode == GL_TRIANGLES || mode == GL_TRIANGLE_FAN || mode == GL_TRIANGLE_STRIP ) { int num_vert = vt -> getNumVertices () ; // V: vertex coordinates. for ( int i = 0; i < num_vert; i++ ) { sgVec3 vert ; sgCopyVec3 ( vert, vt -> getVertex ( i ) ) ; fprintf ( fileout, "v %f %f %f %f\n", vert[0], vert[1], vert[2], w ); } // VN: Vertex face normal vectors. bool haveNormals = ( vt -> getNumNormals () >= num_vert ) ; if ( haveNormals ) { fprintf ( fileout, "\n" ); for ( int i = 0; i < num_vert; i++ ) { sgVec3 vert ; sgCopyVec3 ( vert, vt -> getNormal ( i ) ) ; fprintf ( fileout, "vn %f %f %f\n", vert[0], vert[1], vert[2] ); } } // F: faces. fprintf ( fileout, "\n" ); int num_face = vt -> getNumTriangles () ; for ( int j = 0; j < num_face; j++ ) { short face[3]; vt -> getTriangle ( j, &face[0], &face[1], &face[2] ) ; fprintf ( fileout, "f" ); for ( int ivert = 0; ivert < 3; ivert++ ) { if ( haveNormals ) fprintf ( fileout, " %d//%d", total_vert + face[ivert] + 1, total_normal + face[ivert] + 1 ); else fprintf ( fileout, " %d", total_vert + face[ivert] + 1 ); } fprintf ( fileout, "\n" ); } total_vert += num_vert ; if ( haveNormals ) total_normal += num_vert ; } } static void save_entities ( ssgEntity *e ) { if ( e -> isAKindOf ( ssgTypeBranch() ) ) { ssgBranch *br = (ssgBranch *) e ; for ( int i = 0 ; i < br -> getNumKids () ; i++ ) save_entities ( br -> getKid ( i ) ) ; } else if ( e -> isAKindOf ( ssgTypeVtxTable() ) ) { ssgVtxTable *vt = (ssgVtxTable *) e ; save_vtx_table ( vt ) ; } } /******************************************************************************/ int ssgSaveOBJ ( const char *filename, ssgEntity *ent ) /******************************************************************************/ /* Purpose: OBJ_WRITE writes a Wavefront OBJ file. Example: # magnolia.obj mtllib ./vp.mtl g v -3.269770 -39.572201 0.876128 v -3.263720 -39.507999 2.160890 ... v 0.000000 -9.988540 0.000000 g stem s 1 usemtl brownskn f 8 9 11 10 f 12 13 15 14 ... f 788 806 774 Modified: 01 September 1998 Author: John Burkardt */ { fileout = fopen ( filename, "wa" ) ; if ( fileout == NULL ) { ulSetError ( UL_WARNING, "ssgSaveOBJ: Failed to open '%s' for writing", filename ) ; return FALSE ; } /* Initialize. */ fprintf ( fileout, "# %s created by SSG.\n", filename ); fprintf ( fileout, "\n" ); fprintf ( fileout, "g SSG\n" ); fprintf ( fileout, "\n" ); total_vert = 0 ; total_normal = 0 ; save_entities ( ent ) ; /* Close. */ fclose ( fileout ) ; return TRUE; } plib-1.8.5/src/ssg/ssgVertSplitter.cxx0000644000175000001440000002641710765364437014714 00000000000000//////////////////////////////////////////////////////////////////////// // // Copyright 2003, Andrew Ross // // Walk through an indexed triangle list, splitting vertices that // share "sharp" edges, and calculate normals for the resulting mesh. // // This code should really live inside the OptVertexList class in // ssgOptimizer.cxx, whose data model is almost 1:1 compatible with // the indexed triangle representation here. It is a separate file // because it comes from separate code that Andy Ross wrote for a // different project, and this was the cleanest way to do the port. // //////////////////////////////////////////////////////////////////////// #include "ssgVertSplitter.h" #include #include "sg.h" // //////////////////////////////////////////////////////////////////////// int ssgVertSplitter::origVert(int i) { return _newVertMap[i]; } ssgVertSplitter::ssgVertSplitter(int nVerts, int nTris) { setSharpAngle(61); _nVerts = _origVerts = _vertsAlloced = nVerts; _verts = new float[3*_nVerts]; _norms = new float[3*_nVerts]; _nTris = nTris; _tris = new Tri[3*_nTris]; _triNorms = new float[3*_nTris]; _geomVerts = new int[_nVerts]; _newVertMap = 0; } ssgVertSplitter::~ssgVertSplitter() { delete[] _verts; delete[] _norms; delete[] _tris; delete[] _triNorms; delete[] _newVertMap; delete[] _geomVerts; } void ssgVertSplitter::setTri(int tidx, int va, int vb, int vc) { _tris[tidx].verts[0] = _tris[tidx].oVerts[0] = va; _tris[tidx].verts[1] = _tris[tidx].oVerts[1] = vb; _tris[tidx].verts[2] = _tris[tidx].oVerts[2] = vc; _tris[tidx].degenerate = false; } int* ssgVertSplitter::getTri(int t) { return &(_tris[t].verts[0]); } void ssgVertSplitter::setSharpAngle(float deg) { _threshold = (float) cos(deg*SG_DEGREES_TO_RADIANS); } int ssgVertSplitter::findTriWithVert(int fidx, int vidx, int* tris, int ntris) { // check each triangle in the list for a matching edge for(int t=0; tverts[i] == oldIdx) { t->verts[i] = newIdx; return; } } } // Find geometrically identical vertices and fixup triangle indices to // point to the first one. void ssgVertSplitter::condenseGeometry() { for(int i=0; i<_nVerts; i++) { _geomVerts[i] = i; for(int j=0; j= 0) continue; // No existing record, make one. if(!used[sv] && sv >= _origVerts) fv = sv; else if(!used[ov]) fv = ov; else { fv = _nVerts++; _nextNewVert++; } int r = nvrecs++; vrecs[r].sv = sv; vrecs[r].ov = ov; vrecs[r].fv = fv; // __builtin_printf("s %d o %d f %d\n", sv, ov, fv); sgCopyVec3(vert(fv), vert(sv)); sgCopyVec3(norm(fv), norm(sv)); if(fv >= _origVerts) _newVertMap[fv - _origVerts] = ov; used[fv] = true; _tris[i].verts[j] = fv; } } delete[] vrecs; delete[] used; } void ssgVertSplitter::splitAndCalcNormals() { int i, j; float zero[] = {0,0,0}; for(i=0; i<_nVerts; i++) sgCopyVec3(norm(i), zero); // First, find duplicate vertices and coalesce the geometry condenseGeometry(); // Calculate a normal for each face, and count the number of // references to each vertex. float* faceNorms = _triNorms; int* vCounts = new int[_nVerts]; for(i=0; i<_nVerts; i++) vCounts[i] = 0; for(i=0; i<_nTris; i++) { sgVec3 a, b; float *fnorm = faceNorms + 3*i; int* verts = _tris[i].verts ; sgCopyVec3(a, vert(verts[1])); sgSubVec3(a, vert(verts[0])); sgCopyVec3(b, vert(verts[2])); sgSubVec3(b, vert(verts[0])); sgVectorProductVec3(fnorm, a, b); sgNormaliseVec3(fnorm); vCounts[verts[0]]++; vCounts[verts[1]]++; vCounts[verts[2]]++; if(verts[0]==verts[1] || verts[1]==verts[2] || verts[2]==verts[0]) { _tris[i].degenerate = true; fnorm[0] = fnorm[1] = 0; fnorm[2] = 1; } } // Build a table mapping vertices to arrays of triangle indices // vTris[v] is a pointer to a list of vCounts[v] triangle indices. int* vtspace = new int[3*_nTris]; int** vTris = new int*[_nVerts]; int* vtptr = vtspace; for(i=0; i<3*_nTris; i++) vtspace[i] = -1; for(i=0; i<_nVerts; i++) { vTris[i] = vtptr; vtptr += vCounts[i]; } int *vctmp = new int[_nVerts]; for(i=0; i<_nVerts; i++) vctmp[i] = 0; for(i=0; i<_nTris; i++) { if(_tris[i].degenerate) continue; for(int v=0; v<3; v++) vTris[_tris[i].verts[v]][vctmp[_tris[i].verts[v]]++] = i; } delete[] vctmp; // Make some temp space for new vertices and their normals int maxNewVerts = 8*_nVerts; _newVertMap = new int[maxNewVerts]; float* newNorms = new float[3*maxNewVerts]; _nextNewVert = 0; // Now the hard part. For each vertex, pick a face. Walk forward // and backwards from that face until you hit a sharp edge or // already-done face, summing normals along the way and marking // off the face as "done". If there are faces left, split off a // *new* vertex for the remaining ones, pick a remaining face, and // repeat. Repeat until we run out of faces. for(int vidx=0; vidx<_nVerts; vidx++) { while(1) { // Pick a face int fidx = -1; bool someDone = false; for(int face=0; face= 0) { float* n = faceNorms + 3*vTris[vidx][nextidx]; if(sgScalarProductVec3(n, lastNorm) < _threshold) break; lastNorm = n; sgAddVec3(fnorm, n); int oldnext = nextidx; nextidx = nextTri(nextidx, vidx, vTris[vidx], vCounts[vidx]); if(someDone) fixVidx(_tris + vTris[vidx][oldnext], vidx, realvert); vTris[vidx][oldnext] = -1; } lastNorm = lastNorm0; while(previdx >= 0) { if(vTris[vidx][previdx] < 0) break; float* n = faceNorms + 3*vTris[vidx][previdx]; if(sgScalarProductVec3(n, lastNorm) < _threshold) break; lastNorm = n; sgAddVec3(fnorm, faceNorms + 3*vTris[vidx][previdx]); int oldprev = previdx; previdx = prevTri(previdx, vidx, vTris[vidx], vCounts[vidx]); if(someDone) fixVidx(_tris + vTris[vidx][oldprev], vidx, realvert); vTris[vidx][oldprev] = -1; } } }; // Reallocate the new vertex/normal tables. _vertsAlloced = _nVerts + maxNewVerts; float* newVerts = new float[3*_vertsAlloced]; for(i=0; i<3*_nVerts; i++) newVerts[i] = _verts[i]; for(i=0; i<_nextNewVert; i++) for(j=0; j<3; j++) newVerts[3*(_nVerts+i)+j] = _verts[3*_newVertMap[i]+j]; delete[] _verts; _verts = newVerts; float* tmpnorms = new float[3*_vertsAlloced]; for(i=0; i<3*_nVerts; i++) tmpnorms[i] = _norms[i]; for(i=0; i<3*_nextNewVert; i++) tmpnorms[3*_nVerts+i] = newNorms[i]; delete[] _norms; _norms = tmpnorms; _nVerts += _nextNewVert; // Finally, renormalize everything for(i=0; i<_nVerts; i++) if(i >= _origVerts || _geomVerts[i] == i) sgNormaliseVec3(norm(i)); for(i=0; i<_origVerts; i++) if(_geomVerts[i] != i) sgCopyVec3(norm(i), norm(_geomVerts[i])); // Now, if necessary, duplicate the vertices that got "condensed" // earlier by creating a new vertex and cloning the normal. expandDuplicates(); #if 0 static int allOrig = 0; static int allFinal = 0; allOrig += _origVerts; allFinal += _nVerts; fprintf(stderr, "%d -> %d (%d/%d)\n", _origVerts, _nVerts, allOrig, allFinal); #endif delete[] vCounts; delete[] vtspace; delete[] vTris; delete[] newNorms; } plib-1.8.5/src/ssg/ssgInvisible.cxx0000644000175000001440000000311110765364437014153 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgInvisible.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgInvisible::copy_from ( ssgInvisible *src, int clone_flags ) { ssgBranch::copy_from ( src, clone_flags ) ; } ssgBase *ssgInvisible::clone ( int clone_flags ) { ssgInvisible *b = new ssgInvisible ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgInvisible::ssgInvisible (void) { type = ssgTypeInvisible () ; } ssgInvisible::~ssgInvisible (void) { } void ssgInvisible::cull ( sgFrustum *, sgMat4, int /* test_needed */ ) { } int ssgInvisible::load ( FILE *fd ) { return ssgBranch::load(fd) ; } int ssgInvisible::save ( FILE *fd ) { return ssgBranch::save(fd) ; } plib-1.8.5/src/ssg/ssgLocal.h0000644000175000001440000001234010765364437012712 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLocal.h 1996 2004-12-29 07:19:40Z sjbaker $ */ #define _SSG_PUBLIC public #include "ssg.h" void _ssgStartOfFrameInit () ; void _ssgEndOfFrameCleanup () ; extern void (*__ssgEnableTable[64])() ; extern void (*__ssgDisableTable[64])() ; extern sgMat4 _ssgOpenGLAxisSwapMatrix ; extern int _ssgIsHotTest ; extern int _ssgIsLosTest ; extern int _ssgFileVersionNumber ; void _ssgForceLineState () ; void _ssgDrawDList () ; void _ssgSetTweenState ( float state, int mode ) ; void _ssgPushMatrix ( sgMat4 m ) ; void _ssgPopMatrix () ; void _ssgLoadMatrix ( sgMat4 m ) ; void _ssgLoadTexMatrix ( sgMat4 m ) ; void _ssgUnloadTexMatrix () ; void _ssgDrawLeaf ( ssgLeaf *l ) ; void _ssgAddHit ( ssgLeaf *l, int trinum, sgMat4 mat, sgVec4 pl ) ; void _ssgPushPath ( ssgEntity *l ) ; void _ssgPopPath () ; extern int stats_num_vertices ; extern int stats_num_leaves ; extern int stats_isect_triangles ; extern int stats_cull_test ; extern int stats_isect_test ; extern int stats_bind_textures ; extern int stats_hot_triangles ; extern int stats_hot_test ; extern int stats_hot_no_trav ; extern int stats_hot_radius_reject ; extern int stats_hot_triv_accept ; extern int stats_hot_straddle ; extern int stats_los_triangles ; extern int stats_los_test ; extern int stats_los_no_trav ; extern int stats_los_radius_reject ; extern int stats_los_triv_accept ; extern int stats_los_straddle ; extern ssgState *( *_ssgGetAppState)( char *) ; void _ssgReadFloat ( FILE *fd, float *var ) ; void _ssgWriteFloat ( FILE *fd, const float var ) ; void _ssgReadUInt ( FILE *fd, unsigned int *var ) ; void _ssgWriteUInt ( FILE *fd, const unsigned int var ) ; void _ssgReadInt ( FILE *fd, int *var ) ; void _ssgWriteInt ( FILE *fd, const int var ) ; void _ssgReadUShort ( FILE *fd, unsigned short *var ) ; void _ssgWriteUShort ( FILE *fd, const unsigned short var ) ; void _ssgReadShort ( FILE *fd, short *var ) ; void _ssgWriteShort ( FILE *fd, const short var ) ; void _ssgReadFloat ( FILE *fd, const unsigned int n, float *var ) ; void _ssgWriteFloat ( FILE *fd, const unsigned int n, const float *var ) ; void _ssgReadUInt ( FILE *fd, const unsigned int n, unsigned int *var ) ; void _ssgWriteUInt ( FILE *fd, const unsigned int n, const unsigned int *var ) ; void _ssgReadInt ( FILE *fd, const unsigned int n, int *var ) ; void _ssgWriteInt ( FILE *fd, const unsigned int n, const int *var ) ; void _ssgReadUShort ( FILE *fd, const unsigned int n, unsigned short *var ) ; void _ssgWriteUShort ( FILE *fd, const unsigned int n, const unsigned short *var ) ; void _ssgReadShort ( FILE *fd, const unsigned int n, short *var ) ; void _ssgWriteShort ( FILE *fd, const unsigned int n, const short *var ) ; void _ssgReadBytes ( FILE *fd, const unsigned int n, void *var ) ; void _ssgWriteBytes ( FILE *fd, const unsigned int n, const void *var ) ; void _ssgReadString ( FILE *fd, char **var ) ; void _ssgWriteString ( FILE *fd, const char *var ) ; void _ssgReadVec2 ( FILE *fd, sgVec2 var ) ; void _ssgWriteVec2 ( FILE *fd, const sgVec2 var ) ; void _ssgReadVec3 ( FILE *fd, sgVec3 var ) ; void _ssgWriteVec3 ( FILE *fd, const sgVec3 var ) ; void _ssgReadVec4 ( FILE *fd, sgVec4 var ) ; void _ssgWriteVec4 ( FILE *fd, const sgVec4 var ) ; void _ssgReadMat4 ( FILE *fd, sgMat4 var ) ; void _ssgWriteMat4 ( FILE *fd, const sgMat4 var ) ; int _ssgReadError ( void ) ; int _ssgWriteError ( void ) ; float _ssgGetCurrentTweenState () ; int _ssgGetCurrentTweenMode () ; void _ssgSetCurrentTweenSettings ( float tweenstate, int tweenmode ) ; void _ssgSetRealCurrentTweenSettings ( float tweenstate, int tweenmode ) ; /* Routines for storing arbitrary ssgBase derived objects within SSG files. Both functions return 1 on success, and 0 on failure. If an object is encountered that is not derived from type_mask, then the loading is aborted and 0 returned. */ int _ssgSaveObject ( FILE * , ssgBase * ) ; int _ssgLoadObject ( FILE * , ssgBase ** , int type_mask = 0 ) ; extern class ssgStatistics _ssgCurrStatistics ; extern bool _ssgBackFaceCollisions ; plib-1.8.5/src/ssg/ssgLoadVRML.h0000644000175000001440000001344710765364437013251 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002, 2002 William Lachance, Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ class ssgListOfNodes : public ssgSimpleList // list of POINTERs to ssgBase // used for storing/querying DEF'd info { public: virtual ssgBase *clone ( int clone_flags = 0 ) { return NULL; }; // Fixme NIV14: 2do ssgListOfNodes ( int init = 3 ) : ssgSimpleList ( sizeof(ssgBase*), init ) {} class ssgBase *get ( unsigned int n ) { return *( (class ssgBase **) raw_get ( n ) ) ; } void add ( class ssgBase *thing ) { raw_add ( (char *) &thing ) ; } ; void replace( class ssgBase *thing, unsigned int n ) { raw_set( (char *) &thing, n); } virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) {}; // Fixme NIV14: 2do }; class _nodeIndex { private: ssgListOfNodes *nodeList; public: _nodeIndex() { nodeList = new ssgListOfNodes(); } ~_nodeIndex() { for( int i=0; igetNum(); i++ ) { ssgBase *extractedThing = nodeList->get( i ); if( extractedThing->getRef() == 0 ) delete( extractedThing ); } } void insert( ssgBase *thing ) { // replace the node if a node with an identical tag already exists for( int i=0; igetNum(); i++ ) { ssgBase *tempThing = nodeList->get( i ); if( !strcmp( tempThing->getName(), thing->getName() ) ) { nodeList->replace( thing, i ); ulSetError(UL_DEBUG, "Replaced element %i.", i); return; } } // otherwise add it to end of list nodeList->add( thing ); } ssgBase * extract( char *defName ) { for( int i=0; igetNum(); i++ ) { ssgBase *extractedThing = nodeList->get( i ); if( !strcmp( extractedThing->getName(), defName ) ) return extractedThing; } return NULL; } }; // the current properties for a certain point in scene traversal class _traversalState { private: ssgVertexArray *vertices; ssgTexCoordArray *textureCoordinates; ssgTransform *transform; ssgTexture *texture; bool textureCoordinatesArePerFaceAndVertex; GLenum frontFace; bool enableCullFace; public: bool getEnableCullFace() { return enableCullFace; } void setEnableCullFace( bool newEnableCullFace ) { enableCullFace = newEnableCullFace; } GLenum getFrontFace( void ) { return frontFace; } void setFrontFace( GLenum newFrontFace ) { frontFace = newFrontFace; } ssgTransform * getTransform( void ) { return transform; } void setTransform( ssgTransform *newTransform ) { transform = newTransform; } ssgVertexArray * getVertices( void ) { return vertices; } void setVertices( ssgVertexArray *newVertices ) { vertices = newVertices; } ssgTexCoordArray *getTextureCoordinates( void ) { return textureCoordinates; } void setTextureCoordinates( ssgTexCoordArray *newTextureCoordinates ) { textureCoordinates = newTextureCoordinates; } ssgTexture * getTexture( void ) { return texture; } void setTexture( ssgTexture *newTexture ) { texture = newTexture; } bool areTextureCoordinatesArePerFaceAndVertex( void ) { return textureCoordinatesArePerFaceAndVertex; } _traversalState *clone() { return new _traversalState(*this); } _traversalState() { vertices = NULL; textureCoordinates = NULL; transform = NULL; texture = NULL; textureCoordinatesArePerFaceAndVertex = TRUE; enableCullFace = FALSE; } }; // tags for functions which may actually modify the scene graph struct _parseTag { const char *token ; bool (*func) ( ssgBranch *parentBranch, _traversalState *parentData, char *defName ) ; } ; // the vrml1 common subset that is shared with inventor bool vrml1_parseCoordinate3( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); bool vrml1_parseTextureCoordinate2( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); bool vrml1_parseShapeHints( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); bool vrml1_parseMatrixTransform( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); bool vrml1_parseScale( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); bool vrml1_parseRotation( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); bool vrml1_parseTranslation( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); bool vrml1_parseUseDirective( ssgBranch *parentBranch, _traversalState *currentData, char *useName, char *defName ); bool vrml1_parseCoordIndex( ssgLoaderWriterMesh *loaderMesh, _traversalState *currentData ); bool vrml1_parseTextureCoordIndex( ssgLoaderWriterMesh *loaderMesh, _traversalState *currentData ); bool parseUnidentified(); void applyTransform( ssgTransform *currentTransform, _traversalState *currentData ); void mergeTransformNodes( ssgTransform *newTransform, ssgTransform *oldTransform1, ssgTransform *oldTransform2 ); bool parseVec( SGfloat *v, int vSize ); ssgIndexArray * parseIndexArray( _traversalState *currentData ); extern _ssgParser vrmlParser; plib-1.8.5/src/ssg/ssgSaveVRML1.cxx0000644000175000001440000004033410765364437013717 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveVRML1.cxx 1568 2002-09-02 06:05:49Z sjbaker $ -------------------------------------------------------------------- This save routine was written by Warren Wilbur to support a sub-set of the standard Virtual Reality Modelling Language v1.0 (i.e. VRML1.0). The Version 1.0 Specification, 9-Nov-95 was used and should be available at www.vrml.org When reporting bugs/difficulties please mention 'VRML' in the subject of your email and post to the plib developers mailing list. */ #include #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" /* Function name: SaveVRML1MaterialNode * * Limitations: Before calling this function you must verify that * at least one material exists whose textureName * matches the one passed in to this function, * otherwise you might save a empty Material node! * * Notes: Saving empty Material notes will create an * unnecessary choking hazard for VRML loaders :( */ static void SaveVRML1MaterialNode(FILE *fd, ssgIndexArray *materials_ptr, ssgSimpleStateArray *ssa_ptr, char *textureName, bool saveDiffuse, bool saveAmbient, bool saveEmission, bool saveSpecular) { ssgSimpleState *ss_ptr; int i; /* Tell VRML loaders that we are providing a single color for each * face in the array of indices written below. */ fprintf(fd, " MaterialBinding { value PER_FACE }\n"); fprintf(fd, " Material {\n"); if (saveDiffuse) { fprintf(fd, " diffuseColor [\n"); for (i = 0; i < materials_ptr->getNum(); i++) { ss_ptr = ssa_ptr->get(*(materials_ptr->get(i))); /* If we are trying to save all untextured materials then check * if either ptr is NULL */ if ( ( (textureName == NULL)&& ((ss_ptr == NULL)||(ss_ptr->getTextureFilename() == NULL)) )|| /* If we are trying to save all materials that are textured by * a specific texture then check if the texture filename matches */ ( (textureName != NULL)&&(ss_ptr != NULL)&& (ss_ptr->getTextureFilename() != NULL)&& (!strcmp(textureName, ss_ptr->getTextureFilename())) ) ) { float diffuse0, diffuse1, diffuse2; diffuse0 = ss_ptr->diffuse_colour[0]; diffuse1 = ss_ptr->diffuse_colour[1]; diffuse2 = ss_ptr->diffuse_colour[2]; #ifdef EXPERIMENTAL_ADD_AMBIENT_TO_DIFFUSE diffuse0 += ss_ptr->ambient_colour[0]; diffuse1 += ss_ptr->ambient_colour[1]; diffuse2 += ss_ptr->ambient_colour[2]; #endif //EXPERIMENTAL_ADD_AMBIENT_TO_DIFFUSE #ifdef EXPERIMENTAL_ADD_EMISSION_TO_DIFFUSE diffuse0 += ss_ptr->emission_colour[0]; diffuse1 += ss_ptr->emission_colour[1]; diffuse2 += ss_ptr->emission_colour[2]; #endif //EXPERIMENTAL_ADD_EMISSION_TO_DIFFUSE #ifdef EXPERIMENTAL_ADD_SPECULAR_TO_DIFFUSE diffuse0 += ss_ptr->specular_colour[0]; diffuse1 += ss_ptr->specular_colour[1]; diffuse2 += ss_ptr->specular_colour[2]; #endif //EXPERIMENTAL_ADD_SPECULAR_TO_DIFFUSE /* OpenGL caps the maximum RGB value for a colour to 1.0 when it * calculates colours in a scene. If we don't cap the value OpenGL * will do it for us. */ fprintf(fd, " %f %f %f,\n", diffuse0 > 1.0 ? 1.0:diffuse0, diffuse1 > 1.0 ? 1.0:diffuse1, diffuse2 > 1.0 ? 1.0:diffuse2); } } fprintf(fd, " ]\n"); //close diffuseColor array } if (saveAmbient) { fprintf(fd, " ambientColor [\n"); for (i = 0; i < materials_ptr->getNum(); i++) { ss_ptr = ssa_ptr->get(*(materials_ptr->get(i))); /* If we are trying to save all untextured materials then check * if either ptr is NULL */ if ( ( (textureName == NULL)&& ((ss_ptr == NULL)||(ss_ptr->getTextureFilename() == NULL)) )|| /* If we are trying to save all materials that are textured by * a specific texture then check if the texture filename matches */ ( (textureName != NULL)&&(ss_ptr != NULL)&& (ss_ptr->getTextureFilename() != NULL)&& (!strcmp(textureName, ss_ptr->getTextureFilename())) ) ) { fprintf(fd, " %f %f %f,\n", ss_ptr->ambient_colour[0], ss_ptr->ambient_colour[1], ss_ptr->ambient_colour[2]); } fprintf(fd, " ]\n"); //close ambientColor array } } if(saveEmission) { fprintf(fd, " emissiveColor [\n"); for (i = 0; i < materials_ptr->getNum(); i++) { ss_ptr = ssa_ptr->get(*(materials_ptr->get(i))); /* If we are trying to save all untextured materials then check * if either ptr is NULL */ if ( ( (textureName == NULL)&& ((ss_ptr == NULL)||(ss_ptr->getTextureFilename() == NULL)) )|| /* If we are trying to save all materials that are textured by * a specific texture then check if the texture filename matches */ ( (textureName != NULL)&&(ss_ptr != NULL)&& (ss_ptr->getTextureFilename() != NULL)&& (!strcmp(textureName, ss_ptr->getTextureFilename())) ) ) { fprintf(fd, " %f %f %f,\n", ss_ptr->emission_colour[0], ss_ptr->emission_colour[1], ss_ptr->emission_colour[2]); } fprintf(fd, " ]\n"); //close emissionColor array } } if(saveSpecular) { fprintf(fd, " specularColor [\n"); for (i = 0; i < materials_ptr->getNum(); i++) { ss_ptr = ssa_ptr->get(*(materials_ptr->get(i))); /* If we are trying to save all untextured materials then check * if either ptr is NULL */ if ( ( (textureName == NULL)&& ((ss_ptr == NULL)||(ss_ptr->getTextureFilename() == NULL)) )|| /* If we are trying to save all materials that are textured by * a specific texture then check if the texture filename matches */ ( (textureName != NULL)&&(ss_ptr != NULL)&& (ss_ptr->getTextureFilename() != NULL)&& (!strcmp(textureName, ss_ptr->getTextureFilename())) ) ) { fprintf(fd, " %f %f %f,\n", ss_ptr->specular_colour[0], ss_ptr->specular_colour[1], ss_ptr->specular_colour[2]); } fprintf(fd, " ]\n"); //close specularColor array } } fprintf(fd, " }\n"); //close Material node return; } /* The 'main' entry point for saving a model in VRML1.0 */ int ssgSaveVRML1( const char* fname, ssgEntity *ent ) { ssgVertexArray *vertices_ptr; ssgIndexArray *indices_ptr; FILE *fd; ssgSimpleStateArray ssa; ssgTexCoordArray *texcoord_ptr; ssgIndexArray *materials_ptr; bool textured_faces_found, untextured_faces_found, textureFacesAlreadySaved; int i, j, index1, index2, index3; ssgSimpleState *ss_ptr, *ss_ptr2; fd = fopen ( fname, "w" ) ; if ( fd == NULL ) { ulSetError ( UL_WARNING, "ssgSaveVRML1: Failed to open '%s' for writing", fname ); return FALSE ; } vertices_ptr = new ssgVertexArray(); indices_ptr = new ssgIndexArray(); materials_ptr = new ssgIndexArray(); texcoord_ptr = new ssgTexCoordArray(); sgMat4 ident; sgMakeIdentMat4( ident ); ssgAccumVerticesAndFaces( ent, ident, vertices_ptr, indices_ptr, -1.0f, &ssa, materials_ptr, texcoord_ptr); /* The spec requires every file to begin with these characters */ fprintf(fd, "#VRML V1.0 ascii\n\n"); /* Since a VRML file contains only one parent node we must use a * node type that can have several child 'nodes' so we can save * the materials, texture coordinates, vertices, and indices each * as (seperate) child nodes. */ fprintf(fd, "Separator {\n"); /* Save all the individual vertices used in the model. It doesn't * matter if there are duplicates... */ fprintf(fd, " Coordinate3 {\n point [\n"); for (i = 0; i < vertices_ptr->getNum(); i++) { fprintf(fd, " %f %f %f,\n", vertices_ptr->get(i)[0], vertices_ptr->get(i)[1], vertices_ptr->get(i)[2]); } fprintf(fd, " ]\n }\n"); //close point array and //Coordinate3 /* Chcck if the model is textured at all. This test will help us parse * out how to save the model since it may be totally textured, partially * textured, or not textured at all. */ textured_faces_found = false; untextured_faces_found = false; for (i = 0; i < materials_ptr->getNum(); i++) { ss_ptr = ssa.get(*(materials_ptr->get(i))); if ( (ss_ptr != NULL)&&(ss_ptr->getTextureFilename() != NULL) ) { textured_faces_found = true; } else { untextured_faces_found = true; } } if (untextured_faces_found) { /* Save all the material node fields which VRML supports. Note that the * VRML spec discourages complicated uses of the Material Node. We * cannot expect VRML implementations to support the full syntax * of the Material Node including ambient, diffuse, specular, emissive, * shininess, and transparency. We should be always be okay if we just * use diffuse. */ SaveVRML1MaterialNode(fd, materials_ptr, &ssa, NULL, true, false, false, false); /* Save all faces that are not textured in a single IndexedFaceSet node */ fprintf(fd, " IndexedFaceSet {\n coordIndex [\n"); for (i = 0; i < indices_ptr->getNum(); i+=3) { ss_ptr = ssa.get(*(materials_ptr->get(i/3))); /* Make sure this face doesn't have a texture associated with it */ if ( (ss_ptr == NULL)||(ss_ptr->getTextureFilename() == NULL) ) { index1 = *indices_ptr->get(i); index2 = *indices_ptr->get(i+1); index3 = *indices_ptr->get(i+2); /* Check for index overflow since PLIB stores it as a short */ if ( (index1 < 0)||(index2 < 0)||(index3 < 0) ) { ulSetError(UL_WARNING, "ssgSaveVRML1: Save error: index overflow, " "value won't fit in 16bits."); } else { fprintf(fd, " %d, %d, %d, -1,\n", index1, index2, index3); } } } fprintf(fd, " ]\n }\n"); //close coordIndex array and //IndexedFaceSet } if (textured_faces_found) { /* Save all texture coordinates (per-vertex) for all the textures in * the model. It doesn't matter if there is one texture or more than * one since we will specify which texture to use with the coordinates * before saving the portion of the indexed face set which uses that * texture. */ fprintf(fd, " TextureCoordinate2 {\n point [\n"); for (i = 0; i < texcoord_ptr->getNum(); i++) { /* In VrmlView Pro 3.0 (Linux) textured models appear correct Left-Right * but the texture is reversed Top-Bottom. Enabling the INVERSE_REPEAT * macro fixes the problem for VrmlView. I don't want to enable this until * I figure out where the problem really is!? */ //#define INVERSE_REPEAT(a) (a > 0.0 ? 1.0 - a:a + 1.0) #define INVERSE_REPEAT(a) a fprintf(fd, " %f %f,\n", texcoord_ptr->get(i)[0], INVERSE_REPEAT(texcoord_ptr->get(i)[1])); } fprintf(fd, " ]\n }\n"); /* Now save separate Texture2 and IndexedFaceSet node pairs for each * texture used in the model. Each of the IndexedFaceSet(s) will * reference back to the initial vertices, materials, and texture * coordinates (due to the lack of Seperator nodes in between). * Find the first textured face starting at the i'th face. In this * manner we will find the next texture used in the model and save * all faces that are textured with it. */ for (i = 0; i < indices_ptr->getNum(); i+=3) { ss_ptr = ssa.get(*(materials_ptr->get(i/3))); if ( (ss_ptr != NULL)&&(ss_ptr->getTextureFilename() != NULL) ) { /* We've found the next textured face. Since we save all * faces using a texture when we find the first face using * that texture we must check if the faces for this texture * have already been saved. If we can find a face using * this texture earlier in the list of faces then we know * that it has already been saved. */ textureFacesAlreadySaved = false; for (j = 0; j < i; j+=3) { ss_ptr2 = ssa.get(*(materials_ptr->get(j/3))); if ( (ss_ptr2 != NULL)&& (ss_ptr2->getTextureFilename() != NULL)&& (!strcmp(ss_ptr->getTextureFilename(), ss_ptr2->getTextureFilename())) ) { textureFacesAlreadySaved = true; break; } } if (!textureFacesAlreadySaved) { fprintf(fd, " Texture2 {\n"); fprintf(fd, " filename %s\n", ss_ptr->getTextureFilename()); //TODO: support CLAMP mode as well. fprintf(fd, " wrapS REPEAT\n"); fprintf(fd, " wrapT REPEAT\n"); fprintf(fd, " }\n"); /* Save all the materials needed by this following indexed face * set. This will save all materials that have the same texture * filename specified below. */ SaveVRML1MaterialNode(fd, materials_ptr, &ssa, ss_ptr->getTextureFilename(), true, false, false, false); fprintf(fd, " IndexedFaceSet {\n coordIndex [\n"); for (j = i; j < indices_ptr->getNum(); j+=3) { /* Save each face which is textured by the Texture2 node defined * above. */ ss_ptr2 = ssa.get(*(materials_ptr->get(j/3))); if ( (ss_ptr2 != NULL)&& (ss_ptr2->getTextureFilename() != NULL)&& (!strcmp(ss_ptr->getTextureFilename(), ss_ptr2->getTextureFilename())) ) { index1 = *indices_ptr->get(j); index2 = *indices_ptr->get(j+1); index3 = *indices_ptr->get(j+2); /* Check for index overflow since PLIB stores it as a * short */ if ( (index1 < 0)||(index2 < 0)||(index3 < 0) ) { ulSetError(UL_WARNING, "ssgSaveVRML1: Save error: index " "overflow, value won't fit in 16bits."); } else { fprintf(fd, " %d, %d, %d, -1,\n", index1, index2, index3); } } } fprintf(fd, " ]\n }\n"); //close coordIndex array and //IndexedFaceSet } } } } fprintf(fd, "}\n"); //close Seperator fclose( fd ) ; delete vertices_ptr; delete indices_ptr; delete materials_ptr; delete texcoord_ptr; return TRUE; } plib-1.8.5/src/ssg/ssgSaveIV.cxx0000644000175000001440000001661710765364437013403 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveIV.cxx 2011 2005-01-15 17:59:31Z sjbaker $ */ // // IV ( Open Inventor ASCII ) export for SSG/PLIB // Written by Bram Stolk (bram at sara.nl) // // Keep in mind that: // ssg's Transform's are non-leaf nodes, which correspond to Inventor's // Transform nodes which are leaf nodes. // Inventor's Material nodes are scene graph leaf nodes. // The corresponding State objects from ssg however, are not scene graph nodes. // // DONE: // scene graph hierarchy // transformation // states // colour per vertex // normal per vertex // textures // texture coordinates // alpha transparency // // TODO: // lights // rendermodes // #include #include "ssgLocal.h" // auxiliary stuff for indenting the inventor file. static int indentLevel ; static void indent ( FILE *f ) { for ( int i=0; igetTransform( m ) ; fprintf ( f, "MatrixTransform { matrix %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f }\n", m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1], m[3][2], m[3][3] ) ; } // ssg leaf nodes contain the geometry, which we will convert to // Inventor's IndexedFaceSet. static void writeLeaf ( ssgLeaf *leaf, FILE *f ) { int cnt = leaf->getNumTriangles() ; int nv = leaf->getNumVertices() ; int nn = leaf->getNumNormals() ; int nc = leaf->getNumColours() ; int nt = leaf->getNumTexCoords() ; ssgState *st = leaf->getState() ; ssgSimpleState *state = 0 ; char *textureName = 0 ; int i; indent( f ); fprintf( f, "# %d triangles, %d verts, %d normals, %d colours, %d texturecoords\n", cnt, nv,nn,nc,nt ) ; if ( st && st -> isAKindOf ( ssgTypeSimpleState() ) ) { state = (ssgSimpleState*) st ; textureName = state->getTextureFilename(); } else state = NULL ; if ( state || nc ) { indent( f ) ; fprintf( f, "Material {\n" ) ; indentLevel++ ; indent( f ) ; fprintf( f, "diffuseColor " ) ; if ( nc ) { // multiple colour values: colour-per-vertex fprintf( f, "[ " ) ; for ( i=0; igetColour( i ) ; fprintf( f,"%f %f %f, ", col[0],col[1],col[2] ) ; } fprintf( f, "]\n" ) ; } else { // single colour value float r=0, g=0, b=0; if ( state ) { r = state->diffuse_colour[ 0 ] ; g = state->diffuse_colour[ 1 ] ; b = state->diffuse_colour[ 2 ] ; } fprintf( f, "%f %f %f\n", r,g,b ) ; } if ( state ) { indent( f ); fprintf( f,"ambientColor %f %f %f\n", state->ambient_colour[0], state->ambient_colour[1], state->ambient_colour[2] ) ; indent( f ); fprintf( f,"specularColor %f %f %f\n", state->specular_colour[0], state->specular_colour[1], state->specular_colour[2] ) ; indent( f ); fprintf( f,"emissiveColor %f %f %f\n", state->emission_colour[0], state->emission_colour[1], state->emission_colour[2] ) ; indent( f ); fprintf( f, "shininess %f\n", state->shininess ) ; if ( state->isEnabled( GL_BLEND ) ) { float a = state->diffuse_colour[ 3 ] ; indent( f ) ; fprintf( f, "transparency %f\n", 1.0-a ); } } indentLevel-- ; indent( f ) ; fprintf( f, "}\n" ) ; } if ( textureName ) { indent( f ) ; fprintf( f, "Texture2 { filename %c%s%c }\n", '"', textureName, '"' ) ; } if ( nn ) { indent( f ) ; fprintf( f, "Normal {\n") ; indentLevel++ ; indent( f ) ; fprintf( f, "vector [ " ) ; for ( i=0; igetNormal( i ) ; fprintf( f, "%f %f %f, ", nrm[ 0 ], nrm[ 1 ], nrm[ 2 ] ); } fprintf( f, " ]\n" ); indentLevel-- ; indent( f ) ; fprintf( f, "}\n" ) ; } if ( nt && textureName ) { indent( f ) ; fprintf( f, "SoTextureCoordinate2 { point [ " ) ; for ( i=0; igetTexCoord( i ) ; fprintf( f, "%f %f, ", t[ 0 ], t[ 1 ] ) ; } fprintf( f, " ] }\n" ) ; } indent( f ) ; fprintf( f, "Coordinate3 { point [ " ) ; for ( i=0; igetVertex( i ) ; assert( v ) ; fprintf( f, "%f %f %f, ", v[ 0 ], v[ 1 ], v[ 2 ] ) ; } fprintf( f, " ] }\n" ) ; indent( f ) ; fprintf( f, "IndexedFaceSet {\n" ) ; indent( f ) ; fprintf( f, " coordIndex [ " ) ; for ( i=0; igetTriangle( i, &idx0, &idx1, &idx2 ) ; fprintf( f, "%d,%d,%d,-1,", idx0, idx1, idx2 ) ; } fprintf( f, " ]\n" ) ; indent( f ) ; fprintf( f, "}\n" ) ; } // Handles pre-order traversal of the ssg hierarchy. static void preHandle ( ssgEntity *ent, FILE *f ) { // Put some comments in the inventor output file. indent( f ) ; const char *name = ent->getName() ; fprintf( f, "# %s (%s)\n", ent->getTypeName(), (name)?name:"unnamed") ; if ( ent && ent -> isAKindOf ( ssgTypeBranch () ) ) { ssgBranch *branch = (ssgBranch*) ent ; // ssg's branch nodes are translated to inventor's separator node. indent( f ) ; fprintf( f,"Separator {\n" ) ; indentLevel++ ; if ( branch -> isAKindOf ( ssgTypeTransform() ) ) writeTransform( (ssgTransform*) branch, f ) ; } else writeLeaf( (ssgLeaf*) ent, f ) ; } // Handles post-order traversal of the ssg hierarchy. static void postHandle ( ssgEntity *ent, FILE *f ) { if ( ent && ent -> isAKindOf ( ssgTypeBranch() ) ) { // For branches, we use IV's Seperator, which we need to close now. indentLevel-- ; indent( f ) ; fprintf( f, "}\n" ) ; } } // Traverses ssg hierarchy. static void walkTree ( ssgEntity *ent, FILE *f ) { preHandle( ent, f ) ; if ( ent && ent -> isAKindOf ( ssgTypeBranch() ) ) { ssgBranch *branch = (ssgBranch*) ent ; for ( int i=0; igetNumKids(); i++ ) { ssgEntity *kid = branch->getKid( i ); assert( kid ) ; walkTree( kid, f ) ; } } postHandle( ent, f ) ; } // Entry point: save ssg hierarchy as an OpenInventor file. int ssgSaveIV ( const char *filename, ssgEntity *ent ) { FILE *f = fopen( filename, "w" ) ; if ( !f ) return FALSE ; fprintf( f, "#Inventor V2.1 ascii\n" ) ; fprintf ( f, "#Export from plib version %d.%d.%d\n\n", PLIB_MAJOR_VERSION, PLIB_MINOR_VERSION, PLIB_TINY_VERSION ) ; indentLevel = 0 ; walkTree( ent, f ) ; return TRUE ; } plib-1.8.5/src/ssg/ssgLoadMDL.h0000644000175000001440000005273310765364437013106 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadMDL.h 1568 2002-09-02 06:05:49Z sjbaker $ */ //=========================================================================== // // File: fsPalettes.h // // Created: Fri Oct 1 15:34:29 1999 // // Author: Thomas Engh Sevaldrud // // Revision: $Id: ssgLoadMDL.h 1568 2002-09-02 06:05:49Z sjbaker $ // // Description: // //=========================================================================== // Copyright (c) 1999 Thomas E. Sevaldrud //=========================================================================== #ifndef _SSGLOADMDL_H #define _SSGLOADMDL_H //=========================================================================== // Aircraft color palette. The aircraft in MSFS has // a different palette than the default fs5.pal file. // Entries with (?) means that I am not sure of the // values. Entries with (L), means that the color is // emissive (bright at night). struct acColor { unsigned char r, g, b, emissive; }; static const acColor fsAcPalette[53] = { { 0, 0, 0 , 0 }, // Black { 89, 89, 89 , 0 }, // Dark gray { 169, 169, 169 , 0 }, // Gray { 211, 211, 211 , 0 }, // Light gray { 255, 255, 255 , 0 }, // White { 255, 0, 0 , 0 }, // Red { 0, 255, 0 , 0 }, // Green { 0, 0, 255 , 0 }, // Blue { 255, 165, 0 , 0 }, // Orange { 255, 255, 0 , 0 }, // Yellow { 165, 42, 42 , 0 }, // Brown { 210, 180, 140 , 0 }, // Tan { 255, 69, 0 , 0 }, // Rust (?) { 107, 142, 35 , 0 }, // Olive (?) { 0, 87, 112 , 0 }, // Water { 255, 0, 0 , 1 }, // Red (L) { 0, 255, 0 , 1 }, // Green (L) { 0, 0, 255 , 1 }, // Blue (L) { 57, 57, 112 , 1 }, // Aqua (L) (?) { 255, 165, 0 , 1 }, // Orange (L) { 255, 255, 0 , 1 }, // Yellow (L) { 255, 255, 255 , 1 }, // White (L) { 255, 255, 255 , 1 }, // White (L) { 139, 0, 0 , 0 }, // Dark red { 0, 100, 0 , 0 }, // Dark green { 0, 0, 139 , 0 }, // Dark blue { 205, 120, 0 , 0 }, // Dark orange { 139, 100, 0 , 0 }, // Dark yellow (?) { 82, 21, 21 , 0 }, // Dark brown (?) { 105, 90, 70 , 0 }, // Dark tan { 128, 35, 0 , 0 }, // Dark rust (?) { 53, 71, 17 , 0 }, // Dark olive (?) { 205, 0, 0 , 0 }, // Medium red { 0, 179, 0 , 0 }, // Medium green { 0, 0, 205 , 0 }, // Medium blue { 255, 140, 0 , 0 }, // Medium orange (?) { 205, 179, 0 , 0 }, // Medium yellow (?) { 120, 32, 32 , 0 }, // Medium brown (?) { 155, 135, 105 , 0 }, // Medium tan (?) { 186, 52, 0 , 0 }, // Medium rust (?) { 80, 106, 25 , 0 }, // Medium olive (?) { 238, 173, 173 , 0 }, // Light red (?) { 144, 238, 144 , 0 }, // Light green { 173, 216, 230 , 0 }, // Light Blue { 255, 162, 68 , 0 }, // Light Orange (?) { 255, 255, 224 , 0 }, // Light Yellow { 255, 130, 58 , 0 }, // Light Brown (?) { 255, 220, 180 , 0 }, // Light Tan (?) { 255, 137, 0 , 0 }, // Light rust (?) { 157, 200, 54 , 0 }, // Light olive (?) { 89, 89, 89 , 1 }, // Dark gray (?) (L) { 169, 169, 169 , 1 }, // Gray (L) { 211, 211, 211 , 1 } // Light Gray (L) }; //=========================================================================== // Alternative palette for transparent colors (?) // (same as in fs5.pal?) static const acColor fsAltPalette[113] = { { 0, 0, 0}, { 8, 8, 8}, { 16, 16, 16}, { 24, 24, 24}, { 32, 32, 32}, { 40, 40, 40}, { 48, 48, 48}, { 56, 56, 56}, { 65, 65, 65}, { 73, 73, 73}, { 81, 81, 81}, { 89, 89, 89}, { 97, 97, 97}, { 105, 105, 105}, { 113, 113, 113}, { 121, 121, 121}, { 130, 130, 130}, { 138, 138, 138}, { 146, 146, 146}, { 154, 154, 154}, { 162, 162, 162}, { 170, 170, 170}, { 178, 178, 178}, { 186, 186, 186}, { 195, 195, 195}, { 203, 203, 203}, { 211, 211, 211}, { 219, 219, 219}, { 227, 227, 227}, { 235, 235, 235}, { 247, 247, 247}, { 255, 255, 255}, { 21, 5, 5}, { 42, 10, 10}, { 63, 15, 15}, { 84, 20, 20}, { 105, 25, 25}, { 126, 30, 30}, { 147, 35, 35}, { 168, 40, 40}, { 189, 45, 45}, { 210, 50, 50}, { 231, 55, 55}, { 252, 60, 60}, { 5, 21, 5}, { 10, 42, 10}, { 15, 63, 15}, { 20, 84, 20}, { 25, 105, 25}, { 30, 126, 30}, { 35, 147, 35}, { 40, 168, 40}, { 45, 189, 45}, { 50, 210, 50}, { 55, 231, 55}, { 60, 252, 60}, { 0, 7, 23}, { 0, 15, 40}, { 0, 23, 58}, { 0, 40, 84}, { 0, 64, 104}, { 0, 71, 122}, { 0, 87, 143}, { 0, 99, 156}, { 0, 112, 179}, { 0, 128, 199}, { 0, 143, 215}, { 0, 153, 230}, { 28, 14, 0}, { 56, 28, 0}, { 84, 42, 0}, { 112, 56, 0}, { 140, 70, 0}, { 168, 84, 0}, { 196, 98, 0}, { 224, 112, 0}, { 252, 126, 0}, { 28, 28, 0}, { 56, 56, 0}, { 84, 84, 0}, { 112, 112, 0}, { 140, 140, 0}, { 168, 168, 0}, { 196, 196, 0}, { 224, 224, 0}, { 252, 252, 0}, { 25, 21, 16}, { 50, 42, 32}, { 75, 63, 48}, { 100, 84, 64}, { 125, 105, 80}, { 150, 126, 96}, { 175, 147, 112}, { 200, 168, 128}, { 225, 189, 144}, { 28, 11, 7}, { 56, 22, 14}, { 84, 33, 21}, { 112, 44, 28}, { 140, 55, 35}, { 168, 66, 42}, { 196, 77, 49}, { 224, 88, 56}, { 252, 99, 63}, { 17, 22, 9}, { 34, 44, 18}, { 51, 66, 27}, { 68, 88, 36}, { 85, 110, 45}, { 102, 132, 54}, { 119, 154, 63}, { 136, 176, 72}, { 153, 198, 81} }; struct _ssgBGLOpCode { unsigned short opcode; const char *name; int size; /* size includes opcode (2 bytes) -1 indicates that special treatment is needed to find the size */ }; static const _ssgBGLOpCode opcodes[] = { { 0x00, "BGL_EOF" , 2 }, { 0x01, "OBSOLETE 0x01" , 2 }, { 0x02, "BGL_NOOP" , 2 }, { 0x03, "BGL_CASE" , -1 }, { 0x04, "RESERVED 0x04" , 2 }, { 0x05, "BGL_SURFACE - Area" , 2 }, { 0x06, "BGL_SPNT" , 8 }, { 0x07, "BGL_CPNT" , 8 }, { 0x08, "BLG_CLOSURE" , 2 }, { 0x09, "OBSOLETE 0x09" , 2 }, { 0x0a, "OBSOLETE 0x0a" , 10 }, { 0x0b, "OBSOLETE 0x0b" , 10 }, { 0x0c, "OBSOLETE 0x0c" , 2 }, { 0x0d, "BGL_JUMP" , 4 }, { 0x0e, "BGL_DEFRES" , 8 }, { 0x0f, "BGL_STRRES" , 4 }, { 0x10, "BGL_CNTRES" , 4 }, { 0x11, "OBSOLETE 0x11" , 10 }, { 0x12, "OBSOLETE 0x12" , 4 }, { 0x13, "OBSOLETE 0x13" , 4 }, { 0x14, "BGL_SCOLOR" , 4 }, { 0x15, "BGL_ELEVATION_MAP" , -1 }, { 0x16, "RESERVED 0x16" , -1 }, { 0x17, "BGL_TEXTURE_ENABLE" , 4 }, { 0x18, "BGL_TEXTURE" , 24 }, { 0x19, "BGL_PALETTE" , 16 }, { 0x1a, "BGL_RESLIST" , -1 }, { 0x1b, "BGL_IFIN_BOX_RAW_PLANE" , 22 }, { 0x1c, "BGL_IFIN2" , 16 }, { 0x1d, "BGL_FACE" , -1 }, { 0x1e, "BGL_HAZE" , 4 }, { 0x1f, "RESERVED 0x1f" , 4 }, { 0x20, "BGL_FACET_TMAP" , -1 }, { 0x21, "BGL_IFIN3" , 22 }, { 0x22, "BGL_RETURN - Return" , 2 }, { 0x23, "BGL_CALL" , 4 }, { 0x24, "BGL_IFIN1" , 10 }, { 0x25, "BGL_SEPARATION_PLANE" , 14 }, { 0x26, "BGL_SETWRD" , 6 }, { 0x27, "OBSOLETE 0x27" , -1 }, { 0x28, "OBSOLETE 0x28" , 10 }, { 0x29, "BGL_GRESLIST" , -1 }, { 0x2a, "BGL_GFACET" , -1 }, { 0x2b, "BGL_ADDOBJ32" , 6 }, { 0x2c, "BGL_REJECT" , 12 }, { 0x2d, "BGL_SCOLOR24" , 6 }, { 0x2e, "BGL_LCOLOR24" , 6 }, { 0x2f, "BGL_SCALE" , 32 }, { 0x30, "OBSOLETE 0x30" , 4 }, { 0x31, "BGL_RESROW" , 18 }, { 0x32, "BGL_ADDOBJ - PerspectiveCall" , 4 }, { 0x33, "BGL_INSTANCE - RotatedCall" , 10 }, { 0x34, "BGL_SUPER_SCALE" , 10 }, { 0x35, "BGL_PNTROW" , 16 }, { 0x36, "OBSOLETE 0x36" , -1 }, { 0x37, "BGL_POINT" , 8 }, { 0x38, "BGL_CONCAVE" , 2 }, { 0x39, "BGL_IFMSK" , 8 }, { 0x3a, "BGL_VPOSITION" , 12 }, { 0x3b, "BGL_VINSTANCE" , 6 }, { 0x3c, "BGL_POSITION" , 28 }, { 0x3d, "BGL_SEED" , 24 }, { 0x3e, "BGL_FACET" , -1 }, { 0x3f, "BGL_SHADOW_CALL" , 4 }, { 0x40, "BGL_SHADOW_VPOSITION" , 12 }, { 0x41, "BGL_SHADOW_VICALL" , 6 }, { 0x42, "BGL_POLYGON_RUNWAY" , 40 }, { 0x43, "BGL_TEXTURE2" , -1 }, { 0x44, "BGL_TEXTURE_RUNWAY" , 64 }, // 40 { 0x45, "OBSOLETE 0x45" , 16 }, { 0x46, "BGL_POINT_VICALL" , 22 }, { 0x47, "RESERVED" , 4 }, { 0x48, "BGL_VAR_SEG" , 4 }, { 0x49, "BGL_BUILDING" , 18 }, { 0x4a, "OBSOLETE 0x4A" , 22 }, { 0x4b, "OBSOLETE 0x4B" , -1 }, { 0x4c, "BGL_VSCALE" , 16 }, { 0x4d, "BGL_MOVEL2G" , 6 }, { 0x4e, "BGL_MOVEG2L" , 6 }, { 0x4f, "BGL_MOVEWORD" , 6 }, { 0x50, "BGL_GCOLOR" , 4 }, { 0x51, "BGL_NEW_LCOLOR" , 4 }, { 0x52, "BGL_NEW_SCOLOR" , 4 }, { 0x53, "OBSOLETE 0x53" , 4 }, { 0x54, "OBSOLETE 0x54" , 6 }, { 0x55, "BGL_SURFACE_TYPE" , 10 }, { 0x56, "BGL_SET_WEATHER" , 4 }, { 0x57, "BGL_SET_WEATHER" , 10 }, { 0x58, "BLG_TEXTURE_BOUNDS" , 10 }, { 0x59, "OBSOLETE 0x59" , 4 }, { 0x5a, "OBSOLETE 0x5a" , 4 }, { 0x5b, "OBSOLETE 0x5b" , 4 }, { 0x5c, "OBSOLETE 0x5c" , 6 }, { 0x5d, "BGL_TEXTURE_REPEAT" , 8 }, { 0x5e, "OBSOLETE 0x5e" , 4 }, { 0x5f, "BGL_IFSIZEV" , 8 }, { 0x60, "BGL_FACE_TMAP" , -1 }, { 0x61, "RESERVED 0x53" , 6 }, { 0x62, "BGL_IFVIS" , -1 }, { 0x63, "BGL_LIBRARY_CALL" , 20 }, { 0x64, "BGL_LIST" , -1 }, { 0x65, "BGL_VSCOLOR" , 4 }, { 0x66, "BGL_VGCOLOR" , 4 }, { 0x67, "BGL_VLCOLOR" , 4 }, { 0x68, "OBSOLETE" , 8 }, { 0x69, "BGL_ROAD_START" , 10 }, { 0x6a, "BGL_ROAD_CONT" , 8 }, { 0x6b, "BGL_RIVER_START" , 10 }, { 0x6c, "BGL_RIVER_CONT" , 8 }, { 0x6d, "BGL_IFSIZEH" , 8 }, { 0x6e, "BGL_TAXIWAY_START" , 10 }, { 0x6f, "BGL_TAXIWAY_CONT" , 8 }, { 0x70, "BGL_AREA_SENSE" , -1 }, { 0x71, "BGL_ALTITUDE_SET" , 4 }, { 0x72, "OBSOLETE 0x72" , 20 }, { 0x73, "BGL_IFINBOXP" , 16 }, { 0x74, "BGL_ADDCAT" , 6 }, { 0x75, "BGL_ADDMNT" , 4 }, { 0x76, "BGL_BGL - Perspective" , 2 }, { 0x77, "BGL_SCALE_AGL - RefPoint" , 32 }, { 0x78, "BGL_ROAD_CONTW" , 10 }, { 0x79, "BGL_RIVER_CONTW" , 10 }, { 0x7a, "BGL_GFACET_TMAP" , -1 }, { 0x7b, "OBSOLETE 0x7b" , -1 }, { 0x7c, "BGL_SELECT" , 10 }, { 0x7d, "BGL_PERSPECTIVE" , 2 }, { 0x7e, "BGL_SETWRD_GLOBAL" , 6 }, { 0x7f, "OBSOLETE 0x7f" , 2 }, { 0x80, "BGL_RESPNT" , 4 }, { 0x81, "OBSOLETE 0x81" , 4 }, { 0x82, "OBSOLETE 0x82" , 28 }, { 0x83, "BGL_RESCALE" , 32 }, { 0x84, "OBSOLETE 0x84" , 8 }, { 0x85, "OBSOLETE 0x85" , 2 }, { 0x86, "OBSOLETE 0x86" , 3 }, { 0x87, "BGL_FIXED_COLORS" , 4 }, { 0x88, "BGL_JUMP32" , 6 }, { 0x89, "BGL_VAR_BASE32" , 6 }, { 0x8a, "BGL_CALL32" , 6 }, { 0x8b, "BGL_ADDCAT32" , 8 }, { 0x8c, "RESERVED 0x8c" , 6 }, { 0x8d, "RESERVED 0x8d" , 6 }, { 0x8e, "BGL_VFILE_MARKER" , 4 }, { 0x8f, "BGL_ALPHA" , 6 }, { 0x90, "RESERVED 0x90" , -1 }, { 0x91, "BGL_TEXT" , 12 }, { 0x92, "OBSOLETE 0x92" , 4 }, { 0x93, "RESERVED 0x93" , 4 }, { 0x94, "BGL_CRASH" , 12 }, { 0x95, "BGL_CRASH_INDIRECT" , 10 }, { 0x96, "BGL_CRASH_START" , 6 }, { 0x97, "BGL_CRASH_SPHERE" , 6 }, { 0x98, "BGL_CRASH_BOX" , 22 }, { 0x99, "BGL_SET_CRASH" , 4 }, { 0x9a, "OBSOLETE 0x9a" , -1 }, { 0x9b, "RESERVED 0x9b" , 8 }, { 0x9c, "RESERVED 0x9c" , 6 }, { 0x9d, "RESERVED 0x9d" , 14 }, { 0x9e, "BGL_INTERPOLATE" , 20 }, { 0x9f, "BGL_OVERRIDE" , 6 }, { 0xa0, "BGL_OBJECT" , -1 }, { 0xa1, "OBSOLETE 0xA1" , 10 }, { 0xa2, "OBSOLETE 0xA2" , 8 }, { 0xa3, "OBSOLETE 0xA3" , -1 }, { 0xa4, "BGL_VALPHA" , 4 }, { 0xa5, "OBSOLETE 0xA5" , 4 }, { 0xa6, "OBSOLETE 0xA6" , 8 }, { 0xa7, "BGL_SPRITE_VCALL" , 22 }, { 0xa8, "BGL_TEXTURE_ROAD_START" , 12}, { 0xa9, "BGL_IFIN_INSTANCE_BOX_PLANE" , 22}, { 0xaa, "BGL_NEW_RUNWAY" , -1 }, { 0xab, "RESERVED 0xAB" , 38 }, { 0xac, "BGL_ZBIAS" , 4 }, { 0xad, "BGL_ANIMATE" , 30 }, { 0xae, "BGL_TRANSFORM_END" , 2 }, { 0xaf, "BGL_TRANSFORM_MATRIX" , 50 }, { 0xb0, "UNKNOWN 0xB0" , -1 }, { 0xb1, "UNKNOWN 0xB1" , -1 }, { 0xb2, "BGL_LIGHT" , 44 }, { 0xb3, "BGL_IFINF1" , 14 }, { 0xb4, "UNKNOWN 0xB4" , -1 }, { 0xb5, "UNKNOWN 0xB5" , -1 }, { 0xb6, "UNKNOWN 0xB6" , -1 }, { 0xb7, "UNKNOWN 0xB7" , -1 }, { 0xb8, "UNKNOWN 0xB8" , -1 }, { 0xb9, "UNKNOWN 0xB9" , -1 }, { 0xba, "UNKNOWN 0xBA" , -1 }, { 0xbb, "UNKNOWN 0xBB" , -1 }, { 0xbc, "UNKNOWN 0xBC" , -1 }, { 0xbd, "UNKNOWN 0xBD" , -1 }, { 0xbe, "UNKNOWN 0xBE" , -1 }, { 0xbf, "UNKNOWN 0xBF" , -1 }, { 0xc0, "UNKNOWN 0xC0" , -1 }, { 0xc1, "UNKNOWN 0xC1" , -1 }, { 0xc2, "UNKNOWN 0xC2" , -1 }, { 0xc3, "UNKNOWN 0xC3" , -1 }, { 0xc4, "UNKNOWN 0xC4" , -1 }, { 0xc5, "UNKNOWN 0xC5" , -1 }, { 0xc6, "UNKNOWN 0xC6" , -1 }, { 0xc7, "UNKNOWN 0xC7" , -1 }, { 0xc8, "UNKNOWN 0xC8" , -1 }, { 0xc9, "UNKNOWN 0xC9" , -1 }, { 0xca, "UNKNOWN 0xCA" , -1 }, { 0xcb, "UNKNOWN 0xCB" , -1 }, { 0xcc, "UNKNOWN 0xCC" , -1 }, { 0xcd, "UNKNOWN 0xCD" , -1 }, { 0xce, "UNKNOWN 0xCE" , -1 }, { 0xcf, "UNKNOWN 0xCF" , -1 }, { 0xd0, "UNKNOWN 0xD0" , -1 }, { 0xd1, "UNKNOWN 0xD1" , -1 }, { 0xd2, "UNKNOWN 0xD2" , -1 }, { 0xd3, "UNKNOWN 0xD3" , -1 }, { 0xd4, "UNKNOWN 0xD4" , -1 }, { 0xd5, "UNKNOWN 0xD5" , -1 }, { 0xd6, "UNKNOWN 0xD6" , -1 }, { 0xd7, "UNKNOWN 0xD7" , -1 }, { 0xd8, "UNKNOWN 0xD8" , -1 }, { 0xd9, "UNKNOWN 0xD9" , -1 }, { 0xda, "UNKNOWN 0xDA" , -1 }, { 0xdb, "UNKNOWN 0xDB" , -1 }, { 0xdc, "UNKNOWN 0xDC" , -1 }, { 0xdd, "UNKNOWN 0xDD" , -1 }, { 0xde, "UNKNOWN 0xDE" , -1 }, { 0xdf, "UNKNOWN 0xDF" , -1 }, { 0xe0, "UNKNOWN 0xE0" , -1 }, { 0xe1, "UNKNOWN 0xE1" , -1 }, { 0xe2, "UNKNOWN 0xE2" , -1 }, { 0xe3, "UNKNOWN 0xE3" , -1 }, { 0xe4, "UNKNOWN 0xE4" , -1 }, { 0xe5, "UNKNOWN 0xE5" , -1 }, { 0xe6, "UNKNOWN 0xE6" , -1 }, { 0xe7, "UNKNOWN 0xE7" , -1 }, { 0xe8, "UNKNOWN 0xE8" , -1 }, { 0xe9, "UNKNOWN 0xE9" , -1 }, { 0xea, "UNKNOWN 0xEA" , -1 }, { 0xeb, "UNKNOWN 0xEB" , -1 }, { 0xec, "UNKNOWN 0xEC" , -1 }, { 0xed, "UNKNOWN 0xED" , -1 }, { 0xee, "UNKNOWN 0xEE" , -1 }, { 0xef, "UNKNOWN 0xEF" , -1 }, { 0xf0, "UNKNOWN 0xF0" , -1 }, { 0xf1, "UNKNOWN 0xF1" , -1 }, { 0xf2, "UNKNOWN 0xF2" , -1 }, { 0xf3, "UNKNOWN 0xF3" , -1 }, { 0xf4, "UNKNOWN 0xF4" , -1 }, { 0xf5, "UNKNOWN 0xF5" , -1 }, { 0xf6, "UNKNOWN 0xF6" , -1 }, { 0xf7, "UNKNOWN 0xF7" , -1 }, { 0xf8, "UNKNOWN 0xF8" , -1 }, { 0xf9, "UNKNOWN 0xF9" , -1 }, { 0xfa, "UNKNOWN 0xFA" , -1 }, { 0xfb, "UNKNOWN 0xFB" , -1 }, { 0xfc, "UNKNOWN 0xFC" , -1 }, { 0xfd, "UNKNOWN 0xFD" , -1 }, { 0xfe, "UNKNOWN 0xFE" , -1 }, { 0xff, "UNKNOWN 0xFF" , -1 } }; //=========================================================================== #endif // _SSGLOADMDL_H plib-1.8.5/src/ssg/ssgStatistics.cxx0000644000175000001440000000032110765364437014361 00000000000000 #include "ssgLocal.h" ssgStatistics _ssgCurrStatistics ; void ssgStatistics::reset () { vertex_count = leaf_count = 0 ; } ssgStatistics *ssgGetLatestStatistics () { return & _ssgCurrStatistics ; } plib-1.8.5/src/ssg/ssgCutout.cxx0000644000175000001440000000753410765364437013527 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgCutout.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgCutout::copy_from ( ssgCutout *src, int clone_flags ) { ssgBranch::copy_from ( src, clone_flags ) ; point_rotate = src -> isPointRotate () ; } ssgBase *ssgCutout::clone ( int clone_flags ) { ssgCutout *b = new ssgCutout ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgCutout::ssgCutout (int pntrot) { point_rotate = pntrot ; type = ssgTypeCutout () ; } ssgCutout::~ssgCutout () { } void ssgCutout::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) ) return ; sgMat4 tmp ; if ( point_rotate ) { /* Trash the current viewpoint transform and replace it with one that only contains the OpenGL axis swap kludge along with the current translation. This prevents the object from rotating relative to the screen so that the modelled X/Z axis are always parallel to the screen X/Y axes. */ sgCopyMat4 ( tmp, _ssgOpenGLAxisSwapMatrix ) ; sgCopyVec3 ( tmp[3], m[3] ) ; } else { sgCopyMat4 ( tmp, m ) ; /* Figure out where the Z axis of the model ends up - that isn't changed by the billboarding process. Next, figure out where the X axis should go - which will be at right angles to the Z axis - and at right angles to the view vector. A cross product achieves that. Finally, figure out where the Y axis should go - which will be at right angles to the new X and Z axes. A second cross product sorts that out. Notice that the SSG coordinate system's Z axis is really GL's Y axis. */ sgVec3 x_axis ; sgVec3 y_axis ; sgVec3 z_axis ; sgSetVec3 ( y_axis, 0.0f, 0.0f, -1.0f ) ; sgCopyVec3 ( z_axis, tmp[ 2 ] ) ; sgVectorProductVec3 ( x_axis, y_axis, z_axis ) ; sgVectorProductVec3 ( y_axis, z_axis, x_axis ) ; sgNormaliseVec3 ( x_axis ) ; sgNormaliseVec3 ( y_axis ) ; /* Optional if your cutout is flat */ /* Now we know where we want the three axes to end up, change the matrix to make it so. */ sgCopyVec3 ( tmp[0], x_axis ) ; sgCopyVec3 ( tmp[1], y_axis ) ; } _ssgPushMatrix ( tmp ) ; glPushMatrix () ; glLoadMatrixf ( (float *) tmp ) ; ssgBranch::cull ( f, tmp, test_needed ) ; glPopMatrix () ; _ssgPopMatrix () ; postTravTests ( SSGTRAV_CULL ) ; } void ssgCutout::hot ( sgVec3 s, sgMat4 m, int test_needed ) { ssgBranch::hot ( s, m, test_needed ) ; } void ssgCutout::los ( sgVec3 s, sgMat4 m, int test_needed ) { ssgBranch::los ( s, m, test_needed ) ; } void ssgCutout::isect ( sgSphere *s, sgMat4 m, int test_needed ) { ssgBranch::isect ( s, m, test_needed ) ; } int ssgCutout::load ( FILE *fd ) { _ssgReadInt ( fd, & point_rotate ) ; return ssgBranch::load(fd) ; } int ssgCutout::save ( FILE *fd ) { _ssgWriteInt ( fd, point_rotate ) ; return ssgBranch::save(fd) ; } plib-1.8.5/src/ssg/ssgLoaderWriterStuff.h0000644000175000001440000001570610765364437015304 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoaderWriterStuff.h 1935 2004-05-04 12:37:33Z wolfram_kuss $ */ //#include "ssgLocal.h" // ******************** small utility functions ************************ void ssgAccumVerticesAndFaces( ssgEntity* node, sgMat4 transform, ssgVertexArray* vertices, ssgIndexArray* indices, SGfloat epsilon, ssgSimpleStateArray* ssa = NULL, ssgIndexArray* materialIndices = NULL, ssgTexCoordArray *texCoordArray = NULL); /* ssgTriangulate - Triangulate a simple polygon (possibly concave, but not self-intersecting). The number of triangles written to 'triangles' is returned, which is always less than or equal to num - 2. The polygon index array 'indices' may be null, in which case an identity mapping is assumed. Note that the implementation is optimized for small polygons, and since the algorithm is O(num^2) it is not efficient on large polygons. */ int _ssgTriangulate( sgVec3 *vertices, int *indices, int num, int *triangles ); // ******************** class ssgLoaderWriterMesh ************************ class ssgListOfLists : public ssgSimpleList // list of POINTERs to ssgSimpleLists { public: virtual ssgBase *clone ( int clone_flags = 0 ) { return NULL; }; // Fixme NIV14: 2do ssgListOfLists ( int init = 3 ) : ssgSimpleList ( sizeof(ssgSimpleList*), init ) {} class ssgSimpleList **get ( unsigned int n ) { return (class ssgSimpleList **) raw_get ( n ) ; } void add ( class ssgSimpleList **thing ) { raw_add ( (char *) thing ) ; } ; void set ( class ssgSimpleList **thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) {}; // Fixme NIV14: 2do } ; //ssgSimpleState* class ssgSimpleStateList : public ssgSimpleList // list of POINTERs to ssgSimpleStates { public: virtual ssgBase *clone ( int clone_flags = 0 ) { return NULL; }; // Fixme NIV14: 2do ssgSimpleStateList( int init = 3 ) : ssgSimpleList ( sizeof(ssgSimpleState*), init ) {} class ssgSimpleState **get ( unsigned int n ) { return (class ssgSimpleState **) raw_get ( n ) ; } void add ( class ssgSimpleState **thing ) { raw_add ( (char *) thing ) ; } ; void set ( class ssgSimpleState **thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) {}; // Fixme NIV14: 2do } ; class ssgLoaderWriterMesh { // ***** general **** char *name; // array of Vec3s: class ssgVertexArray *theVertices; // one index per face: class ssgIndexArray *materialIndices; // Each sublist is of type ssgIndexArray and contains the indexes of the vertices: class ssgListOfLists *theFaces; // material list: class ssgSimpleStateList *theMaterials; // ***** mode switches ***** int textureCoordinatesArePerVertex; // and not per vertex and face (bTCs_are_per_vertex) // ***** complicated (texture coordinates are per face and vertex) mode ***** // Each sublist is of type ssgTexCoordArray and contains the texture coordinates class ssgListOfLists *perFaceAndVertexTextureCoordinate2Lists; // was: tCPFAV = TextureCoordinatesPerFaceAndVertex // ***** easy (texture coordinates are per vertex) mode ********* class ssgTexCoordArray *perVertexTextureCoordinates2; // was: tCPV = TextureCoordinatesPerVertex void addOneNodeToSSGFromPerVertexTextureCoordinates2( class ssgVertexArray *theVertices, class ssgTexCoordArray *theTextureCoordinates2, class ssgListOfLists *theFaces, class ssgSimpleState *currentState,// Pfusch, kludge. NIV135 class ssgLoaderOptions* current_options, class ssgBranch *curr_branch_ ); // was: AddOneNode2SSGFromCPV void addOneNodeToSSGFromPerFaceAndVertexTextureCoordinates2( class ssgVertexArray *theVertices, class ssgListOfLists *theTextureCoordinate2Lists, class ssgListOfLists *theFaces, class ssgSimpleState *currentState,// Pfusch, kludge. NIV135 class ssgLoaderOptions* current_options, class ssgBranch *curr_branch_ ); // was: AddOneNodeToSSGFromCPFAV public: class ssgVertexArray *getVertices(void) { return theVertices; } void setVertices( class ssgVertexArray *vertexArray ); class ssgTexCoordArray *getPerVertexTextureCoordinates2(void) { return perVertexTextureCoordinates2; } void setPerVertexTextureCoordinates2( class ssgTexCoordArray *texCoordArray ); void setName( const char *meshName ); void addToSSG( class ssgSimpleState *currentstate, class ssgLoaderOptions* currentOptions, class ssgBranch *curr_branch_ ); // construction/destruction: ssgLoaderWriterMesh(); ~ssgLoaderWriterMesh(); void reInit(void); void deletePerFaceAndVertexTextureCoordinates2(); // was: deleteTCPFAV // creation: void createVertices( int numReservedVertices = 8 ) ; // was: ThereAreNVertices void addVertex( sgVec3 v ) ; void createFaces( int numReservedFaces = 3 ) ; // was: ThereAreNFaces void addFace( ssgIndexArray **indexArray ) ; void addFaceFromIntegerArray( int numVertices, int *vertices );// AddFaceFromCArray void createPerFaceAndVertexTextureCoordinates2( int numReservedTextureCoordinate2Lists = 3 ) ; // ThereAreNTCPFAV void addPerFaceAndVertexTextureCoordinate2( ssgTexCoordArray **textureCoordinateArray ) ; // addTCPFAV void createPerVertexTextureCoordinates2( int numReservedTextureCoordinates2 = 3 ); // was: ThereAreNTCPV void addPerVertexTextureCoordinate2( sgVec2 textureCoordinate ); // was; addTCPV void createMaterialIndices( int numReservedMaterialIndices = 3 ); // ThereAreNMaterialIndexes void addMaterialIndex( short materialIndex ) ; void createMaterials( int numReservedMaterials = 3 ); // was: ThereAreNMaterials void addMaterial( class ssgSimpleState **simpleState ) ; unsigned int getNumVertices(void) { return theVertices->getNum(); } ; unsigned int getNumFaces (void) { return theFaces->getNum(); } ; unsigned int getNumMaterials(void) { return theMaterials->getNum(); } ; // tools: int checkMe(); }; plib-1.8.5/src/ssg/ssgLoaderWriterStuff.cxx0000644000175000001440000007374610765364437015667 00000000000000 /* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoaderWriterStuff.cxx 2060 2006-01-05 20:54:15Z fayjf $ */ // ssgLoaderWriterStuff.cxx // Here you will find classes and functions you can use to // implement loaders and writers for ssg // Also, there is the parser for loading ASCII files, which // has its own file ssgParser.cxx and there are functions like // the stripifier that are usefull not only for loaders/writers. // // 1. Version written by Wolfram Kuss (Wolfram.Kuss@t-online.de) // in Nov of 2000 // Distributed with Steve Bakers plib under the LGPL licence #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" #undef ABS #undef MIN #undef MAX #define ABS(x) ((x) >= 0 ? (x) : -(x)) #define MIN(a,b) ((a) <= (b) ? (a) : (b)) #define MAX(a,b) ((a) >= (b) ? (a) : (b)) #define MIN3(a,b,c) ((a) <= (b) ? MIN(a,c) : MIN(b,c)) #define MAX3(a,b,c) ((a) >= (b) ? MAX(a,c) : MAX(b,c)) // texture coord epsilon #define TC_EPSILON 0.01 sgVec4 currentDiffuse; // *********************************************************************** // ******************** small utility functions ************************ // *********************************************************************** void ssgAccumVerticesAndFaces( ssgEntity* node, sgMat4 transform, ssgVertexArray* vertices, ssgIndexArray* indices, SGfloat epsilon, ssgSimpleStateArray* ssa, ssgIndexArray* materialIndices, ssgTexCoordArray *texCoordArray) // Accumulates all vertices and Faces (indexes of vertices making up faces) // from node and any node below. // Calls itself recursively. // If indices is NULL, no face info is accumulated // if epsilon is < 0.0, it is ignored. Else vertices are only accumulated if // there is no vertex inside epsilon yet { assert( vertices != NULL ); assert( (epsilon < 0.0) || (indices == NULL) ); // sorry: using epsilon AND using indices not implemented if ( ssa != NULL ) { assert( indices != NULL ); } assert ( ((ssa==NULL) && (materialIndices==NULL)) || ((ssa!=NULL) && (materialIndices!=NULL))); if ( node->isAKindOf( ssgTypeTransform() ) ) { sgMat4 local_transform; ssgTransform *t_node = (ssgTransform*)node; t_node->getTransform(local_transform); sgPostMultMat4( local_transform, transform ); for (ssgEntity* kid = t_node->getKid(0); kid != NULL; kid = t_node->getNextKid()) { ssgAccumVerticesAndFaces( kid, local_transform, vertices, indices, epsilon, ssa, materialIndices, texCoordArray); } } else if ( node->isAKindOf( ssgTypeBranch() ) ) { ssgBranch *b_node = (ssgBranch*)node; for (ssgEntity* kid = b_node->getKid(0); kid != NULL; kid = b_node->getNextKid()) { ssgAccumVerticesAndFaces( kid, transform, vertices, indices, epsilon, ssa, materialIndices, texCoordArray); } } else if ( node->isAKindOf( ssgTypeLeaf() ) ) { ssgLeaf* l_node = (ssgLeaf*)node; int i, vert_low = vertices->getNum(); int useTexture = FALSE; if ( texCoordArray ) if ( l_node->getState() ) if (l_node->getState()->isAKindOf(ssgTypeSimpleState())) { ssgSimpleState * ss = (ssgSimpleState *) l_node->getState(); if ( ss->isEnabled ( GL_TEXTURE_2D ) ) // wk kludge!!! if ( l_node -> getNumTexCoords () == l_node -> getNumVertices() ) useTexture = TRUE; } for (i = 0; i < l_node->getNumVertices(); i++) { sgVec3 new_vertex; sgXformVec3(new_vertex, l_node->getVertex(i), transform); if ( epsilon < 0.0 ) { vertices->add(new_vertex); if ( useTexture ) texCoordArray ->add ( l_node->getTexCoord(i) ); else if ( texCoordArray ) texCoordArray ->add ( _ssgTexCoord00 ); } else { int j, bFound = FALSE, nv1 = vertices -> getNum (); for ( j = 0; j < nv1; j++) { float *oldvertex = vertices -> get(j); if (( new_vertex[0] - oldvertex[0] > -epsilon) && ( new_vertex[0] - oldvertex[0] < epsilon) && ( new_vertex[1] - oldvertex[1] > -epsilon) && ( new_vertex[1] - oldvertex[1] < epsilon) && ( new_vertex[2] - oldvertex[2] > -epsilon) && ( new_vertex[2] - oldvertex[2] < epsilon)) { float *f = 0; if ( useTexture ) { assert( texCoordArray ); // if texCoordArray would be NULL, useTexture would not be set. f = texCoordArray -> get(j); } if ( !useTexture || ((l_node->getTexCoord(i)[0] == f[0]) && (l_node->getTexCoord(i)[1] == f[1]))) { bFound = TRUE; break; } } } if ( ! bFound ) { vertices -> add ( new_vertex ); if ( useTexture ) texCoordArray ->add ( l_node->getTexCoord(i) ); else if ( texCoordArray ) texCoordArray ->add ( _ssgTexCoord00 ); } } } if ( indices != NULL ) { int index=-1; if ( ssa != NULL ) { ssgState *s = l_node->getState(); if ( s != NULL ) { index = ssa->findIndex (reinterpret_cast (s) ); if ( index < 0 ) { ssa -> add(reinterpret_cast (s) ); index = ssa->getNum()-1; } } } for (i = 0; i < l_node->getNumTriangles(); i++) { short v1, v2, v3; l_node->getTriangle(i, &v1, &v2, &v3); indices->add( vert_low + v1 ); indices->add( vert_low + v2 ); indices->add( vert_low + v3 ); if ( materialIndices != NULL ) materialIndices->add(index); // index is -1 for leafs without state } } } if ( texCoordArray ) { assert( vertices->getNum() == texCoordArray->getNum() ); } } ; /* ssgTriangulate - triangulate a simple polygon. */ static int triangulateConcave(sgVec3 *coords, int *w, int n, int x, int y, int *tris) { struct Vtx { int index; float x, y; Vtx *next; }; Vtx buf[16], *arr, *p0, *p1, *p2, *m0, *m1, *m2, *t; int i, chk, num_tris; float a0, a1, a2, b0, b1, b2, c0, c1, c2; /* construct a circular linked list of the vertices */ arr = (n > 16) ? new Vtx [ n ] : buf; p0 = &arr[0]; p0->index = w ? w[0] : 0; p0->x = coords[p0->index][x]; p0->y = coords[p0->index][y]; p1 = p0; p2 = 0; for (i = 1; i < n; i++) { p2 = &arr[i]; p2->index = w ? w[i] : i; p2->x = coords[p2->index][x]; p2->y = coords[p2->index][y]; p1->next = p2; p1 = p2; } p2->next = p0; m0 = p0; m1 = p1 = p0->next; m2 = p2 = p1->next; chk = 0; num_tris = 0; while (p0 != p2->next) { if (chk && m0 == p0 && m1 == p1 && m2 == p2) { /* no suitable vertex found.. */ ulSetError(UL_WARNING, "ssgTriangulate: Self-intersecting polygon."); if (arr != buf) delete [] arr; return 0; } chk = 1; a0 = p1->y - p2->y; a1 = p2->y - p0->y; a2 = p0->y - p1->y; b0 = p2->x - p1->x; b1 = p0->x - p2->x; b2 = p1->x - p0->x; if (b0 * a2 - b2 * a0 < 0) { /* current angle is concave */ p0 = p1; p1 = p2; p2 = p2->next; } else { /* current angle is convex */ float xmin = MIN3(p0->x, p1->x, p2->x); float xmax = MAX3(p0->x, p1->x, p2->x); float ymin = MIN3(p0->y, p1->y, p2->y); float ymax = MAX3(p0->y, p1->y, p2->y); c0 = p1->x * p2->y - p2->x * p1->y; c1 = p2->x * p0->y - p0->x * p2->y; c2 = p0->x * p1->y - p1->x * p0->y; for (t = p2->next; t != p0; t = t->next) { /* see if the triangle contains this vertex */ if (xmin <= t->x && t->x <= xmax && ymin <= t->y && t->y <= ymax && a0 * t->x + b0 * t->y + c0 > 0 && a1 * t->x + b1 * t->y + c1 > 0 && a2 * t->x + b2 * t->y + c2 > 0) break; } if (t != p0) { p0 = p1; p1 = p2; p2 = p2->next; } else { /* extract this triangle */ tris[3 * num_tris + 0] = p0->index; tris[3 * num_tris + 1] = p1->index; tris[3 * num_tris + 2] = p2->index; num_tris++; p0->next = p1 = p2; p2 = p2->next; m0 = p0; m1 = p1; m2 = p2; chk = 0; } } } tris[3 * num_tris + 0] = p0->index; tris[3 * num_tris + 1] = p1->index; tris[3 * num_tris + 2] = p2->index; num_tris++; if (arr != buf) delete [] arr; return num_tris; } int _ssgTriangulate( sgVec3 *coords, int *w, int n, int *tris ) { float *a, *b; int i, x, y; /* trivial case */ if (n <= 3) { if (n == 3) { tris[0] = w ? w[0] : 0; tris[1] = w ? w[1] : 1; tris[2] = w ? w[2] : 2; return 1; } ulSetError(UL_WARNING, "ssgTriangulate: Invalid number of vertices (%d).", n); return 0; } /* compute areas */ { float s[3], t[3]; int swap; s[0] = s[1] = s[2] = 0; b = coords[w ? w[n - 1] : n - 1]; for (i = 0; i < n; i++) { a = b; b = coords[w ? w[i] : i]; s[0] += a[1] * b[2] - a[2] * b[1]; s[1] += a[2] * b[0] - a[0] * b[2]; s[2] += a[0] * b[1] - a[1] * b[0]; } /* select largest area */ t[0] = ABS(s[0]); t[1] = ABS(s[1]); t[2] = ABS(s[2]); i = t[0] > t[1] ? t[0] > t[2] ? 0 : 2 : t[1] > t[2] ? 1 : 2; swap = (s[i] < 0); /* swap coordinates if clockwise */ x = (i + 1 + swap) % 3; y = (i + 2 - swap) % 3; } /* concave check */ { float x0, y0, x1, y1; a = coords[w ? w[n - 2] : n - 2]; b = coords[w ? w[n - 1] : n - 1]; x1 = b[x] - a[x]; y1 = b[y] - a[y]; for (i = 0; i < n; i++) { a = b; b = coords[w ? w[i] : i]; x0 = x1; y0 = y1; x1 = b[x] - a[x]; y1 = b[y] - a[y]; if (x0 * y1 - x1 * y0 < 0) return triangulateConcave(coords, w, n, x, y, tris); } } /* convert to triangles */ { int v0 = 0, v1 = 1, v = n - 1; int even = 1; for (i = 0; i < n - 2; i++) { if (even) { tris[3 * i + 0] = w ? w[v0] : v0; tris[3 * i + 1] = w ? w[v1] : v1; tris[3 * i + 2] = w ? w[v] : v; v0 = v1; v1 = v; v = v0 + 1; } else { tris[3 * i + 0] = w ? w[v1] : v1; tris[3 * i + 1] = w ? w[v0] : v0; tris[3 * i + 2] = w ? w[v] : v; v0 = v1; v1 = v; v = v0 - 1; } even = !even; } } return n - 2; } // *********************************************************************** // ******************** class ssgLoaderWriterMesh ************************ // *********************************************************************** void ssgLoaderWriterMesh::reInit(void) // was: ReInit { theVertices = NULL ; materialIndices = NULL ; theFaces = NULL ; perFaceAndVertexTextureCoordinate2Lists = NULL ; theMaterials = NULL ; perVertexTextureCoordinates2 = NULL ; name = NULL ; textureCoordinatesArePerVertex = TRUE ; } ssgLoaderWriterMesh::ssgLoaderWriterMesh() { reInit(); } ssgLoaderWriterMesh::~ssgLoaderWriterMesh() {} void ssgLoaderWriterMesh::deletePerFaceAndVertexTextureCoordinates2() // was: deleteTCPFAV {} // creation stuff: void ssgLoaderWriterMesh::createVertices( int numReservedVertices ) // was: ThereAreNVertices { assert( theVertices == NULL ); theVertices = new ssgVertexArray ( numReservedVertices ); } void ssgLoaderWriterMesh::addVertex( sgVec3 v ) { assert( theVertices!=NULL ); theVertices->add ( v ); } void ssgLoaderWriterMesh::setVertices( class ssgVertexArray *vertexArray ) { assert( theVertices == NULL ); theVertices = vertexArray; } void ssgLoaderWriterMesh::setPerVertexTextureCoordinates2( class ssgTexCoordArray *texCoordArray ) { assert( perVertexTextureCoordinates2 == NULL ); perVertexTextureCoordinates2 = texCoordArray; } void ssgLoaderWriterMesh::createFaces( int numReservedFaces ) // was: ThereAreNFaces { assert( theFaces == NULL ); theFaces = new ssgListOfLists ( numReservedFaces ); } void ssgLoaderWriterMesh::addFace( ssgIndexArray **indexArray ) { assert( theFaces!=NULL ); theFaces->add ( (ssgSimpleList **)indexArray ); } void ssgLoaderWriterMesh::addFaceFromIntegerArray( int numVertices, int *vertices ) { int j; class ssgIndexArray *oneFace = new ssgIndexArray( numVertices ); oneFace->ref(); for( j=0; jadd( vertices[j] ); addFace( (ssgIndexArray **) &oneFace ); } void ssgLoaderWriterMesh::createPerFaceAndVertexTextureCoordinates2( int numReservedTextureCoordinateLists ) // was: ThereAreNTCPFAV { assert( perFaceAndVertexTextureCoordinate2Lists == NULL ); perFaceAndVertexTextureCoordinate2Lists = new ssgListOfLists( numReservedTextureCoordinateLists ); } void ssgLoaderWriterMesh::addPerFaceAndVertexTextureCoordinate2( ssgTexCoordArray **textureCoordinates2 ) // was: addTCPFAV { assert( perFaceAndVertexTextureCoordinate2Lists != NULL ); perFaceAndVertexTextureCoordinate2Lists->add( (ssgSimpleList **)textureCoordinates2 ); } void ssgLoaderWriterMesh::createPerVertexTextureCoordinates2( int numReservedTextureCoordinates ) { assert( perVertexTextureCoordinates2 == NULL ); perVertexTextureCoordinates2 = new ssgTexCoordArray ( numReservedTextureCoordinates ); } void ssgLoaderWriterMesh::addPerVertexTextureCoordinate2( sgVec2 textureCoordinate ) { assert( perVertexTextureCoordinates2 != NULL ); perVertexTextureCoordinates2->add ( textureCoordinate ); } void ssgLoaderWriterMesh::createMaterialIndices( int numReservedMaterialIndices ) // ThereAreNMaterialIndexes { assert( materialIndices == NULL ); materialIndices = new ssgIndexArray ( numReservedMaterialIndices ); } void ssgLoaderWriterMesh::addMaterialIndex( short materialIndex ) { assert( materialIndices != NULL ); materialIndices->add ( materialIndex ); } void ssgLoaderWriterMesh::createMaterials( int numReservedMaterials ) // ThereAreNMaterials( int n ) { assert( theMaterials == NULL ); theMaterials = new ssgSimpleStateList( numReservedMaterials ); } void ssgLoaderWriterMesh::addMaterial ( class ssgSimpleState **simpleState ) { assert( theMaterials != NULL ); theMaterials->add( simpleState ); } static void recalcNormals( ssgIndexArray* indexList, ssgVertexArray* vertexList, ssgNormalArray *normalList ) // wl: modified to use more code from sg { sgVec3 v1, v2, n; for (int i = 0; i < indexList->getNum() / 3; i++) { short indices[3] = { *indexList->get( i*3 ), *indexList->get( i*3 + 1), *indexList->get( i*3 + 2) }; sgSubVec3(v1, vertexList->get(indices[1]), vertexList->get(indices[0])); sgSubVec3(v2, vertexList->get(indices[2]), vertexList->get(indices[0])); sgVectorProductVec3( n, v1, v2 ); SGfloat normalLength = sgLengthVec3( n ); if( normalLength > 0.00001 ) sgNormaliseVec3( n ); sgCopyVec3( normalList->get( indices[0] ), n ); sgCopyVec3( normalList->get( indices[1] ), n ); sgCopyVec3( normalList->get( indices[2] ), n ); } } // addOneNodeToSSGFromPerFaceAndVertexTextureCoordinates: this function replicates each vertex (based on face usage) and // assigns the appropriate texture coordinates to them (based on the per-face texture indices) void ssgLoaderWriterMesh::addOneNodeToSSGFromPerFaceAndVertexTextureCoordinates2( class ssgVertexArray *theVertices, class ssgListOfLists *thePerFaceAndVertexTextureCoordinates2, class ssgListOfLists *theFaces, class ssgSimpleState *currentState,// Pfusch, kludge. NIV135 class ssgLoaderOptions* current_options, class ssgBranch *curr_branch_) // was: AddOneNode2SSGFromCPFAV { int i, j; assert( theVertices!=NULL ); assert( theFaces!=NULL ); // note: I am changing theVertices here, but that is allowed. class ssgTexCoordArray *perVertexTextureCoordinates2 = new ssgTexCoordArray( theVertices->getNum() ); sgVec2 unUsed; unUsed[0]=-99999; // FixMe: It would be nicer to have an extra array of booleans unUsed[1]=-99999; for( i=0; igetNum(); i++) perVertexTextureCoordinates2->add( unUsed ); for( i=0; igetNum(); i++) { class ssgIndexArray *oneFace = *((class ssgIndexArray **) theFaces->get( i )); class ssgTexCoordArray *textureCoordsForOneFace = *( (ssgTexCoordArray **) thePerFaceAndVertexTextureCoordinates2->get( i ) ); if ( textureCoordsForOneFace != NULL ) // It is allowed that some or even all faces are untextured. { for( j=0; jgetNum(); j++ ) { short *ps = oneFace->get(j); float *newTextureCoordinate2 = textureCoordsForOneFace->get( j ); float *oldTextureCoordinate2 = perVertexTextureCoordinates2->get( *ps ); assert( oldTextureCoordinate2 != NULL ); if ((oldTextureCoordinate2[0]==-99999) && (oldTextureCoordinate2[1]==-99999)) // tc unused until now. Use it { sgVec2 pv; // FixMe: mem leak? pv[0]=newTextureCoordinate2[0]; pv[1]=newTextureCoordinate2[1]; perVertexTextureCoordinates2->set( pv, *ps ); } else { // can we simply use the "old" value? if ( TC_EPSILON < ABS ( newTextureCoordinate2[0]-oldTextureCoordinate2[0] ) + ABS ( newTextureCoordinate2[1]-oldTextureCoordinate2[1] )) { // NO, we can't. Duplicate vertex // not allowed: theVertices->add(theVertices->get(*ps)); // create duplicate 3D. FixMe: clone needed? float * f = theVertices->get(*ps); sgVec3 v; v[0] = f[0]; v[1] = f[1]; v[2] = f[2]; theVertices->add( v ); sgVec2 pv; pv[0]=newTextureCoordinate2[0]; pv[1]=newTextureCoordinate2[1]; perVertexTextureCoordinates2->add( pv ); // create duplicate 2D *ps=theVertices->getNum()-1; // use duplicate assert ( *oneFace->get(j) == theVertices->getNum()-1); } } } } } addOneNodeToSSGFromPerVertexTextureCoordinates2(theVertices, perVertexTextureCoordinates2, theFaces, currentState, current_options, curr_branch_); } void ssgLoaderWriterMesh::addOneNodeToSSGFromPerVertexTextureCoordinates2( class ssgVertexArray *theVertices, class ssgTexCoordArray *theTextureCoordinates2, class ssgListOfLists *theFaces, class ssgSimpleState *currentState,// kludge NIV135 class ssgLoaderOptions* current_options, class ssgBranch *curr_branch_) // was: AddOneNode2SSGFromCPV { int i, j; //start Normals, FixMe, kludge NIV135 ssgNormalArray *normalList = new ssgNormalArray( theVertices->getNum() ); sgVec3 kludge; for( i=0; igetNum(); i++ ) normalList->add(kludge); //currentMesh.vl->get(i)); class ssgIndexArray* indexList = new ssgIndexArray ( theFaces->getNum() * 3 ) ; // there are MINIMAL n * 3 indexes for( i=0; igetNum(); i++ ) { class ssgIndexArray *oneFace = *((class ssgIndexArray **) theFaces->get( i )); if ( oneFace->getNum() >= 3 ) { for(j=0;jgetNum();j++) { if (j<3) indexList->add(*oneFace->get(j)); else // add a complete triangle { indexList->add(*oneFace->get(0)); indexList->add(*oneFace->get(j-1)); indexList->add(*oneFace->get(j)); } } } } recalcNormals( indexList, theVertices, normalList ); // Fixme, NIV14: only do this if there are no normals in the file ssgColourArray* colours = NULL ; if ( currentState -> isEnabled ( GL_LIGHTING ) ) { if ( colours == NULL ) { colours = new ssgColourArray ( 1 ) ; sgVec4 currentDiffuseColour; sgCopyVec4(currentDiffuseColour, currentState->getMaterial(GL_DIFFUSE)); colours -> add ( currentDiffuseColour ) ; } } ssgVtxArray* leaf = new ssgVtxArray ( GL_TRIANGLES, theVertices, normalList, theTextureCoordinates2, colours, indexList ) ; leaf -> setCullFace ( TRUE ) ; leaf -> setState ( currentState ) ; ssgEntity *model = current_options -> createLeaf ( leaf, NULL) ; assert( model != NULL ); model->setName(name); curr_branch_->addKid(model); } void ssgLoaderWriterMesh::setName( const char *meshName ) { delete [] name; if ( !meshName ) name = NULL; else name = ulStrDup(meshName); } void ssgLoaderWriterMesh::addToSSG( class ssgSimpleState *currentState,// FixMe, kludge. NIV135 class ssgLoaderOptions* current_options, class ssgBranch *curr_branch_ ) { int i, j, k; unsigned short oldVertexIndex, newVertexIndex; class ssgIndexArray *thisFace; #ifdef WRITE_MESH_TO_STDOUT if ( theMaterials == NULL ) ulSetError(UL_DEBUG, "( theMaterials == NULL )"); else { ulSetError(UL_DEBUG, "%d Materials:", theMaterials->getNum()); for(i=0;igetNum();i++) { ulSetError(UL_DEBUG, "%ld", (long)theMaterials->get(i)); } } if ( materialIndices == NULL ) ulSetError(UL_DEBUG, "( materialIndices == NULL )"); else { ulSetError(UL_DEBUG, "%d Material Indexes:", materialIndices->getNum()); for(i=0;igetNum();i++) { short s=*(materialIndices->get(i)); ulSetError(UL_DEBUG, "%ld", (long)s); } } #endif if ( theMaterials == NULL ) { if ( perFaceAndVertexTextureCoordinate2Lists == NULL ) addOneNodeToSSGFromPerVertexTextureCoordinates2( theVertices, perVertexTextureCoordinates2 /* may be NULL */, theFaces, currentState, current_options, curr_branch_); else addOneNodeToSSGFromPerFaceAndVertexTextureCoordinates2(theVertices, perFaceAndVertexTextureCoordinate2Lists, theFaces, currentState, current_options, curr_branch_); } else { assert( theVertices != NULL ); assert( theFaces != NULL ); // FixMe: What about faces without state? They should have material -1 for( i=0; i < theMaterials->getNum(); i++ ) { // I often allocate too much; This is wastefull on memory, but fast since it never "resizes": class ssgVertexArray *newVertices = new ssgVertexArray ( theVertices->getNum() ); class ssgListOfLists *newFaces = new ssgListOfLists ( theFaces->getNum() ); class ssgIndexArray *oldVertexIndexToNewVertexIndex = new ssgIndexArray ( theVertices->getNum() ); class ssgListOfLists *newPerFaceAndVertexTextureCoordinate2Lists = NULL; class ssgTexCoordArray *newPerVertexTextureCoordinates2 = NULL; if( perFaceAndVertexTextureCoordinate2Lists != NULL ) newPerFaceAndVertexTextureCoordinate2Lists = new ssgListOfLists(); if ( perVertexTextureCoordinates2 != NULL ) newPerVertexTextureCoordinates2 = new ssgTexCoordArray(); for (j=0; jgetNum(); j++) oldVertexIndexToNewVertexIndex->add ( short(0xFFFF) ); // 0xFFFF stands for "unused in new Mesh" // Go through all the old Faces, look for the correct material and copy those // faces and indexes into the new // FixMe, 2do, NIV135: if the Materials just differ through the colour, one would not need // several meshes, but could use the colour array. However, this is not possible, // if they differ by for example the texture assert( materialIndices != NULL ); for ( j=0; jgetNum(); j++ ) if ( i == *(materialIndices->get( // for *.x-files, there may be less materialIndices than faces. I then simply repeat // the last index all the time: jgetNum() ? j : materialIndices->getNum()-1 )) ) { // take this face thisFace = *((class ssgIndexArray **) theFaces->get( j )); newFaces->add( (class ssgSimpleList **)&thisFace); //thisFace = *((class ssgIndexArray **) newFaces->get( newFaces->getNum()-1 )); if( perFaceAndVertexTextureCoordinate2Lists != NULL ) newPerFaceAndVertexTextureCoordinate2Lists ->add( perFaceAndVertexTextureCoordinate2Lists -> get( j ) ); for( k=0; k < thisFace->getNum(); k++ ) { oldVertexIndex = * thisFace->get(k); newVertexIndex = *oldVertexIndexToNewVertexIndex->get( oldVertexIndex ); if ( 0xFFFF == newVertexIndex ) { newVertexIndex = newVertices->getNum(); newVertices->add( theVertices->get( oldVertexIndex ) ); oldVertexIndexToNewVertexIndex->set( newVertexIndex, oldVertexIndex ); if ( perVertexTextureCoordinates2 != NULL ) newPerVertexTextureCoordinates2 -> add( perVertexTextureCoordinates2->get( oldVertexIndex ) ); } // From here on the indexes in thisFace are only valid in relation to // newVertices and newtextureCoordinatePerVertex. Since this face will not be used for any // further material, this doesn't lead to problems. thisFace->set( newVertexIndex, k ); } } #ifdef WRITE_MESH_TO_STDOUT ulSetError(UL_DEBUG, "NumVert: %d", newVertices->getNum()); for(j=0;jgetNum();j++) { float *f=newVertices->get(j); ulSetError(UL_DEBUG, "%f, %f, %f",f[0], f[1], f[2]); } for(j=0;jgetNum();j++) { thisFace = *((class ssgIndexArray **) newFaces->get( j )); fprintf(stderr, "%d EP:", thisFace->getNum()); for(k=0;kgetNum();k++) { oldVertexIndex = * thisFace->get(k); fprintf(stderr, "%d, ", oldVertexIndex); } putc('\n', stderr); } #endif if ( newFaces->getNum() > 0 ) { currentState = *theMaterials->get(i); if ( perFaceAndVertexTextureCoordinate2Lists == NULL ) // FixMe: textureCoordinatePerVertex-indices are not compatible to newVertices-indices?!? addOneNodeToSSGFromPerVertexTextureCoordinates2( newVertices, newPerVertexTextureCoordinates2 /* may be NULL */, newFaces, currentState, current_options, curr_branch_); else addOneNodeToSSGFromPerFaceAndVertexTextureCoordinates2(newVertices, newPerFaceAndVertexTextureCoordinate2Lists, newFaces, currentState, current_options, curr_branch_); } } } } int ssgLoaderWriterMesh::checkMe() // returns TRUE; if ok. // Writes out errors by calling ulSetError with severity UL_WARNING, // and a bit of debug info as UL_DEBUG // May stop on first error. // FixMe; todo: textureCoordinatePerVertex and tCPFAV. NIV135 { int i, oneIndex; class ssgIndexArray * vertexIndsForOneFace; class ssgTexCoordArray * textureCoordsForOneFace; // **** check theVertices ***** if ( theVertices == NULL ) { if (( materialIndices == NULL ) && (theFaces == NULL ) && ( perFaceAndVertexTextureCoordinate2Lists == NULL )) { ulSetError( UL_DEBUG, "LoaderWriterMesh::checkMe(): The mesh is empty\n"); return TRUE; } else { ulSetError( UL_WARNING, "LoaderWriterMesh::checkMe(): No theVertices is NULL; but not the rest!\n"); return FALSE; } } // **** check materialIndices and theMaterials ***** /* FixMe; kludge: 2do. NIV135 // one index per face: class ssgIndexArray *materialIndices; theMaterials */ if ((( theMaterials == NULL ) && ( materialIndices != NULL )) || (( theMaterials != NULL ) && ( materialIndices == NULL ))) { ulSetError( UL_WARNING, "LoaderWriterMesh::checkMe(): " "One of theMaterials and materialIndices was NULL and the other != NULL!\n"); return FALSE; } if ( materialIndices != NULL ) { for (i=0;igetNum();i++) { oneIndex = *materialIndices->get(i); assert(theMaterials!=NULL); if (( oneIndex < 0 ) || ( oneIndex >= theMaterials->getNum())) { ulSetError( UL_WARNING, "LoaderWriterMesh::checkMe(): " "Material index out of range. Index = %d, " "theMaterials->getNum() = %d.\n", oneIndex, theMaterials->getNum()); return FALSE; } } } // **** check theFaces ***** // Each sublist is of type ssgIndexArray and contains the indexes of the vertices: if ( theFaces == NULL ) { ulSetError( UL_WARNING, "LoaderWriterMesh::checkMe(): There are vertices but no faces.\n"); return FALSE; } for(i=0;igetNum();i++) { vertexIndsForOneFace = *((ssgIndexArray **) theFaces->get ( i )); if ( vertexIndsForOneFace == NULL ) { ulSetError( UL_WARNING, "LoaderWriterMesh::checkMe(): the vertexindexes for one face are NULL!\n"); return FALSE; } } // **** check textureCoordinates ***** // Each sublist is of type ssgTexCoordArray and contains the texture coordinates if ( perFaceAndVertexTextureCoordinate2Lists != NULL ) // may be NULL { if ( theFaces->getNum() != perFaceAndVertexTextureCoordinate2Lists->getNum()) { ulSetError( UL_WARNING, "LoaderWriterMesh::checkMe(): " "There must be as many faces in theFaces as in textureCoordinates. But " "theFaces->getNum() =%d, tCPFAV->getNum() = %d!\n", theFaces->getNum(), perFaceAndVertexTextureCoordinate2Lists->getNum()); return FALSE; } for(i=0;igetNum();i++) { textureCoordsForOneFace = *((ssgTexCoordArray **) perFaceAndVertexTextureCoordinate2Lists->get ( i )); if ( textureCoordsForOneFace != NULL ) // It is allowed that some or even all faces are untextured. { vertexIndsForOneFace = *((ssgIndexArray **) theFaces->get ( i )); if ( textureCoordsForOneFace->getNum() != vertexIndsForOneFace ->getNum()) { ulSetError( UL_WARNING, "LoaderWriterMesh::checkMe(): Face %d: " "Each face must have as many texture corrdinates (or none) as vertices. But " "textureCoordsForOneFace->getNum() =%d, vertexIndsForOneFace ->getNum() = %d!\n", i, textureCoordsForOneFace->getNum(), vertexIndsForOneFace ->getNum()); return FALSE; } } } } return TRUE; // success } plib-1.8.5/src/ssg/ssgLoadOBJ.cxx0000644000175000001440000004152010765364437013447 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadOBJ.cxx 2020 2005-03-25 01:04:04Z wolfram_kuss $ */ // // Wavefront OBJ import for SSG/PLIB // Ported from IVCON by Dave McClurg (dpm@efn.org) in March-2000 // Updated by Dave McClurg in April-2000 (added textures) // /* Purpose: OBJ_READ reads a Wavefront OBJ file. Example: # magnolia.obj mtllib ./vp.mtl g v -3.269770 -39.572201 0.876128 v -3.263720 -39.507999 2.160890 ... v 0.000000 -9.988540 0.000000 g stem s 1 usemtl brownskn f 8 9 11 10 f 12 13 15 14 ... f 788 806 774 Modified: 20 October 1998 Author: John Burkardt */ #include "ssgLocal.h" #define MAX_LINE_LEN 1024 #define MAX_LINE 100000 #define MAX_FACE 100000 #define MAX_VERT 100000 #define MAX_MATERIALS 1000 struct faceData { int vlist [3] ; int tlist [3] ; int nlist [3] ; int mat_index ; } ; struct matData { char* name ; sgVec4 amb ; sgVec4 diff ; sgVec4 spec ; float shine ; float trans ; char* tfname ; } ; static int num_line ; static int* line_dex ; static int num_face ; static faceData* face ; static int num_vert ; static int num_vert_tex ; static int num_vert_normal ; static sgVec3* vert ; static sgVec3* vert_tex ; static sgVec3* vert_normal ; static int num_mat ; static matData* materials ; static ssgBranch *current_branch = NULL ; static ssgState* get_state( matData* mat ) { if (mat->tfname != NULL) { ssgState *st = ssgGetCurrentOptions () -> createState ( mat->tfname ) ; if ( st != NULL ) return st ; } ssgSimpleState *st = new ssgSimpleState () ; st -> setMaterial ( GL_AMBIENT, mat -> amb ) ; st -> setMaterial ( GL_DIFFUSE, mat -> diff ) ; st -> setMaterial ( GL_SPECULAR, mat -> spec ) ; st -> setShininess ( mat -> shine ) ; st -> enable ( GL_COLOR_MATERIAL ) ; st -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; st -> enable ( GL_LIGHTING ) ; st -> setShadeModel ( GL_SMOOTH ) ; if ( mat -> trans < 0.99f ) { st -> disable ( GL_ALPHA_TEST ) ; st -> enable ( GL_BLEND ) ; st -> setTranslucent () ; } else { st -> disable ( GL_BLEND ) ; st -> setOpaque () ; } if (mat->tfname != NULL) { st -> setTexture( ssgGetCurrentOptions () -> createTexture(mat->tfname) ) ; st -> enable( GL_TEXTURE_2D ) ; } else { st -> disable( GL_TEXTURE_2D ) ; } return st ; } static int leqi ( const char* string1, const char* string2 ) //LEQI compares two strings for equality, disregarding case. { int i; int nchar; int nchar1; int nchar2; nchar1 = strlen ( string1 ); nchar2 = strlen ( string2 ); if ( nchar1 < nchar2 ) { nchar = nchar1; } else { nchar = nchar2; } /* The strings are not equal if they differ over their common length. */ for ( i = 0; i < nchar; i++ ) { if ( toupper ( string1[i] ) != toupper ( string2[i] ) ) { return FALSE; } } /* The strings are not equal if the longer one includes nonblanks in the tail. */ if ( nchar1 > nchar ) { for ( i = nchar; i < nchar1; i++ ) { if ( string1[i] != ' ' ) { return FALSE; } } } else if ( nchar2 > nchar ) { for ( i = nchar; i < nchar2; i++ ) { if ( string2[i] != ' ' ) { return FALSE; } } } return TRUE; } static char filename [ 1024 ] ; static void load_materials ( const char* fname ) { num_mat = 0 ; char path [ 1024 ] ; ssgGetCurrentOptions () -> makeModelPath ( path, fname ) ; FILE* filein = fopen (path,"r") ; if ( filein == 0 ) { char mtl_filename[ 1024 ]; strcpy(mtl_filename, filename); if(NULL!=strrchr(mtl_filename, '/')) *strrchr(mtl_filename, '/') = 0; if(NULL!=strrchr(mtl_filename, '\\')) *strrchr(mtl_filename, '\\') = 0; strncat(mtl_filename, "\\", 1024); strncat(mtl_filename, fname, 1024); filein = fopen (mtl_filename,"r") ; if ( filein == 0 ) return ; // give up finding the material file } int index = -1 ; char input[MAX_LINE_LEN]; while ( fgets ( input, MAX_LINE_LEN, filein ) != NULL ) { char *next; for ( next = input; *next != '\0' && isspace(*next); next++ ) ; if ( *next == '\0' ) continue; if ( *next == '#' || *next == '$' ) continue; char token[MAX_LINE_LEN]; int width; int count; float r1,r2,r3; sscanf ( next, "%s%n", token, &width ) ; next = next + width ; if ( leqi ( token, "NEWMTL" ) == TRUE ) { char name[MAX_LINE_LEN]; count = sscanf ( next, "%s%n", name, &width ) ; if ( count == 1 ) { index ++ ; memset( &materials[ index ], 0, sizeof(matData) ) ; materials[ index ].name = ulStrDup ( name ) ; materials[ index ].amb[3] = 1.0f ; materials[ index ].diff[3] = 1.0f ; materials[ index ].spec[3] = 1.0f ; materials[ index ].shine = 0.0f ; materials[ index ].trans = 1.0f ; } } else if ( leqi ( token, "Ka" ) == TRUE ) { count = sscanf ( next, "%e %e %e", &r1, &r2, &r3 ) ; if ( count == 3 && index >= 0 ) { materials[ index ].amb[0] = r1 ; materials[ index ].amb[1] = r2 ; materials[ index ].amb[2] = r3 ; } } else if ( leqi ( token, "Kd" ) == TRUE ) { count = sscanf ( next, "%e %e %e", &r1, &r2, &r3 ) ; if ( count == 3 && index >= 0 ) { materials[ index ].diff[0] = r1 ; materials[ index ].diff[1] = r2 ; materials[ index ].diff[2] = r3 ; } } else if ( leqi ( token, "Ks" ) == TRUE ) { count = sscanf ( next, "%e %e %e", &r1, &r2, &r3 ) ; if ( count == 3 && index >= 0 ) { materials[ index ].spec[0] = r1 ; materials[ index ].spec[1] = r2 ; materials[ index ].spec[2] = r3 ; } } else if ( leqi ( token, "map_Kd" ) == TRUE ) { char tfname[MAX_LINE_LEN]; count = sscanf ( next, "%s%n", tfname, &width ) ; if ( count == 1 && index >= 0 ) materials[ index ].tfname = ulStrDup ( tfname ) ; } } fclose (filein) ; num_mat = (index+1) ; } static void add_mesh ( int mat_index ) { int i ; //count faces with same material int num = 0 ; for ( i=0; i add ( vert[ face[i].vlist[j] ] ) ; if ( num_vert_tex ) tlist -> add ( vert_tex[ face[i].tlist[j] ] ) ; if ( num_vert_normal ) nlist -> add ( vert_normal[ face[i].nlist[j] ] ) ; } } } ssgState *st = NULL ; if ( mat_index < num_mat ) { matData* mat = &materials[ mat_index ]; if ( mat->tfname != 0 ) st = ssgGetCurrentOptions() -> createState ( mat->tfname ) ; if ( st == NULL ) st = get_state ( mat ) ; } ssgVtxTable *vtab = new ssgVtxTable ( GL_TRIANGLES, vlist, nlist, tlist, 0 ) ; vtab -> setCullFace ( TRUE ); if ( st ) vtab -> setState ( st ) ; current_branch -> addKid ( vtab ) ; } static int obj_read ( FILE *filein ) { int count; char *next; char *next2; char *next3; int node; float r1; float r2; float r3; char input[MAX_LINE_LEN]; char token[MAX_LINE_LEN]; char token2[MAX_LINE_LEN]; int width; int mat_current = 0 ; /* Initialize. */ num_line = 0 ; line_dex = new int[ MAX_LINE ] ; num_face = 0 ; face = new faceData[ MAX_FACE ] ; num_vert = 0 ; num_vert_tex = 0 ; num_vert_normal = 0 ; vert = new sgVec3[ MAX_VERT ] ; vert_tex = new sgVec3[ MAX_VERT ] ; vert_normal = new sgVec3[ MAX_VERT ] ; num_mat = 0 ; materials = new matData [ MAX_MATERIALS ] ; /* Read the next line of the file into INPUT. */ while ( fgets ( input, MAX_LINE_LEN, filein ) != NULL ) { for ( next = input; *next != '\0' && isspace(*next); next++ ) ; if ( *next == '\0' ) continue; if ( *next == '#' || *next == '$' ) continue; sscanf ( next, "%s%n", token, &width ); next = next + width; /* F V1 V2 V3 or F V1/VT1/VN1 V2/VT2/VN2 ... or F V1//VN1 V2//VN2 ... Face. A face is defined by the vertices. Optionally, slashes may be used to include the texture vertex and vertex normal indices. OBJ line node indices are 1 based rather than 0 based. So we have to decrement them before loading them into FACE. */ if ( leqi ( token, "F" ) == TRUE ) { int vlist [4] ; int tlist [4] ; int nlist [4] ; int ivert = 0 ; /* Read each item in the F definition as a token, and then take it apart. */ for ( ;; ) { count = sscanf ( next, "%s%n", token2, &width ); next = next + width; if ( count != 1 ) { break; } count = sscanf ( token2, "%d%n", &node, &width ); next2 = token2 + width; if ( count != 1 ) { break; } if ( ivert >= 4 ) { break; } vlist[ivert] = 0 ; tlist[ivert] = 0 ; nlist[ivert] = 0 ; if ( 0 < node && node <= num_vert ) { vlist[ivert] = node-1; } /* If there's a slash, extract the index of the texture vector. If there's another slash, extract the index of the normal vector. */ if ( *next2 == '/' ) { next3 = next2 + 1; count = sscanf ( next3, "%d%n", &node, &width ); if ( 0 < node && node <= num_vert_tex ) { tlist[ivert] = node-1; } for ( ; next3 < token2 + MAX_LINE_LEN; next3++ ) { if ( *next3 == '/' ) { next3 = next3 + 1; count = sscanf ( next3, "%d%n", &node, &width ); if ( 0 < node && node <= num_vert_normal ) { nlist[ivert] = node-1; } break; } } } ivert = ivert + 1; } if ( ivert >= 3 ) { //quad? if ( ivert == 4 ) { if ( num_face+1 < MAX_FACE ) { //0,1,3 face[num_face].vlist[0] = vlist[0] ; face[num_face].tlist[0] = tlist[0] ; face[num_face].nlist[0] = nlist[0] ; face[num_face].vlist[1] = vlist[1] ; face[num_face].tlist[1] = tlist[1] ; face[num_face].nlist[1] = nlist[1] ; face[num_face].vlist[2] = vlist[3] ; face[num_face].tlist[2] = tlist[3] ; face[num_face].nlist[2] = nlist[3] ; face[num_face].mat_index = mat_current ; num_face = num_face + 1; //3,1,2 face[num_face].vlist[0] = vlist[3] ; face[num_face].tlist[0] = tlist[3] ; face[num_face].nlist[0] = nlist[3] ; face[num_face].vlist[1] = vlist[1] ; face[num_face].tlist[1] = tlist[1] ; face[num_face].nlist[1] = nlist[1] ; face[num_face].vlist[2] = vlist[2] ; face[num_face].tlist[2] = tlist[2] ; face[num_face].nlist[2] = nlist[2] ; face[num_face].mat_index = mat_current ; num_face = num_face + 1; } } else { if ( num_face < MAX_FACE ) { for ( int i = 0 ; i < 3 ; i ++ ) { face[num_face].vlist[i] = vlist[i] ; face[num_face].tlist[i] = tlist[i] ; face[num_face].nlist[i] = nlist[i] ; } face[num_face].mat_index = mat_current ; num_face = num_face + 1; } } } } /* G Group name. */ else if ( leqi ( token, "G" ) == TRUE ) { continue; } /* L I believe OBJ line node indices are 1 based rather than 0 based. So we have to decrement them before loading them into LINE_DEX. */ else if ( leqi ( token, "L" ) == TRUE ) { int lastnode = -1 ; for ( ;; ) { count = sscanf ( next, "%d%n", &node, &width ); next = next + width; if ( count != 1 ) { break; } if ( lastnode != -1 && num_line + 2 <= MAX_LINE ) { line_dex[num_line] = lastnode-1; num_line = num_line + 1; line_dex[num_line] = node-1; num_line = num_line + 1; } lastnode = node ; } } /* LOD Level of detail. */ else if ( leqi ( token, "LOD" ) == TRUE ) { continue; } /* MG Merging group. */ else if ( leqi ( token, "MG" ) == TRUE ) { continue; } /* MTLLIB Material library. */ else if ( leqi ( token, "MTLLIB" ) == TRUE ) { count = sscanf ( next, "%s%n", token2, &width ); next = next + width; if ( count != 1 ) { continue; } load_materials ( token2 ) ; mat_current = 0 ; } /* USEMTL Material name. */ else if ( leqi ( token, "USEMTL" ) == TRUE ) { mat_current = 0 ; count = sscanf ( next, "%s%n", token2, &width ); next = next + width; if ( count != 1 ) { continue; } for ( int i = 0 ; i < num_mat ; i ++ ) if ( strcmp ( token2, materials[ i ].name ) == 0 ) { mat_current = i ; break ; } } /* O Object name. */ else if ( leqi ( token, "O" ) == TRUE ) { continue; } /* P Point. */ else if ( leqi ( token, "P" ) == TRUE ) { continue; } /* SURF Surface. */ else if ( leqi ( token, "SURF" ) == TRUE ) { continue; } /* V X Y Z W Geometric vertex. W is optional, a weight for rational curves and surfaces. The default for W is 1. */ else if ( leqi ( token, "V" ) == TRUE ) { sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); if ( num_vert < MAX_VERT ) { vert[num_vert][0] = r1; vert[num_vert][1] = r2; vert[num_vert][2] = r3; num_vert = num_vert + 1; } } /* VT Vertex texture. */ else if ( leqi ( token, "VT" ) == TRUE ) { sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); if ( num_vert_tex < MAX_VERT ) { vert_tex[num_vert_tex][0] = r1; vert_tex[num_vert_tex][1] = r2; vert_tex[num_vert_tex][2] = r3; num_vert_tex = num_vert_tex + 1; } } /* VN Vertex normals. */ else if ( leqi ( token, "VN" ) == TRUE ) { sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); if ( num_vert_normal < MAX_VERT ) { vert_normal[num_vert_normal][0] = r1; vert_normal[num_vert_normal][1] = r2; vert_normal[num_vert_normal][2] = r3; num_vert_normal = num_vert_normal + 1; } } } //create ssg nodes if ( num_face ) { if ( num_mat ) { for ( int i=0; i add ( vert[ line_dex[i] ] ) ; ssgVtxTable *vtab = new ssgVtxTable ( GL_LINES, vlist, 0, 0, 0 ); current_branch -> addKid ( vtab ) ; } delete[] materials ; delete[] vert ; delete[] vert_tex ; delete[] vert_normal ; delete[] face ; delete[] line_dex ; return TRUE; } ssgEntity *ssgLoadOBJ ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; const ssgLoaderOptions* current_options = ssgGetCurrentOptions () ; current_branch = NULL ; current_options -> makeModelPath ( filename, fname ) ; FILE *loader_fd = fopen ( filename, "ra" ) ; if ( loader_fd == NULL ) { ulSetError ( UL_WARNING, "ssgLoadOBJ: Failed to open '%s' for reading", filename ) ; return NULL ; } current_branch = new ssgTransform () ; obj_read ( loader_fd ) ; fclose ( loader_fd ) ; return current_branch ; } plib-1.8.5/src/ssg/ssgLoadOFF.cxx0000644000175000001440000002223310765364437013447 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadOFF.cxx 1970 2004-10-04 08:11:26Z wolfram_kuss $ */ // // .off loader for SSG/PLIB // Warning: There are two formats called OFF // // There is Geomview off, see http://www.neuro.sfc.keio.ac.jp/~aly/polygon/format/off.html // and http://www.graphics.cornell.edu/~gordon/peek/old/off.html // This is the format implmented in this file. // // And there is off (Object File Format) by Digital Equipment Corporation, Workstation Systems Engineering // (WSE), see for ex. http://www.dcs.ed.ac.uk/home/mxr/gfx/3d/OFF.spec. // and http://www.landfield.com/faqs/graphics/fileformats-faq/part3/section-95.html // We don't support this format. // Written by Wolfram Kuss (Wolfram.Kuss@t-online.de) in February 2001 // // We only support 2D and 3D data #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" #include "ssgParser.h" #define u32 unsigned int static int _ssgLoadTranslucent=TRUE; extern sgVec4 currentDiffuse; void ssgSetLoadOFFTranslucent ( int i ) // this is a kludge. // it might be removed/replaced later on. { _ssgLoadTranslucent = i; } static /* const */ ssgLoaderOptions* current_options = NULL ; static _ssgParserSpec parser_spec = { "\r\n\t ", // delim_chars_skipable ",;", // delim_chars_non_skipable NULL, // pre_processor "", // open_brace_chars "", // close_brace_chars '"', // quote_char. not used for OFF '#', // comment_char "%" // comment_string } ; static _ssgParser parser; static ssgBranch* top_branch; /*static int Ascii2Int(int &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = int(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } }*/ static int Ascii2UInt(unsigned int &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = (unsigned int)(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } static int Ascii2Float(SGfloat &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = SGfloat(strtod( token, &endptr)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } #define MAX_NO_VERTICES_PER_FACE 1000 static class ssgLoaderWriterMesh theMesh; static int _ssgNoFacesToRead=-1, _ssgNoVerticesToRead; static int thereIs_ST=FALSE, thereIs_C=FALSE, thereIs_N=FALSE, thereIs_4=FALSE, thereIs_n=TRUE; static unsigned int dimension; // may be 2 or 3 static int parse() { char* token; token = parser.getLine( 0 ); if ( token == NULL ) { parser.error("The file seems to be empty"); return FALSE; } // If first line is "off", swallow it if ( strlen(token) >= 3 ) { char *p = token; p += strlen(token)-3; if (0==strcmp("OFF", p) ) { if ( strlen(token) > 3 ) // parse line { thereIs_ST = ( NULL != strstr( token, "ST" )); thereIs_C = ( NULL != strstr( token, "C" )); thereIs_N = ( NULL != strstr( token, "N" )); thereIs_4 = ( NULL != strstr( token, "4" )); thereIs_n = ( NULL != strstr( token, "n" )); if ( thereIs_ST || thereIs_C || thereIs_N ) { parser.error("This is a \"ST\"- \"C\"- or \"N\"-OFF. These are not supoorted, sorry."); return FALSE; } if ( thereIs_4 && !thereIs_n ) { parser.error("This is a 4D-OFF file. We only support 3D data, sorry."); return FALSE; } } token = parser.getLine( 0 ); assert( token != NULL ); } } if ( thereIs_n ) { if ( ! Ascii2UInt(dimension, token, "Dimension" )) return FALSE; if ( thereIs_4 && thereIs_n ) dimension++; if ( (dimension != 3) && (dimension != 2)) { parser.error("This is a %udD-OFF file. We only support 2D and 3D data, sorry.", dimension); return FALSE; } token = parser.getLine( 0 ); // read space dimension assert( token != NULL ); } // ****** read NVertices, NFaces and NEdges ************ unsigned int uInt; int i; if ( ! Ascii2UInt(uInt, token, "NVertices")) return FALSE; _ssgNoVerticesToRead = uInt; token = parser.parseToken( "NFaces" ); if ( ! Ascii2UInt(uInt, token, "NFaces")) return FALSE; _ssgNoFacesToRead = uInt; token = parser.parseToken( "NEdges" ); if ( ! Ascii2UInt(uInt, token, "NEdges")) return FALSE; // **** init theMesh *** theMesh.reInit (); theMesh.createVertices( _ssgNoVerticesToRead ); theMesh.createFaces ( _ssgNoFacesToRead ); // ***** read Vertex Coords for ( i = 0; i < _ssgNoVerticesToRead ; i++ ) { sgVec3 vert; token = parser.getLine( ); // may return NULL? assert(token!=NULL); if (!Ascii2Float(vert[0], token, "x")) return FALSE; if (!parser.parseFloat(vert[1], "y")) return FALSE; if ( dimension == 2 ) vert[2] = 0.0; else if (!parser.parseFloat(vert[2], "z")) return FALSE; theMesh.addVertex(vert); } // ********* Read Faces ********** int iVertex, aiVertices[MAX_NO_VERTICES_PER_FACE]; unsigned int nNoOfVerticesForThisFace, j; for(i=0;i<_ssgNoFacesToRead ;i++) { token = parser.getLine( ); // may return NULL? assert(token!=NULL); if (!Ascii2UInt(nNoOfVerticesForThisFace , token, "number of vertices for this face")) return FALSE; assert(nNoOfVerticesForThisFace setTranslucent () ; ss -> disable ( GL_ALPHA_TEST ) ; ss -> enable ( GL_BLEND ) ; //new glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ss->setAlphaClamp(0.1f); } float *ssf=ss->getMaterial ( GL_DIFFUSE ); ssf[0]=0.8f; ssf[1]=0.8f; ssf[2]=1.0f; if ( _ssgLoadTranslucent ) ssf[3]=0.4f; else ssf[3]=1.0f; sgCopyVec4 ( currentDiffuse, ssf ); ssf=ss->getMaterial ( GL_EMISSION ); ssf[0]=0.0f; ssf[1]=0.0f; ssf[2]=0.0f; ssf[3]=1.0f; ssf=ss->getMaterial ( GL_SPECULAR ); ssf[0]=1.0f; ssf[1]=1.0f; ssf[2]=1.0f; ssf[3]=1.0f; ssf=ss->getMaterial ( GL_AMBIENT ); ssf[0]=0.3f; ssf[1]=0.3f; ssf[2]=0.3f; ssf[3]=1.0f; if ( !_ssgLoadTranslucent ) // This code has simply been copyied over from ssgLoadM, where it works { ss->setOpaque(); ss->disable(GL_BLEND); ss->disable(GL_ALPHA_TEST); ss->disable(GL_TEXTURE_2D); ss->enable(GL_COLOR_MATERIAL); ss->enable(GL_LIGHTING); ss->setShadeModel(GL_SMOOTH); ss->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.0f, 1.0f); ss->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.0f, 1.0f); ss->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f); ss->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f); ss->setShininess(50); } theMesh.createMaterials( 1 ); theMesh.addMaterial( &ss ); theMesh.createMaterialIndices( _ssgNoFacesToRead ) ; for(i=0;i<_ssgNoFacesToRead ;i++) theMesh.addMaterialIndex ( 0 ) ; theMesh.addToSSG( ss, // kludge. NIV135 current_options, top_branch); return TRUE ; } ssgEntity *ssgLoadOFF ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; top_branch = new ssgBranch ; if ( !parser.openFile( fname, &parser_spec )) { delete top_branch ; return 0; } if ( !parse() ) { delete top_branch ; top_branch = 0 ; } // parse_free(); parser.closeFile(); return top_branch ; } plib-1.8.5/src/ssg/pcx.h0000644000175000001440000000505210765364437011737 00000000000000// Loading of the PCX texture file format // // This file is used for both PLIB and for BoB. // // Written by Wolfram Kuss in december 2003 // // This file is published as public domain struct pcxHeaderType { char manufacturer; // always 10 char version; // usually 5 char encoding; // 1 = RLE char bitsPerPixel; // number of bits to represent a pixel short x, y; // upper left coordinates short xmax, ymax; short hDPI, vDPI; // DPI char egaPalette[48]; // obsolete char reserved; // unused, always 0 char nColorPlanes; // number of color planes. not implemented yet? short bytesPerLine; // bytes per scan line. not implemented yet? todo kludge short paletteInfo; // colored or grey scale. not implemented yet? short hScreenSize, cScreenSize; char padding[54]; // reserved, always 0 }; #define READ_BYTE (buffer[0]); buffer++; #define READ_SHORT ((((unsigned long)buffer[0])<<8) + buffer[1]); buffer += 2; #define READ_LONG ((((unsigned long)buffer[0])<<24) + (((unsigned long)buffer[1])<<16) + (((unsigned long)buffer[2])<<8) + buffer[3]); buffer += 4; // It is bad style to have a function inside a header file, but this way there is only one file // I need to "synchronise" between PLIB and BoB. static int ReadPCXBody(UByte*& buffer, pcxHeaderType *ppcxHeader, UByte * pBody) // returns TRUE on success. // reads from buffer (which will normally just hold the file contents, but in memory, // writes to pBody, which must have been allocated { unsigned short x,y; if ((ppcxHeader->bitsPerPixel != 8) // unsupported pcx || (ppcxHeader->encoding>1) // invalid PCX // || (pcxHeader.nColorPlanes != 1) // unsupported pcx || (ppcxHeader->manufacturer != 10)) // invalid pcx return (FALSE); unsigned short width = ppcxHeader->xmax-ppcxHeader->x+1; x=0; y=0; // upper left coordinates for(;;) { UByte color = READ_BYTE; if ((color &0xC0) != 0xC0) // uncompressed? { *pBody++ = color; x++; if (x >= width) { x=0; y++; // next line if(y > ppcxHeader->ymax-ppcxHeader->y) break; } } else { UByte counter, length = color & 0x3F; // number of times next byte repeated color = READ_BYTE; for (counter=0; counter= width) { x=0; y++; // next line counter=length; if(y > ppcxHeader->ymax-ppcxHeader->y) break; // breaks for (counter=0; counte... } } if(y > ppcxHeader->ymax-ppcxHeader->y) break; // breaks for(;;) } } return TRUE; } plib-1.8.5/src/ssg/ssgTexTrans.cxx0000644000175000001440000000540010765364437014002 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgTexTrans.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgTexTrans::copy_from ( ssgTexTrans *src, int clone_flags ) { ssgBaseTransform::copy_from ( src, clone_flags ) ; } ssgBase *ssgTexTrans::clone ( int clone_flags ) { ssgTexTrans *b = new ssgTexTrans ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgTexTrans::ssgTexTrans ( sgCoord *c ) { type = ssgTypeTexTrans () ; setTransform ( c ) ; } ssgTexTrans::ssgTexTrans (void) { type = ssgTypeTexTrans () ; } ssgTexTrans::~ssgTexTrans (void) { } void ssgTexTrans::setTransform ( sgVec3 xyz ) { sgMakeTransMat4 ( transform, xyz ) ; } void ssgTexTrans::setTransform ( sgCoord *xform, float sx, float sy, float sz ) { sgMakeCoordMat4 ( transform, xform ) ; sgScaleVec3 ( transform[0], sx ) ; sgScaleVec3 ( transform[1], sy ) ; sgScaleVec3 ( transform[2], sz ) ; } void ssgTexTrans::setTransform ( sgCoord *xform ) { sgMakeCoordMat4 ( transform, xform ) ; } void ssgTexTrans::setTransform ( sgMat4 xform ) { sgCopyMat4 ( transform, xform ) ; } void ssgTexTrans::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) ) return ; int cull_result = cull_test ( f, m, test_needed ) ; if ( cull_result == SSG_OUTSIDE ) return ; _ssgLoadTexMatrix ( transform ) ; glMatrixMode ( GL_TEXTURE ) ; glLoadMatrixf ( (float *) transform ) ; glMatrixMode ( GL_MODELVIEW ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> cull ( f, m, cull_result != SSG_INSIDE ) ; glMatrixMode ( GL_TEXTURE ) ; glLoadIdentity () ; glMatrixMode ( GL_MODELVIEW ) ; _ssgUnloadTexMatrix () ; postTravTests ( SSGTRAV_CULL ) ; } int ssgTexTrans::load ( FILE *fd ) { return ssgBaseTransform::load(fd) ; } int ssgTexTrans::save ( FILE *fd ) { return ssgBaseTransform::save(fd) ; } plib-1.8.5/src/ssg/ssgLoadFLT.cxx0000644000175000001440000023565210765364437013475 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadFLT.cxx 1762 2003-04-17 13:10:12Z stromberg $ */ // // $Id: ssgLoadFLT.cxx 1762 2003-04-17 13:10:12Z stromberg $ // // // OpenFlight loader for SSG // // // The loading of FLT files can to some degree be controlled by // setting environment variables: // // FLTNOCLEAN - if set disables all kinds of scene graph optimisations // FLTNOEXT - ignore external references // FLTNOTEX - disables textures altogether // FLTNOMIPMAP - configure textures for bilinear filtering (no mipmaps) // // // Some known issues: // // 1. The color table in v14.0 and earlier is defined differently and // cannot be parsed. It may consist of 16 colours of 16 brightnesses // each, and the RGB values are passed as shorts. // // 2. Geometry in v11.0 and earlier are defined using obsolete records // (opcodes 6, 7, 8 and 9). Need specifications to parse them. // // 3. How to find external files properly. Some loaders (most notably // IRIS Performer and MultiGen) uses the variable FLTEXTERNPATH. // (MultiGen also uses FLTPATH and TXTPATH I think). // // 4. How to do mmap on Mac and PS2. // // 5. No optimisations are done on the geometry. New triangle strip // generation code planned for SSG, and should be used when ready. // // 6. Optimisation done on the scene graph level are minimal. // // // /* * Another OpenFlight loader for Performer * Copyright (C) 1998-2000 Marten Stromberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ssg.h" #include "ssgLoaderWriterStuff.h" /* define this to compile against older versions of SSG */ /*#define NO_LOADER_OPTIONS*/ /* debug */ /*#define NO_LIGHTING*/ /*#define NO_TEXTURES*/ /*#define NO_COLORS*/ /* Try to figure out how to do mmap. */ #ifdef UL_WIN32 # define USE_WIN32_MMAP #else # include # ifdef _POSIX_MAPPED_FILES # define USE_POSIX_MMAP # endif #endif #include #include #include #include #ifdef UL_IRIX # include #endif #ifdef USE_POSIX_MMAP # include # include /* Need both for Mandrake 8.0 !! */ # include # include #endif #ifdef UL_MSVC # include #endif #ifndef O_BINARY # define O_BINARY 0 #endif #ifndef R_OK # define R_OK 4 #endif #ifndef ABS # define ABS(x) ((x)>=0?(x):-(x)) #endif #ifndef MIN # define MIN(a,b) ((a)<=(b)?(a):(b)) #endif #ifndef MAX # define MAX(a,b) ((a)>=(b)?(a):(b)) #endif #define MIN3(a,b,c) ((a)<=(b)?MIN(a,c):MIN(b,c)) #define MAX3(a,b,c) ((a)>=(b)?MAX(a,c):MAX(b,c)) #define CLAMP(x,lo,hi) ((x)<=(lo)?(lo):(x)>=(hi)?(hi):(x)) #define template _template /* trams */ typedef unsigned char ubyte; #ifdef UL_WIN32 typedef unsigned short ushort; typedef unsigned int uint; #endif // 525 = negative identation, 539= did not expect positive identation //lint -save -e525 -e539 /* * byte sex */ /* XXX what about PDP_ENDIAN? */ /* Help! Is this correct? */ #if (!defined(BYTE_ORDER) && defined(UL_WIN32) && !defined(NOT_INTEL_BYTE_ORDER)) # define LITTLE_ENDIAN 1234 # define BIG_ENDIAN 4321 # define BYTE_ORDER LITTLE_ENDIAN #endif /* #undef BYTE_ORDER */ #if !defined(BYTE_ORDER) || BYTE_ORDER != BIG_ENDIAN #if !defined(BYTE_ORDER) static void _swab16(const void *src, void *dst, int n) { ushort *s = (ushort *)src; ushort *d = (ushort *)dst; while (n--) { ushort t = *s++; *d++ = (((t & 0xff00U) >> 8) | ((t & 0x00ffU) << 8)); } } #endif static void _swab32(const void *src, void *dst, int n) { uint *s = (uint *)src; uint *d = (uint *)dst; while (n--) { uint t = *s++; *d++ = (((t & 0xff000000U) >> 24) | ((t & 0x00ff0000U) >> 8) | ((t & 0x0000ff00U) << 8) | ((t & 0x000000ffU) << 24)); } } static void _swab64(const void *src, void *dst, int n) { /* XXX how to check if 64-bit integers are available?? */ uint *s = (uint *)src; uint *d = (uint *)dst; while (n--) { uint t0 = *s++; uint t1 = *s++; *d++ = (((t1 & 0xff000000U) >> 24) | ((t1 & 0x00ff0000U) >> 8) | ((t1 & 0x0000ff00U) << 8) | ((t1 & 0x000000ffU) << 24)); *d++ = (((t0 & 0xff000000U) >> 24) | ((t0 & 0x00ff0000U) >> 8) | ((t0 & 0x0000ff00U) << 8) | ((t0 & 0x000000ffU) << 24)); } } #endif #if !defined(BYTE_ORDER) || BYTE_ORDER != LITTLE_ENDIAN static void _copy16(const void *src, void *dst, int n) { memcpy(dst, src, 2*n); } static void _copy32(const void *src, void *dst, int n) { memcpy(dst, src, 4*n); } static void _copy64(const void *src, void *dst, int n) { memcpy(dst, src, 8*n); } #endif #if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN /* big endian */ inline uint get16u(const void *ptr) { return *(ushort *)ptr; } inline uint get32u(const void *ptr) { return *(uint *)ptr; } #define get16v _copy16 #define get32v _copy32 #define get64v _copy64 #elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN /* little endian */ inline uint get16u(const void *ptr) { ushort tmp = *(ushort *)ptr; return (((tmp & 0xff00U) >> 8) | ((tmp & 0x00ffU) << 8)); } inline uint get32u(const void *ptr) { uint tmp = *(uint *)ptr; return (((tmp & 0xff000000U) >> 24) | ((tmp & 0x00ff0000U) >> 8) | ((tmp & 0x0000ff00U) << 8) | ((tmp & 0x000000ffU) << 24)); } #define get16v _swab16 #define get32v _swab32 #define get64v _swab64 #else /* any endian */ inline uint get16u(const void *ptr) { ubyte *u = (ubyte *)ptr; return (((uint)u[0] << 8) | ((uint)u[1] << 0)); } inline uint get32u(const void *ptr) { ubyte *u = (ubyte *)ptr; return (((uint)u[0] << 24) | ((uint)u[1] << 16) | ((uint)u[2] << 8) | ((uint)u[3] << 0)); } static void (*get16v)(const void *, void *, int); static void (*get32v)(const void *, void *, int); static void (*get64v)(const void *, void *, int); #define PROBE_ENDIAN 1 #endif #define get16i(ptr) (short)get16u(ptr) #define get32i(ptr) (int)get32u(ptr) /* splay trees * * for further details, see "Self-adjusting Binary Search Trees" * by Sleator and Tarjan, JACM Volume 32, No 3, July 1985, pp 652-686. */ struct snode { struct snode *left, *right; void *key; void *data; }; typedef int (*sfunc)(const void *key1, const void *key2); static struct snode *splay(struct snode *t, const void *key, sfunc comp) { struct snode N, *l, *r, *y; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { if (comp(key, t->key) < 0) { if (t->left == NULL) break; if (comp(key, t->left->key) < 0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (comp(key, t->key) > 0) { if (t->right == NULL) break; if (comp(key, t->right->key) > 0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static struct snode *sinsert(struct snode *root, void *key, size_t size, sfunc comp) { struct snode *t, *x; t = splay(root, key, comp); if (t != NULL && comp(t->key, key) == 0) return t; //x = (struct snode *)malloc(sizeof(struct snode)); x = new snode; assert( x != NULL ); if (t == NULL) { x->left = x->right = NULL; } else if (comp(key, t->key) < 0) { x->left = t->left; x->right = t; t->left = NULL; } else { x->right = t->right; x->left = t; t->right = NULL; } if (size > 0) { //x->key = malloc(size); x->key = new ubyte[size]; memcpy(x->key, key, size); } else { x->key = key; } x->data = (void *)-1; return x; } #define S_KEY 1 /* free key */ #define S_DATA 2 /* free data */ #define S_TREE 4 /* delete scene graph (SSG special) */ static void deltree(ssgEntity *node) { if (node->getRef() <= 1 && node->isAKindOf(ssgTypeBranch())) { ssgBranch *grp = (ssgBranch *)node; int n = grp->getNumKids(); while (n--) { deltree(grp->getKid(n)); grp->removeKid(n); // delete kid (iff ref == 0) } } } static void sfree(struct snode *x, int flags) { if (x) { sfree(x->left, flags); sfree(x->right, flags); if ((flags & S_KEY)) //free(x->key); delete [] (ubyte *)x->key; if (x->data != (void *)-1 && x->data != 0) { if ((flags & S_DATA)) //free(x->data); delete [] (ubyte *)x->data; if ((flags & S_TREE)) { deltree((ssgEntity *)x->data); ssgDeRefDelete((ssgEntity *)x->data); } } } } static int ptrcmp(const void *key1, const void *key2) { return (const char *)key1 - (const char *)key2; } static void hexdump(enum ulSeverity severity, const ubyte *buf, int size, int offset) { #define COLS 16 char line[1024], *lp; while (size > 0) { int i, n = MIN(size, COLS); lp = line; lp += sprintf(lp, "%04x ", offset); for (i = 0; i < n; i++) lp += sprintf(lp, " %02x", buf[i]); for (; i < COLS; i++) lp += sprintf(lp, " "); *lp++ = ' '; *lp++ = ' '; for (i = 0; i < n; i++) *lp++ = (buf[i] & 0x7f) < 0x20 ? '.' : buf[i]; *lp = 0; ulSetError(severity, line); buf += COLS; offset += COLS; size -= COLS; } } #define MAXDEPTH 256 #define UNPACK_ABGR(dst, src) \ ((dst)[0] = (1.0f/255.0f)*(src)[3], \ (dst)[1] = (1.0f/255.0f)*(src)[2], \ (dst)[2] = (1.0f/255.0f)*(src)[1], \ (dst)[3] = 1.0f) #define UNPACK_ABGR2(dst, src, intensity) \ ((dst)[0] = (1.0f/255.0f/127.0f)*(src)[3]*(intensity), \ (dst)[1] = (1.0f/255.0f/127.0f)*(src)[2]*(intensity), \ (dst)[2] = (1.0f/255.0f/127.0f)*(src)[1]*(intensity), \ (dst)[3] = 1.0f) /* triangle flags */ #define TRI_COLOR_MATERIAL 0x01 /* --> apply material on vertex colors */ #define TRI_TRANSLUCENT 0x02 #define TRI_SUBFACE 0x04 /* offset geometry */ #define TRI_BBOARD_AXIAL 0x08 #define TRI_BBOARD_POINT 0x10 /*#define TRI_WIREFRAME 0x20*/ #define TRI_BBOARD (TRI_BBOARD_AXIAL | TRI_BBOARD_POINT) /* vertex bind */ #define BIND_COLOR 0x01 #define BIND_NORMAL 0x02 #define BIND_TEXCOORD 0x04 #define BIND_FLAT_COLOR 0x08 #define BIND_FLAT_NORMAL 0x10 #define BIND_FLAT (BIND_FLAT_COLOR | BIND_FLAT_NORMAL) struct fltTriangle { ssgState *state; ubyte flags; ubyte bind; #if 0 short priority; /* affects the ordering within the geoset */ ushort transparency; /* eventually applied to colors when done */ #endif int index[3]; sgVec4 color; /* face color *or* material contributions to vertex colors */ }; struct fltTexture { char *file; ssgState *state; /* user-defined state */ ssgTexture *tex; int alpha; }; struct fltState { fltState() { memset(this, 0, sizeof(*this)); notex_state = (ssgState *)-1; atris = 256; //tris = (fltTriangle *)malloc(sizeof(fltTriangle) * atris); tris = new fltTriangle[atris]; } ~fltState() { sfree(texs, S_DATA); sfree(mtls, S_DATA); sfree(refs, S_TREE); if (vtab) { delete [] offset; delete [] bind; delete [] coord; delete [] color; delete [] normal; delete [] texcoord; } //free(tris); delete [] tris; } const char *filename; int revision; int major; int minor; /* Vertex Table */ ubyte *vtab; /* start of vertex table */ int vnum; int *offset; /* chunk offset (used as index) */ ubyte *bind; /* 1 - color, 2 - normal, 4 - texcoord */ sgVec3 *coord; sgVec4 *color; sgVec3 *normal; sgVec2 *texcoord; /* Other Tables (these may be sparse, that is why arrays are not used) */ struct snode *mtls; /* index --> float[14] */ struct snode *texs; /* index --> fltTexture */ struct snode *refs; /* index --> ssgEntity */ ubyte (*ctab)[4]; /* packed ABGR color table */ int cnum; ssgState *notex_state; /* special user-defined state if no texture */ /* Collected Geometry */ fltTriangle *tris; int ntris, atris; fltTriangle *temp; char *parent_name; }; struct fltNodeAttr { /* allocated using new/delete for convenience */ fltNodeAttr() { memset(this, 0, sizeof(*this)); } ~fltNodeAttr() { if (name) delete name; if (mask_words) delete mask_words; } /* properies that are not applied immediately */ char *name; int replicate; int transform; int islod; sgMat4 mat; sgVec2 range; sgVec3 center; /* switch record info */ int num_masks; int num_words; uint *mask_words; int current_mask; }; static int Inited = 0; static int NoTextures = 0; static int NoMipmaps = 0; static int NoExternals = 0; static int NoClean = 0; #ifndef NO_LOADER_OPTIONS static ssgLoaderOptions *LoaderOptions; #endif static struct snode *TexCache; /* filename --> fltTexture */ static fltTexture *LoadTex(char *fname) { TexCache = sinsert(TexCache, fname, strlen(fname) + 1, (sfunc)strcmp); if (TexCache->data == (void *)-1) { //fltTexture *tex = (fltTexture *)malloc(sizeof(fltTexture)); fltTexture *tex = new fltTexture; assert ( tex != NULL ); tex->file = fname; #ifdef NO_LOADER_OPTIONS tex->state = 0; tex->tex = new ssgTexture(fname, 1, 1, !NoMipmaps); #else tex->state = LoaderOptions->createState(fname); tex->tex = tex->state ? 0 : LoaderOptions->createTexture(fname, 1, 1, !NoMipmaps); #endif tex->alpha = tex->tex ? tex->tex->hasAlpha() : 0; TexCache->data = tex; } return (fltTexture *)TexCache->data; } struct StateInfo { int cf; /* cull face */ int tr; /* translucent */ int cm; /* color material */ ssgTexture *tex; float *mtl; float alpha; }; static int StateCompare(const void *key1, const void *key2) { const StateInfo *s1 = (const StateInfo *)key1; const StateInfo *s2 = (const StateInfo *)key2; int d; d = s1->cf - s2->cf; if (d == 0) { d = s1->tr - s2->tr; if (d == 0) { d = s1->cm - s2->cm; if (d == 0) { d = (char *)s1->tex - (char *)s2->tex; if (d == 0) { if (s1->mtl == 0 || s2->mtl == 0) d = (char *)s1->mtl - (char *)s2->mtl; else { int i = s1->cm ? 6 : 0; for (; i < 12 && d == 0; i++) if (s1->mtl[i] < s2->mtl[i] - 0.01f) d = -1; else if (s1->mtl[i] > s2->mtl[i] + 0.01f) d = 1; if (d == 0) { if (s1->alpha < s2->alpha - 0.01f) d = -1; else if (s1->alpha > s2->alpha + 0.01f) d = 1; } } } } } } return d; } static struct snode *StateCache; /* StateInfo --> ssgSimpleState */ static ssgSimpleState *ConstructState(StateInfo *key) { StateCache = sinsert(StateCache, key, sizeof(StateInfo), StateCompare); if (StateCache->data == (void *)-1) { ssgSimpleState *s; /*ulSetError(UL_DEBUG, "new state --");*/ s = new ssgSimpleState; if (key->cf) { s->enable(GL_CULL_FACE); } else { s->disable(GL_CULL_FACE); /*ulSetError(UL_DEBUG, " two-sided");*/ } if (key->tr) { s->setTranslucent(); s->enable(GL_BLEND); /* XXX what about multisampling? */ /*ulSetError(UL_DEBUG, " transparent");*/ } else { s->setOpaque(); s->disable(GL_BLEND); } /* leave the alpha test to the application */ if (key->mtl) { float *m = key->mtl; sgVec4 c; /*ulSetError(UL_DEBUG, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %d", m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], key->cm);*/ if (key->cm) { s->enable(GL_COLOR_MATERIAL); s->setColourMaterial(GL_AMBIENT_AND_DIFFUSE); //ulSetError(UL_DEBUG, " color material"); } else { s->disable(GL_COLOR_MATERIAL); sgSetVec4(c, m[0], m[1], m[2], key->alpha); s->setMaterial(GL_AMBIENT, c); sgSetVec4(c, m[3], m[4], m[5], key->alpha); s->setMaterial(GL_DIFFUSE, c); //ulSetError(UL_DEBUG, " ambient %.2f %.2f %.2f", m[0], m[1], m[2]); //ulSetError(UL_DEBUG, " diffuse %.2f %.2f %.2f", m[3], m[4], m[5]); } sgSetVec4(c, m[6], m[7], m[8], key->alpha); s->setMaterial(GL_SPECULAR, c); sgSetVec4(c, m[9], m[10], m[11], key->alpha); s->setMaterial(GL_EMISSION, c); //ulSetError(UL_DEBUG, " specular %.2f %.2f %.2f", m[6], m[7], m[8]); //ulSetError(UL_DEBUG, " emission %.2f %.2f %.2f", m[9], m[10], m[11]); //ulSetError(UL_DEBUG, " alpha %.2f", key->alpha); s->setShininess(m[12]); s->enable(GL_LIGHTING); } else { s->disable(GL_LIGHTING); /*ulSetError(UL_DEBUG, " no lighting");*/ } if (key->tex) { s->enable(GL_TEXTURE_2D); s->setTexture(key->tex); /*ulSetError(UL_DEBUG, " texture %s", key->tex->getFilename());*/ } else { s->disable(GL_TEXTURE_2D); } s->setShadeModel(GL_SMOOTH); s->ref(); StateCache->data = s; } return (ssgSimpleState *)StateCache->data; } static int tricmp(const void *a, const void *b) { /* this comparison is used to sort the list of triangles in order to * generate as few geosets as possible. */ fltTriangle *ta = (fltTriangle *)a; fltTriangle *tb = (fltTriangle *)b; int d = (char *)ta->state - (char *)tb->state; if (d == 0) { d = ta->flags - tb->flags; if (d == 0) d = ta->bind - tb->bind; } return d; } #if 0 /* no longer needed since this is now the default blend equation */ static int PreDrawTranslucent(ssgEntity *) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); return 1; } #endif static int PreDrawSubface(ssgEntity *) { #ifdef GL_VERSION_1_1 glPolygonOffset(-2.0f, -1.0f); glEnable(GL_POLYGON_OFFSET_FILL); #else glPolygonOffsetEXT(-0.1f, -0.002f); glEnable(GL_POLYGON_OFFSET_EXT); #endif return 1; } static int PostDrawSubface(ssgEntity *) { #ifdef GL_VERSION_1_1 glDisable(GL_POLYGON_OFFSET_FILL); #else glDisable(GL_POLYGON_OFFSET_EXT); #endif return 1; } /* convert a list of triangles to geosets using the pfdMesher * need a seperate geostate for each comb of tex/mtl/bind */ static ssgEntity *Build(fltState *state) { /*const char t[9] = "plsTQSfFP";*/ ssgBranch *grp = 0; ssgCutout *bboard1 = 0; ssgCutout *bboard2 = 0; ssgLeaf *leaf = 0; fltTriangle *arr; int num, i, j, k, m, n; //int *index; //int *vertex; arr = state->tris; num = state->ntris; state->ntris = 0; if (num == 0) return 0; /* sort the triangles (put them in bins according to their attributes) * one geoset will be generated for each such bin */ qsort(arr, num, sizeof(fltTriangle), tricmp); int *index = new int [ state->vnum ]; int *vertex = new int [ 32768 ]; for (i = 0; i < num; ) { ssgVertexArray *va; ssgColourArray *ca = 0; ssgNormalArray *na = 0; ssgTexCoordArray *ta = 0; ssgVtxTable *geom; int flags = arr[i].flags; int bind = arr[i].bind; /* see how many tris that belong to this group */ for (j = i + 1; (j < num && arr[j].state == arr[i].state && arr[j].flags == flags && arr[j].bind == bind ); j++) ; /*fprintf(stderr, " %d", j - i);*/ /* simply construct a triangle soup */ /* XXX fixme! */ if ((bind & BIND_FLAT) || (flags & TRI_COLOR_MATERIAL)) { n = 3*(j - i); va = new ssgVertexArray(n); for (k = i; k < j; k++) { va->add(state->coord[arr[k].index[0]]); va->add(state->coord[arr[k].index[1]]); va->add(state->coord[arr[k].index[2]]); } if ((bind & BIND_FLAT_COLOR)) { ca = new ssgColourArray(n); for (k = i; k < j; k++) { ca->add(arr[k].color); ca->add(arr[k].color); ca->add(arr[k].color); } } else if ((bind & BIND_COLOR)) { ca = new ssgColourArray(n); if ((flags & TRI_COLOR_MATERIAL)) { for (k = i; k < j; k++) { for (m = 0; m < 3; m++) { sgVec4 color; float *mtl_color = arr[k].color; float *vtx_color = state->color[arr[k].index[m]]; color[0] = mtl_color[0] * vtx_color[0]; color[1] = mtl_color[1] * vtx_color[1]; color[2] = mtl_color[2] * vtx_color[2]; color[3] = mtl_color[3] * vtx_color[3]; ca->add(color); } } } else { for (k = i; k < j; k++) { ca->add(state->color[arr[k].index[0]]); ca->add(state->color[arr[k].index[1]]); ca->add(state->color[arr[k].index[2]]); } } } else if ((flags & TRI_TRANSLUCENT)) { ca = new ssgColourArray(1); ca->add(arr[i].color); } if ((bind & BIND_FLAT_NORMAL)) { na = new ssgNormalArray(n); for (k = i; k < j; k++) { sgVec3 a, b, normal; int *w = arr[k].index; sgSubVec3(a, state->coord[w[1]], state->coord[w[0]]); sgSubVec3(b, state->coord[w[2]], state->coord[w[0]]); sgVectorProductVec3(normal, a, b); sgNormalizeVec3(normal); na->add(normal); na->add(normal); na->add(normal); } } else if ((bind & BIND_NORMAL)) { na = new ssgNormalArray(n); for (k = i; k < j; k++) { na->add(state->normal[arr[k].index[0]]); na->add(state->normal[arr[k].index[1]]); na->add(state->normal[arr[k].index[2]]); } } if ((bind & BIND_TEXCOORD)) { ta = new ssgTexCoordArray(n); for (k = i; k < j; k++) { ta->add(state->texcoord[arr[k].index[0]]); ta->add(state->texcoord[arr[k].index[1]]); ta->add(state->texcoord[arr[k].index[2]]); } } geom = new ssgVtxTable(GL_TRIANGLES, va, na, ta, ca); } else { ssgIndexArray *ia = new ssgIndexArray(3*(j - i)); memset(index, -1, sizeof(index[0]) * state->vnum); n = 0; for (k = i; k < j; k++) { int *tri = arr[k].index; int save = n; for (m = 0; m < 3; m++) { if (index[tri[m]] == -1) { if (n == 65536) { ulSetError(UL_DEBUG, "[flt] More than 65536 vertices, split forced."); n = save; j = k; //goto hopp; break; } vertex[n] = tri[m]; index[tri[m]] = n++; } ia->add((short)index[tri[m]]); } if (m < 3) break; } //hopp: va = new ssgVertexArray(n); for (k = 0; k < n; k++) va->add(state->coord[vertex[k]]); if ((bind & BIND_COLOR)) { ca = new ssgColourArray(n); for (k = 0; k < n; k++) ca->add(state->color[vertex[k]]); } else if ((flags & TRI_TRANSLUCENT)) { ca = new ssgColourArray(1); ca->add(arr[i].color); } if ((bind & BIND_NORMAL)) { na = new ssgNormalArray(n); for (k = 0; k < n; k++) na->add(state->normal[vertex[k]]); } if ((bind & BIND_TEXCOORD)) { ta = new ssgTexCoordArray(n); for (k = 0; k < n; k++) ta->add(state->texcoord[vertex[k]]); } if (n == 3*(j - i)) { delete ia; geom = new ssgVtxTable(GL_TRIANGLES, va, na, ta, ca); } else { geom = new ssgVtxArray(GL_TRIANGLES, va, na, ta, ca, ia); } } geom->setState(arr[i].state); /*ulSetError(UL_DEBUG, "build: [%d..%d] %02x %d indices, %d vertices", i, j - 1, bind, 3*(j - i), n);*/ if (leaf) { if (grp == 0) grp = new ssgBranch; grp->addKid(leaf); } leaf = geom; #if 0 if ((flags & TRI_TRANSLUCENT)) { leaf->setCallback(SSG_CALLBACK_PREDRAW, PreDrawTranslucent); } else #endif if ((flags & TRI_SUBFACE)) { leaf->setCallback(SSG_CALLBACK_PREDRAW, PreDrawSubface); leaf->setCallback(SSG_CALLBACK_POSTDRAW, PostDrawSubface); } #ifndef NO_LOADER_OPTIONS leaf = LoaderOptions->createLeaf(leaf, state->parent_name); #endif if ((flags & TRI_BBOARD)) { if ((flags & TRI_BBOARD_AXIAL)) { if (bboard1 == 0) bboard1 = new ssgCutout(0); bboard1->addKid(leaf); } else { if (bboard2 == 0) bboard2 = new ssgCutout(1); bboard2->addKid(leaf); } leaf = 0; } i = j; } delete [] vertex; delete [] index; if (((leaf != 0) + (bboard1 != 0) + (bboard2 != 0)) > 1 && !grp) //lint !e514 Lint warning "unusual use of a boolean" grp = new ssgBranch; if (grp) { if (bboard1) grp->addKid(bboard1); if (bboard2) grp->addKid(bboard2); if (leaf) grp->addKid(leaf); return grp; } if (bboard1) return bboard1; if (bboard2) return bboard2; return leaf; } /* add a triangle */ static void AddTri(fltState *state, int v0, int v1, int v2) { fltTriangle *tri; if (state->ntris == state->atris) { state->atris += state->atris; //state->tris = (fltTriangle *)realloc(state->tris, sizeof(fltTriangle) * state->atris); fltTriangle *old = state->tris; state->tris = new fltTriangle[state->atris]; memcpy(state->tris, old, sizeof(fltTriangle) * state->atris / 2); delete [] old; } tri = state->tris + state->ntris++; memcpy(tri, state->temp, sizeof(fltTriangle)); tri->index[0] = v0; tri->index[1] = v1; tri->index[2] = v2; } static void Triangulate(int *w, int n, fltState *state) { int buf[3 * (16 - 2)]; int *tris = (n > 16) ? new int [ 3 * (n - 2) ] : buf; int num_tris = _ssgTriangulate(state->coord, w, n, tris); for (int i = 0; i < num_tris; i++) AddTri(state, tris[3*i + 0], tris[3*i + 1], tris[3*i + 2]); if (tris != buf) delete [] tris; } static int ObsoleteFlag; static int NotImplementedFlag; static void Obsolete(int op) { if (!ObsoleteFlag) { ulSetError(UL_WARNING, "[flt] This file is probably rather old (obsolete opcodes ignored)."); ObsoleteFlag = 1; } //printf("op %d obsolete\n", op); } static void NotImplemented(int op) { if (!NotImplementedFlag) { ulSetError(UL_WARNING, "[flt] This file contains opcodes that are not implemented."); NotImplementedFlag = 1; } //printf("op %d not implemented\n", op); } static void ReportBadChunk(const ubyte *ptr, const char *name) { int op = get16u(ptr); int len = get16u(ptr + 2); ulSetError(UL_WARNING, "[flt] Bad record, opcode %d (%s), length %d:", op, name, len); hexdump(UL_WARNING, ptr, len, 0); ulSetError(UL_WARNING, "Please report this, either at http://plib.sourceforge.net/,"); ulSetError(UL_WARNING, "or by email to plib-devel@lists.sourceforge.net. Thanks."); } #define BAD_CHUNK(ptr, name)\ do {\ static int first = 1;\ if (first) {\ ReportBadChunk(ptr, name);\ first = 0;\ }\ } while (0) static int intcmp(const void *a, const void *b) { return *(int *)a - *(int *)b; } /* polygon chunks */ static int GeomChunks(ubyte *ptr0, ubyte *end, fltState *state, ssgEntity **nodep, int objflags, int objtrans) { ubyte *ptr = ptr0; int sp = 0, op, len, done = 0, triflg = 0; int w[512]; /* enough? */ fltTriangle tri; StateInfo info; int subface = 0; char long_id[256] = {0}; state->temp = &tri; memset(&tri, 0, sizeof(tri)); /* read as many polygon chunks as possible. * can be done since objects may not contain groups. * color table etc should also be defined before any polygon. * (the purpose is to keep the switch(op) relatively small to speed up this "inner loop") */ do { if (ptr + 4 > end) break; op = get16u(ptr); len = get16u(ptr+2); if (len < 4 || (len & 3) != 0 || ptr + len > end) break; switch (op) { case 5: { /* Face (appearence) */ /* * Face Record Format * * Int 0 2 Face Opcode 5 * Unsigned 2 2 Length of the record * Char 4 8 7 char ASCII ID; 0 terminates * Int 12 4 IR color code * Int 16 2 Relative priority * Int 18 1 Draw type * 0 = Draw solid with backface culling * 1 = Draw solid, no backface culling * 2 = Draw wireframe * 3 = Draw wireframe and close * 4 = Surround with wireframe in alternate color * 8 = Omnidirectional light * 9 = Unidirectional light * 10 = Bidirectional light * Int 19 1 Texture white = if TRUE, draw textured face white * Unsigned 20 2 Color name index * Unsigned 22 2 Alternate color name index * Int 24 1 Reserved * Int 25 1 Template (billboard) * 0 = Fixed, no alpha blending * 1 = Fixed, alpha blending * 2 = Axial rotate * 4 = Point rotate * Int 26 2 Detail texture pattern index, -1 if none * Int 28 2 Texture pattern index, -1 if none * Int 30 2 Material index, -1 if none * Int 32 2 Surface material code (for DFAD) * Int 34 2 Feature ID (for DFAD) * Int 36 4 IR material code * Unsigned 40 2 Transparency 0 = Opaque 65535 = Totally clear * Unsigned 42 1 LOD generation control * Unsigned 43 1 Line style index * Boolean 44 4 Flags (bits from left to right) * 0 = Terrain * 1 = No color * 2 = No alternate color * 3 = Packed color * 4 = Terrain culture cutout (footprint) * 5 = Hidden, not drawn * 6-31 = Spare * Unsigned 48 1 Light mode * 0 = Use face color, not illuminated * 1 = Use vertex colors, not illuminated * 2 = Use face color and vertex normal * 3 = Use vertex color and vertex normal * Unsigned 49 1 Reserved * Unsigned 50 2 Reserved * Boolean 52 4 Reserved * Unsigned 56 4 Packed color, primary (A, B, G, R) * Unsigned 60 4 Packed color, alternate (A, B, G, R) * Int 64 2 Texture mapping index * Int 66 2 Reserved * Unsigned 68 4 Primary color index * Unsigned 72 4 Alternate color index * Int 76 2 Reserved * Int 78 2 Reserved * */ static float default_mtl[14] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, 1.0f }; int flags = len < 48 ? 0 : get32i(ptr + 44); int drawtype = ptr[18]; if (drawtype > 4 || (flags & (1 << 5)) || len < 32) { triflg = 0; } else { int index; struct snode *t; int tex_alpha = 0; tri.state = 0; tri.flags = 0; #ifdef NO_TEXTURES info.tex = 0; #else /* texture */ info.tex = 0; index = get16i(ptr + 28); /* texture index */ t = 0; if (index != -1) { state->texs = t = splay(state->texs, (void *)index, ptrcmp); if (t == 0 || t->key != (void *)index) { /*ulSetError(UL_DEBUG, "[flt] undefined texture %d", index);*/ t = 0; } } if (t) { fltTexture *tex = (fltTexture *)t->data; if (tex->state == (ssgState *)-1) { fltTexture *tmp = LoadTex(tex->file); tex->state = tmp->state; tex->tex = tmp->tex; tex->alpha = tmp->alpha; } tri.state = tex->state; info.tex = tex->tex; tex_alpha = tex->alpha; } #ifndef NO_LOADER_OPTIONS else { if (state->notex_state == (ssgState *)-1) state->notex_state = LoaderOptions->createState(0); tri.state = state->notex_state; } #endif #endif if (tri.state) { tri.bind = BIND_COLOR | BIND_NORMAL | BIND_TEXCOORD; } else { int template = ptr[25]; int white = ptr[19] || template > 1; /* OK ?? */ int lmode = len >= 49 ? ptr[48] : 3; int trans = get16u(ptr + 40); //ulSetError(UL_DEBUG, "light mode %d", lmode); /*lmode = 0;*/ /* wireframe */ /*tri.wireframe = (drawtype > 1);*/ /* backface culling */ info.cf = (drawtype == 0); /* alpha component */ #if 0 if (state->major >= 15) { /* this is according to the spec, but it sure is suspicious */ int a = trans >> 1; int b = objtrans >> 1; info.alpha = 1.0f - 1.0f/(32767*32767) * (a * b); } else #endif { info.alpha = 1.0f - 1.0f/65535.0f * trans; } sgSetVec4(tri.color, 1, 1, 1, info.alpha); #ifdef NO_LIGHTING info.mtl = 0; #else /* material */ if (/*lmode < 2 ||*/ /* (objflags & (1 << 3)) || */ white) { info.mtl = 0; } else { index = get16i(ptr + 30); /* material index */ state->mtls = t = splay(state->mtls, (void *)index, ptrcmp); if (t && t->key == (void *)index) { info.mtl = (float *)t->data; } else { info.mtl = default_mtl; } info.alpha *= info.mtl[13]; tri.color[3] = 1.0f; } #endif /* transparency */ info.tr = (tex_alpha > 0 || info.alpha < 0.999f); /* && template > 0 */ if (info.tr) tri.flags |= TRI_TRANSLUCENT; /* initial bindings */ tri.bind = 0; if ((lmode & 1) && !white) tri.bind |= BIND_COLOR; if (info.mtl) { tri.bind |= BIND_NORMAL; if (!(lmode & 2) || (objflags & (1 << 4))) tri.bind |= BIND_FLAT_NORMAL; } if (info.tex) tri.bind |= BIND_TEXCOORD; #ifdef NO_COLORS tri.bind &= ~BIND_COLOR; #else /* face color */ if (!(lmode & 1) && !(flags & 2) && !white && state->major >= 14) { /* will probably not work with old files */ if ((flags & 8) && len >= 60) { UNPACK_ABGR(tri.color, ptr + 56); /* packed ABGR */ tri.bind |= BIND_FLAT_COLOR; } else if (state->revision > 1400) { int color; if (state->revision > 1500 && len >= 72) color = get32i(ptr + 68); else { color = get16u(ptr + 20); if (color == 65535) color = -1; } int index = color / 128; int intensity = color % 128; if (color >= 0 && state->ctab && index < state->cnum) { UNPACK_ABGR2(tri.color, state->ctab[index], intensity); tri.bind |= BIND_FLAT_COLOR; } else if (color != -1) ulSetError(UL_DEBUG, "[flt] Bad face color %d.", color); } tri.color[3] = info.alpha; } #endif /* if (tri.bind & BIND_COLOR) ulSetError(UL_DEBUG, "use vertex colors"); if (tri.bind & BIND_FLAT_COLOR) ulSetError(UL_DEBUG, "face color %.2f %.2f %.2f", tri.color[0], tri.color[1], tri.color[2]); */ /* billboard */ if (template == 4) tri.flags |= TRI_BBOARD_POINT; else if (template == 2) tri.flags |= TRI_BBOARD_AXIAL; /* cannot create the state yet, * need to know the vertex bindings. */ } triflg = 1; } ptr += len; break; } case 72: /* Vertex List (aka polygon) */ if (triflg) { int i, n = (len - 4) >> 2; if (state->vtab && n > 2 && n < 512) { /* silently ignore if suspicious.. */ int bind = tri.bind; ubyte *p = ptr + 4; for (i = 0; i < n; ++i) { /* could this be done any faster? */ /* it is tempting to reparse the vertex at the given offset */ int offset = get32i(p), *ptr; ptr = (int *)bsearch(&offset, state->offset, state->vnum, sizeof(int), intcmp); if (!ptr) { ulSetError(UL_DEBUG, "[flt] Bad vertex offset %i.", offset); break; } w[i] = ptr - state->offset; bind &= state->bind[w[i]] | BIND_FLAT; p += 4; } if (i == n) { tri.bind = bind; if (subface) tri.flags |= TRI_SUBFACE; else tri.flags &= ~TRI_SUBFACE; if (tri.state) { Triangulate(w, n, state); } else { /* finalize state */ /* setup color material */ if ((bind & (BIND_COLOR | BIND_FLAT_COLOR)) && (bind & (BIND_NORMAL | BIND_FLAT_NORMAL))) { sgVec4 color; color[0] = 0.2f*info.mtl[0] + 0.8f*info.mtl[3]; color[1] = 0.2f*info.mtl[1] + 0.8f*info.mtl[4]; color[2] = 0.2f*info.mtl[2] + 0.8f*info.mtl[5]; color[3] = info.alpha; if ((tri.bind & BIND_FLAT_COLOR)) { tri.color[0] *= color[0]; tri.color[1] *= color[1]; tri.color[2] *= color[2]; tri.color[3] *= color[3]; } else { sgCopyVec4(tri.color, color); /* apply to vertex colors */ } info.cm = 1; tri.flags |= TRI_COLOR_MATERIAL; } else { info.cm = 0; tri.flags &= ~TRI_COLOR_MATERIAL; } tri.state = ConstructState(&info); Triangulate(w, n, state); tri.state = 0; } } } } ptr += len; break; case 89: /* Morph Vertex List */ ptr += len; break; case 10: /* Push */ sp++; ptr += len; break; case 11: /* Pop */ if (sp == 0) { done = 1; break; } sp--; ptr += len; /*if (sp == 0) done = 1;*/ break; case 19: /* Push Subface */ subface++; ptr += len; break; case 20: /* Pop Subface */ subface--; ptr += len; break; case 33: /* Long ID */ if (long_id[0] == 0) { int n = CLAMP(len - 4, 0, 255); memcpy(long_id, ptr + 4, n); long_id[n] = 0; } ptr += len; break; case 31: /* Text Comment */ case 50: /* Vector (for light points) */ case 21: /* Push Extension */ case 22: /* Pop Extension */ case 97: /* Line Style Record */ case 122: /* Push Attribute */ case 123: /* Pop Attribute */ ptr += len; break; case 6: /* Vertex with ID (obsolete) */ case 7: /* Short Vertex (obsolete) */ case 8: /* Vertex with Color (obsolete) */ case 9: /* Vertex with Color and Normal (obsolete) */ Obsolete(op); ptr += len; break; default: if (sp == 0) { /* you never know what this might be. better let someone else take car of it. */ done = 1; break; } NotImplemented(op); ptr += len; } } while (!done); *nodep = Build(state); if (long_id[0] != 0 && *nodep != NULL) (*nodep)->setName(long_id); return ptr - ptr0; } struct LODInfo { ssgTransform *scs; ssgRangeSelector *lod; }; static int LODCompare(const void *a, const void *b) { float d = ((LODInfo *)a)->lod->getRange(0) - ((LODInfo *)b)->lod->getRange(0); return d < 0 ? -1 : d > 0 ? 1 : 0; } static void MergeLODs(ssgBranch *grp) { LODInfo info[64]; int i, j, k, m, n; n = grp->getNumKids(); if (n <= 1) return; m = 0; for (i = 0; i < n && m < 64; i++) { ssgEntity *kid; kid = grp->getKid(i); info[m].scs = 0; if (kid->isA(ssgTypeTransform()) && kid->getNumParents() == 1) { info[m].scs = (ssgTransform *)kid; if (info[m].scs->getNumKids() != 1) continue; kid = info[m].scs->getKid(0); } if (!kid->isA(ssgTypeRangeSelector()) || kid->getNumParents() != 1) continue; info[m].lod = (ssgRangeSelector *)kid; m++; } if (m > 1) { qsort(info, m, sizeof(info[0]), LODCompare); //grp->print(); for (i = 0; i < m; i++) { sgMat4 mat1, mat2; float ranges[33], range2; int num1, num2; int flag = 0; if (info[i].lod == 0) continue; if (info[i].scs) info[i].scs->getTransform(mat1); else sgMakeIdentMat4(mat1); num1 = info[i].lod->getNumKids(); for (k = 0; k <= num1; k++) ranges[k] = info[i].lod->getRange(k); for (j = i + 1; j < m; j++) { if (info[j].lod == 0) continue; if (info[j].scs) info[j].scs->getTransform(mat2); else sgMakeIdentMat4(mat2); num2 = info[j].lod->getNumKids(); range2 = info[j].lod->getRange(0); if (sgDistanceVec3(mat1[3], mat2[3]) > 0.1f * range2) /* XXX */ continue; if (num1 + num2 > 32) /* XXX */ continue; if (ABS(ranges[num1] - range2) > 0.1f * range2) /* XXX */ continue; for (k = 0; k < num2; k++) { info[i].lod->addKid(info[j].lod->getKid(k)); ranges[num1 + k + 1] = info[j].lod->getRange(k + 1); num1++; } if (info[j].scs == 0 || info[j].scs->getRef() == 1) { if (info[j].lod->getRef() == 1) { while (num2--) info[j].lod->removeKid(num2); } if (info[j].scs) info[j].scs->removeKid(info[j].lod); // delete info[j].lod else grp->removeKid(info[j].lod); } if (info[j].scs) grp->removeKid(info[j].scs); // delete info[j].scs info[j].lod = 0; flag = 1; } if (flag) { info[i].lod->setRanges(ranges, num1 + 1); assert(info[i].scs == 0 || !info[i].scs->isA(0xDeadBeef)); assert(!info[i].lod->isA(0xDeadBeef)); } } } } static ssgEntity *PostClean(ssgEntity *node, fltNodeAttr *attr) { if (node && attr && attr->name) node->setName(attr->name); #if 1 /* remove empty or redundant groups */ while (!NoClean && node && node->isA(ssgTypeBranch())) { ssgBranch *grp = (ssgBranch *)node; int num = grp->getNumKids(); if (num > 1) break; if (num == 1) { ssgEntity *kid = grp->getKid(0); if (grp->getName()) { if (kid->getName()) break; kid->setName(grp->getName()); } if (grp->getRef() == 0) { kid->ref(); grp->removeKid(0); kid->deRef(); delete grp; } node = kid; assert(!node->isA(0xDeadBeef)); } else { if (grp->getRef() == 0) delete grp; node = 0; } } #endif #if 1 /* see if we can merge LOD nodes */ if (node && node->isAKindOf(ssgTypeBranch()) && !node->isAKindOf(ssgTypeSelector())) { MergeLODs((ssgBranch *)node); assert(!node->isA(0xDeadBeef)); } #endif /* set limits on animated nodes */ if (node && node->isA(ssgTypeTimedSelector())) { ssgTimedSelector *sw = (ssgTimedSelector *) node; if (sw->getNumKids() > 1) { sw->setDuration(30.0f); sw->setLimits(0, sw->getNumKids() - 1); sw->control(SSG_ANIM_START); } } /* apply node attributes */ if (node && attr) { if (attr->transform) { ssgTransform *scs = new ssgTransform; scs->setTransform(attr->mat); scs->addKid(node); if (attr->replicate > 0) { ssgBranch *grp; sgMat4 mat; int i; grp = new ssgBranch; grp->addKid(scs); sgCopyMat4(mat, attr->mat); #if 0 ulSetError(UL_DEBUG, "replicating %d times", attr->replicate); for (i = 0; i < 4; i++) ulSetError(UL_DEBUG, " %6.2f %6.2f %6.2f %6.2f", mat[i][0], mat[i][1], mat[i][2], mat[i][3]); #endif for (i = 0; i < attr->replicate; ++i) { sgPostMultMat4(mat, attr->mat); scs = new ssgTransform; scs->setTransform(mat); scs->addKid(node); grp->addKid(scs); } node = grp; /* there's no point in cleaning this construction */ /*ulSetError(UL_DEBUG, "[flt] replicated %d times", attr->replicate);*/ } else { node = scs; // PostClean(scs, 0); /*ulSetError(UL_DEBUG, "[flt] added transformation");*/ } } /* apply level of detail */ if (attr->islod) { float ranges[2]; ranges[0] = MIN(attr->range[0], attr->range[1]); ranges[1] = MAX(attr->range[0], attr->range[1]); if (ranges[1] > MAX(0, ranges[0])) { ssgRangeSelector *lod = new ssgRangeSelector; lod->setRanges(ranges, 2); if (sgLengthVec3(attr->center) > 0.01f) { /* XXX */ ssgTransform *t1, *t2; sgMat4 mat; sgMakeTransMat4(mat, attr->center[0], attr->center[1], attr->center[2]); t1 = new ssgTransform; t1->setTransform(mat); sgMakeTransMat4(mat, -attr->center[0], -attr->center[1], -attr->center[2]); t2 = new ssgTransform; t2->setTransform(mat); t1->addKid(lod); lod->addKid(t2); t2->addKid(node); node = t1; } else { lod->addKid(node); node = lod; } } } /* setup switch records */ if (attr->num_masks > 0) { ssgTimedSelector *sw = new ssgTimedSelector; int n = ((ssgBranch *) node) -> getNumKids(); if (n > 32 * attr->num_words) n = 32 * attr->num_words; for (int i = 0; i < attr->num_masks; i++) { ssgBranch *br = new ssgBranch; for (int j = 0; j < n; j++) { if (attr->mask_words[j / 32] & (1u << (j % 32))) br -> addKid(((ssgBranch *) node) -> getKid(j)); } sw -> addKid(br); } if (node->getRef() == 0) { ((ssgBranch *) node) -> removeAllKids(); delete node; } sw->setMode(SSG_ANIM_SHUTTLE); sw->setDuration(30.0f); sw->setLimits(0, attr->num_masks - 1); sw->control(SSG_ANIM_START); node = sw; } } if (attr) delete attr; assert(node == 0 || !node->isA(0xDeadBeef)); return node; } /* link nodes while removing crap (post traversal) */ static void PostLink(ssgEntity **stack, fltNodeAttr **attr, int instance, fltState *state) { #if 0 ulSetError(UL_DEBUG, "PostLink: %s %s <-- %s %s", stack[0] ? pfGetTypeName(stack[0]) : "0", stack[0] ? pfGetNodeName(stack[0]) : "0", stack[1] ? pfGetTypeName(stack[1]) : "0", stack[1] ? pfGetNodeName(stack[1]) : "0"); #endif if (stack[1] == 0) { if (attr[1]) { delete attr[1]; attr[1] = 0; } return; } assert(!stack[1]->isA(0xDeadBeef)); stack[1] = PostClean(stack[1], attr[1]); if (stack[1] && instance >= 0) { state->refs = sinsert(state->refs, (void *)instance, 0, ptrcmp); if (state->refs->data != (void *)-1) { ulSetError(UL_WARNING, "[flt] Instance %d redefined.", instance); ssgDeRefDelete((ssgEntity *) state->refs->data); } state->refs->data = stack[1]; stack[1]->ref(); } if (stack[0] == 0) { stack[0] = stack[1]; if (attr[0]) { delete attr[0]; attr[0] = 0; } } else { assert(!stack[0]->isA(0xDeadBeef)); if (stack[1]) { if (stack[0]->isAKindOf(ssgTypeBranch())) { ((ssgBranch *)stack[0])->addKid(stack[1]); } else { ssgBranch *grp = new ssgBranch; grp->addKid(stack[0]); grp->addKid(stack[1]); stack[0] = PostClean(grp, 0); } } } stack[1] = 0; attr[1] = 0; } /* group/object ancillary chunks */ static int AttrChunks(ubyte *ptr0, ubyte *end, fltNodeAttr **attrp) { ubyte *ptr = ptr0; int op, len, done = 0; fltNodeAttr *attr; attr = *attrp; while (!done) { if (ptr + 4 > end) break; op = get16u(ptr); len = get16u(ptr + 2); if (len < 4 || (len & 3) != 0 || ptr + len > end) break; switch (op) { case 31: /* Comment */ ptr += len; break; case 33: { /* Long ID */ int n = len - 4; if (n > 0 && n < 256) { if (attr == 0) attr = new fltNodeAttr; //attr->name = (char *)malloc(n + 1); attr->name = new char[n + 1]; memcpy(attr->name, ptr + 4, n); attr->name[n] = 0; } ptr += len; break; } case 60: { /* Replicate */ if (attr == 0) attr = new fltNodeAttr; attr->replicate = get16u(ptr + 4); ptr += len; break; } case 49: { /* Transfomation Matrix */ sgMat4 mat; int i, j; get32v(ptr + 4, mat, 16); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { float d = mat[i][j] - (i == j ? 1.0f : 0.0f); if (ABS(d) > 0.001f) break; } if (j < 4) break; } if (i < 4) { if (attr == 0) attr = new fltNodeAttr; attr->transform = 1; sgCopyMat4(attr->mat, mat); } ptr += len; break; } case 12: /* Translate (obsolete) */ case 40: /* Translate (obsolete) */ case 41: /* Rotate about Point (obsolete) */ case 42: /* Rotate about Edge (obsolete) */ case 43: /* Scale (obsolete) */ case 44: /* Translate (obsolete) */ case 45: /* Scale (obsolete) */ case 46: /* Rotate about Point (obsolete) */ case 47: /* Rotate and/or Scale about Point (obsolete) */ case 48: /* Put Transform (obsolete) */ case 51: /* Bounding Box (obsolete) */ case 77: /* Scale (obsolete) */ case 110: /* Histogram Bounding Volume (obsolete) */ Obsolete(op); ptr += len; break; case 74: /* Bounding Box */ case 76: /* Rotate about Edge */ case 78: /* Translate */ case 79: /* Scale */ case 80: /* Rotate about Point */ case 81: /* Rotate and/or Scale */ case 82: /* Put */ case 88: /* Road Zone */ case 94: /* General Matrix */ case 100: /* Extension Attribute */ case 105: /* Bounding Sphere */ case 106: /* Bounding Cylinder */ case 108: /* Bounding Volume Center */ case 109: /* Bounding Volume Orientation */ case 116: /* CAT Data */ /* these are safe to ignore */ ptr += len; break; default: done = 1; break; } } *attrp = attr; return ptr - ptr0; } static ssgEntity *LoadFLT(const char *path); /* object hierarchy chunks */ static ssgEntity *HierChunks(ubyte *ptr, ubyte *end, fltState *state) { ssgEntity *stack[MAXDEPTH + 1]; fltNodeAttr *attr[MAXDEPTH + 1]; int instance[MAXDEPTH + 1]; int sp, op, len, k; stack[0] = new ssgBranch; stack[0]->setName("reserved"); attr[0] = 0; instance[0] = -1; stack[1] = 0; attr[1] = 0; instance[1] = -1; sp = 1; for (;;) { if (ptr + 4 > end) break; op = get16u(ptr); if (op < 1 || op > 150) break; len = get16u(ptr + 2); if (len < 4 || (len & 3) != 0 || ptr + len > end) break; #if 0 for (int i = 0; i < sp; i++) putchar('\t'); printf("op %d\n", op); #endif switch (op) { case 10: /* Push */ if (stack[sp] && !stack[sp]->isAKindOf(ssgTypeBranch())) { /* shouldn't happen */ ulSetError(UL_DEBUG, "[flt] Objects are not allowed to contain other objects or groups."); PostLink(stack + sp - 1, attr + sp - 1, instance[sp], state); instance[sp] = -1; } if (sp >= MAXDEPTH) { ulSetError(UL_WARNING, "[flt] Stack overflow."); } else { sp++; stack[sp] = 0; attr[sp] = 0; instance[sp] = -1; } ptr += len; break; case 11: /* Pop */ if (sp == 1) ulSetError(UL_WARNING, "[flt] Stack underflow."); else { PostLink(stack + sp - 1, attr + sp - 1, instance[sp], state); sp--; } ptr += len; break; case 4: { /* Object */ /* * Object Record Format * * Int 0 2 Object Opcode 4 * Unsigned 2 2 Length of the record * Char 4 8 7 char ASCII ID; 0 terminates * Boolean 12 4 Flags (bits from to right) * 0 = Don't display in daylight * 1 = Don't display at dusk * 2 = Don't display at night * 3 = Don't illuminate * 4 = Flat shaded * 5 = Group's shadow object * 6-31 = Spare * Int 16 2 Relative priority * Unsigned 18 2 Transparency * 0 = Opaque * 65535 = Totally clear * Int 20 2 Special effect ID1 - application defined * Int 22 2 Special effect ID2 - application defined * Int 24 2 Significance * Int 26 2 Spare * */ int flags = get32i(ptr + 12); int trans = get16u(ptr + 18); PostLink(stack + sp - 1, attr + sp - 1, instance[sp], state); instance[sp] = -1; ptr += len; ptr += AttrChunks(ptr, end, &attr[sp]); state->parent_name = (char *)ptr + 4; /* OK?? */ ptr += GeomChunks(ptr, end, state, &stack[sp], flags, trans); state->parent_name = 0; if (stack[sp] && stack[sp]->getName() == 0 && ptr[4]) stack[sp]->setName((char *)ptr + 4); break; } case 5: /* Face */ /* polygons are not allowed to be outside objects, but this rule is not always respected */ //ulSetError(UL_DEBUG, "[flt] Implicit object."); PostLink(stack + sp - 1, attr + sp - 1, instance[sp], state); instance[sp] = -1; ptr += GeomChunks(ptr, end, state, &stack[sp], 0, 0); break; case 2: /* Group */ case 14: /* Degree of Freedom */ case 73: /* Level of Detail */ case 96: /* Switch */ case 98: /* Clip Region */ PostLink(stack + sp - 1, attr + sp - 1, instance[sp], state); instance[sp] = -1; switch (op) { case 2: { /* Group */ #if 0 /* group animation - seems wrong... */ int flags = (len >= 20) ? get32i(ptr + 16) : 0; if ((flags & 3) != 0) { ssgTimedSelector *sw = new ssgTimedSelector; sw->setMode((flags & 2) ? SSG_ANIM_SWING : SSG_ANIM_SHUTTLE); stack[sp] = sw; } else #endif { stack[sp] = new ssgBranch; } break; } case 14: { /* Degree of Freedom */ stack[sp] = new ssgTransform; break; } case 73: { /* Level of Detail */ fltNodeAttr *a; double v[3]; attr[sp] = a = new fltNodeAttr; a->islod = 1; get64v(ptr + 16, v, 2); sgSetVec2(a->range, (float)v[0], (float)v[1]); get64v(ptr + 40, v, 3); sgSetVec3(a->center, (float)v[0], (float)v[1], (float)v[2]); stack[sp] = new ssgBranch; break; } case 96: { /* Switch */ int num_words = (len > 28) ? get32i(ptr + 20) : -1; int num_masks = (len > 28) ? get32i(ptr + 24) : -1; if (num_words <= 0 || num_masks <= 0 || len < 28 + 4 * num_words * num_masks) { ulSetError(UL_DEBUG, "[flt] Incomplete switch record."); } else { fltNodeAttr *a = new fltNodeAttr; a->current_mask = get32i(ptr + 16); a->num_masks = num_masks; a->num_words = num_words; a->mask_words = new uint [ num_masks * num_words ]; get32v(ptr + 28, a->mask_words, num_masks * num_words); attr[sp] = a; } stack[sp] = new ssgBranch; break; } default: { /* Others (i.e. 98 Clip Region) */ stack[sp] = new ssgBranch; break; } } if (ptr[4]) stack[sp]->setName((char *)ptr + 4); ptr += len; ptr += AttrChunks(ptr, end, &attr[sp]); break; case 61: /* Instance Reference */ k = get16u(ptr + 6); if (k != instance[sp]) { // current instance inserted by default PostLink(stack + sp - 1, attr + sp - 1, instance[sp], state); instance[sp] = -1; if (state->refs) { state->refs = splay(state->refs, (void *)k, ptrcmp); if (state->refs->key == (void *)k) { stack[sp] = (ssgEntity *)state->refs->data; } } } ptr += len; ptr += AttrChunks(ptr, end, &attr[sp]); break; case 62: /* Instance Definition */ k = get16u(ptr + 6); #if 0 if (stack[sp]) { state->refs = sinsert(state->refs, (void *)k, 0, ptrcmp); if (state->refs->data == (void *)-1) { state->refs->data = stack[sp]; stack[sp]->ref(); } } else { ulSetError(UL_DEBUG, "[flt] yeah, but the node is empty!"); } #else instance[sp] = k; #endif ptr += len; break; case 63: /* External Reference */ /*ulSetError(UL_DEBUG, "external reference %s", ptr + 4);*/ PostLink(stack + sp - 1, attr + sp - 1, instance[sp], state); instance[sp] = -1; if (!NoExternals) { char *file = (char *)ptr + 4, *p; if ((p = strrchr(file, '/'))) file = p + 1; //stack[sp] = LoadFLT(file); stack[sp] = ssgLoad (file); } ptr += len; ptr += AttrChunks(ptr, end, &attr[sp]); break; case 31: /* Text Comment */ case 21: /* Push Extension */ case 22: /* Pop Extension */ case 55: /* Binary Separating Plane */ case 87: /* Road Segment */ case 90: /* Linkage */ case 91: /* Sound Bead */ case 92: /* Path Bead */ case 95: /* Text */ case 101: /* Light Source Bead */ case 122: /* Push Attribute */ case 123: /* Pop Attribute */ //printf("op %d ignored\n", op); ptr += len; break; case 3: /* Level of Detail (obsolete) */ case 13: /* Degree of Freedom (obsolete) */ case 16: /* Instance Reference (obsolete) */ case 17: /* Instance Definition (obsolete) */ Obsolete(op); ptr += len; break; default: NotImplemented(op); ptr += len; } } /* pop stack (expected one iteration but may be more for incomplete databases) */ while (sp-- > 0) PostLink(stack + sp, attr + sp, -1, 0); if (stack[0]) stack[0] = PostClean(stack[0], attr[0]); else if (attr[0]) delete attr[0]; // possible? return stack[0]; } /* parse the vertex table */ static int VertexTable(ubyte *ptr0, ubyte *end, fltState *state) { int len, size, num, i; ubyte *ptr = ptr0; assert(get16u(ptr) == 67); /* vtx tab op code */ len = get16u(ptr + 2); size = get32i(ptr + 4); /*ulSetError(UL_DEBUG, "vertex table header len %d, total size %d", len, size);*/ num = (size - len)/40; /* max # of vertices */ if (num <= 0 || state->vtab) { if (state->vtab) ulSetError(UL_WARNING, "[flt] Multiple vertex tables not allowed."); return size; } state->vtab = ptr; end = MIN(end, ptr + size); ptr += len; state->offset = new int [num]; state->bind = new ubyte [num]; state->coord = new sgVec3 [num]; state->color = new sgVec4 [num]; state->normal = new sgVec3 [num]; state->texcoord = new sgVec2 [num]; for (i = 0; i < num && ptr + 40 <= end; ++i) { double tmp[3]; ubyte *p = ptr; int op = get16u(p); int len = get16u(p + 2); int flags = get16u(p + 6); int bind = 0; if (ptr + len > end) break; state->offset[i] = ptr - ptr0; get64v(p + 8, tmp, 3); sgSetVec3(state->coord[i], (float)tmp[0], (float)tmp[1], (float)tmp[2]); sgSetVec4(state->color[i], 1, 1, 1, 1); sgSetVec3(state->normal[i], 0, 0, 1); sgSetVec2(state->texcoord[i], 0, 0); p += 32; if (op == 69 || op == 70) { get32v(p, state->normal[i], 3); sgNormalizeVec3(state->normal[i]); p += 12; bind |= BIND_NORMAL; } if (op == 70 || op == 71) { get32v(p, state->texcoord[i], 2); p += 8; bind |= BIND_TEXCOORD; } if (!(flags & 4)) { if ((flags & 8) && p + 4 <= ptr + len) { UNPACK_ABGR(state->color[i], p); //ulSetError(UL_DEBUG, "packed ABGR: %d %d %d %d", p[0], p[1], p[2], p[3]); bind |= BIND_COLOR; } else if (state->revision > 1400) { int color; if (state->revision > 1500 && p + 8 <= ptr + len) { color = get32i(p + 4); } else { color = get16u(ptr + 4); if (color == 65535) color = -1; } int index = color / 128; int intensity = color % 128; if (color >= 0 && state->ctab && index < state->cnum) { //ulSetError(UL_DEBUG, "colour %d: index %d, intensity %d", color, index, intensity); UNPACK_ABGR2(state->color[i], state->ctab[index], intensity); bind |= BIND_COLOR; } } } /* if (bind & BIND_COLOR) ulSetError(UL_DEBUG, "vertex #%d color %.2f %.2f %.2f", i, state->color[i][0], state->color[i][1], state->color[i][2]); */ state->bind[i] = bind; ptr += len; } /*ulSetError(UL_DEBUG, "got %d vertices", i);*/ state->vnum = i; return size; } /* header ancillary chunks */ static int TableChunks(ubyte *ptr0, ubyte *end, fltState *state) { ubyte *ptr = ptr0; int op, len, index, done = 0; while (!done) { if (ptr + 4 > end) break; op = get16u(ptr); len = get16u(ptr + 2); if (len < 4 || (len & 3) != 0 || ptr + len > end) break; switch (op) { case 32: /* Color Table */ if (len < 132 + 4 * 512) { /* note: in older files it appears that the * color table is stored as 16-bit integers. * i have no documentation on this. * maybe 16 x 16 colors (rather than 512 or 1024 x 128). */ if (state->revision <= 1400) { ulSetError(UL_WARNING, "[flt] Color table ignored (unknown format)."); /*hexdump(UL_DEBUG, ptr, len, 0);*/ } else BAD_CHUNK(ptr, "Color Table"); } else if (state->ctab == 0) { int max = (len - 132) / 4; state->ctab = (ubyte (*)[4])(ptr + 132); state->cnum = MIN(state->revision > 1500 ? 1024 : 512, max); #if 0 int i; for (i = 0; i < state->cnum; i++) ulSetError(UL_DEBUG, "%d %02x %02x %02x %02x", i, state->ctab[i][0], state->ctab[i][1], state->ctab[i][2], state->ctab[i][3]); #endif } else { ulSetError(UL_WARNING, "[flt] Multiple color tables are not allowed."); } ptr += len; break; case 64: /* Texture Reference */ if (!NoTextures) { if (len == 96 || len == 216) { char *file = (char *)ptr + 4, *p; if ((p = strrchr(file, '/'))) file = p + 1; index = get32i(ptr + len - 12); state->texs = sinsert(state->texs, (void *)index, 0, ptrcmp); if (state->texs->data == (void *)-1) { //fltTexture *tex = (fltTexture *)malloc(sizeof(fltTexture)); fltTexture *tex = new fltTexture; assert ( tex != NULL ); tex->file = file; tex->state = (ssgState *)-1; tex->tex = (ssgTexture *)-1; state->texs->data = tex; } } else { BAD_CHUNK(ptr, "Texture Reference"); } } ptr += len; break; case 66: /* Material Table */ if ((len - 4) % 184 != 0) { BAD_CHUNK(ptr, "Material Table"); } else if (state->mtls == 0) { ubyte *p = ptr + 4; int i, j, n = (len - 4) / 184; for (i = 0; i < n; ++i) { float *mtl; state->mtls = sinsert(state->mtls, (void *)i, 0, ptrcmp); //state->mtls->data = malloc(sizeof(float)*14); state->mtls->data = new float[14]; mtl = (float *)state->mtls->data; get32v(p, mtl, 14); for (j = 0; j < 12; j++) mtl[j] = CLAMP(mtl[j], 0, 1); mtl[12] = CLAMP(mtl[12], 8, 128); mtl[13] = CLAMP(mtl[13], 0, 1); #if 0 float r, g, b, s; r = mtl[0] + mtl[3] + mtl[6] + mtl[9]; g = mtl[1] + mtl[4] + mtl[7] + mtl[10]; b = mtl[2] + mtl[5] + mtl[8] + mtl[11]; s = MAX3(r, g, b); if (s > 1.0f) { s = 1.0f/s; for (j = 0; j < 12; j++) mtl[j] *= s; } #endif p += 184; } } else { ulSetError(UL_WARNING, "[flt] Multiple material tables are not allowed"); } ptr += len; break; case 67: /* Vertex Table (header) */ ptr += VertexTable(ptr, end, state); break; case 113: /* Material */ index = get32i(ptr + 4); state->mtls = sinsert(state->mtls, (void *)index, 0, ptrcmp); if (state->mtls->data == (void *)-1) { float *mtl; int i; //state->mtls->data = malloc(sizeof(float)*14); state->mtls->data = new float[14]; mtl = (float *)state->mtls->data; get32v(ptr + 24, mtl, 14); for (i = 0; i < 12; i++) mtl[i] = CLAMP(mtl[i], 0, 1); mtl[12] = CLAMP(mtl[12], 8, 128); mtl[13] = CLAMP(mtl[13], 0, 1); #if 0 float r, g, b, s; r = mtl[0] + mtl[3] + mtl[6] + mtl[9]; g = mtl[1] + mtl[4] + mtl[7] + mtl[10]; b = mtl[2] + mtl[5] + mtl[8] + mtl[11]; s = MAX3(r, g, b); if (s > 1.0f) { s = 1.0f/s; for (i = 0; i < 12; i++) mtl[i] *= s; } #endif } ptr += len; break; case 65: /* Eyepoint Palette (obsolete) */ Obsolete(op); ptr += len; break; case 31: /* Text Comment */ case 83: /* Eyepoint and Trackplane */ case 90: /* Linkage Palette */ case 93: /* Sound Palette */ case 97: /* Line Style Palette */ case 102: /* Light Source Palette */ case 103: /* Reserved */ case 104: /* Reserved */ case 112: /* Texture Mapping */ case 114: /* Name Table */ /* these are safe to ignore */ ptr += len; break; default: //printf("op %d: end of table chunks\n", op); done = 1; } } return ptr - ptr0; } static int CheckHeader(ubyte *ptr, ubyte *end, fltState *state) { /*const char *unit[9] = {"meters", "kilometers", "", "", "feet", "inches", "", "", "nautical miles"};*/ int len, k; if (get16u(ptr) != 1) { ulSetError(UL_WARNING, "[flt] Wrong header opcode (%d).", get16i(ptr)); return -1; } len = get16u(ptr + 2); if (len < 128 || len > 1024) { ulSetError(UL_WARNING, "[flt] Suspicious header record length (%d).", len); return -1; } k = get32i(ptr + 12); if (k < 100) { state->revision = 100 * k; state->major = k; state->minor = 0; } else { state->revision = k; state->major = k / 100; state->minor = k % 100; } if (state->major < 11 || state->major > 16) { ulSetError(UL_WARNING, "[flt] Suspicious format revision number (%d).", k); return -1; } /* ulSetError(UL_DEBUG, "[flt] Loading %s %sFlight v%d.%d", state->filename, state->major > 13 ? "Open" : "", state->major, state->minor); */ return len; } #if 0 struct snode *refs; static int nrefs; static void ptree(ssgEntity *node, FILE *f, int d) { int i; for (i = 0; i < d; ++i) fprintf(f, " "); { const char *p = node->getName(); fprintf(f, "%s \"%s\"", node->getTypeName(), p ? p : ""); } if (node->getNumParents() > 1) { refs = sinsert(refs, node, 0, ptrcmp); if (refs->data == (void *)-1) { fprintf(f, " (%d)", nrefs); refs->data = (void *)nrefs++; } else { fprintf(f, " (%d) ...\n", (int)refs->data); return; } } assert(!node->isA(0xDeadBeef)); if (node->isAKindOf(ssgTypeLeaf())) { ssgLeaf *leaf = (ssgLeaf *)node; ssgState *st = leaf->getState(); fprintf(f, " %d tris", leaf->getNumTriangles()); if (st && st->isAKindOf(ssgTypeSimpleState())) { ssgSimpleState *ss = (ssgSimpleState *)st; char *file = ss->getTextureFilename(); if (file) { char *p; if ((p = strrchr(file, '/'))) file = p + 1; fprintf(f, " %s", file); } } } if (node->isAKindOf(ssgTypeTransform())) { sgMat4 mat; ((ssgTransform *)node)->getTransform(mat); fprintf(f, " pos %.2f %.2f %.2f", mat[3][0], mat[3][1], mat[3][2]); } if (node->isAKindOf(ssgTypeRangeSelector())) { ssgRangeSelector *lod = (ssgRangeSelector *)node; fprintf(f, " ranges"); for (i = 0; i <= lod->getNumKids(); i++) fprintf(f, " %.2f", lod->getRange(i)); } putc('\n', f); if (node->isAKindOf(ssgTypeBranch())) { ssgBranch *grp = (ssgBranch *)node; int n = grp->getNumKids(); for (i = 0; i < n; ++i) ptree(grp->getKid(i), f, d+1); } } #endif static const char *FindFile(const char *file) { /* XXX fixme! */ static char path[1024]; if (ulFileExists((char *)file)) return file; ssgGetCurrentOptions () -> makeModelPath ( path, file ) ; if (ulFileExists(path)) return path; ulSetError(UL_WARNING, "[flt] %s not found.", file); return 0; } static struct snode *FltCache; #ifdef UL_WIN32 static void win32_perror(const char *s) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); fprintf(stderr, "%s: %s\n", s, lpMsgBuf); LocalFree( lpMsgBuf ); } #endif static ssgEntity *LoadFLT(const char *file) { struct snode *cache; cache = FltCache = sinsert(FltCache, (void *)file, strlen(file) + 1, (sfunc)strcmp); if (cache->data == (void *)-1) { cache->data = NULL; /* avoid looping */ fltState *state = 0; int size = 0, len; ubyte *ptr = 0, *end; ssgEntity *node = 0; #ifdef USE_WIN32_MMAP HANDLE fd = INVALID_HANDLE_VALUE; HANDLE map = 0; #else int fd = -1; #ifdef USE_POSIX_MMAP struct stat st; #else ubyte buf[256]; #endif #endif do { /* dummy loop */ const char *path, *name; path = FindFile(file); if (path == 0) break; #ifdef USE_WIN32_MMAP fd = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (fd == INVALID_HANDLE_VALUE) { win32_perror(path); break; } size = GetFileSize(fd, NULL); if (size < 256) break; map = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, size, NULL); if (map == 0) { win32_perror(path); break; } ptr = (ubyte *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0); if (ptr == 0) { win32_perror(path); break; } #else /* USE_WIN32_MAP */ if ((fd = open(path, O_RDONLY|O_BINARY)) == -1) { perror(path); break; } #ifdef USE_POSIX_MMAP if (fstat(fd, &st)) { perror(file); break; } size = st.st_size; if (size < 256) break; ptr = (ubyte *)mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); if (ptr == (ubyte *)-1) { perror(file); break; } close(fd); fd = -1; #else /* USE_POSIX_MMAP */ if (read(fd, buf, 256) != 256) { perror(file); break; } ptr = buf; #endif /* ! USE_POSIX_MMAP */ #endif /* ! USE_WIN32_MMAP */ /*putc('\n', stderr);*/ name = strrchr(file, '/'); if (name) name++; else name = file; state = new fltState; state->filename = name; len = CheckHeader(ptr, ptr + 256, state); if (len == -1) break; #if !defined(USE_POSIX_MMAP) && !defined(USE_WIN32_MMAP) if ((size = lseek(fd, 0, SEEK_END)) == -1) { perror(file); break; } //ptr = (ubyte *)malloc(size); ptr = new ubyte[size]; lseek(fd, 0, SEEK_SET); if (read(fd, ptr, size) != size) { perror(file); break; } close(fd); fd = -1; #endif end = ptr + size; len += TableChunks(ptr + len, end, state); node = HierChunks(ptr + len, end, state); if (node) node->setName((char *)name); } while (0); delete state; #ifdef USE_WIN32_MMAP if (ptr) UnmapViewOfFile(ptr); if (map) CloseHandle(map); if (fd != INVALID_HANDLE_VALUE) CloseHandle(fd); #else /* USE_WIN32_MMAP */ if (fd != -1) close(fd); #ifdef USE_POSIX_MMAP if (ptr != 0 && ptr != (ubyte *)-1) munmap((char *)ptr, size); #else if (ptr != 0 && ptr != buf) //free(ptr); delete [] ptr; #endif #endif /* ! USE_WIN32_MMAP */ cache->data = node; if (node) node->ref(); } return (ssgEntity *)cache->data; } #if 0 static struct snode *Flattened; static ssgEntity *Flatten(ssgEntity *node, float (*mat)[4]) { if (node == 0) return 0; assert(!node->isA(0xDeadBeef)); /* some nodes cannot be flattened. only types that may be * generated by the loader are considered here. */ if (node->getRef() > 0 || node->isAKindOf(ssgTypeRangeSelector()) || node->isAKindOf(ssgTypeCutout())) { if (node->isAKindOf(ssgTypeBranch())) { /* see if we have flattened beyond this node already */ int completed = 0; if (node->getNumParents() > 0) { Flattened = sinsert(Flattened, node, 0, ptrcmp); if (Flattened->data == (void *)-1) { Flattened->data = 0; } else { completed = 1; } } if (!completed) { /* traverse */ ssgBranch *grp = (ssgBranch *)node; int i, n = grp->getNumKids(); if (n > 0) { ssgEntity *kids[32]; for (i = n; i--;) { kids[i] = grp->getKid(i); kids[i]->ref(); grp->removeKid(i); kids[i]->deRef(); kids[i] = Flatten(kids[i], 0); assert(kids[i] == 0 || !kids[i]->isA(0xDeadBeef)); } for (i = 0; i < n; i++) if (kids[i]) grp->addKid(kids[i]); grp->recalcBSphere(); } } } /* insert a transform if required */ if (mat) { ssgTransform *scs = new ssgTransform; scs->setTransform(mat); scs->addKid(node); node = scs; } return node; } assert(node->getNumParents() == 0); /* accumulate transformations */ if (node->isAKindOf(ssgTypeTransform())) { ssgTransform *scs = (ssgTransform *)node; int i, n = scs->getNumKids(); if (n <= 0) { delete scs; return 0; } else { sgMat4 tmp; scs->getTransform(tmp); if (mat) sgPostMultMat4(tmp, mat); if (n == 1) { node = scs->getKid(0); node->ref(); scs->removeKid(0); node->deRef(); delete scs; assert(!node->isA(0xDeadBeef)); return Flatten(node, tmp); } else { ssgBranch *grp = new ssgBranch; grp->setName(scs->getName()); for (i = 0; i < n; i++) grp->addKid(scs->getKid(i)); while (n--) scs->removeKid(n); delete scs; return Flatten(grp, tmp); } } } /* recurse the scene graph */ if (node->isAKindOf(ssgTypeBranch())) { ssgBranch *grp = (ssgBranch *)node; int i, n = grp->getNumKids(); if (n <= 0) { delete grp; return 0; } else if (n == 1 && grp->isA(ssgTypeBranch())) { ssgEntity *kid = grp->getKid(0); kid->ref(); grp->removeKid(0); kid->deRef(); delete grp; assert(!kid->isA(0xDeadBeef)); return Flatten(kid, mat); } else { ssgEntity *kids[32]; for (i = n; i--;) { kids[i] = grp->getKid(i); kids[i]->ref(); grp->removeKid(i); kids[i]->deRef(); kids[i] = Flatten(kids[i], mat); assert(kids[i] == 0 || !kids[i]->isA(0xDeadBeef)); } assert(!grp->isA(0xDeadBeef)); for (i = 0; i < n; i++) { if (kids[i]) { assert(!kids[i]->isA(0xDeadBeef)); grp->addKid(kids[i]); } } grp->recalcBSphere(); return grp; } } /* transform geometry */ if (node->isAKindOf(ssgTypeVtxTable()) && mat) { ssgVtxTable *g = (ssgVtxTable *)node; sgVec3 *a; int i, n; n = g->getNumVertices(); if (n > 0) { g->getVertexList((void **)&a); for (i = 0; i < n; i++) sgXformPnt3(a[i], a[i], mat); } n = g->getNumNormals(); if (n > 0) { g->getNormalList((void **)&a); for (i = 0; i < n; i++) sgXformVec3(a[i], a[i], mat); } g->recalcBSphere(); } assert(!node->isA(0xDeadBeef)); return node; } #endif static void Init(void) { if (Inited) return; Inited = 1; #if !defined(USE_POSIX_MMAP) && !defined(USE_WIN32_MMAP) ulSetError(UL_DEBUG, "[flt] Memory mapped files not enabled, please check source code."); #endif #ifdef PROBE_ENDIAN { short tmp = 42; if (*(char *)&tmp == 42) { /* little endian */ get16v = _swab16; get32v = _swab32; get64v = _swab64; ulSetError(UL_DEBUG, "[flt] Little endian architecture."); } else { /* big endian */ get16v = _copy16; get32v = _copy32; get64v = _copy64; ulSetError(UL_DEBUG, "[flt] Big endian architecture."); } } #endif if (getenv("FLTNOTEX")) NoTextures = 1; if (getenv("FLTNOMIPMAP")) NoMipmaps = 1; if (getenv("FLTNOEXT")) NoExternals = 1; if (getenv("FLTNOCLEAN")) NoClean = 1; return; } ssgEntity *ssgLoadFLT(const char *filename, #ifdef NO_LOADER_OPTIONS ssgHookFunc #else const ssgLoaderOptions *options #endif ) { static int depth = 0; ssgEntity *node; if (depth == 0) { Init(); ObsoleteFlag = 0; NotImplementedFlag = 0; TexCache = 0; StateCache = 0; FltCache = 0; #ifndef NO_LOADER_OPTIONS ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; LoaderOptions = ssgGetCurrentOptions () ; #endif } // no longjmp()'s please! (or this recursion test will fail) depth++; node = LoadFLT(filename); depth--; if (depth == 0) { sfree(TexCache, S_KEY | S_DATA); sfree(StateCache, S_KEY); if (node) node->ref(); // prevent this node from being deleted! sfree(FltCache, S_KEY | S_TREE); if (node) node->deRef(); } #if 0 if (node && !NoClean) { Flattened = 0; node = Flatten(node, 0); sfree(Flattened, 0); } #endif #if 0 /* debug */ if (node && getenv("FLTDUMP")) { const char *file = "/tmp/tree.txt"; FILE *f = fopen(file, "w"); if (f == 0) perror(file); else { refs = 0; nrefs = 0; ptree(node, f, 0); sfree(refs, 0); fclose(f); ulSetError(UL_DEBUG, "wrote %s", file); } } #endif return node; } //lint -restore plib-1.8.5/src/ssg/ssgBase.cxx0000644000175000001440000000654210765364437013114 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgBase.cxx 1673 2002-09-15 01:29:12Z ude $ */ #include "ssgLocal.h" static int next_unique_id = 1 ; void *ssgBase::operator new ( size_t sz ) { return malloc ( sz ) ; } void ssgBase::operator delete ( void *ptr ) { free ( ptr ) ; } void ssgBase::copy_from ( ssgBase *src, int clone_flags ) { if ( this == src ) return ; /* Avoid corrupting userdata when copying to self */ // type = src -> getType () ; - cannot change the virtual function table... spare = src -> getSpare () ; // refc = 0 ; - okay? if ( clone_flags & SSG_CLONE_USERDATA ) setUserData ( src -> getUserData () ) ; else setUserData ( NULL ) ; setName ( src -> getName () ) ; } ssgBase *ssgBase::clone ( int /* clone_flags */ ) { ulSetError ( UL_FATAL, "SSG: Can't clone abstract SSG class objects" ) ; return NULL ; } ssgBase:: ssgBase (void) { spare = refc = 0 ; type = ssgTypeBase () ; unique = next_unique_id++ ; user_data = NULL ; name = NULL ; } ssgBase::~ssgBase (void) { ssgDeRefDelete ( user_data ) ; deadBeefCheck () ; assert ( refc == 0 ) ; delete [] name ; /* Set the type of deleted nodes to 0xDeadBeef so we'll stand a chance of detecting re-use of deleted nodes. */ type = (int) 0xDeadBeef ; } void ssgBase::setName ( const char *nm ) { delete [] name ; if ( nm == NULL ) name = NULL ; else name = ulStrDup ( nm ) ; } void ssgBase::zeroSpareRecursive (){ zeroSpare () ; } void ssgBase::zeroSpare () { spare = 0 ; } void ssgBase::incSpare () { spare++ ; } void ssgBase::setSpare ( int ss ) { spare = ss ; } int ssgBase::getSpare () { return spare ; } void ssgBase::print ( FILE *fd, char *indent, int how_much ) { if ( how_much > 2 ) { fprintf ( fd, "%s%s: Ref Count=%d\n", indent, getTypeName(), getRef () ) ; fprintf ( fd, "%s Name = \"%s\"\n", indent, getPrintableName() ) ; } else fprintf ( fd, "%s%s: Name=%s\n", indent, getTypeName(), getPrintableName()); if ( how_much > 1 ) fprintf ( fd, "%s Userdata = %p\n", indent, getUserData() ) ; deadBeefCheck () ; } int ssgBase::load ( FILE *fd ) { delete [] name ; name = NULL ; _ssgReadString ( fd, &name ) ; return ! _ssgReadError () ; } int ssgBase::save ( FILE *fd ) { _ssgWriteString ( fd, name ) ; return ! _ssgWriteError () ; } plib-1.8.5/src/ssg/ssgSaveX.cxx0000644000175000001440000000244410765364437013265 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveX.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ // // .X loader for SSG/PLIB // .X is the 3D file format for Micro$ofts directX retained mode. // Written by Wolfram Kuss (Wolfram.Kuss@t-online.de) in Oct/Nov of 2000 // #include "ssgLocal.h" int ssgSaveX ( const char *filename, ssgEntity *ent ) { ulSetError ( UL_WARNING, "ssgSaveX: Not implemented yet" ) ; return FALSE; } plib-1.8.5/src/ssg/ssgLoadASC.cxx0000644000175000001440000007052010765364437013445 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ // // .ASC loader for SSG/PLIB // ASC = ascii files, used for example by 3DS R4 (the DOS version) // Written by Wolfram Kuss (Wolfram.Kuss@t-online.de) on 3.10.2004 // #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" #include "ssgParser.h" #define u32 unsigned int // These functions return TRUE on success typedef int AscHandlerFunctionType(); static char *globEmpty=""; static ssgBranch *curr_branch_; struct AscEntityType { const char * sName; AscHandlerFunctionType *HandleEntity; bool appearsInsideAMesh; } ; void AscLinePreProcessor(char *line) // there are lines like this // Page 2 // in *.asc files. They should be completely ignored. { char *p = line; while((*p == ' ') || (*p == 9)) p++; // p points to the first word (or the line end) now. if(ulStrNEqual(p, "Page", strlen("Page"))) { // Since this loader ignores the line structure, // we can also ignore the \n or \r and just "delete" the whole line line[0] = 0; } if(ulStrNEqual(p, "Camera", strlen("Camera"))) line[0] = 0; } static /* const */ ssgLoaderOptions* current_options = NULL ; static _ssgParserSpec parser_spec = { "\r\n\t ", // delim_chars_skipable "=:", // delim_chars_non_skipable so that things like "red=0.5" or "vertex 0:" work AscLinePreProcessor, // pre_processor "{", // open_brace_chars - unused "}", // close_brace_chars - unused '"', // quote_char '#', // comment_char - I am not sure there are comments and if so which char starts them "//" // comment_string - I am not sure there are comments and if so which string starts them } ; static _ssgParser parser; static ssgBranch* top_branch; static int Ascii2Int(int &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = int(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } static int Ascii2UInt(unsigned int &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = (unsigned int)(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } static int Ascii2Float(SGfloat &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = SGfloat(strtod( token, &endptr)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } struct MeshStatusType { bool isvalid; // rest of this is valid, IOW I am inside reading a mesh char *sName; bool mapped; bool materialed_but_not_mapped; // only defined if mapped = FALSE bool hidden; // unused int maxVertex, maxFace, curVertex, curFace; void set_sName(char *s); // material + smoothing is per poly!!! } MeshStatus; void MeshStatusType::set_sName(char *s) { if(sName) delete [] sName; sName = new char[strlen(s)+1]; strcpy(sName, s); } void CheckIndex(int &i, int max) { if((i<0) || (i>=max)) { fprintf(stderr, "Mesh '%s': Index %d is not in the range 0 to %d!", MeshStatus.sName, i, max); i = 0; } } void CheckWhetherMeshHasEnded(); static int HandleMeshMaterialList(const char *firstToken); static int HandleMaterialOld(const char *firstToken); static int HandleTextureFileName(const char *firstToken); static int HandleAmbient(); static int HandleSolid(); static int HandleNamed(); static int HandleTriMesh(); static int HandleHidden(); static int HandleMapped(); static int HandleVertex(); static int HandleFace(); static int HandleMaterial(); static int HandleSmoothing(); static int HandleDirect(); static int HandlePosition(); static int HandleLight(); static int HandleSpotlight(); static int HandleHotspot (); static int HandleFalloff (); static int HandleGlobal (); // unneeded static int HandleCamera(); static int HandleTarget(); static int HandleBank(); static int HandleNear(); static AscEntityType aEntities[] = { { "Spotlight", HandleSpotlight, FALSE}, { "Hotspot", HandleHotspot , FALSE}, { "Falloff", HandleFalloff , FALSE}, { "Global", HandleGlobal , FALSE}, // unneeded { "Camera", HandleCamera, FALSE}, { "Target", HandleTarget, FALSE}, { "Bank", HandleBank, FALSE}, { "Near", HandleNear, FALSE}, { "Ambient", HandleAmbient, FALSE}, { "Solid", HandleSolid, FALSE}, { "Named", HandleNamed, FALSE}, { "Tri-mesh,", HandleTriMesh, TRUE}, { "Hidden", HandleHidden, TRUE}, { "Mapped", HandleMapped, TRUE}, { "Vertex", HandleVertex, TRUE}, { "Face", HandleFace, TRUE}, { "Material", HandleMaterial, TRUE}, { "Smoothing", HandleSmoothing}, { "Direct", HandleDirect, FALSE}, { "Position", HandlePosition, FALSE}, { "Light", HandleLight, FALSE}, { NULL, NULL} }; static int ParseEntity(char *token) // called recursively // copied from ssgLoadX; A bit (?) of overkill for *.asc. { int i=0; while(aEntities[i].sName!=NULL) { if (!strcmp(token,aEntities[i].sName)) { if (aEntities[i].HandleEntity != NULL) { /*char *sNextToken, *sName=globEmpty; sNextToken=parser.getNextToken(0); if ( parser.eof ) { parser.error("unexpected end of file\n"); return FALSE; }*/ if(!aEntities[i].appearsInsideAMesh) CheckWhetherMeshHasEnded(); if (!aEntities[i].HandleEntity(/*sNextToken*/)) return FALSE; } else { parser.error("I am sorry, but Entity-type '%s' is not yet implemented.", aEntities[i].sName); return FALSE ; } break; } i++; } if (aEntities[i].sName==NULL) { parser.error("unexpected token %s", token); return FALSE ; } return TRUE; } #define MAX_ASC_MATERIALS 1024 struct AscMaterialType { char *sName; ssgSimpleState *ss; } AscMaterials[MAX_ASC_MATERIALS]; static int noOfAscmaterials=0; #define MAX_NO_VERTICES_PER_FACE 1000 static class ssgLoaderWriterMesh currentMesh; static ssgSimpleState *currentState; // we only need one of these, since obviously the texture name is the only materialproperty in asc: static ssgSimpleState *untexturedState = NULL; extern sgVec4 currentDiffuse; static int HandleDirect() // example line: // "Direct light" { parser.expectNextToken("light"); return TRUE; } /* not needed since handled via the PreProcessor static int HandleCamera() // example line: // Camera (51.944435mm) { float Dummy; parser.expectNextToken("("); if (!parser.getNextFloat(Dummy, "Camera")) return FALSE; parser.expectNextToken("mm)"); return TRUE; } */ static int HandleTarget() // example line: // Target: X:7.573029 Y:-989.009766 Z:6.24827() { float Dummy; parser.expectNextToken(":"); parser.expectNextToken("X"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Target X")) return FALSE; parser.expectNextToken("Y"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Target Y")) return FALSE; parser.expectNextToken("Z"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Target Z")) return FALSE; return TRUE; } static int HandleBank() // example line: // Bank angle: 0 degrees { float Dummy; parser.expectNextToken("angle"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Bank angle")) return FALSE; parser.expectNextToken("degrees"); return TRUE; } static int HandleNear() // example line: // Near 0 Far 1000 { float Dummy; if (!parser.getNextFloat(Dummy, "Near")) return FALSE; parser.expectNextToken("Far"); if (!parser.getNextFloat(Dummy, "Far")) return FALSE; return TRUE; } static int HandlePosition() // example line: // "Position: X:-534.261475 Y:484.437958 Z:203.464706" { float Dummy; parser.expectNextToken(":"); parser.expectNextToken("X"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "light X")) return FALSE; parser.expectNextToken("Y"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "light Y")) return FALSE; parser.expectNextToken("Z"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "light Z")) return FALSE; return TRUE; } static int HandleSpotlight() // example line: // "Spotlight to: X:-1.4 Y:-0.607239 Z:-16.277397" { float Dummy; parser.expectNextToken("to"); parser.expectNextToken(":"); parser.expectNextToken("X"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Spotlight to X")) return FALSE; parser.expectNextToken("Y"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Spotlight to Y")) return FALSE; parser.expectNextToken("Z"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Spotlight to Z")) return FALSE; return TRUE; } static int HandleHotspot () // example line: // "Hotspot size: 54 degrees" { float Dummy; parser.expectNextToken("size"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Hotspot size")) return FALSE; parser.expectNextToken("degrees"); return TRUE; } static int HandleFalloff () // example line: // "Falloff size: 54.5 degrees" { float Dummy; parser.expectNextToken("size"); parser.expectNextToken(":"); if (!parser.getNextFloat(Dummy, "Falloff size")) return FALSE; parser.expectNextToken("degrees"); return TRUE; } static int HandleGlobal () // example line: // "Global Shadow" { parser.expectNextToken("Shadow"); return TRUE; } static int HandleLight() // example line: // "Light color: Red=1 Green=1 Blue=1" { float Dummy; parser.expectNextToken("color"); parser.expectNextToken(":"); parser.expectNextToken("Red"); parser.expectNextToken("="); if (!parser.getNextFloat(Dummy, "Light red")) return FALSE; parser.expectNextToken("Green"); parser.expectNextToken("="); if (!parser.getNextFloat(Dummy, "Light Green")) return FALSE; parser.expectNextToken("Blue"); parser.expectNextToken("="); if (!parser.getNextFloat(Dummy, "Light Blue")) return FALSE; return TRUE; } static int HandleAmbient() // example line: // "Ambient light color: Red=0.180392 Green=0.180392 Blue=0.180392" { float Dummy; parser.expectNextToken("light"); parser.expectNextToken("color"); parser.expectNextToken(":"); parser.expectNextToken("Red"); parser.expectNextToken("="); if (!parser.getNextFloat(Dummy, "Ambient red")) return FALSE; parser.expectNextToken("Green"); parser.expectNextToken("="); if (!parser.getNextFloat(Dummy, "Ambient green")) return FALSE; parser.expectNextToken("Blue"); parser.expectNextToken("="); if (!parser.getNextFloat(Dummy, "Ambient blue")) return FALSE; return TRUE; } static int HandleSolid() // example line: // "Solid background color: Red=0.345098 Green=0.6 Blue=0.807843" { parser.expectNextToken("background"); parser.expectNextToken("color"); parser.expectNextToken(":"); parser.expectNextToken("Red"); parser.expectNextToken("="); float Dummy; if (!parser.getNextFloat(Dummy, "Background red")) return FALSE; parser.expectNextToken("Green"); parser.expectNextToken("="); if (!parser.getNextFloat(Dummy, "Background green")) return FALSE; parser.expectNextToken("Blue"); parser.expectNextToken("="); if (!parser.getNextFloat(Dummy, "Background blue")) return FALSE; return TRUE; } static int HandleNamed() // example line: // "Named object: "EX1_A"" { parser.expectNextToken("object"); parser.expectNextToken(":"); // assert(MeshStatus.isvalid); comes before trimesh ! char *s; // cleaned up sName s = parser.getNextToken("Mesh name"); if(*s=='"') s++; if(s[strlen(s)-1]=='"') s[strlen(s)-1]=0; MeshStatus.set_sName(s); return TRUE; } static int HandleTriMesh() // example line: // "Tri-mesh, Vertices: 22 Faces: 18" { parser.expectNextToken("Vertices"); parser.expectNextToken(":"); if (!parser.getNextInt(MeshStatus.maxVertex, "Number vertices")) return FALSE; parser.expectNextToken("Faces"); parser.expectNextToken(":"); if (!parser.getNextInt(MeshStatus.maxFace, "Number faces")) return FALSE; if(MeshStatus.isvalid) { fprintf(stderr, "MeshStatus.isvalid is TRUE. Probably, in the mesh preceding '%s', there are more faces than predicted", MeshStatus.sName); return FALSE; } MeshStatus.isvalid = TRUE; MeshStatus.curVertex = -1; MeshStatus.curFace = -1; MeshStatus.mapped = FALSE; MeshStatus.materialed_but_not_mapped = FALSE; MeshStatus.hidden = FALSE; // unused noOfAscmaterials=0; currentState = untexturedState; currentMesh.reInit (); currentMesh.setName( MeshStatus.sName ); currentMesh.createVertices( MeshStatus.maxVertex ); currentMesh.createFaces( MeshStatus.maxFace ); return TRUE; } static int HandleHidden() // example line: // "Hidden" { assert(MeshStatus.isvalid); MeshStatus.hidden = TRUE; // unused return TRUE; } static int HandleMapped() // example line: // "Mapped" { assert(MeshStatus.isvalid); currentMesh.createPerVertexTextureCoordinates2( MeshStatus.maxVertex ) ; currentMesh.createMaterials(); currentMesh.createMaterialIndices( MeshStatus.maxFace ); MeshStatus.mapped = TRUE; return TRUE; } static int HandleSmoothing() // example line: // "Smoothing: 1" { int i; parser.expectNextToken(":"); if (!parser.getNextInt(i, "Smoothing")) return FALSE; return TRUE; } int SetOrGetMaterial(char *sMatName) // if exists, gets the index. Else sets sName and creates the ss { char *s; // cleaned up sName s = sMatName; if(*s=='"') s++; if(s[strlen(s)-1]=='"') s[strlen(s)-1]=0; // **** search for it **** for(int i=0; isetOpaque(); currentState->disable(GL_BLEND); currentState->disable(GL_ALPHA_TEST); currentState->disable(GL_TEXTURE_2D); currentState->enable(GL_COLOR_MATERIAL); currentState->enable(GL_LIGHTING); currentState->setShadeModel(GL_SMOOTH); currentState->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.7f, 1.0f); currentState->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.7f, 1.0f); currentState->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f); currentState->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f); currentState->setShininess(50); // set texture currentState -> setTexture( current_options -> createTexture( s ) ); currentState -> setName(s); currentState -> enable( GL_TEXTURE_2D ); currentMesh.addMaterial(¤tState); return noOfAscmaterials-1; } static int HandleMaterial() // example line: // "Material:"BEXHUST"" { parser.expectNextToken(":"); if(!MeshStatus.mapped && !MeshStatus.materialed_but_not_mapped) { currentMesh.createMaterials(); currentMesh.createMaterialIndices( MeshStatus.maxFace ); MeshStatus.materialed_but_not_mapped = TRUE; } char *sMaterialName = parser.getNextToken("Material name"); int i = SetOrGetMaterial(sMaterialName); currentMesh.addMaterialIndex(i); return TRUE; } static int HandleVertex() // example line: // "Vertex list:" // *or* (!!) // "Vertex 0: X:115.710701 Y:180.000305 Z:-60.796242 U:0.048042 V:0.996284" { char *sNextToken = parser.peekAtNextToken( "vertex list?" ); if(ulStrEqual("list", sNextToken)) { parser.expectNextToken("list"); parser.expectNextToken(":"); } else { sgVec3 vert; int i; if (!parser.getNextInt(i, "vertex index")) return FALSE; assert(MeshStatus.isvalid); assert(MeshStatus.maxVertex > i); assert(MeshStatus.curVertex == i-1); MeshStatus.curVertex ++; parser.expectNextToken(":"); parser.expectNextToken("X"); parser.expectNextToken(":"); if (!parser.getNextFloat(vert[0], "X")) return FALSE; parser.expectNextToken("Y"); parser.expectNextToken(":"); if (!parser.getNextFloat(vert[1], "Y")) return FALSE; parser.expectNextToken("Z"); parser.expectNextToken(":"); if (!parser.getNextFloat(vert[2], "Z")) return FALSE; if(MeshStatus.mapped) { // read texture coordinates sgVec2 tv; parser.expectNextToken("U"); parser.expectNextToken(":"); if (!parser.getNextFloat(tv[0], "U")) return FALSE; parser.expectNextToken("V"); parser.expectNextToken(":"); if (!parser.getNextFloat(tv[1], "V")) return FALSE; currentMesh.addPerVertexTextureCoordinate2( tv ) ; } currentMesh.addVertex(vert); } return TRUE; } static int HandleFace() // example line: // "Face list:" // *or* (!!) // "Face 0: A:0 B:10 C:7 AB:1 BC:1 CA:1" { char *sNextToken = parser.peekAtNextToken( "Face list?" ); if(ulStrEqual("list", sNextToken)) { parser.expectNextToken("list"); parser.expectNextToken(":"); } else { int iFace, AB, _BC, CA; int aiVertices[3]; if (!parser.getNextInt(iFace, "Face index")) return FALSE; assert(MeshStatus.isvalid); assert(MeshStatus.maxFace > iFace); assert(MeshStatus.curFace == iFace-1); MeshStatus.curFace ++; parser.expectNextToken(":"); parser.expectNextToken("A"); parser.expectNextToken(":"); if (!parser.getNextInt(aiVertices[0], "A")) return FALSE; CheckIndex(aiVertices[0], MeshStatus.maxVertex); parser.expectNextToken("B"); parser.expectNextToken(":"); if (!parser.getNextInt(aiVertices[1], "B")) return FALSE; CheckIndex(aiVertices[1], MeshStatus.maxVertex); parser.expectNextToken("C"); parser.expectNextToken(":"); if (!parser.getNextInt(aiVertices[2], "C")) return FALSE; CheckIndex(aiVertices[2], MeshStatus.maxVertex); parser.expectNextToken("AB"); parser.expectNextToken(":"); if (!parser.getNextInt(AB, "AB")) return FALSE; parser.expectNextToken("BC"); parser.expectNextToken(":"); if (!parser.getNextInt(_BC, "BC")) return FALSE; // "BC" is already used :-/ parser.expectNextToken("CA"); parser.expectNextToken(":"); if (!parser.getNextInt(CA, "CA")) return FALSE; currentMesh.addFaceFromIntegerArray(3, aiVertices); } return TRUE; } // end todo ############################################################## /////////////////////////////////////////////////// old // start alt todo ############################################################## static int HandleTextureFileName(const char *firstToken) {/* TextureFilename { "../image/box_top.gif"; } #TextureFilename */ char *filename_ptr, *filename = new char [ strlen(firstToken)+1 ] ; assert(filename!=NULL); strcpy ( filename, firstToken ) ; filename_ptr = filename ; if ( filename_ptr[0] == '"' ) filename_ptr++; if (filename_ptr[strlen(filename_ptr)-1] == '"') filename_ptr[strlen(filename_ptr)-1] = 0; currentState -> setTexture( current_options -> createTexture( filename_ptr ) ); currentState -> enable( GL_TEXTURE_2D ); parser.expectNextToken(";"); parser.expectNextToken("}"); delete [] filename; return TRUE; } static int HandleMaterialOld(const char *firstToken) // return TRUE on success { SGfloat power; int bFoundTextureFileName = FALSE; sgVec4 specularColour, EmissiveColour; // read body if (! Ascii2Float(currentDiffuse[0], firstToken, "Facecolour R")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(currentDiffuse[1], "Facecolour G")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(currentDiffuse[2], "Facecolour B")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(currentDiffuse[3], "Facecolour A")) return FALSE; parser.expectNextToken(";"); parser.expectNextToken(";"); if (!parser.getNextFloat(power, "power")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(specularColour[0], "Specular R")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(specularColour[1], "Specular G")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(specularColour[2], "Specular B")) return FALSE; specularColour[3] = 0.0; parser.expectNextToken(";"); parser.expectNextToken(";"); if (!parser.getNextFloat(EmissiveColour[0], "Emissive R")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(EmissiveColour[1], "Emissive G")) return FALSE; parser.expectNextToken(";"); if (!parser.getNextFloat(EmissiveColour[2], "Emissive B")) return FALSE; EmissiveColour[3] = 0.0; parser.expectNextToken(";"); parser.expectNextToken(";"); // create SimpleState currentState = new ssgSimpleState () ; // currentState -> setMaterial ( GL_AMBIENT, mat -> amb ) ; currentState -> setMaterial ( GL_DIFFUSE, currentDiffuse) ; currentState -> setMaterial ( GL_SPECULAR, specularColour) ; currentState -> setMaterial ( GL_SPECULAR, specularColour[0], specularColour[1], specularColour[2], currentDiffuse[3] ) ; currentState -> setMaterial ( GL_EMISSION, EmissiveColour[0], EmissiveColour[1], EmissiveColour[2], currentDiffuse[3] ) ; currentState -> setShininess ( power ) ; // Fixme, NIV14: Is that correct? currentState -> enable ( GL_COLOR_MATERIAL ) ; currentState -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; currentState -> enable ( GL_LIGHTING ) ; currentState -> setShadeModel ( GL_SMOOTH ) ; if ( currentDiffuse[3] > 0.0f ) { currentState -> disable ( GL_ALPHA_TEST ) ; currentState -> enable ( GL_BLEND ) ; currentState -> setTranslucent () ; } else { currentState -> disable ( GL_BLEND ) ; currentState -> setOpaque () ; } currentState -> disable( GL_TEXTURE_2D ); while(TRUE) { char *nextToken =parser.getNextToken(0); if (0==strcmp("}", nextToken)) { currentMesh.addMaterial( ¤tState ); return TRUE; // Material is finished. success } if ( 0!= strcmp("TextureFilename", nextToken) ) { parser.error("TextureFilename expected!\n"); return FALSE; } if ( bFoundTextureFileName ) { parser.error("Only one TextureFileName per Material please!\n"); return FALSE; } if (!ParseEntity(nextToken)) // read "TextureFileName" return FALSE; bFoundTextureFileName = TRUE; } return TRUE; //lint !e527 } static int HandleMeshMaterialList(const char *firstToken) { u32 i, nFaceIndexes, nMaterialsRead = 0, nMaterials; if (! Ascii2UInt(nMaterials, firstToken, "nMaterials")) return FALSE; parser.expectNextToken(";"); currentMesh.createMaterials( nMaterials ); if (!parser.getNextUInt(nFaceIndexes, "number of Face Indexes")) return FALSE; currentMesh.createMaterialIndices( nFaceIndexes ) ; parser.expectNextToken(";"); if ( nFaceIndexes > currentMesh.getNumFaces()) { parser.error("No of face indexes of materiallist (%d) is greater than then no " "of faces (%d)!\n" "Therefore the material list is ignored!", ( int ) nFaceIndexes, ( int ) currentMesh.getNumFaces()); return TRUE; // go on parsing } if ( nFaceIndexes > currentMesh.getNumFaces()) parser.message("Informational: No of face indexes of materiallist (%d) is less than then no " "of faces (%d)\n" , ( int ) nFaceIndexes, ( int ) currentMesh.getNumFaces()); for ( i=0 ; i= nMaterials ) { parser.error("Too many Materials!\n"); return FALSE; } if (!ParseEntity(nextToken)) // read "Material" return FALSE; nMaterialsRead++; } return TRUE; //lint !e527 } // end alt todo ############################################################## void CheckWhetherMeshHasEnded() { if(MeshStatus.isvalid && (MeshStatus.curFace == MeshStatus.maxFace-1) && (MeshStatus.curVertex == MeshStatus.maxVertex-1)) { // end mesh PART FROM MATREEIAL AND SMOOTH //u32 i, j, nNoOfVertices, nNoOfVerticesForThisFace, nNoOfFaces; if ( currentState == NULL ) { currentState = new ssgSimpleState(); currentState->setOpaque(); currentState->disable(GL_BLEND); currentState->disable(GL_ALPHA_TEST); currentState->disable(GL_TEXTURE_2D); currentState->enable(GL_COLOR_MATERIAL); currentState->enable(GL_LIGHTING); currentState->setShadeModel(GL_SMOOTH); currentState->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.7f, 1.0f); currentState->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.7f, 1.0f); currentState->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f); currentState->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f); currentState->setShininess(50); /* currentState -> setMaterial ( GL_AMBIENT, 0.5, 0.5, 0.5); currentState -> setMaterial ( GL_DIFFUSE, 0.7, 0.7, 0.7); // light grey currentState -> setMaterial ( GL_SPECULAR, 1.0, 1.0, 1.0); currentState -> setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0); currentState -> setShininess ( 3 ) ; //currentState -> enable ( GL_COLOR_MATERIAL ) ; //currentState -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; currentState -> enable ( GL_LIGHTING ) ; currentState -> setShadeModel ( GL_SMOOTH ) ; currentState -> disable ( GL_BLEND ) ; currentState -> setOpaque () ; currentState -> disable( GL_TEXTURE_2D ); */ } currentMesh.addToSSG( currentState // Pfusch, kludge. NIV135 , current_options, curr_branch_); MeshStatus.isvalid = FALSE; } } static int parse() { char* token; token = parser.getNextToken(0); // getNextToken -> line structure is ignored (IOW line ends are ignored) while (! parser.eof ) { if (!ParseEntity(token)) return FALSE; token = parser.getNextToken(0); } CheckWhetherMeshHasEnded(); return TRUE ; } ssgEntity *ssgLoadASC ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; MeshStatus.isvalid=FALSE; MeshStatus.sName = NULL; untexturedState = new ssgSimpleState; untexturedState->setOpaque(); untexturedState->disable(GL_BLEND); untexturedState->disable(GL_ALPHA_TEST); untexturedState->disable(GL_TEXTURE_2D); untexturedState->enable(GL_COLOR_MATERIAL); untexturedState->enable(GL_LIGHTING); untexturedState->setShadeModel(GL_SMOOTH); untexturedState->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.7f, 1.0f); untexturedState->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.7f, 1.0f); untexturedState->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f); untexturedState->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f); untexturedState->setShininess(50); untexturedState->ref(); currentState = untexturedState; top_branch = new ssgBranch ; curr_branch_ = top_branch; if ( !parser.openFile( fname, &parser_spec )) { delete top_branch ; return 0; } if ( !parse() ) { delete top_branch ; top_branch = 0 ; } // parse_free(); parser.closeFile(); untexturedState->deRef(); if(untexturedState->getRef()==0) delete untexturedState; return top_branch ; } plib-1.8.5/src/ssg/ssgBaseTransform.cxx0000644000175000001440000000420710765364437015004 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgBaseTransform.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgBaseTransform::copy_from ( ssgBaseTransform *src, int clone_flags ) { ssgBranch::copy_from ( src, clone_flags ) ; src -> getTransform ( transform ) ; src -> getLastTransform ( last_transform ) ; last_updated = src -> last_updated ; first_time = src -> first_time ; } ssgBaseTransform::ssgBaseTransform (void) { type = ssgTypeBaseTransform () ; last_updated = -9999999 ; first_time = TRUE ; sgMakeIdentMat4 ( transform ) ; sgMakeIdentMat4 ( last_transform ) ; } ssgBaseTransform::~ssgBaseTransform (void) { } int ssgBaseTransform::load ( FILE *fd ) { _ssgReadMat4 ( fd, transform ) ; updateTransform () ; first_time = TRUE ; return ssgBranch::load(fd) ; } int ssgBaseTransform::save ( FILE *fd ) { _ssgWriteMat4 ( fd, transform ) ; return ssgBranch::save(fd) ; } void ssgBaseTransform::print ( FILE *fd, char *indent, int how_much ) { ssgBranch::print ( fd, indent, how_much ) ; if ( how_much >= 2 ) for ( int row = 0 ; row < 4 ; row++ ) fprintf ( fd, "%s Transform[%d]= %f,%f,%f,%f\n", indent, row, transform[row][0], transform[row][1], transform[row][2], transform[row][3] ) ; } plib-1.8.5/src/ssg/ssgAxisTransform.cxx0000644000175000001440000000650710765364437015043 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgAxisTransform.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgAxisTransform::copy_from ( ssgAxisTransform *src, int clone_flags ) { ssgBaseTransform::copy_from ( src, clone_flags ) ; sgCopyVec3 ( rotation_axis , src->rotation_axis ) ; sgCopyVec3 ( rotation_center, src->rotation_center ) ; limit_low = src->limit_low ; limit_high = src->limit_high ; } ssgBase *ssgAxisTransform::clone ( int clone_flags ) { ssgAxisTransform *b = new ssgAxisTransform ; b -> copy_from ( this, clone_flags ) ; return b; } ssgAxisTransform::ssgAxisTransform (void) { type = ssgTypeAxisTransform () ; sgZeroVec3 ( rotation_axis ) ; limit_low = limit_high = 0.f; } ssgAxisTransform::ssgAxisTransform ( sgVec3 axis, sgVec3 center ) { type = ssgTypeAxisTransform () ; setAxis ( axis ); setCenter ( center ); limit_low = limit_high = 0.f; } ssgAxisTransform::~ssgAxisTransform (void) { } void ssgAxisTransform::setAxis ( sgVec3 axis ) { sgCopyVec3 ( rotation_axis, axis ) ; } float *ssgAxisTransform::getAxis (void) { return rotation_axis; } void ssgAxisTransform::setCenter ( sgVec3 center ) { sgCopyVec3 ( rotation_center, center ) ; } float *ssgAxisTransform::getCenter (void) { return rotation_center; } void ssgAxisTransform::setRotation ( float rot ) { sgMat4 rot_mat ; sgMat4 trans1, trans2; sgVec3 neg_center; sgNegateVec3 ( neg_center, rotation_center ) ; sgMakeTransMat4 ( trans1 , neg_center ) ; sgMakeTransMat4 ( trans2 , rotation_center ) ; sgMakeRotMat4 ( rot_mat, rot, rotation_axis ) ; sgPreMultMat4 ( rot_mat, trans1 ) ; sgPostMultMat4 ( rot_mat, trans2 ) ; setTransform ( rot_mat ) ; } void ssgAxisTransform::setRotationLimits ( float low, float high ) { limit_low = low ; limit_high = high ; } void ssgAxisTransform::setLinearRotation ( float rot ) { assert( rot >= 0.0f && rot <= 1.0f ); setRotation( limit_low + (limit_high - limit_low) * rot ) ; } int ssgAxisTransform::load ( FILE *fd ) { _ssgReadFloat ( fd, 3, rotation_axis ) ; _ssgReadFloat ( fd, 3, rotation_center ) ; _ssgReadFloat ( fd, & limit_low ) ; _ssgReadFloat ( fd, & limit_high ) ; return ssgTransform::load(fd) ; } int ssgAxisTransform::save ( FILE *fd ) { _ssgWriteFloat ( fd, 3, rotation_axis ) ; _ssgWriteFloat ( fd, 3, rotation_center ) ; _ssgWriteFloat ( fd, limit_low ) ; _ssgWriteFloat ( fd, limit_high ) ; return ssgTransform::save(fd) ; } plib-1.8.5/src/ssg/ssgLoadPNG.cxx0000644000175000001440000000325710765364437013466 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadPNG.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" #ifdef SSG_LOAD_PNG_SUPPORTED #include bool ssgLoadPNG ( const char *fname, ssgTextureInfo* info ) { pngInfo png_info; if (!pngLoad(fname, PNG_BUILDMIPMAP, PNG_ALPHA, &png_info)) { ulSetError ( UL_WARNING, "ssgLoadTexture: Failed to load '%s'.", fname ) ; return false ; } if ( info != NULL ) { info -> width = png_info.Width ; info -> height = png_info.Height ; info -> depth = png_info.Depth ; info -> alpha = png_info.Alpha ; } return true ; } #else bool ssgLoadPNG ( const char *fname, ssgTextureInfo* info ) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - you need glpng for PNG format support", fname ) ; return false ; } #endif plib-1.8.5/src/ssg/ssgSelector.cxx0000644000175000001440000000776710765364437014034 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSelector.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgSelector::copy_from ( ssgSelector *src, int clone_flags ) { ssgBranch::copy_from ( src, clone_flags ) ; max_kids = src -> max_kids ; selection = new unsigned char [ max_kids ] ; memcpy ( selection, src -> selection, max_kids ) ; } ssgBase *ssgSelector::clone ( int clone_flags ) { ssgSelector *b = new ssgSelector ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgSelector::ssgSelector ( int _max_kids ) { type = ssgTypeSelector () ; max_kids = _max_kids ; selection = new unsigned char [ max_kids ] ; memset ( selection, 1, max_kids ) ; } ssgSelector::~ssgSelector (void) { delete [] selection ; } void ssgSelector::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) ) return ; int cull_result = cull_test ( f, m, test_needed ) ; if ( cull_result == SSG_OUTSIDE ) return ; int s = 0 ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid(), s++ ) if ( selection [s] ) e -> cull ( f, m, cull_result != SSG_INSIDE ) ; postTravTests ( SSGTRAV_CULL ) ; } void ssgSelector::hot ( sgVec3 sp, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) ) return ; int hot_result = hot_test ( sp, m, test_needed ) ; if ( hot_result == SSG_OUTSIDE ) return ; int s = 0 ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid(), s++ ) if ( selection [s] ) e -> hot ( sp, m, hot_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_HOT ) ; } void ssgSelector::los ( sgVec3 sp, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) ) return ; int los_result = los_test ( sp, m, test_needed ) ; if ( los_result == SSG_OUTSIDE ) return ; int s = 0 ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid(), s++ ) if ( selection [s] ) e -> los ( sp, m, los_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_LOS ) ; } void ssgSelector::isect ( sgSphere *sp, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) ) return ; int isect_result = isect_test ( sp, m, test_needed ) ; if ( isect_result == SSG_OUTSIDE ) return ; int s = 0 ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid(), s++ ) if ( selection [s] ) e -> isect ( sp, m, isect_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_ISECT ) ; } int ssgSelector::load ( FILE *fd ) { _ssgReadInt ( fd, & max_kids ) ; delete [] selection ; selection = new unsigned char [ max_kids ] ; for ( int i=0; i= SSG_MAXPATH ) { next_path++ ; /* So pop works! */ return ; } pathlist [ next_path++ ] = e ; } void _ssgPopPath () { next_path-- ; } void _ssgAddHit ( ssgLeaf *l, int trinum, sgMat4 mat, sgVec4 pl ) { if ( next_hit + 1 >= MAX_HITS ) return ; ssgHit *h = & hitlist [ next_hit++ ] ; h -> leaf = l ; h -> triangle = trinum ; h -> num_entries = (next_path>=SSG_MAXPATH) ? SSG_MAXPATH : next_path ; memcpy ( h -> path, pathlist, h->num_entries * sizeof ( ssgEntity * ) ) ; sgCopyMat4 ( h -> matrix, mat ) ; sgCopyVec4 ( h -> plane, pl ) ; } int ssgIsect ( ssgBranch *root, sgSphere *s, sgMat4 mat, ssgHit **results ) { _ssgIsHotTest = FALSE ; _ssgIsLosTest = FALSE ; next_hit = 0 ; next_path = 0 ; root -> isect ( s, mat, TRUE ) ; *results = & hitlist [ 0 ] ; return next_hit ; } int ssgHOT ( ssgBranch *root, sgVec3 s, sgMat4 mat, ssgHit **results ) { _ssgIsHotTest = TRUE ; _ssgIsLosTest = FALSE ; next_hit = 0 ; next_path = 0 ; root -> hot ( s, mat, TRUE ) ; *results = & hitlist [ 0 ] ; return next_hit ; } int ssgLOS ( ssgBranch *root, sgVec3 s, sgMat4 mat, ssgHit **results ) { _ssgIsHotTest = FALSE ; _ssgIsLosTest = TRUE ; next_hit = 0 ; next_path = 0 ; root -> los ( s, mat, TRUE ) ; *results = & hitlist [ 0 ] ; return next_hit ; } plib-1.8.5/src/ssg/ssgStateSelector.cxx0000644000175000001440000002261310765364437015020 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgStateSelector.cxx 1950 2004-09-13 11:28:34Z wolfram_kuss $ */ #include "ssgLocal.h" void ssgStateSelector::copy_from ( ssgStateSelector *src, int clone_flags ) { ssgSimpleState::copy_from ( src, clone_flags ) ; nstates = src -> getNumSteps () ; selection = src -> getSelectStep () ; statelist = new ssgSimpleState * [ nstates ] ; for ( int i = 0 ; i < nstates ; i++ ) { ssgSimpleState *s = src -> getStep ( i ) ; if ( s != NULL && (clone_flags & SSG_CLONE_STATE_RECURSIVE) ) statelist [ i ] = (ssgSimpleState *)( s -> clone ( clone_flags )) ; else statelist [ i ] = s ; //~~ T.G. needs ref count incremented if (statelist [ i ] != NULL ) statelist [ i ] -> ref(); } } ssgBase *ssgStateSelector::clone ( int clone_flags ) { ssgStateSelector *b = new ssgStateSelector ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgStateSelector::ssgStateSelector () { type = ssgTypeStateSelector () ; nstates = 0 ; selection = -1 ; statelist = NULL ; } ssgStateSelector::ssgStateSelector ( int ns ) { type = ssgTypeStateSelector () ; nstates = ns ; selection = -1 ; statelist = new ssgSimpleState * [ nstates ] ; for ( int i = 0 ; i < nstates ; i++ ) statelist [ i ] = NULL ; } ssgStateSelector::~ssgStateSelector (void) { //~~ T.G. deref states before deleting list for ( int i = 0 ; i < nstates ; i++ ) ssgDeRefDelete( statelist [ i ] ); delete [] statelist ; } void ssgStateSelector::selectStep ( unsigned int s ) { selection = s ; } unsigned int ssgStateSelector::getSelectStep (void) { return selection ; } ssgSimpleState *ssgStateSelector::getCurrentStep (void) { return ( selection < 0 || selection >= nstates || statelist [ selection ] == NULL ) ? this : statelist[selection] ; } ssgSimpleState *ssgStateSelector::getStep ( int i ) { return ( i < 0 || i >= nstates || statelist [ i ] == NULL ) ? this : statelist[i] ; } void ssgStateSelector::setStep (int i, ssgSimpleState *step) { if ( i < 0 || i >= nstates ) return ; //~~ T.G. removed null test -- not necessary ssgDeRefDelete ( statelist[i] ) ; statelist [ i ] = step ; if ( step != NULL ) step -> ref () ; } int ssgStateSelector::isTranslucent (void) { return getCurrentStep()->isTranslucent() ; } void ssgStateSelector::setTranslucent (void) { getCurrentStep()->setTranslucent() ; } void ssgStateSelector::setOpaque (void) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setOpaque() ; else s -> setOpaque() ; } void ssgStateSelector::force (void) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::force() ; else s -> force() ; } void ssgStateSelector::apply (void) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::apply() ; else s -> apply() ; } void ssgStateSelector:: care_about ( int mode ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::care_about (mode) ; else s -> care_about (mode); } void ssgStateSelector::dont_care_about ( int mode ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::dont_care_about(mode) ; else s -> dont_care_about(mode); } int ssgStateSelector::isEnabled ( GLenum mode ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) return ssgSimpleState::isEnabled(mode) ; else return s -> isEnabled(mode) ; } void ssgStateSelector::disable ( GLenum mode ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::disable(mode) ; else s -> disable(mode) ; } void ssgStateSelector::enable ( GLenum mode ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::enable(mode) ; else s -> enable(mode) ; } void ssgStateSelector::setTexture ( char *fname, int _wrapu, int _wrapv, int _mipmap ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setTexture ( fname, _wrapu, _wrapv, _mipmap ) ; else s -> setTexture ( fname, _wrapu, _wrapv, _mipmap ) ; } char *ssgStateSelector::getTextureFilename (void) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) return ssgSimpleState::getTextureFilename() ; else return s -> getTextureFilename(); } GLuint ssgStateSelector::getTextureHandle (void) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) return ssgSimpleState::getTextureHandle() ; else return s -> getTextureHandle() ; } void ssgStateSelector::setTexture ( ssgTexture *tex ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setTexture(tex) ; else s -> setTexture(tex) ; } void ssgStateSelector::setTextureFilename ( char *fname ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; ssgTexture* texture ; if ( s == this ) texture = ssgSimpleState::getTexture () ; else texture = s -> getTexture () ; if ( texture != NULL ) texture -> setFilename ( fname ) ; } void ssgStateSelector::setTexture ( GLuint tex ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; ssgTexture* texture ; if ( s == this ) texture = ssgSimpleState::getTexture () ; else texture = s -> getTexture () ; if ( texture != NULL ) texture -> setHandle (tex) ; } void ssgStateSelector::setColourMaterial(GLenum which) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setColourMaterial(which) ; else s -> setColourMaterial(which) ; } void ssgStateSelector::setMaterial ( GLenum which, float r, float g, float b, float a ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setMaterial(which,r,g,b,a) ; else s -> setMaterial(which,r,g,b,a) ; } void ssgStateSelector::setMaterial ( GLenum which, sgVec4 rgba ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setMaterial(which,rgba) ; else s -> setMaterial(which,rgba) ; } float *ssgStateSelector::getMaterial ( GLenum which ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) return ssgSimpleState::getMaterial(which) ; else return s -> getMaterial(which) ; } float ssgStateSelector::getShininess (void) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) return ssgSimpleState::getShininess() ; else return s -> getShininess() ; } void ssgStateSelector::setShininess ( float sh ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setShininess(sh) ; else s -> setShininess(sh) ; } void ssgStateSelector::setShadeModel ( GLenum model ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setShadeModel(model) ; else s -> setShadeModel(model) ; } void ssgStateSelector::setAlphaClamp ( float clamp ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::setAlphaClamp(clamp) ; else s -> setAlphaClamp(clamp) ; } void ssgStateSelector::print ( FILE *fd, char *indent, int how_much ) { ssgStateSelector * s = (ssgStateSelector *) getCurrentStep() ; if ( s == this ) ssgSimpleState::print(fd, indent, how_much) ; else s -> print(fd, indent, how_much) ; } int ssgStateSelector::load ( FILE *fd ) { int i ; _ssgReadInt ( fd, & nstates ) ; _ssgReadInt ( fd, & selection ) ; if (statelist != NULL) { for ( i = 0 ; i < nstates ; i++ ) ssgDeRefDelete( statelist [ i ] ); delete [] statelist ; } statelist = new ssgSimpleState * [ nstates ] ; for ( i = 0 ; i < nstates ; i++ ) { if ( ! _ssgLoadObject ( fd, (ssgBase **) &statelist[i], ssgTypeState () ) ) return FALSE ; } return ssgSimpleState::load(fd) ; } int ssgStateSelector::save ( FILE *fd ) { _ssgWriteInt ( fd, nstates ) ; _ssgWriteInt ( fd, selection ) ; for ( int i = 0 ; i < nstates ; i++ ) { if ( ! _ssgSaveObject ( fd, statelist[i] ) ) return FALSE ; } return ssgSimpleState::save(fd) ; } plib-1.8.5/src/ssg/ssgEntity.cxx0000644000175000001440000003024410765364437013512 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgEntity.cxx 1954 2004-09-13 11:49:36Z wolfram_kuss $ */ #include "ssgLocal.h" void ssgEntity::copy_from ( ssgEntity *src, int clone_flags ) { ssgBase::copy_from ( src, clone_flags ) ; traversal_mask = src -> getTraversalMask () ; setTravCallback( SSG_CALLBACK_PRETRAV, src->getTravCallback( SSG_CALLBACK_PRETRAV ) ); setTravCallback( SSG_CALLBACK_POSTTRAV, src->getTravCallback( SSG_CALLBACK_POSTTRAV ) ); dirtyBSphere () ; } ssgEntity::ssgEntity (void) { traversal_mask = 0xFFFFFFFF ; type = ssgTypeEntity () ; bsphere_is_invalid = TRUE ; preTravCB = NULL ; postTravCB = NULL ; } ssgEntity::~ssgEntity (void) { } void ssgEntity::dirtyBSphere () { if ( bsphere_is_invalid ) return ; bsphere_is_invalid = TRUE ; int np = getNumParents () ; for ( int i = 0 ; i < np ; i++ ) getParent ( i ) -> dirtyBSphere () ; } void ssgEntity::visualiseBSphere () { if ( bsphere.isEmpty () ) return ; glDisable ( GL_LIGHTING ) ; glTranslatef ( bsphere.getCenter()[0], bsphere.getCenter()[1], bsphere.getCenter()[2] ) ; #ifdef USE_GLUT_SPHERES int spherebotch = (int)(this) % 9 ; switch ( spherebotch++ ) { case 0 : glutWireSphere(bsphere.getRadius(),10,10); break ; case 1 : glutWireSphere(bsphere.getRadius(),11,10); break ; case 2 : glutWireSphere(bsphere.getRadius(),12,10); break ; case 3 : glutWireSphere(bsphere.getRadius(),10,11); break ; case 4 : glutWireSphere(bsphere.getRadius(),11,11); break ; case 5 : glutWireSphere(bsphere.getRadius(),12,11); break ; case 6 : glutWireSphere(bsphere.getRadius(),10,12); break ; case 7 : glutWireSphere(bsphere.getRadius(),11,12); break ; case 8 : glutWireSphere(bsphere.getRadius(),12,12); spherebotch=0 ; break ; } #endif glTranslatef ( -bsphere.getCenter()[0], -bsphere.getCenter()[1], -bsphere.getCenter()[2] ) ; glEnable ( GL_LIGHTING ) ; } void ssgEntity::print ( FILE *fd, char *indent, int how_much ) { ssgBase::print ( fd, indent, how_much ) ; if ( how_much > 1 ) fprintf ( fd, "%s Num Parents=%d\n", indent, parents.getNumEntities () ) ; } /* Get the entity whos name equals match (case sensitive) or 0 if there isn't This will be overridden by descendant classes to search trees, etc. This makes recovery of tagged parts of objects simple. I envisage it being used to find axles, gimbals etc and to separate many objects from a single loaded model file. The base version in ssgEntity returns the ssgEntity if the name refers to this entity or 0 if not. */ ssgEntity* ssgEntity::getByName ( char *match ) { return ( getName() != NULL && strcmp ( getName(), match ) == 0 ) ? this : (ssgEntity *) NULL ; } /* Get the entity specified by the path. A path is a series of names separated by '/'. Each sub-unit is searched so long as the path matches. A single leading '/' on the path is ignored. */ ssgEntity* ssgEntity::getByPath ( char *path ) { /* ignore leading '/' */ if ( *path == '/' ) ++path ; /* return this if the name is the path else NULL */ return ( getName() != NULL && strcmp ( getName(), path ) == 0 ) ? this : (ssgEntity *) NULL ; } ssgCallback ssgEntity::getCallback ( int cb_type ) { if ( isAKindOf ( ssgTypeLeaf() ) ) return ((ssgLeaf*)this) -> getCallback ( cb_type ) ; /* * Because of transparency sorting, having a pre/post draw callback * doesn't make sense for anything but a leaf. */ ulSetError ( UL_WARNING, "getCallback() ignored for non-leaf entity"); return NULL ; } void ssgEntity::setCallback ( int cb_type, ssgCallback cb ) { if ( isAKindOf ( ssgTypeLeaf() ) ) { ((ssgLeaf*)this) -> setCallback ( cb_type, cb ) ; } else { /* * Because of transparency sorting, having a pre/post draw callback * doesn't make sense for anything but a leaf. */ ulSetError ( UL_WARNING, "setCallback() ignored for non-leaf entity"); } } int ssgEntity::preTravTests ( int *test_needed, int which ) { if ( (getTraversalMask() & which) == 0 ) { if ( which & SSGTRAV_HOT ) stats_hot_no_trav ++ ; /* if ( which & SSGTRAV_LOS ) stats_hot_no_trav ++ ;*/ return FALSE ; } if ( preTravCB != NULL ) { int result = (*preTravCB)(this,which) ; if ( result == 0 ) return FALSE ; if ( result == 2 ) *test_needed = 0 ; } return TRUE ; } void ssgEntity::postTravTests ( int which ) { if ( postTravCB != NULL ) (*postTravCB)(this,which) ; } ssgCullResult ssgEntity::cull_test ( sgFrustum *f, sgMat4 m, int test_needed ) { if ( ! test_needed ) return SSG_INSIDE ; stats_cull_test++ ; sgSphere tmp = *(getBSphere()) ; if ( tmp.isEmpty () ) return SSG_OUTSIDE ; tmp . orthoXform ( m ) ; return (ssgCullResult) f -> contains ( &tmp ) ; } ssgCullResult ssgEntity::isect_test ( sgSphere *s, sgMat4 m, int test_needed ) { if ( ! test_needed ) return SSG_INSIDE ; stats_isect_test++ ; sgSphere tmp = *(getBSphere()) ; if ( tmp.isEmpty () ) return SSG_OUTSIDE ; tmp . orthoXform ( m ) ; /* Check axial distances for trivial reject */ sgVec3 center_vec ; float sum_radii = s->getRadius() + tmp.getRadius() ; sgSubVec3 ( center_vec, s->getCenter(), tmp.getCenter() ) ; if ( sgAbs(center_vec[0]) > sum_radii || sgAbs(center_vec[1]) > sum_radii || sgAbs(center_vec[2]) > sum_radii ) return SSG_OUTSIDE ; float separation_sqd = sgScalarProductVec3 ( center_vec, center_vec ) ; float tmp_radius_sqd = sgSquare ( tmp.getRadius() ) ; float sph_radius_sqd = sgSquare ( s ->getRadius() ) ; float sum_radii_sqd = tmp_radius_sqd + sph_radius_sqd ; if ( separation_sqd >= sum_radii_sqd ) return SSG_OUTSIDE ; if ( separation_sqd + tmp_radius_sqd <= sph_radius_sqd ) return SSG_INSIDE ; return SSG_STRADDLE ; } /* Places the addresses of the entities whose names or paths are listed in bind into the variables whose addresses are listed in bind. The bind array must terminate with a NULL name. Returns TRUE if all names were found and bound to variables. */ int ssgEntity::bindEntities ( ssgEntityBinding *bind ) { int success = TRUE ; while ( bind -> nameOrPath != NULL ) { ssgEntity *e = NULL ; if ( strchr ( bind -> nameOrPath, '/' ) ) e = getByPath ( bind -> nameOrPath ) ; else e = getByName ( bind -> nameOrPath ) ; if ( e != NULL ) *( bind -> entity ) = e ; else success = FALSE ; ++bind ; } return success ; } ssgCullResult ssgEntity::hot_test ( sgVec3 s, sgMat4 m, int test_needed ) { /* Height-Off-Terrain Test */ stats_hot_test++ ; if ( !test_needed ) { stats_hot_triv_accept++ ; return SSG_INSIDE ; } sgSphere tmp = *(getBSphere()) ; if ( tmp.isEmpty () ) return SSG_OUTSIDE ; tmp . orthoXform ( m ) ; float d = sgSquare ( s[0] - tmp.getCenter()[0] ) + sgSquare ( s[1] - tmp.getCenter()[1] ) ; if ( d > sgSquare ( tmp.getRadius() ) ) { stats_hot_radius_reject++ ; return SSG_OUTSIDE ; } stats_hot_straddle++ ; return SSG_STRADDLE ; } ssgCullResult ssgEntity::los_test ( sgVec3 s, sgMat4 m, int test_needed ) { /* Line of Sight Test * Determine whether a line of sight that starts at the origin and proceeds along the * vector "s" intersects the B-sphere of this entity (I think that's right) * Algorithm: (please bear with the vector calculus) * Define the line of sight to be L = O + u S * where "O" is the origin of the line of sight (always (0.0.0) for this application) * "u" is a parametric coordinate which measures distance along the line of sight * "S" is the direction vector, given by the variable "s" in this function * Define the B-sphere as a sphere of radius "r" centered at a point "C". * The vector from the center of the sphere to a point on the line is given by * V = O + u S - C = ( O - C ) + u S * The line of sight intersects the sphere if the shortest length of this vector is less * than the radius of the sphere. We will work with the square of the length as it is * easier and gives the same result. This distance-squared from the point on the line to * the center of the sphere is given by the dot product of "V" with itself: * d2 = V dot V = ( O - C ) dot ( O - C ) + 2 u * ( O - C ) dot S + u^2 * S dot S * To get the shortest distance, differentiate "d2" with respect to "u" and set the * derivative to zero: * 2 ( O - C ) dot S + 2 u * S dot S = 0 * u = - [ ( O - C ) dot S ] / [ S dot S ] * For this value of "u", the distance squared becomes * d2 = ( O - C ) dot ( O - C ) - [ ( O - C ) dot S ] ^2 / [ S dot S ] * If d2 < radius of sphere squared, then the line of sight intersects the sphere. */ stats_los_test++ ; if ( !test_needed ) { stats_los_triv_accept++ ; return SSG_INSIDE ; } sgSphere tmp = *(getBSphere()) ; /* If there is no B-sphere, the LOS is outside of it by definition */ if ( tmp.isEmpty () ) return SSG_OUTSIDE ; tmp . orthoXform ( m ) ; sgVec3 p1 ; /* End point at eye of Line-Of-Sight */ sgSetVec3 ( p1, 0.0, 0.0, 0.0 ) ; /* Eye point always at origin */ /* Get the center and square the radius of the sphere */ sgFloat const *center = tmp.getCenter () ; sgFloat radius2 = sgSquare ( tmp.getRadius () ) ; /* Calculate the distance from the line to the center of the sphere */ sgVec3 oc ; sgSubVec3 ( oc, p1, center ) ; /* Check whether the eyepoint is within the sphere */ sgFloat eye_to_center_squared = sgSquare ( oc[0] ) + sgSquare ( oc[1] ) + sgSquare ( oc[2] ) ; if ( eye_to_center_squared < radius2 ) { stats_los_straddle++ ; return SSG_STRADDLE ; } /* Calculate the dot product of the vector from the center to the eyepoint and the * line of sight vector. If this dot product is positive or zero, then the point of * closest approach to the sphere is behind the eyepoint or at the eyepoint. Since the * eyepoint is outside the sphere, this means that the line of sight forward from the * eyepoint will not intersect the sphere. */ sgFloat oc_dot_s = oc[0] * s[0] + oc[1] * s[1] + oc[2] * s[2] ; if ( oc_dot_s >= 0.0 ) { stats_los_radius_reject++ ; return SSG_OUTSIDE ; } float dmin2 = eye_to_center_squared - sgSquare ( oc_dot_s ) / ( sgSquare ( s[0] ) + sgSquare ( s[1] ) + sgSquare ( s[2] ) ) ; /* Compare minimum distance squared with sphere radius squared */ if ( dmin2 > radius2 ) { stats_los_radius_reject++; return SSG_OUTSIDE; } stats_los_straddle++ ; return SSG_STRADDLE ; } int ssgEntity::load ( FILE *fd ) { dirtyBSphere(); _ssgReadInt ( fd, &traversal_mask ) ; return ssgBase::load(fd) ; } int ssgEntity::save ( FILE *fd ) { _ssgWriteInt ( fd, traversal_mask ) ; return ssgBase::save(fd) ; } void ssgEntity::getNetTransform ( sgMat4 xform ) { if ( getNumParents () > 0 ) getParent ( 0 ) -> getNetTransform ( xform ) ; else sgMakeIdentMat4 ( xform ) ; } void ssgEntity::getLastNetTransform ( sgMat4 xform ) { if ( getNumParents () > 0 ) getParent ( 0 ) -> getLastNetTransform ( xform ) ; else sgMakeIdentMat4 ( xform ) ; } plib-1.8.5/src/ssg/ssgRangeSelector.cxx0000644000175000001440000001026110765364437014770 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgRangeSelector.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgRangeSelector::copy_from ( ssgRangeSelector *src, int clone_flags ) { ssgSelector::copy_from ( src, clone_flags ) ; additive = src -> isAdditive () ; for ( unsigned int i = 0 ; i < 33 ; i++ ) rng_list [ i ] = src -> getRange ( i ) ; } ssgBase *ssgRangeSelector::clone ( int clone_flags ) { ssgRangeSelector *b = new ssgRangeSelector ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgRangeSelector::ssgRangeSelector (void) { type = ssgTypeRangeSelector () ; additive = FALSE ; rng_list[0] = 0.0f ; for ( int i = 1 ; i < 33 ; i++ ) rng_list[i] = SG_MAX ; } ssgRangeSelector::~ssgRangeSelector (void) { } void ssgRangeSelector::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) ) return ; int cull_result = cull_test ( f, m, test_needed ) ; if ( cull_result == SSG_OUTSIDE ) return ; float range = sgLengthVec3 ( m [ 3 ] ) ; if ( range < rng_list [ 0 ] ) /* Too close */ { select ( 0 ) ; return ; } unsigned int sel = 0 ; for ( int i = 1 ; i < 33 ; i++ ) { ssgEntity *e = getKid ( i-1 ) ; if ( e == NULL || rng_list [ i ] == SG_MAX ) { select ( 0 ) ; return ; } if ( e != NULL && range < rng_list [ i ] ) { e -> cull ( f, m, cull_result != SSG_INSIDE ) ; sel |= 1 << (i-1) ; if ( ! additive ) { selectStep ( i-1 ) ; return ; } } } select ( sel ) ; postTravTests ( SSGTRAV_CULL ) ; } void ssgRangeSelector::hot ( sgVec3 sp, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) ) return ; if ( additive ) ssgBranch::hot ( sp, m, test_needed ) ; else { /* No point in testing this node since it only has one child */ _ssgPushPath ( this ) ; ssgEntity *e = getKid ( 0 ) ; if ( e != NULL ) e -> hot ( sp, m, test_needed ) ; _ssgPopPath () ; } postTravTests ( SSGTRAV_HOT ) ; } void ssgRangeSelector::los ( sgVec3 sp, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) ) return ; if ( additive ) ssgBranch::los ( sp, m, test_needed ) ; else { /* No point in testing this node since it only has one child */ _ssgPushPath ( this ) ; ssgEntity *e = getKid ( 0 ) ; if ( e != NULL ) e -> los ( sp, m, test_needed ) ; _ssgPopPath () ; } postTravTests ( SSGTRAV_LOS ) ; } void ssgRangeSelector::isect ( sgSphere *sp, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) ) return ; if ( additive ) ssgBranch::isect ( sp, m, test_needed ) ; else { /* No point in testing this node since it only has one child */ _ssgPushPath ( this ) ; ssgEntity *e = getKid ( 0 ) ; if ( e != NULL ) e -> isect ( sp, m, test_needed ) ; _ssgPopPath () ; } postTravTests ( SSGTRAV_ISECT ) ; } int ssgRangeSelector::load ( FILE *fd ) { _ssgReadInt ( fd, & additive ) ; _ssgReadFloat ( fd, 33, rng_list ) ; return ssgSelector::load(fd) ; } int ssgRangeSelector::save ( FILE *fd ) { _ssgWriteInt ( fd, additive ) ; _ssgWriteFloat ( fd, 33, rng_list ) ; return ssgSelector::save(fd) ; } plib-1.8.5/src/ssg/ssgLoadTGA.cxx0000644000175000001440000002447310765364437013460 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadTGA.cxx 1749 2003-01-30 00:51:59Z stromberg $ */ #include "ssgLocal.h" #ifdef SSG_LOAD_TGA_SUPPORTED //#include /* * Submitted by Sam Stickland : sam@spacething.org * Targe loading code based on code written Dave Gay : f00Dave@bigfoot.com, http://personal.nbnet.nb.ca/daveg/ * * Jan 29, 2003: * Added support for other image types, as well as run-length encoding. * /marten (stromberg@users.sf.net) */ inline int get16u(const GLubyte *ptr) // little endian { return (ptr[0] | (ptr[1] << 8)); } bool ssgLoadTGA ( const char *fname, ssgTextureInfo* info ) { #if 1 // new loader: /* TGA file layout: * * ============================= * Header: * Ofs Sz Desc * ---------------- * 0 1 Image ID Length * 1 1 Colormap Type * 2 1 Image Type * 3 2 Colormap Origin * 5 2 Colormap Length * 7 1 Colormap Entry Size * 8 2 X Origin of Image * 10 2 Y Origin of Image * 12 2 Image Width * 14 2 Image Height * 16 1 Image Pixel Size * 17 1 Image Descriptor * ============================= * Image Identification * ============================= * Colormap Data * ============================= * Image Data * ============================= */ GLubyte header[18]; FILE *f = fopen(fname, "rb"); if ( f == NULL ) { ulSetError( UL_WARNING, "ssgLoadTGA: Failed to open '%s' for reading.", fname ); return false; } if ( fread(header, 18, 1, f) != 1 ) { ulSetError( UL_WARNING, "ssgLoadTGA: Failed to read header of '%s'.", fname ); fclose(f); return false; } // colormap info int cm_type = header[1]; int cm_first = get16u(header + 3); int cm_count = get16u(header + 5); int cm_bits = header[7]; // image info int type = header[2]; int xsize = get16u(header + 12); int ysize = get16u(header + 14); int bits = header[16]; /* image types: * * 0 - no image * 1 - colormap * 2 - RGB * 3 - grayscale * 9 - colormap, RLE * 10 - RGB, RLE * 11 - grayscale, RLE * */ if ( cm_type > 1 || (type & ~(8+3)) != 0 || (type & 3) == 0 || ((type & 3) == 1 && cm_type == 0) ) { ulSetError( UL_WARNING, "ssgLoadTGA: '%s' is not a TGA image.", fname ); fclose(f); return false; } if ( (type & 3) == 1 && cm_bits != 8 && cm_bits != 16 && cm_bits != 24 && cm_bits != 32 ) { ulSetError( UL_WARNING, "ssgLoadTGA: Unsupported colormap depth %d.", cm_bits ); fclose(f); return false; } if ( ((type & 3) != 2 && bits != 8) || // colormap and grayscale must be 8-bit ((type & 3) == 2 && bits != 16 && bits != 24 && bits != 32) ) // RGB may not be 8-bit { ulSetError( UL_WARNING, "ssgLoadTGA: Unsupported depth %d for image type %d.", bits, type ); fclose(f); return false; } ulSetError( UL_DEBUG, "ssgLoadTGA: Loading '%s', %s %dx%d-%d%s.", fname, (type & 3) == 1 ? "colormap" : (type & 3) == 2 ? "RGB" : "grayscale", xsize, ysize, bits, (type & 8) != 0 ? " RLE" : ""); bool eof = false; // skip image identification if (fseek(f, header[0], SEEK_CUR) != 0) eof = true; // read colormap GLubyte *cm_data = 0; if (cm_type != 0) { cm_data = new GLubyte [ (cm_bits / 8) * cm_count ]; if (fread(cm_data, (cm_bits / 8) * cm_count, 1, f) != 1) eof = true; } // read image data GLubyte *image = new GLubyte [ (bits / 8) * xsize * ysize ]; if ((type & 8) != 0) { // unpack RLE data int comp = (bits / 8); int current = 0; for (;;) { int code = getc(f); if (code == EOF) { eof = true; break; } int length = (code & 0x7f) + 1; if (current + length > xsize * ysize) { ulSetError( UL_WARNING, "ssgLoadTGA: RLE unpack problems." ); fclose(f); delete [] cm_data; delete [] image; return false; } if ((code & 0x80) == 0) { // raw packet if (fread(image + current * comp, length * comp, 1, f) != 1) { eof = true; break; } current += length; } else { // run-length packet GLubyte data[4]; if (fread(data, comp, 1, f) != 1) { eof = true; break; } for (int i = 0; i < length; i++) memcpy(image + (current++) * comp, data, comp); } if (current == xsize * ysize) break; } } else { if (fread(image, (bits / 8) * xsize * ysize, 1, f) != 1) eof = true; } if (eof || ferror(f)) { ulSetError( UL_WARNING, "ssgLoadTGA: %s.", ferror(f) ? "Read error" : "Unexpected end of file" ); fclose(f); delete [] cm_data; delete [] image; return false; } fclose(f); // apply colormap if ((type & 3) == 1) { int comp = (cm_bits / 8); GLubyte *source = image; GLubyte *target = new GLubyte [ comp * xsize * ysize ]; for (int i = 0; i < xsize * ysize; i++) { int index = source[i] - cm_first; if (index < 0 || index > cm_count) memset(target + i * comp, 0, comp); else memcpy(target + i * comp, cm_data + index * comp, comp); } delete [] source; image = target; bits = cm_bits; } delete [] cm_data; // convert image to plain GL_LUMINANCE, GL_RGB or GL_RGBA int zsize = (bits == 8) ? 1 : (bits == 24) ? 3 : 4; GLubyte *pixels = new GLubyte [ xsize * ysize * zsize ]; for (int i = 0; i < xsize * ysize; i++) { switch (bits) { case 8: pixels[i] = image[i]; break; case 16: { int temp = get16u(image + 2*i); // ARRR RRGG GGGB BBBB pixels[4*i + 0] = (temp & 0x7c00) >> 7; pixels[4*i + 1] = (temp & 0x03e0) >> 2; pixels[4*i + 2] = (temp & 0x001f) << 3; pixels[4*i + 3] = (temp & 0x8000) ? 255 : 0; break; } case 24: pixels[3*i + 0] = image[3*i + 2]; pixels[3*i + 1] = image[3*i + 1]; pixels[3*i + 2] = image[3*i + 0]; break; case 32: pixels[4*i + 0] = image[4*i + 2]; pixels[4*i + 1] = image[4*i + 1]; pixels[4*i + 2] = image[4*i + 0]; pixels[4*i + 3] = image[4*i + 3]; break; } } delete [] image; #if 0 if (zsize == 3) { printf("writing 'out.ppm'...\n"); FILE *f = fopen("out.ppm", "wb"); fprintf(f, "P6\n%d %d\n255\n", xsize, ysize); fwrite(pixels, 3 * xsize * ysize, 1, f); fclose(f); } #endif if ( info != NULL ) { info -> width = xsize; info -> height = ysize; info -> depth = zsize; info -> alpha = (zsize == 4); } return ssgMakeMipMaps ( pixels, xsize, ysize, zsize ); #else // old loader: #define DEF_targaHeaderLength 12 #define DEF_targaHeaderContent "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" struct stat fileinfo; int bytesRead, width, height, maxLen; char *pData = NULL; if ( stat(fname, &fileinfo) == -1 ) { ulSetError ( UL_WARNING, "ssgLoadTexture: Failed to load '%s'.", fname); return false ; } FILE *tfile; if( (tfile = fopen(fname, "rb")) == NULL) { ulSetError ( UL_WARNING, "ssgLoadTexture: Failed to load '%s'.", fname); return false ; } maxLen = fileinfo.st_size; pData = new char [maxLen]; fread (pData, maxLen, 1, tfile); fclose (tfile); pData[0] = 0x00; if( memcmp( pData, DEF_targaHeaderContent, DEF_targaHeaderLength ) != 0 ) { ulSetError ( UL_WARNING, "ssgLoadTexture: Failed to load '%s'. Not a targa (apparently).", fname); delete[] pData; return false ; } unsigned char smallArray[ 2 ]; memcpy( smallArray, pData + DEF_targaHeaderLength + 0, 2 ); width = smallArray[ 0 ] + smallArray[ 1 ] * 0x0100; memcpy( smallArray, pData + DEF_targaHeaderLength + 2, 2 ); height = smallArray[ 0 ] + smallArray[ 1 ] * 0x0100; memcpy( smallArray, pData + DEF_targaHeaderLength + 4, 2 ); int depth = smallArray[ 0 ]; // + smallArray[ 1 ] * 0x0100; if( ( width <= 0 ) || ( height <= 0 ) ) { ulSetError ( UL_WARNING, "ssgLoadTexture: Failed to load '%s'. Width and height < 0.", fname); delete[] pData; return false ; } // Only allow 24-bit and 32-bit! bool is24Bit( depth == 24 ); bool is32Bit( depth == 32 ); if( !( is24Bit || is32Bit ) ) { ulSetError ( UL_WARNING, "ssgLoadTexture: Failed to load '%s'. Not 24 or 32 bit.", fname); delete[] pData; return false ; } // Make it a BGRA array for now. int bodySize( width * height * 4 ); unsigned char * texels = new unsigned char[ bodySize ]; if( is32Bit ) { // Texture is 32 bit // Easy, just copy it. memcpy( texels, pData + DEF_targaHeaderLength + 6, bodySize ); } else if( is24Bit ) { // Texture is 24 bit bytesRead = DEF_targaHeaderLength + 6; for( int loop = 0; loop < bodySize; loop += 4, bytesRead += 3 ) { memcpy( texels + loop, pData + bytesRead, 3 ); texels[ loop + 3 ] = 255; // Force alpha to max. } } // Swap R & B (convert to RGBA). for( int loop = 0; loop < bodySize; loop += 4 ) { unsigned char tempC = texels[ loop + 0 ]; texels[ loop + 0 ] = texels[ loop + 2 ]; texels[ loop + 2 ] = tempC; } delete[] pData; if ( info != NULL ) { info -> width = width ; info -> height = height ; info -> depth = 4 ; info -> alpha = is32Bit? 1: 0 ; } return ssgMakeMipMaps ( texels, width, height, 4) ; #endif } #else bool ssgLoadTGA ( const char *fname, ssgTextureInfo* info ) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - TGA support not configured", fname ) ; return false ; } #endif plib-1.8.5/src/ssg/ssgLoadMD2.cxx0000644000175000001440000002334410765364437013423 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadMD2.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ /*************************************************************************** ssgloadmd2.cpp - description ------------------- begin : Thu Sep 7 2000 copyright : (C) 2000 by Jon Anderson email : janderson@onelink.com ***************************************************************************/ /******************************************************* ** This was written to be a part of Stephen J Bakers ** PLIB (http://plib.sourceforge.net) *******************************************************/ #include "ssgLocal.h" //defaults #define FRAME_DELAY 3 #define NUM_SEQUENCES 22 /** MD2 file loader for SSG. ssgLoadMD2 loads a given MD2 file into an ssgSelector hiearchy. Each animation sequence is loaded into a ssgTimedSelector. Each sequence is then put into a top level ssgSelector. In addition, all the skins are loaded into a ssgStateSelector that is attached to each frame's ssgVtxTable. Animation sequences can then be played by: ssgSelector::selectStep ( SSG_MD2_STAND ); ssgTimedSelector *ts = (ssgTimedSelector *)s -> getKid ( i ); ts -> setMode ( SSG_ANIM_SHUTTLE ); ts -> control ( SSG_ANIM_START ); Notes: -Not all md2 files will contain the complete animation sequences. -Not all md2 files contain skin info/locations. -By default, it displays each animation frame for 3 screen frames. MD2 animations were designed to be played at ~ 10hz MD2 File format documentaion: http://www.ugrad.cs.jhu.edu/~dansch/md2 MD2 Frames documentation: http://www.planetquake.com/polycount/resources/quake2/q2frameslist.shtml MD2 Models: http://www.planetquake.com/polycount/ */ /* int seq_sizes[][2] = { { SSG_MD2_STAND, 40 }, { SSG_Md2_RUN, 6 }, { SSG_MD2_ATTACK, 8 }, { SSG_MD2_PAIN_1, 4 }, { SSG_MD2_PAIN_2, 4 }, { SSG_MD2_PAIN_3, 4 }, { SSG_MD2_JUMP, 6 }, { SSG_MD2_FLIPOFF,12 }, { SSG_MD2_SALUTE, 11 }, { SSG_MD2_TAUNT, 17 }, { SSG_MD2_WAVE, 11 }, { SSG_MD2_POINT, 12 }, { SSG_MD2_CROUCH_STAND, 19 }, { SSG_MD2_CROUCH_WALK, 9 }, { SSG_MD2_CROUCH_ATTACK, 9 }, { SSG_MD2_CROUCH_PAIN, 4 }, { SSG_MD2_CROUCH_DEATH, 5 }, { SSG_MD2_DEATH_1, 6 }, { SSG_MD2_DEATH_2, 6 }, { SSG_MD2_DEATH_3, 6 }, { SSG_MD2_ALL, 1 }, { SSG_MD2_POSE, 1 } }; */ static int seq_frames[] = { 40, 6, 8, 4, 4, 4, 6, 12, 11, 17, 11, 12, 19, 9, 9, 4, 5, 6, 6, 6, 1, //this may or may not be in the file. 1 //this may or may not be in the file. }; typedef struct { int magic; int version; int skinWidth; int skinHeight; int frameSize; int numSkins; int numVertices; int numTexCoords; int numTriangles; int numGlCommands; int numFrames; int offsetSkins; int offsetTexCoords; int offsetTriangles; int offsetFrames; int offsetGlCommands; int offsetEnd; } t_model; typedef struct { unsigned char vertex[3]; unsigned char lightNormalIndex; } t_vertex; typedef struct { short vertexIndices[3]; short textureIndices[3]; } t_triangle; typedef struct { short s, t; } t_tcoord; typedef struct { float s, t; int vertexIndex; } t_glCommandVertex; typedef struct { float scale[3]; float translate[3]; char name[16]; } t_frame; static int is_little_endian; static ssgLoaderOptions* current_options = NULL ; static FILE *loader_fd; static t_tcoord *uvs; static t_frame *frames; static t_vertex **vertices; static t_triangle *triangles; static char skins[32][1024]; static t_model header; static void read_header() { fread(&header, sizeof(t_model), 1, loader_fd); } static void read_frames(int offset) { fseek(loader_fd, offset, SEEK_SET); frames = new t_frame[header.numFrames]; vertices = new t_vertex* [header.numFrames]; for(int i=0; i enable ( GL_TEXTURE_2D ); //state -> setTexture( filepath ) ; state -> setTexture( current_options -> createTexture ( skins[i] ) ); states -> setStep ( i, state ); } /**Activate the first state*/ if(stated) states -> selectStep( 0 ); else { ulSetError(UL_WARNING, "ssgLoadMD2: No skins specified in MD2 file!"); ssgSimpleState *state = new ssgSimpleState(); state -> disable ( GL_TEXTURE_2D ); states -> setStep(0, state); states -> selectStep( 0 ); } ssgSelector *sequences; if(header.numFrames == 200) sequences = new ssgSelector(NUM_SEQUENCES); else sequences = new ssgSelector(NUM_SEQUENCES - 2); int current_sequence_num = 0; int current_sequence_frame = 0; ssgTimedSelector *current_sequence = new ssgTimedSelector(seq_frames[current_sequence_num]); sequences->addKid(current_sequence); for(i=0; i-1; k--){ int vert_index = triangles[j].vertexIndices[k]; int bx = vertices[i][vert_index].vertex[0]; int by = vertices[i][vert_index].vertex[1]; int bz = vertices[i][vert_index].vertex[2]; vert[0] = ((float)bx)*frames[i].scale[0] + frames[i].translate[0]; vert[1] = ((float)by)*frames[i].scale[1] + frames[i].translate[1]; vert[2] = ((float)bz)*frames[i].scale[2] + frames[i].translate[2]; uv[0] = ((float)uvs[triangles[j].textureIndices[k]].s)/header.skinWidth; uv[1] = 1 - ((float)uvs[triangles[j].textureIndices[k]].t)/header.skinHeight; vlist -> add( vert ); tlist -> add( uv ); } } ssgVtxTable *vtab = new ssgVtxTable ( GL_TRIANGLES, vlist, 0, tlist, 0 ) ; vtab -> setState(states); current_sequence ->addKid(vtab); current_sequence_frame++; if( current_sequence_frame > seq_frames[current_sequence_num] -1){ current_sequence -> setLimits( 0, seq_frames[current_sequence_num]-1 ); current_sequence -> setDuration( FRAME_DELAY ); current_sequence -> setMode ( SSG_ANIM_ONESHOT ); current_sequence_num ++; current_sequence_frame = 0; current_sequence = new ssgTimedSelector(seq_frames[current_sequence_num]); sequences -> addKid( current_sequence ); } } sequences -> selectStep( 0 ); return sequences; } ssgEntity * ssgLoadMD2( const char *filename, const ssgLoaderOptions* options) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; int j = 1 ; is_little_endian = *((char *) &j ); char filepath [ 1024 ] ; current_options -> makeModelPath ( filepath, filename ) ; loader_fd = fopen ( filepath, "rb" ); if ( loader_fd == NULL ) { ulSetError ( UL_WARNING, "ssgLoadMD2: Failed to open '%s' for reading", filepath ) ; return NULL ; } read_header(); read_skins(header.offsetSkins); read_uvcoords(header.offsetTexCoords); read_triangles(header.offsetTriangles); read_frames(header.offsetFrames); read_glcommands(header.offsetGlCommands); ssgEntity * model = convert_to_ssg(); //clean up the memory used by the MD2 structure; delete[] uvs; delete[] frames; delete[] triangles; for(int i=0; ideadBeefCheck() ; sizeChk () ; entity_list [ total++ ] = entity ; } void ssgKidList::addEntity ( ssgEntity *entity ) { entity->deadBeefCheck() ; entity -> ref () ; ssgList::addEntity ( entity ) ; } void ssgList::sizeChk (void) { /* Room for one more Entity? */ if ( total >= limit ) { limit += limit ; ssgEntity **nlist = new ssgEntity * [ limit ] ; memmove ( nlist, entity_list, sizeof(ssgEntity *) * total ) ; delete [] entity_list ; entity_list = nlist ; } } int ssgList::searchForEntity ( ssgEntity *entity ) { for ( unsigned int i = 0 ; i < total ; i++ ) if ( entity_list [ i ] == entity ) return (int) i ; return -1 ; } void ssgList::removeAllEntities () { while ( total > 0 ) removeEntity ( (unsigned int) total-1 ) ; } void ssgList::removeEntity ( unsigned int n ) { memmove ( &(entity_list[n]), &(entity_list[n+1]), sizeof(ssgEntity *) * (total-n-1) ) ; total-- ; if ( next >= n ) next-- ; } void ssgKidList::removeEntity ( unsigned int n ) { entity_list[n]->deadBeefCheck(); ssgEntity *e = entity_list [ n ] ; ssgList::removeEntity ( n ) ; e -> deadBeefCheck () ; // wk 20.4.2002 problems with mywalk... when merging hiearchy nodes: ssgDeRefDelete ( e ) ; } void ssgList::replaceEntity ( unsigned int n, ssgEntity *new_entity ) { new_entity -> deadBeefCheck () ; entity_list [ n ] -> deadBeefCheck () ; entity_list [ n ] = new_entity; } void ssgKidList::replaceEntity ( unsigned int n, ssgEntity *new_entity ) { ssgEntity *old_entity = entity_list [ n ] ; new_entity -> ref () ; ssgList::replaceEntity ( n, new_entity ) ; ssgDeRefDelete ( old_entity ) ; } plib-1.8.5/src/ssg/ssgTween.cxx0000644000175000001440000003140510765364437013320 00000000000000 /* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgTween.cxx 1996 2004-12-29 07:19:40Z sjbaker $ */ #include "ssgLocal.h" #include "ul.h" static float current_tween_state = 0.0f ; static int current_tween_mode = SSGTWEEN_STOP_AT_END ; const char *ssgTween::getTypeName (void) { return "ssgTween" ; } int _ssgGetCurrentTweenMode () { return current_tween_mode ; } float _ssgGetCurrentTweenState () { return current_tween_state ; } void _ssgSetCurrentTweenSettings ( float state, int mode ) { _ssgSetRealCurrentTweenSettings ( state, mode ) ; _ssgSetTweenState ( state, mode ) ; /* Add it into the Dlist for later */ } void _ssgSetRealCurrentTweenSettings ( float state, int mode ) { current_tween_mode = mode ; current_tween_state = state ; } void ssgTween::copy_from ( ssgTween *src, int clone_flags ) { ssgLeaf::copy_from ( src, clone_flags ) ; gltype = src -> getPrimitiveType () ; if ( src->vertices != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) vertices = (ssgVertexArray *)( src -> vertices -> clone ( clone_flags )) ; else vertices = src -> vertices ; if ( src->normals != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) normals = (ssgNormalArray *)( src -> normals -> clone ( clone_flags )) ; else normals = src -> normals ; if ( src->texcoords != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) texcoords = (ssgTexCoordArray *)( src -> texcoords -> clone ( clone_flags )) ; else texcoords = src -> texcoords ; if ( src->colours != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) colours = (ssgColourArray *)( src -> colours -> clone ( clone_flags )) ; else colours = src -> colours ; if ( vertices != NULL ) vertices -> ref () ; if ( normals != NULL ) normals -> ref () ; if ( texcoords != NULL ) texcoords -> ref () ; if ( colours != NULL ) colours -> ref () ; recalcBSphere () ; } ssgBase *ssgTween::clone ( int clone_flags ) { ssgTween *b = new ssgTween ; b -> copy_from ( this, clone_flags ) ; return b ; } void ssgTween::init () { curr_bank = 0 ; type = ssgTypeTween () ; render_vertices = new ssgVertexArray () ; render_normals = new ssgNormalArray () ; render_texcoords = new ssgTexCoordArray () ; render_colours = new ssgColourArray () ; render_vertices -> ref () ; render_normals -> ref () ; render_texcoords -> ref () ; render_colours -> ref () ; banked_vertices = new ulList ( 2 ) ; banked_normals = new ulList ( 2 ) ; banked_texcoords = new ulList ( 2 ) ; banked_colours = new ulList ( 2 ) ; vertices = render_vertices ; normals = render_normals ; texcoords = render_texcoords ; colours = render_colours ; recalcBSphere () ; } ssgTween::ssgTween () { init () ; gltype = GL_POINTS ; } ssgTween::ssgTween ( GLenum ty ) { init () ; gltype = ty ; } int ssgTween::newBank ( ssgVertexArray *vl, ssgNormalArray *nl, ssgTexCoordArray *tl, ssgColourArray *cl ) { int bank = banked_vertices -> getNumEntities () ; banked_vertices -> addEntity ( vl != NULL ? vl : ( banked_vertices -> getEntity(bank-1) ) ) ; banked_normals -> addEntity ( nl != NULL ? nl : ( banked_normals -> getEntity(bank-1) ) ) ; banked_texcoords -> addEntity ( tl != NULL ? tl : ( banked_texcoords -> getEntity(bank-1) ) ) ; banked_colours -> addEntity ( cl != NULL ? cl : ( banked_colours -> getEntity(bank-1) ) ) ; setBank ( bank ) ; vertices -> ref () ; normals -> ref () ; texcoords -> ref () ; colours -> ref () ; dirtyBSphere () ; /* Cause parents to redo their bspheres */ return bank ; } int ssgTween::newBank ( int newVertices , int newNormals, int newTexCoords, int newColours ) { return newBank ( newVertices ? ( new ssgVertexArray () ) : NULL, newNormals ? ( new ssgNormalArray () ) : NULL, newTexCoords ? ( new ssgTexCoordArray () ) : NULL, newColours ? ( new ssgColourArray () ) : NULL ) ; } void ssgTween::setBank ( int bank ) { assert ( bank < banked_vertices -> getNumEntities () ) ; curr_bank = bank ; vertices = (ssgVertexArray *) banked_vertices -> getEntity ( bank ) ; normals = (ssgNormalArray *) banked_normals -> getEntity ( bank ) ; texcoords = (ssgTexCoordArray *) banked_texcoords -> getEntity ( bank ) ; colours = (ssgColourArray *) banked_colours -> getEntity ( bank ) ; } void ssgTween::setVertices ( ssgVertexArray *vl ) { banked_vertices -> replaceEntity ( curr_bank, vl ) ; ssgVtxTable::setVertices ( vl ) ; dirtyBSphere () ; /* Cause parents to redo their bspheres */ } void ssgTween::setNormals ( ssgNormalArray *nl ) { banked_normals -> replaceEntity ( curr_bank, nl ) ; ssgVtxTable::setNormals ( nl ) ; dirtyBSphere () ; /* Cause parents to redo their bspheres */ } void ssgTween::setTexCoords ( ssgTexCoordArray *tl ) { banked_texcoords -> replaceEntity ( curr_bank, tl ) ; ssgVtxTable::setTexCoords ( tl ) ; dirtyBSphere () ; /* Cause parents to redo their bspheres */ } void ssgTween::setColours ( ssgColourArray *cl ) { banked_colours -> replaceEntity ( curr_bank, cl ) ; ssgVtxTable::setColours ( cl ) ; dirtyBSphere () ; /* Cause parents to redo their bspheres */ } ssgTween::~ssgTween () { /* Need to ref these one more time to avoid problems when the base class destructor deletes them */ vertices -> ref () ; normals -> ref () ; texcoords -> ref () ; colours -> ref () ; for ( int i = 0 ; i < getNumBanks () ; i++ ) { ssgDeRefDelete ( (ssgVertexArray *) banked_vertices -> getEntity (i)) ; ssgDeRefDelete ( (ssgNormalArray *) banked_normals -> getEntity (i)) ; ssgDeRefDelete ( (ssgTexCoordArray *) banked_texcoords -> getEntity (i)) ; ssgDeRefDelete ( (ssgColourArray *) banked_colours -> getEntity (i)) ; } delete banked_vertices ; delete banked_normals ; delete banked_texcoords ; delete banked_colours ; ssgDeRefDelete ( render_vertices ) ; ssgDeRefDelete ( render_normals ) ; ssgDeRefDelete ( render_texcoords ) ; ssgDeRefDelete ( render_colours ) ; } void ssgTween::recalcBSphere () { emptyBSphere () ; bbox . empty () ; for ( int b = 0 ; b < banked_vertices -> getNumEntities () ; b++ ) { ssgVertexArray *va = (ssgVertexArray *) banked_vertices -> getEntity ( b ) ; for ( int i = 0 ; i < va -> getNum() ; i++ ) bbox . extend ( va->get(i) ) ; } extendBSphere ( & bbox ) ; dirtyBSphere () ; /* Cause parents to redo their bspheres */ } void ssgTween::draw () { if ( ! preDraw () ) return ; if ( _ssgCurrentContext-> stateOverridden () ) _ssgCurrentContext -> overriddenState () -> apply () ; else if ( hasState () ) getState () -> apply () ; stats_num_leaves++ ; stats_num_vertices += getNumVertices() ; float tstate = _ssgGetCurrentTweenState () ; int num_banks = banked_vertices -> getNumEntities () ; if ( tstate < 0.0f ) tstate = 0.0f ; int state1 = (int) floor ( tstate ) ; int state2 = state1 + 1 ; float tween = tstate - (float) state1 ; if ( _ssgGetCurrentTweenMode () == SSGTWEEN_REPEAT ) { state1 %= num_banks ; state2 %= num_banks ; } else { if ( state1 >= num_banks ) state1 = num_banks - 1 ; if ( state2 >= num_banks ) state2 = num_banks - 1 ; } if ( state1 == state2 ) tween = 0.0f ; int l1, l2 ; /* Lerp the vertices... */ ssgVertexArray *v1 = (ssgVertexArray *) banked_vertices->getEntity (state1) ; ssgVertexArray *v2 = (ssgVertexArray *) banked_vertices->getEntity (state2) ; l1 = v1 -> getNum () ; l2 = v2 -> getNum () ; assert ( l1 == l2 ) ; if ( render_vertices -> getNum () < l1 ) render_vertices -> setNum ( l1 ) ; if ( v1 == v2 ) vertices = v1 ; else { vertices = render_vertices ; for ( int i = 0 ; i < l1 ; i++ ) sgLerpVec3 ( vertices->get(i),v1->get(i),v2->get(i), tween ) ; } /* Lerp the normals */ ssgNormalArray *n1 = (ssgNormalArray *) banked_normals->getEntity (state1) ; ssgNormalArray *n2 = (ssgNormalArray *) banked_normals->getEntity (state2) ; l1 = n1 -> getNum () ; l2 = n2 -> getNum () ; assert ( l1 == l2 ) ; if ( render_normals -> getNum () < l1 ) render_normals -> setNum ( l1 ) ; if ( n1 == n2 ) normals = n1 ; else { normals = render_normals ; for ( int i = 0 ; i < l1 ; i++ ) sgLerpVec3 ( normals->get(i),n1->get(i),n2->get(i), tween ) ; } /* Lerp the texcoords */ ssgTexCoordArray *t1 = (ssgTexCoordArray *) banked_texcoords->getEntity (state1) ; ssgTexCoordArray *t2 = (ssgTexCoordArray *) banked_texcoords->getEntity (state2) ; l1 = t1 -> getNum () ; l2 = t2 -> getNum () ; assert ( l1 == l2 ) ; if ( render_texcoords -> getNum () < l1 ) render_texcoords -> setNum ( l1 ) ; if ( t1 == t2 ) texcoords = t1 ; else { texcoords = render_texcoords ; for ( int i = 0 ; i < l1 ; i++ ) sgLerpVec2 ( texcoords->get(i),t1->get(i),t2->get(i), tween ) ; } /* Lerp the colours */ ssgColourArray *c1 = (ssgColourArray *) banked_colours->getEntity (state1) ; ssgColourArray *c2 = (ssgColourArray *) banked_colours->getEntity (state2) ; l1 = c1 -> getNum () ; l2 = c2 -> getNum () ; assert ( l1 == l2 ) ; if ( render_colours -> getNum () < l1 ) render_colours -> setNum ( l1 ) ; if ( c1 == c2 ) colours = c1 ; else { colours = render_colours ; for ( int i = 0 ; i < l1 ; i++ ) sgLerpVec4 ( colours->get(i),c1->get(i),c2->get(i), tween ) ; } draw_geometry () ; setBank ( state1 ) ; if ( postDrawCB != NULL ) (*postDrawCB)(this) ; } void ssgTween::transform ( const sgMat4 m ) { int prev_bank = curr_bank ; for ( int i = 0 ; i < getNumBanks(); i++ ) { // see if this bank has been transformed already // (it is really a deeper problem, but this will work in simple cases) int j ; for ( j = 0 ; j < i ; j++ ) if ( banked_vertices -> getEntity ( i ) == banked_vertices -> getEntity ( j ) ) break; if ( j == i ) { setBank ( i ) ; ssgVtxTable::transform ( m ) ; } } setBank ( prev_bank ) ; } int ssgTween::load ( FILE *fd ) { sgVec3 temp; int num_banks ; _ssgReadVec3 ( fd, temp ); bbox.setMin( temp ) ; _ssgReadVec3 ( fd, temp ); bbox.setMax( temp ) ; _ssgReadInt ( fd, (int *)(&gltype) ) ; _ssgReadInt ( fd, & num_banks ) ; if ( ! ssgLeaf::load(fd) ) return FALSE ; for ( int i = 0 ; i < num_banks ; i++ ) { if ( ! _ssgLoadObject (fd,(ssgBase **)&vertices, ssgTypeVertexArray() ) || ! _ssgLoadObject (fd,(ssgBase **)&normals, ssgTypeNormalArray() ) || ! _ssgLoadObject (fd,(ssgBase **)&texcoords, ssgTypeTexCoordArray()) || ! _ssgLoadObject (fd,(ssgBase **)&colours, ssgTypeColourArray() ) ) return FALSE ; newBank ( vertices, normals, texcoords, colours ) ; } return TRUE ; } int ssgTween::save ( FILE *fd ) { int num_banks = banked_vertices -> getNumEntities () ; _ssgWriteVec3 ( fd, bbox.getMin() ) ; _ssgWriteVec3 ( fd, bbox.getMax() ) ; _ssgWriteInt ( fd, (int) gltype ) ; _ssgWriteInt ( fd, num_banks ) ; if ( ! ssgLeaf::save(fd) ) return FALSE ; for ( int i = 0 ; i < num_banks ; i++ ) { setBank ( i ) ; if ( ! _ssgSaveObject ( fd, vertices ) || ! _ssgSaveObject ( fd, normals ) || ! _ssgSaveObject ( fd, texcoords ) || ! _ssgSaveObject ( fd, colours ) ) return FALSE ; } return TRUE ; } void ssgTween::print ( FILE *fd, char *indent, int how_much ) { char in [ 100 ] ; if ( how_much == 0 ) return ; sprintf ( in, "%s ", indent ); ssgLeaf ::print ( fd, indent, how_much ) ; vertices -> print ( fd, in, how_much ) ; normals -> print ( fd, in, how_much ) ; texcoords -> print ( fd, in, how_much ) ; colours -> print ( fd, in, how_much ) ; } plib-1.8.5/src/ssg/ssgLoadXPlaneObj.cxx0000644000175000001440000002437710765364437014672 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadXPlaneObj.cxx 1728 2002-11-09 21:38:28Z sjbaker $ */ /* * XPlane object loader for PLIB. * Written by Bernie Bright , Sept 2002. * * KNOWN ISSUES * * Only version 1 objects are handled. * * The .obj XPlane custom object file extension clashes with Wavefront objects. * For the moment, XPlane objects must be renamed with a .xpl extension. * * Point objects are not handled. */ #include #include #include "ssgLocal.h" /** * XPlane .obj loader. */ class ObjLoader { public: ObjLoader( const ssgLoaderOptions* options ); ~ObjLoader(); ssgEntity* load( const char* fname ); private: ssgState* get_state( const char* tfname ); char* fgets( char* s, int size, FILE* fp ); char* getline( char* line, size_t n, FILE* fp ); char* getTextureName( const char* p, char* tname, size_t n ); const char* file_extension( const char* fname ); private: ssgLoaderOptions* options; ssgBranch* root; }; ObjLoader::ObjLoader( const ssgLoaderOptions* options_ ) : options(0) , root(0) { ssgSetCurrentOptions( const_cast(options_) ); this->options = ssgGetCurrentOptions(); } ObjLoader::~ObjLoader() { } ssgState* ObjLoader::get_state( const char* tfname ) { if (tfname != 0) { ssgState* st = options->createState( const_cast(tfname) ); if (st != 0) return st; } ssgSimpleState* st = new ssgSimpleState; st->setName( tfname ); st->setMaterial( GL_SPECULAR, 0.0f, 0.0f, 0.0f ); st->setMaterial( GL_EMISSION, 0.0f, 0.0f, 0.0f ); st->setMaterial( GL_AMBIENT, 0.0f, 0.0f, 0.0f ); st->setMaterial( GL_DIFFUSE, 0.0f, 0.0f, 0.0f ); st->enable( GL_LIGHTING ); st->setShadeModel( GL_SMOOTH ); bool has_alpha = false; if (tfname != 0) { ssgTexture* tex = options->createTexture( const_cast(tfname) ); has_alpha = tex->hasAlpha(); st->setTexture(tex); st->enable( GL_TEXTURE_2D ); } else { st->disable( GL_TEXTURE_2D ); } if (has_alpha) { st->disable( GL_ALPHA_TEST ); st->enable( GL_BLEND ); st->setTranslucent(); } else { st->disable( GL_ALPHA_TEST ); st->disable( GL_BLEND ); st->setOpaque(); } return st; } /** * XPlane object files have either IBM (\r\n) or Apple (\r) line endings. * Handle both here. */ char* ObjLoader::fgets( char* s, int size, FILE* fp ) { char* p = s; int n = 0; int c = 0; for (--size; n < size; ++n) { c = getc(fp); if (c == EOF) return 0; if (c == '\r') break; *p++ = c; } *p = 0; c = getc(fp); if (c != '\n') ungetc( c, fp ); return s; } /** * Read the next non-blank line. * Returns pointer to first non-whitespace character or NULL on error or EOF. */ char* ObjLoader::getline( char* line, size_t n, FILE* fp ) { for (;;) { char* p = fgets( line, n, fp ); if (p == 0) return 0; // Skip leading whitespace. while (*p != 0 && isspace(*p)) ++p; if (*p != 0) return p; } } /** * */ char* ObjLoader::getTextureName( const char* p, char* buf, size_t bufsize ) { if (p == 0 || buf == 0) return 0; while (*p != 0 && isspace(*p)) ++p; size_t n = 0; char* bp = buf; for ( ; *p != 0 && n < bufsize && !isspace(*p); ++n, ++bp, ++p) { // Replace ':' path separator with '/'. *bp = *p == ':' ? '/' : *p; } if (n < bufsize) *bp = 0; return const_cast(p); } const char* ObjLoader::file_extension( const char *fname ) { const char* p = fname + strlen(fname); while (p != fname && *p != '/' && *p != '.' ) --p; return p; } ssgEntity* ObjLoader::load( const char* fname ) { char mname[1024]; options->makeModelPath( mname, fname ); FILE* fp = fopen( fname, "r" ); if (fp == 0) { ulSetError( UL_WARNING, "ssgLoadXPlaneObj: Failed to open '%s' for reading.", fname ); return 0; } char line[ 1024 ]; // Read obj header. char* p = getline( line, sizeof(line), fp ); if (p == 0) { ulSetError( UL_WARNING, "ssgLoadXPlaneObj: expected header." ); fclose(fp); return 0; } if (*p != 'I' && *p != 'A') { ulSetError( UL_WARNING, "ssgLoadXPlaneObj: invalid header, expected 'I' or 'A'" ); fclose(fp); return 0; } p = getline( line, sizeof(line), fp ); if (p == 0) { ulSetError( UL_WARNING, "ssgLoadXPlaneObj: unexpected EOF while reading header." ); fclose(fp); return 0; } root = new ssgTransform(); root->setName( fname ); if (*p == '2') { // Version 2 obj file. ulSetError( UL_WARNING, "ssgLoadXPlaneObj: Version 2 not yet implemented" ); fclose( fp ); delete root; return 0; // TODO: implement V2. } else { // Version 1 obj file. // Version number is optional. if (*p == '1') { // get TextureDef p = getline( line, sizeof(line), fp ); if (p == 0) { ulSetError( UL_WARNING, "ssgLoadXPlaneObj: unexpected EOF " "while reading data." ); fclose(fp); return 0; } } int type = 0; char* endp; do { type = strtol( p, &endp, 10 ); switch (type) { case 4: { // Get texture filename. // Allow room for extension and terminator. char tname[ 251 + 4 + 1 ]; endp = getTextureName( endp, tname, 251 ); if (endp == 0) { ulSetError( UL_WARNING, "ssgLoadXPlaneObj: Error reading TextureDef" ); delete root; fclose( fp ); return 0; } strcat( tname, ".bmp" ); // TODO: check for comment following texture name. sgVec3* vc = new sgVec3[4]; sgVec2* tc = new sgVec2[4]; sgVec4* cc = new sgVec4[1]; for (int i = 0; i < 4; ++i) { p = getline( line, sizeof(line), fp ); // Read vertices, swapping y and z. sscanf( p, "%f%f%f", &vc[i][0], &vc[i][2], &vc[i][1] ); } sgSetVec2( tc[0], 1.0f, 1.0f ); sgSetVec2( tc[1], 1.0f, 0.0f ); sgSetVec2( tc[2], 0.0f, 0.0f ); sgSetVec2( tc[3], 0.0f, 1.0f ); sgSetVec4( cc[0], 1.0f, 1.0f, 1.0f, 1.0f ); ssgVertexArray* vl = new ssgVertexArray( 4, vc ); ssgTexCoordArray* tl = new ssgTexCoordArray( 4, tc ); ssgNormalArray* nl = new ssgNormalArray(); ssgColourArray* cl = new ssgColourArray( 1, cc ); ssgVtxTable* vtab = new ssgVtxTable( GL_POLYGON, vl, nl, tl, cl ); vtab->setState( get_state( tname ) ); root->addKid( vtab ); } break; case 3: { // Get texture filename. // Allow room for extension and terminator. char tname[ 251 + 4 + 1 ]; endp = getTextureName( endp, tname, 251 ); strcat( tname, ".bmp" ); sgVec3* vc = new sgVec3[3]; sgVec2* tc = new sgVec2[3]; sgVec4* cc = new sgVec4[1]; for (int i = 0; i < 3; ++i) { p = getline( line, sizeof(line), fp ); // Read vertices, swapping y and z. sscanf( p, "%f%f%f", &vc[i][0], &vc[i][2], &vc[i][1] ); } sgSetVec2( tc[0], 1.0f, 1.0f ); sgSetVec2( tc[1], 1.0f, 0.0f ); sgSetVec2( tc[2], 0.0f, 0.0f ); sgSetVec4( cc[0], 1.0f, 1.0f, 1.0f, 1.0f ); ssgVertexArray* vl = new ssgVertexArray( 3, vc ); ssgTexCoordArray* tl = new ssgTexCoordArray( 3, tc ); ssgNormalArray* nl = new ssgNormalArray(); ssgColourArray* cl = new ssgColourArray( 1, cc ); ssgVtxTable* vtab = new ssgVtxTable( GL_POLYGON, vl, nl, tl, cl ); vtab->setState( get_state( tname ) ); root->addKid( vtab ); } break; case 2: { float r, g, b; sscanf( endp, "%f%f%f", &r, &g, &b ); sgVec3* vc = new sgVec3[2]; sgVec4* cc = new sgVec4[1]; for (int i = 0; i < 2; ++i) { p = getline( line, sizeof(line), fp ); // Read vertices, swapping y and z. sscanf( p, "%f%f%f", &vc[i][0], &vc[i][2], &vc[i][1] ); } // Scale rgb values to range 0..1 sgSetVec4( cc[0], r/10.f, g/10.f, b/10.f, 1.0f ); ssgVertexArray* vl = new ssgVertexArray( 2, vc ); ssgTexCoordArray* tl = new ssgTexCoordArray(); ssgNormalArray* nl = new ssgNormalArray(); ssgColourArray* cl = new ssgColourArray( 1, cc ); ssgVtxTable* vtab = new ssgVtxTable( GL_LINES, vl, nl, tl, cl ); ssgSimpleState* st = new ssgSimpleState; st->setMaterial( GL_SPECULAR, 0.0f, 0.0f, 0.0f ); st->setMaterial( GL_EMISSION, 0.0f, 0.0f, 0.0f ); st->setMaterial( GL_AMBIENT, 0.0f, 0.0f, 0.0f ); st->setMaterial( GL_DIFFUSE, 0.0f, 0.0f, 0.0f ); st->enable( GL_LIGHTING ); st->setShadeModel( GL_SMOOTH ); st->disable( GL_TEXTURE_2D ); st->disable( GL_ALPHA_TEST ); st->disable( GL_BLEND ); st->setOpaque(); vtab->setState( st ); root->addKid( vtab ); } break; case 1: { int r, g, b; sscanf( endp, "%d%d%d", &r, &g, &b ); p = getline( line, sizeof(line), fp ); float x, y, z; sscanf( p, "%f%f%f", &x, &z, &y ); // TODO: create appropriate ssgEntity. } break; case 99: break; default: ulSetError( UL_WARNING, "ssgLoadXPlaneObj: invalid line, '%s'", line ); fclose(fp); delete root; return 0; } } while ((p = getline( line, sizeof(line), fp )) != 0 && type != 99); } fclose( fp ); return root; } ssgEntity* ssgLoadXPlaneOBJ( const char* fname, const ssgLoaderOptions* options ) { ObjLoader loader( options ); return loader.load( fname ); } plib-1.8.5/src/ssg/ssgLoadM.cxx0000644000175000001440000001053710765364437013235 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadM.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include #include "ssgLocal.h" static ssgLoaderOptions* current_options; ssgEntity* ssgLoadM( const char* fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; char filename [ 1024 ] ; current_options -> makeModelPath ( filename, fname ) ; FILE* model_file = fopen(filename, "r"); if(!model_file) { ulSetError(UL_WARNING, "ssgLoadM: Couldn't open file '%s'.", filename); return NULL; } ssgVertexArray* vertices = new ssgVertexArray; ssgNormalArray* normals = new ssgNormalArray; ssgIndexArray* indices = new ssgIndexArray; int i, index; char line[256]; sgVec3 zero = {0.0f, 0.0f, 0.0f}; fgets(line, 256, model_file); while ( !feof(model_file) ) { char* token; switch (line[0]) { case '#': // comment, skip this line break; case 'V': sgVec3 vtx; token = strtok(line, " "); // token should now be "Vertex" token = strtok(NULL, " "); // token is vertex index now index = atoi(token) - 1; // fill out non-declared vertices with zero vectors while (index > vertices->getNum()) { vertices->add(zero); normals ->add(zero); } // get vertex coordinate for (i = 0; i < 3; i++) { token = strtok(NULL, " "); vtx[i] = (float) atof(token); } vertices->add(vtx) ; normals ->add(zero); break; case 'F': // face token = strtok(line, " "); // token should now be "Face" token = strtok(NULL, " "); // face index, ignored for (i = 0; i < 3; i++) { token = strtok(NULL, " "); indices->add( atoi(token)-1 ); } break; case 'E': // Edge, ignored break; default: ulSetError(UL_WARNING, "ssgLoadM: Syntax error on line \"%s\".", line); } fgets(line, 256, model_file); } ssgSimpleState* state = new ssgSimpleState(); state->setOpaque(); state->disable(GL_BLEND); state->disable(GL_ALPHA_TEST); state->disable(GL_TEXTURE_2D); state->enable(GL_COLOR_MATERIAL); state->enable(GL_LIGHTING); state->setShadeModel(GL_SMOOTH); state->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.0f, 1.0f); state->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.0f, 1.0f); state->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f); state->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f); state->setShininess(50); // now calculate smooth normals (this code belongs elsewhere) for (i = 0; i < indices->getNum(); i += 3) { short idx0 = *indices->get(i ); short idx1 = *indices->get(i + 1); short idx2 = *indices->get(i + 2); sgVec3 normal; sgMakeNormal( normal, vertices->get(idx0), vertices->get(idx1), vertices->get(idx2) ); sgAddVec3( normals->get(idx0), normal ); sgAddVec3( normals->get(idx1), normal ); sgAddVec3( normals->get(idx2), normal ); } for (i = 0; i < vertices->getNum(); i++) { sgNormaliseVec3( normals->get(i) ); } ssgVtxArray* leaf = new ssgVtxArray( GL_TRIANGLES, vertices, normals, NULL, NULL, indices ); leaf->setCullFace( TRUE ); leaf->setState( state ); ssgLeaf* model = current_options -> createLeaf( leaf, NULL ); return model; } plib-1.8.5/src/ssg/ssgLoadAC.cxx0000644000175000001440000006415410765364437013330 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadAC.cxx 2086 2006-09-30 08:41:21Z bram $ */ #include "ssgLocal.h" #include "ssgVertSplitter.h" static FILE *loader_fd ; struct _ssgMaterial { sgVec4 rgba ; sgVec4 spec ; sgVec4 emis ; sgVec4 amb ; float shi ; } ; static int num_materials = 0 ; static ssgLoaderOptions *current_options = NULL ; static int current_materialind = 0 ; static ssgBranch *current_branch = NULL ; static ssgVertexArray *current_vertexarray = NULL ; static ssgTexCoordArray *current_texcoordarray = NULL ; static ssgIndexArray *current_triindexarray = NULL ; static ssgIndexArray *current_matindexarray = NULL ; static ssgIndexArray *current_flagsarray = NULL ; static char *current_tfname = NULL ; static char *current_data = NULL ; static float current_crease = 61.0 ; #define MAX_MATERIALS 1000 /* This *ought* to be enough! */ static _ssgMaterial *mlist [ MAX_MATERIALS ] ; static sgMat4 current_matrix ; static sgVec2 texrep ; static sgVec2 texoff ; static sgVec2 invalidTexture = { 1e30f, } ; static sgVec3 zero = { 0.0, } ; static int do_material ( char *s ) ; static int do_object ( char *s ) ; static int do_name ( char *s ) ; static int do_data ( char *s ) ; static int do_texture ( char *s ) ; static int do_texrep ( char *s ) ; static int do_texoff ( char *s ) ; static int do_crease ( char *s ) ; static int do_rot ( char *s ) ; static int do_loc ( char *s ) ; static int do_url ( char *s ) ; static int do_numvert ( char *s ) ; static int do_numsurf ( char *s ) ; static int do_surf ( char *s ) ; static int do_mat ( char *s ) ; static int do_refs ( char *s ) ; static int do_kids ( char *s ) ; /*static int do_obj_world ( char *s ) ; static int do_obj_poly ( char *s ) ; static int do_obj_group ( char *s ) ; static int do_obj_light ( char *s ) ;*/ #define PARSE_CONT 0 #define PARSE_POP 1 struct Tag { const char *token ; int (*func) ( char *s ) ; } ; static void skip_spaces ( char **s ) { while ( **s == ' ' || **s == '\t' ) (*s)++ ; } static void skip_quotes ( char **s ) { skip_spaces ( s ) ; if ( **s == '\"' ) { (*s)++ ; char *t = *s ; while ( *t != '\0' && *t != '\"' ) t++ ; if ( *t != '\"' ) ulSetError ( UL_WARNING, "ac_to_gl: Mismatched double-quote ('\"') in '%s'", *s ) ; *t = '\0' ; } else ulSetError ( UL_WARNING, "ac_to_gl: Expected double-quote ('\"') in '%s'", *s ) ; } static int search ( Tag *tags, char *s ) { skip_spaces ( & s ) ; for ( int i = 0 ; tags[i].token != NULL ; i++ ) if ( ulStrNEqual ( tags[i].token, s, strlen(tags[i].token) ) ) { s += strlen ( tags[i].token ) ; skip_spaces ( & s ) ; return (*(tags[i].func))( s ) ; } ulSetError ( UL_FATAL, "ac_to_gl: Unrecognised token '%s'", s ) ; return 0 ; /* Should never get here */ } static Tag top_tags [] = { { "MATERIAL", do_material }, { "OBJECT" , do_object }, { NULL, NULL } } ; static Tag object_tags [] = { { "name" , do_name }, { "data" , do_data }, { "texture" , do_texture }, { "texrep" , do_texrep }, { "texoff" , do_texoff }, { "crease" , do_crease }, { "rot" , do_rot }, { "loc" , do_loc }, { "url" , do_url }, { "numvert" , do_numvert }, { "numsurf" , do_numsurf }, { "kids" , do_kids }, { NULL, NULL } } ; static Tag surf_tag [] = { { "SURF" , do_surf }, { NULL, NULL } } ; static Tag surface_tags [] = { { "mat" , do_mat }, { "refs" , do_refs }, { NULL, NULL } } ; /*static Tag obj_type_tags [] = { { "world", do_obj_world }, { "poly" , do_obj_poly }, { "group", do_obj_group }, { "light", do_obj_light }, { NULL, NULL } } ;*/ #define OBJ_WORLD 0 #define OBJ_POLY 1 #define OBJ_GROUP 2 #define OBJ_LIGHT 3 /*static int do_obj_world ( char * ) { return OBJ_WORLD ; } static int do_obj_poly ( char * ) { return OBJ_POLY ; } static int do_obj_group ( char * ) { return OBJ_GROUP ; } static int do_obj_light ( char * ) { return OBJ_LIGHT ; }*/ static int last_num_kids = -1 ; static int current_flags = -1 ; static ssgState *get_state ( _ssgMaterial *mat ) { if (current_tfname != NULL) { ssgState *st = current_options -> createState ( current_tfname ) ; if ( st != NULL ) return st ; } ssgSimpleState *st = new ssgSimpleState () ; st -> setMaterial ( GL_DIFFUSE, mat -> rgba ) ; st -> setMaterial ( GL_AMBIENT, mat -> amb ) ; st -> setMaterial ( GL_EMISSION, mat -> emis ) ; st -> setMaterial ( GL_SPECULAR, mat -> spec ) ; st -> setShininess ( mat -> shi ) ; st -> enable ( GL_COLOR_MATERIAL ) ; st -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; st -> enable ( GL_LIGHTING ) ; st -> setShadeModel ( GL_SMOOTH ) ; bool has_alpha = false ; if ( current_tfname != NULL ) { ssgTexture *tex = current_options -> createTexture ( current_tfname ) ; has_alpha = tex -> hasAlpha () ; st -> setTexture( tex ) ; st -> enable( GL_TEXTURE_2D ) ; } else { st -> disable( GL_TEXTURE_2D ) ; } if ( mat -> rgba[3] < 0.99 || has_alpha ) { st -> disable ( GL_ALPHA_TEST ) ; st -> enable ( GL_BLEND ) ; st -> setTranslucent () ; } else { st -> disable ( GL_ALPHA_TEST ) ; st -> disable ( GL_BLEND ) ; st -> setOpaque () ; } return st ; } static int do_material ( char *s ) { char name [ 1024 ] ; sgVec4 rgba ; sgVec4 amb ; sgVec4 emis ; sgVec4 spec ; int shi ; float trans ; if ( sscanf ( s, "%s rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f", name, &rgba [0], &rgba [1], &rgba [2], &amb [0], &amb [1], &amb [2], &emis[0], &emis[1], &emis[2], &spec[0], &spec[1], &spec[2], &shi, &trans ) != 15 ) { ulSetError ( UL_WARNING, "ac_to_gl: Can't parse this MATERIAL:" ) ; ulSetError ( UL_WARNING, "ac_to_gl: MATERIAL %s", s ) ; } else { char *nm = name ; skip_quotes ( &nm ) ; amb [ 3 ] = emis [ 3 ] = spec [ 3 ] = 1.0f ; rgba [ 3 ] = 1.0f - trans ; mlist [ num_materials ] = new _ssgMaterial ; _ssgMaterial *current_material ; current_material = mlist [ num_materials ] ; sgCopyVec4 ( current_material -> rgba , rgba ) ; sgCopyVec4 ( current_material -> amb , amb ) ; sgCopyVec4 ( current_material -> emis , emis ) ; sgCopyVec4 ( current_material -> spec , spec ) ; current_material -> shi = (float) shi ; } num_materials++ ; return PARSE_CONT ; } static int do_object ( char * /* s */ ) { /* int obj_type = search ( obj_type_tags, s ) ; */ delete [] current_tfname ; current_tfname = NULL ; char buffer [ 1024 ] ; sgSetVec2 ( texrep, 1.0f, 1.0f ) ; sgSetVec2 ( texoff, 0.0f, 0.0f ) ; sgMakeIdentMat4 ( current_matrix ) ; ssgEntity *old_cb = current_branch ; ssgTransform *tr = new ssgTransform () ; tr -> setTransform ( current_matrix ) ; current_branch -> addKid ( tr ) ; current_branch = tr ; current_matindexarray = new ssgIndexArray ; current_flagsarray = new ssgIndexArray ; current_texcoordarray = new ssgTexCoordArray ; current_vertexarray = new ssgVertexArray ; current_triindexarray = new ssgIndexArray ; while ( fgets ( buffer, 1024, loader_fd ) != NULL ) if ( search ( object_tags, buffer ) == PARSE_POP ) break ; // If he have read some surfaces belonging to that object, // compute normals and distribute the triangels across the materials. int ntris = current_triindexarray -> getNum () / 3; if ( 0 < ntris ) { int i; int nvert = current_vertexarray -> getNum () ; // Put the triangles and the current crease angle into the vertex splitter ... ssgVertSplitter split( nvert, ntris ); split.setSharpAngle ( current_crease ); for ( i = 0 ; i < nvert ; i++ ) sgCopyVec3 ( split.vert ( i ), current_vertexarray -> get ( i ) ) ; for ( i = 0 ; i < ntris ; i++ ) split.setTri ( i, * ( current_triindexarray -> get ( 3*i ) ), * ( current_triindexarray -> get ( 3*i+1 ) ), * ( current_triindexarray -> get ( 3*i+2 ) ) ); // ... and let it compute the normals. split.splitAndCalcNormals () ; // Cycle through all ssgState/colour combinations and emit leafs from them. for ( int cullface = 0 ; cullface < 2 ; cullface++ ) { for ( int material = 0 ; material < num_materials ; material++ ) { ssgVertexArray* vertexarray = (ssgVertexArray *) current_vertexarray -> clone () ; vertexarray -> ref () ; ssgNormalArray* normalarray = new ssgNormalArray ( nvert ) ; normalarray -> ref () ; ssgTexCoordArray* texcoordarray = (ssgTexCoordArray *) current_texcoordarray -> clone () ; texcoordarray -> ref () ; ssgIndexArray* triindexarray = new ssgIndexArray ( nvert ) ; triindexarray -> ref () ; // Mark all normals as unset using a zero vector. for ( i = 0 ; i < nvert ; i++ ) normalarray -> add ( zero ) ; bool has_texture = current_tfname != NULL ; // For every material/state cycle through all triangles and pick // out those ones with that maternial/state. for ( int tri = 0 ; tri < ntris ; tri++ ) { int triMatindex = * ( current_matindexarray -> get ( tri ) ) ; int triFlags = * ( current_flagsarray -> get ( tri ) ) ; int triCullface = ! ( triFlags & 0x20 ) ; if ( triMatindex == material && triCullface == cullface ) { // get the original indices int* triind = split.getTri ( tri ) ; int origtriind[3]; for ( int k = 0 ; k < 3 ; k++ ) origtriind[k] = triind[k] < nvert ? triind[k] : split.origVert( triind[k] - nvert ) ; // Note that copying those values prevents us from a race condion // which occurs when doing something like: // texcoordarray -> add ( texcoordarray -> get ( origtriind[i] ) ) ; // make a local copy of texcoords ... sgVec2 texcoords[3]; for ( i = 0 ; i < 3 ; i++ ) sgCopyVec2 ( texcoords[i], texcoordarray -> get ( origtriind[i] ) ) ; // ... of vertices ... sgVec3 vertices[3]; for ( i = 0 ; i < 3 ; i++ ) sgCopyVec3 ( vertices[i], split.vert ( origtriind[i] ) ) ; int triSmooth = ( triFlags & 0x10 ) ; // ... and of normals. sgVec3 normals[3]; if ( triSmooth ) { for ( i = 0 ; i < 3 ; i++ ) sgCopyVec3 ( normals[i], split.norm ( triind[i] ) ) ; } else { // If we have flat shading, compute one normal for all. sgSubVec3 ( normals[1], vertices[1], vertices[0] ) ; sgSubVec3 ( normals[2], vertices[2], vertices[0] ) ; sgVectorProductVec3 ( normals[0], normals[1], normals[2] ) ; sgNormaliseVec3 ( normals[0] ) ; sgCopyVec3 ( normals[1], normals[0] ) ; sgCopyVec3 ( normals[2], normals[0] ) ; } for ( i = 0 ; i < 3 ; i++ ) { if ( sgEqualVec3 ( normalarray -> get ( origtriind[i] ), zero ) ) { // Case: not yet initialized. sgCopyVec3 ( normalarray -> get ( origtriind[i] ), normals[i] ) ; triindexarray -> add ( origtriind[i] ) ; } else if ( sgEqualVec3 ( normalarray -> get ( origtriind[i] ), normals[i] ) ) { // Case: initialized and the same as before. triindexarray -> add ( origtriind[i] ) ; } else { // Case: initialized and different. // Scan for a vertex/normal/texcoord triple matching the required one. // If there exist one, use that. int num = vertexarray -> getNum () ; int replind = -1 ; for ( int l = nvert ; l < num ; l++ ) { if ( sgEqualVec3( vertices[i], vertexarray -> get ( l ) ) && ( !has_texture || sgEqualVec2( texcoordarray -> get ( origtriind[i] ), texcoordarray -> get ( l ) ) ) && sgEqualVec3( normals[i], normalarray -> get ( l ) ) ) { replind = l ; } } // If we have not yet the required triple in our dataset, add it. if ( replind < 0 ) { vertexarray -> add ( vertices[i] ) ; normalarray -> add ( normals[i] ) ; texcoordarray -> add ( texcoords[i] ) ; replind = num ; } triindexarray -> add ( replind ) ; } } } } if ( 0 < triindexarray -> getNum () ) { ssgColourArray *colour = new ssgColourArray ( 1 ) ; colour -> add ( mlist [ material ] -> rgba ) ; ssgVtxArray* v = new ssgVtxArray ( GL_TRIANGLES, vertexarray, normalarray, has_texture ? texcoordarray : 0, colour, triindexarray ) ; v -> removeUnusedVertices(); v -> setState ( get_state ( mlist [ material ] ) ) ; v -> setCullFace ( cullface ) ; ssgLeaf* leaf = current_options -> createLeaf ( v, 0 ) ; if ( leaf ) tr -> addKid ( leaf ) ; } ssgDeRefDelete ( vertexarray ) ; ssgDeRefDelete ( normalarray ) ; ssgDeRefDelete ( texcoordarray ) ; ssgDeRefDelete ( triindexarray ) ; } } } // Cleanup delete current_matindexarray ; current_matindexarray = NULL ; delete current_flagsarray ; current_flagsarray = NULL ; delete current_vertexarray ; current_vertexarray = NULL ; delete current_texcoordarray ; current_texcoordarray = NULL ; delete current_triindexarray ; current_triindexarray = NULL ; // Process child nodes int num_kids = last_num_kids ; for ( int i = 0 ; i < num_kids ; i++ ) { fgets ( buffer, 1024, loader_fd ) ; search ( top_tags, buffer ) ; } current_branch = (ssgBranch *) old_cb ; return PARSE_CONT ; } static int do_name ( char *s ) { skip_quotes ( &s ) ; current_branch -> setName ( s ) ; return PARSE_CONT ; } static int do_data ( char *s ) { int len = strtol ( s, NULL, 0 ) ; current_data = new char [ len + 1 ] ; for ( int i = 0 ; i < len ; i++ ) current_data [ i ] = getc ( loader_fd ) ; current_data [ len ] = '\0' ; int c; while ( ( c = getc( loader_fd ) ) != EOF ) /* Final RETURN */ if ( c != '\r' && c != '\n' ) { ungetc ( c, loader_fd ) ; break ; } ssgBranch *br = current_options -> createBranch ( current_data ) ; if ( br != NULL ) { current_branch -> addKid ( br ) ; current_branch = br ; } /* delete [] current_data ; */ current_data = NULL ; return PARSE_CONT ; } static int do_texture ( char *s ) { skip_quotes ( &s ) ; delete [] current_tfname ; if ( s == NULL || s[0] == '\0' ) current_tfname = NULL ; else current_tfname = ulStrDup ( s ) ; return PARSE_CONT ; } static int do_texrep ( char *s ) { if ( sscanf ( s, "%f %f", & texrep [ 0 ], & texrep [ 1 ] ) != 2 ) ulSetError ( UL_WARNING, "ac_to_gl: Illegal texrep record." ) ; return PARSE_CONT ; } static int do_texoff ( char *s ) { if ( sscanf ( s, "%f %f", & texoff [ 0 ], & texoff [ 1 ] ) != 2 ) ulSetError ( UL_WARNING, "ac_to_gl: Illegal texoff record." ) ; return PARSE_CONT ; } static int do_crease ( char *s ) { // the crease angle is not yet used. However, reading the crease line correctly means // *.ac lines with "crease" can now be read. if ( sscanf ( s, "%f", & current_crease ) != 1 ) ulSetError ( UL_WARNING, "ac_to_gl: Illegal crease angle." ) ; return PARSE_CONT ; } static int do_rot ( char *s ) { current_matrix [ 0 ][ 3 ] = current_matrix [ 1 ][ 3 ] = current_matrix [ 2 ][ 3 ] = current_matrix [ 3 ][ 0 ] = current_matrix [ 3 ][ 1 ] = current_matrix [ 3 ][ 2 ] = 0.0f ; current_matrix [ 3 ][ 3 ] = 1.0f ; if ( sscanf ( s, "%f %f %f %f %f %f %f %f %f", & current_matrix [ 0 ] [ 0 ], & current_matrix [ 0 ] [ 1 ], & current_matrix [ 0 ] [ 2 ], & current_matrix [ 1 ] [ 0 ], & current_matrix [ 1 ] [ 1 ], & current_matrix [ 1 ] [ 2 ], & current_matrix [ 2 ] [ 0 ], & current_matrix [ 2 ] [ 1 ], & current_matrix [ 2 ] [ 2 ] ) != 9 ) ulSetError ( UL_WARNING, "ac_to_gl: Illegal rot record." ) ; ((ssgTransform *)current_branch) -> setTransform ( current_matrix ) ; return PARSE_CONT ; } static int do_loc ( char *s ) { if ( sscanf ( s, "%f %f %f", & current_matrix [ 3 ][ 0 ], & current_matrix [ 3 ][ 2 ], & current_matrix [ 3 ][ 1 ] ) != 3 ) ulSetError ( UL_WARNING, "ac_to_gl: Illegal loc record." ) ; current_matrix [ 3 ][ 1 ] = - current_matrix [ 3 ][ 1 ] ; current_matrix [ 3 ][ 3 ] = 1.0f ; ((ssgTransform *)current_branch) -> setTransform ( current_matrix ) ; return PARSE_CONT ; } static int do_url ( char *s ) { skip_quotes ( & s ) ; #ifdef PRINT_URLS ulSetError ( UL_DEBUG, "/* URL: \"%s\" */\n", s ) ; #endif return PARSE_CONT ; } static int do_numvert ( char *s ) { char buffer [ 1024 ] ; int nv = strtol ( s, NULL, 0 ) ; for ( int i = 0 ; i < nv ; i++ ) { sgVec3 v; fgets ( buffer, 1024, loader_fd ) ; if ( sscanf ( buffer, "%f %f %f", &v[0], &v[1], &v[2] ) != 3 ) { ulSetError ( UL_FATAL, "ac_to_gl: Illegal vertex record." ) ; } float tmp = v[1] ; v[1] = -v[2] ; v[2] = tmp ; current_vertexarray -> add ( v ) ; current_texcoordarray -> add ( invalidTexture ) ; } return PARSE_CONT ; } static int do_numsurf ( char *s ) { int ns = strtol ( s, NULL, 0 ) ; for ( int i = 0 ; i < ns ; i++ ) { char buffer [ 1024 ] ; fgets ( buffer, 1024, loader_fd ) ; search ( surf_tag, buffer ) ; } return PARSE_CONT ; } static int do_surf ( char *s ) { current_flags = strtol ( s, NULL, 0 ) ; char buffer [ 1024 ] ; while ( fgets ( buffer, 1024, loader_fd ) != NULL ) if ( search ( surface_tags, buffer ) == PARSE_POP ) break ; return PARSE_CONT ; } static int do_mat ( char *s ) { int mat = strtol ( s, NULL, 0 ) ; current_materialind = mat ; return PARSE_CONT ; } static void add_textured_vertex_edge ( short ind, sgVec2 tex ) { // Add a new triangle edge. For that, check for a vertex/texcoord // pair already in the current dataset. Use the already present index if present. bool has_texture = current_tfname != NULL ; if ( sgEqualVec2( tex, current_texcoordarray -> get ( ind ) ) || !has_texture ) { // In this case, we have that vertex/texcoord pair already at the index // within the ac file. current_triindexarray -> add ( ind ) ; } else if ( sgEqualVec2( invalidTexture, current_texcoordarray -> get ( ind ) ) ) { // In this case, we have not yet stored a valid texture coordinate // for the vertex at the given index. Just copy the texturecoordinate // value into that place. sgCopyVec2( current_texcoordarray -> get ( ind ), tex ) ; current_triindexarray -> add ( ind ) ; } else { // Texture coordinate do not match the prevous texcoords stored for this vertex. // Search for a vertex/texcoord pair matching the requested one, if not // yet present, add a new one. int num = current_vertexarray -> getNum () ; for ( int i = 0 ; i < num ; i++ ) { if ( ( !has_texture || sgEqualVec2( tex, current_texcoordarray -> get ( i ) ) ) && sgEqualVec3( current_vertexarray -> get ( ind ), current_vertexarray -> get ( i ) ) ) { current_triindexarray -> add ( i ) ; return ; } } // Need to copy that before, else we run into a racecondition where // we copy from an location which is already freed. sgVec3 vertex ; sgCopyVec3 ( vertex, current_vertexarray -> get ( ind ) ) ; current_vertexarray -> add ( vertex ) ; current_texcoordarray -> add ( tex ) ; current_triindexarray -> add ( num ) ; } } static int do_refs ( char *s ) { int nrefs = strtol ( s, NULL, 0 ) ; char buffer [ 1024 ] ; if ( nrefs == 0 ) return PARSE_POP ; int type = ( current_flags & 0x0F ) ; // Handle line type objects by creating a single leaf for each line segment. if ( type == 1 || type == 2 ) { ssgIndexArray *ind = new ssgIndexArray ; for ( int i = 0 ; i < nrefs ; i++ ) { fgets ( buffer, 1024, loader_fd ) ; int vtx ; float dummy ; if ( sscanf ( buffer, "%d %f %f", &vtx, &dummy, &dummy ) != 3 ) { ulSetError ( UL_FATAL, "ac_to_gl: Illegal ref record." ) ; } ind -> add ( vtx ) ; } ssgColourArray *col = new ssgColourArray ( 1 ) ; col -> add ( mlist [ current_materialind ] -> rgba ) ; GLenum gltype = ( type == 1 ) ? GL_LINE_LOOP : GL_LINE_STRIP ; ssgVtxArray *va = new ssgVtxArray ( gltype, (ssgVertexArray *)current_vertexarray -> clone (), 0, 0, col, ind ); va -> removeUnusedVertices(); va -> setState ( get_state ( mlist [ current_materialind ] ) ) ; ssgLeaf *leaf = current_options -> createLeaf ( va, 0 ) ; if ( leaf ) current_branch -> addKid ( leaf ) ; } if ( type == 0 ) { // Handle surface datatypes. // Each surface is triangulated and each triangle is put // into the index array current_triindexarray. int first_vertind = -1 ; int prev_vertind = 0 ; sgVec2 first_texcoord ; sgVec2 prev_texcoord ; for ( int i = 0 ; i < nrefs ; i++ ) { fgets ( buffer, 1024, loader_fd ) ; int vertind ; sgVec2 texcoord ; if ( sscanf ( buffer, "%d %f %f", &vertind, &texcoord[0], &texcoord[1] ) != 3 ) { ulSetError ( UL_FATAL, "ac_to_gl: Illegal ref record." ) ; } texcoord[0] *= texrep[0] ; texcoord[1] *= texrep[1] ; texcoord[0] += texoff[0] ; texcoord[1] += texoff[1] ; // Store the first index texcoord pair. // This one is referenced for every triangle. if ( first_vertind < 0 ) { first_vertind = vertind ; sgCopyVec2( first_texcoord, texcoord ); } // When we have read the third vertex index we can emit the first triangle. if ( 2 <= i ) { // Store the edges of the triangle add_textured_vertex_edge ( first_vertind, first_texcoord ) ; add_textured_vertex_edge ( prev_vertind, prev_texcoord ) ; add_textured_vertex_edge ( vertind, texcoord ) ; // Store the material and flags for this surface. current_matindexarray -> add ( current_materialind ); current_flagsarray -> add ( current_flags ); } // Copy current -> previous prev_vertind = vertind ; sgCopyVec2( prev_texcoord, texcoord ); } } return PARSE_POP ; } static int do_kids ( char *s ) { last_num_kids = strtol ( s, NULL, 0 ) ; return PARSE_POP ; } ssgEntity *ssgLoadAC3D ( const char *fname, const ssgLoaderOptions* options ) { ssgEntity *obj = ssgLoadAC ( fname, options ) ; if ( obj == NULL ) return NULL ; /* Do some simple optimisations */ ssgBranch *model = new ssgBranch () ; model -> addKid ( obj ) ; ssgFlatten ( obj ) ; return model ; } /* Original function for backwards compatibility... */ ssgEntity *ssgLoadAC ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; char filename [ 1024 ] ; current_options -> makeModelPath ( filename, fname ) ; num_materials = 0 ; current_tfname = NULL ; current_branch = NULL ; current_crease = 61.0 ; sgSetVec2 ( texrep, 1.0, 1.0 ) ; sgSetVec2 ( texoff, 0.0, 0.0 ) ; loader_fd = fopen ( filename, "r" ) ; if ( loader_fd == NULL ) { ulSetError ( UL_WARNING, "ssgLoadAC: Failed to open '%s' for reading", filename ) ; return NULL ; } char buffer [ 1024 ] ; int firsttime = TRUE ; current_branch = new ssgTransform () ; while ( fgets ( buffer, 1024, loader_fd ) != NULL ) { char *s = buffer ; /* Skip leading whitespace */ skip_spaces ( & s ) ; /* Skip blank lines and comments */ if ( *s < ' ' && *s != '\t' ) continue ; if ( *s == '#' || *s == ';' ) continue ; if ( firsttime ) { firsttime = FALSE ; if ( ! ulStrNEqual ( s, "AC3D", 4 ) ) { fclose ( loader_fd ) ; ulSetError ( UL_WARNING, "ssgLoadAC: '%s' is not in AC3D format.", filename ) ; return NULL ; } } else search ( top_tags, s ) ; } for (int i = 0; i < num_materials; i++) { delete mlist[i]; mlist[i]=0; } num_materials=0; delete [] current_tfname ; current_tfname = NULL ; fclose ( loader_fd ) ; return current_branch ; } plib-1.8.5/src/ssg/ssgAnimTransform.cxx0000644000175000001440000001171510765364437015020 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998-2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgAnimTransform.cxx,v */ // Written by Wolfram Kuss in Oct 2004 #include "ssgLocal.h" float _ssgGlobTime = 0.0f; const char *ssgAnimTransform::getTypeName (void) { return "ssgAnimTransform" ; } void ssgAnimTransform::copy_from ( ssgAnimTransform *src, int clone_flags ) { selectBank ( src->getCurrBank () ) ; mode = src->mode; //ARGH!!!!!!!!!!!!!!!!!!!! transformations.copy_from(static_cast(&src->transformations), clone_flags); ssgBranch::copy_from ( src, clone_flags ) ; } ssgBase *ssgAnimTransform::clone ( int clone_flags ) { ssgAnimTransform *b = new ssgAnimTransform ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgAnimTransform::ssgAnimTransform (void) { type = ssgTypeAnimTransform () ; curr_bank = 0.0f ; mode = SSGTWEEN_REPEAT; } ssgAnimTransform::~ssgAnimTransform (void) { removeAllKids () ; } // ********* done till here ************* void ssgAnimTransform::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { // calculate the transformation // comment is partly obsolete: // You need to have a object with animation loaded into memory for the following function to make sense. // Animation can be discreet (in steps) or "smooth" (fluid). // If you loaded an animation made of several meshes, it will use a selector and therefore always be "discreet" // If you loaded some transformation matrices like some rotations to rotate the flap of a plane, // the define DISCREET_STEPS will determine whether the animation is smooth (new code, WK) or // in steps ("old" code, Dave McClurg). // // The anim_frame is for discreet animation and an index determining which matrix / which selector will be used. // For the smooth animation, the parameter curr_time_ms is used that should be the current time, // Typically in MilliSeconds. However, you can speed up or slow down time. // You could even stop changing curr_time_ms to freeze the animation. // // typically, you will call ssgSetAnimTime directly before you call ssgCullAndDraw //void ssgSetAnimTime( ssgEntity *e, int anim_frame, long curr_time_ms ) int num = transformations. getNum () ; if ( num > 0 ) { #ifdef DISCREET_STEPS int frame = curr_bank ; if ( frame >= num ) frame = num-1 ; transformations. selection = frame ; setTransform ( *( transformations. get ( transformations. selection ) ) ) ; #else /* fluid motion */ ///// copied from ssgTween.cxx and changed var names //if(global_mode) curr_bank = _ssgGlobTime; if ( curr_bank < 0.0f ) curr_bank = 0.0f ; int state1 = (int) floor ( curr_bank ) ; int state2 = state1 + 1 ; float tween = curr_bank - (float) state1 ; if ( mode == SSGTWEEN_REPEAT ) { state1 %= num ; state2 %= num ; } else { if ( state1 >= num ) state1 = num - 1 ; if ( state2 >= num ) state2 = num - 1 ; } if ( state1 == state2 ) tween = 0.0f; ///// sgMat4 XForm, *pmFrame1; pmFrame1 = transformations. get ( state1 ); sgMat4 *pmFrame2 = transformations. get ( state2 ); for(int i=0;i<4;i++) for(int j=0; j<4; j++) XForm[i][j] = tween * ((*pmFrame1)[i][j]) + (1.0f-tween) * ((*pmFrame2)[i][j]); setTransform ( XForm ); #endif } ssgTransform::cull ( f, m, test_needed ) ; } // ********* below: done ************* int ssgAnimTransform::load ( FILE *fd ) { _ssgReadFloat ( fd, & curr_bank ) ; int int_mode; _ssgReadInt ( fd, &int_mode ); mode = int_mode; transformations.load( fd ); return ssgBranch::load ( fd ) ; } int ssgAnimTransform::save ( FILE *fd ) { _ssgWriteFloat ( fd, curr_bank ) ; int int_mode = mode; _ssgWriteInt ( fd, int_mode ); transformations.save( fd ); return ssgBranch::save ( fd ) ; } void ssgAnimTransform::print ( FILE *fd, char *indent, int how_much ) { if ( how_much == 0 ) return ; fprintf ( fd, "%sCurrent Bank = %f\n", indent, curr_bank ); fprintf ( fd, "%sMode = %d\n", indent, (int)mode ); if ( how_much > 1 ) transformations.print( fd, indent, how_much ); ssgBranch::print ( fd, indent, how_much ) ; } plib-1.8.5/src/ssg/ssgMSFSPalette.h0000644000175000001440000000213110765364437013744 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgMSFSPalette.h 1568 2002-09-02 06:05:49Z sjbaker $ */ #ifndef __SSGMSFSPALETTE #define __SSGMSFSPALETTE extern unsigned const char ssgFsTexPalette[] ; #endif // __SSGMSFSPALETTE plib-1.8.5/src/ssg/ssgSaveTRI.cxx0000644000175000001440000000555010765364437013515 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveTRI.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ // // TRI ( AC3D triangle file ) export for SSG/PLIB // Written by Dave McClurg (dpm@efn.org) in March-2000 // #include "ssgLocal.h" static FILE *fileout ; static void save_vtx_table ( ssgVtxTable *vt ) { GLenum mode = vt -> getPrimitiveType () ; if ( mode == GL_TRIANGLES || mode == GL_TRIANGLE_FAN || mode == GL_TRIANGLE_STRIP ) { int num_tri = vt -> getNumTriangles () ; for ( int i = 0; i < num_tri; i++ ) { short tri[3]; vt -> getTriangle ( i, &tri[0], &tri[1], &tri[2] ) ; for ( int j = 0; j < 3; j ++ ) { sgVec3 vert; sgCopyVec3 ( vert, vt->getVertex ( tri[j] ) ) ; fprintf ( fileout, "%f %f %f ", vert[0], vert[1], vert[2] ) ; } fprintf ( fileout, "0xFFFFFF\n" ) ; } } } static void save_entities ( ssgEntity *e ) { if ( e -> isAKindOf ( ssgTypeBranch() ) ) { ssgBranch *br = (ssgBranch *) e ; for ( int i = 0 ; i < br -> getNumKids () ; i++ ) save_entities ( br -> getKid ( i ) ) ; } else if ( e -> isAKindOf ( ssgTypeVtxTable() ) ) { ssgVtxTable *vt = (ssgVtxTable *) e ; save_vtx_table ( vt ) ; } } /******************************************************************************/ int ssgSaveTRI ( const char *filename, ssgEntity *ent ) /******************************************************************************/ /* Purpose: writes an AC3D triangle file. Example: Each line contains 9 floating point values and a 1 hex value for color. the 9 floating point values represent 3 vertices of a triangle the color format is 0xRRGGBB (eg 0xffffff is white) 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0xffffff */ { fileout = fopen ( filename, "wa" ) ; if ( fileout == NULL ) { ulSetError ( UL_WARNING, "ssgSaveTRI: Failed to open '%s' for writing", filename ) ; return FALSE ; } save_entities ( ent ) ; fclose ( fileout ) ; return TRUE; } plib-1.8.5/src/ssg/ssgDList.cxx0000644000175000001440000001362110765364437013255 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgDList.cxx 1996 2004-12-29 07:19:40Z sjbaker $ */ #include "ssgLocal.h" enum _ssgDListType { SSG_DLIST_LEAF, SSG_DLIST_SET_TWEEN_STATE, SSG_DLIST_LOAD_MATRIX, SSG_DLIST_PUSH_MATRIX, SSG_DLIST_POP_MATRIX, SSG_DLIST_LOAD_TEX_MATRIX, SSG_DLIST_UNLOAD_TEX_MATRIX, SSG_DLIST_NOTHING } ; class _ssgDList { public: _ssgDListType type ; sgMat4 mat ; ssgLeaf *leaf ; float tween_state ; int tween_mode ; _ssgDList () { setEmpty () ; } void setTweenState ( float _state, int _mode ) { type = SSG_DLIST_SET_TWEEN_STATE ; tween_state = _state ; tween_mode = _mode ; } void setPopMatrix () { type = SSG_DLIST_POP_MATRIX ; } void setLoadTexMatrix ( sgMat4 m ) { sgCopyMat4 ( mat, m ) ; type = SSG_DLIST_LOAD_TEX_MATRIX ; } void setUnloadTexMatrix () { type = SSG_DLIST_UNLOAD_TEX_MATRIX ; } void setLoadMatrix ( sgMat4 m ) { sgCopyMat4 ( mat, m ) ; type = SSG_DLIST_LOAD_MATRIX ; } void setPushMatrix ( sgMat4 m ) { sgCopyMat4 ( mat, m ) ; type = SSG_DLIST_PUSH_MATRIX ; } void setDrawLeaf ( ssgLeaf *l ) { leaf = l ; type = SSG_DLIST_LEAF ; } void setEmpty () { type = SSG_DLIST_NOTHING ; } void draw () { switch ( type ) { case SSG_DLIST_LEAF : leaf -> draw () ; break ; case SSG_DLIST_SET_TWEEN_STATE : _ssgSetRealCurrentTweenSettings ( tween_state, tween_mode ) ; break ; case SSG_DLIST_POP_MATRIX : glPopMatrix () ; break ; case SSG_DLIST_LOAD_TEX_MATRIX : glMatrixMode ( GL_TEXTURE ) ; glLoadMatrixf ( (float *) mat ) ; glMatrixMode ( GL_MODELVIEW ) ; break ; case SSG_DLIST_UNLOAD_TEX_MATRIX : glMatrixMode ( GL_TEXTURE ) ; glLoadIdentity () ; glMatrixMode ( GL_MODELVIEW ) ; break ; case SSG_DLIST_LOAD_MATRIX : glLoadMatrixf ( (float *) mat ) ; break ; case SSG_DLIST_PUSH_MATRIX : glPushMatrix () ; glLoadMatrixf ( (float *) mat ) ; break ; default: break ; } setEmpty () ; } } ; #define MAX_DLIST 8192 //4096 //2048 static int next_dlist = 0 ; static _ssgDList dlist [ MAX_DLIST ] ; void _ssgDrawDList () { for ( int i = 0 ; i < next_dlist ; i++ ) dlist [ i ] . draw () ; next_dlist = 0 ; } void _ssgPushMatrix ( sgMat4 m ) { /* There is no point in having a pop/push sequence, so optimise it to a simple load. */ if ( next_dlist > 0 && dlist [ next_dlist - 1 ] . type == SSG_DLIST_POP_MATRIX ) { next_dlist-- ; _ssgLoadMatrix ( m ) ; } else if ( next_dlist >= MAX_DLIST ) ulSetError ( UL_WARNING, "DList stack overflow!" ) ; else dlist [ next_dlist++ ] . setPushMatrix ( m ) ; } void _ssgSetTweenState ( float state, int mode ) { if ( next_dlist >= MAX_DLIST ) ulSetError ( UL_WARNING, "DList stack overflow!" ) ; else dlist [ next_dlist++ ] . setTweenState ( state, mode ) ; } void _ssgPopMatrix () { /* There is no point in having a push/pop sequence, so optimise it to a single load. */ if ( next_dlist > 0 && dlist [ next_dlist - 1 ] . type == SSG_DLIST_PUSH_MATRIX ) next_dlist-- ; else if ( next_dlist >= MAX_DLIST ) ulSetError ( UL_WARNING, "DList stack overflow!" ) ; else dlist [ next_dlist++ ] . setPopMatrix () ; } void _ssgLoadTexMatrix ( sgMat4 m ) { /* There is no point in having a unload/load or a load/load sequence, so optimise it to a single load. */ while ( next_dlist > 0 && ( dlist [ next_dlist - 1 ] . type == SSG_DLIST_LOAD_TEX_MATRIX || dlist [ next_dlist - 1 ] . type == SSG_DLIST_UNLOAD_TEX_MATRIX ) ) next_dlist-- ; if ( next_dlist >= MAX_DLIST ) ulSetError ( UL_WARNING, "DList stack overflow!" ) ; else dlist [ next_dlist++ ] . setLoadTexMatrix ( m ) ; } void _ssgUnloadTexMatrix () { /* There is no point in having a unload/unload or a load/unload sequence, so optimise it to a single unload. */ while ( next_dlist > 0 && ( dlist [ next_dlist - 1 ] . type == SSG_DLIST_LOAD_TEX_MATRIX || dlist [ next_dlist - 1 ] . type == SSG_DLIST_UNLOAD_TEX_MATRIX ) ) next_dlist-- ; if ( next_dlist >= MAX_DLIST ) ulSetError ( UL_WARNING, "DList stack overflow!" ) ; else dlist [ next_dlist++ ] . setUnloadTexMatrix () ; } void _ssgLoadMatrix ( sgMat4 m ) { /* There is no point in having a load/load sequence, so optimise it to a single load. */ while ( next_dlist > 0 && dlist [ next_dlist - 1 ] . type == SSG_DLIST_LOAD_MATRIX ) next_dlist-- ; if ( next_dlist >= MAX_DLIST ) ulSetError ( UL_WARNING, "DList stack overflow!" ) ; else dlist [ next_dlist++ ] . setLoadMatrix ( m ) ; } void _ssgDrawLeaf ( ssgLeaf *l ) { if ( next_dlist >= MAX_DLIST ) ulSetError ( UL_WARNING, "DList stack overflow!" ) ; else dlist [ next_dlist++ ] . setDrawLeaf ( l ) ; } plib-1.8.5/src/ssg/ssgSaveM.cxx0000644000175000001440000000400310765364437013243 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveM.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" int ssgSaveM( const char* fname, ssgEntity *ent ) { FILE *fd = fopen ( fname, "w" ) ; int i; if ( fd == NULL ) { ulSetError ( UL_WARNING, "ssgSaveM: Failed to open '%s' for writing", fname ); return FALSE ; } ssgVertexArray* vertices = new ssgVertexArray(); ssgIndexArray* indices = new ssgIndexArray (); fprintf(fd, "# Model output by ssgSaveM. Original graph structure was:\n"); ent->print(fd, "#", 0); sgMat4 ident; sgMakeIdentMat4( ident ); ssgAccumVerticesAndFaces( ent, ident, vertices, indices, -1 ); for (i = 0; i < vertices->getNum(); i++) { fprintf(fd, "Vertex %d %f %f %f\n", i+1, vertices->get(i)[0], vertices->get(i)[1], vertices->get(i)[2]); } for (i = 0; i < indices->getNum(); i += 3) { fprintf(fd, "Face %d %d %d %d\n", (i/3)+1, *indices->get(i ) + 1, *indices->get(i + 1) + 1, *indices->get(i + 2) + 1); } fclose( fd ) ; delete vertices; delete indices ; return TRUE; } plib-1.8.5/src/ssg/ssgAnimation.cxx0000644000175000001440000001163110765364437014154 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgAnimation.cxx 1725 2002-11-08 18:35:07Z sjbaker $ */ #include "ssgLocal.h" ulClock ssgTimedSelector::ck; void ssgTimedSelector::copy_from ( ssgTimedSelector *src, int clone_flags ) { ssgSelector::copy_from ( src, clone_flags ) ; running = src -> running ; mode = src -> mode ; time_mode = src -> time_mode ; start_time = src -> start_time ; pause_time = src -> pause_time ; loop_time = src -> loop_time ; delete [] times ; times = new float [ max_kids ] ; for ( int i = 0 ; i < max_kids ; i++ ) times [ i ] = src -> times [ i ] ; curr = src -> curr ; start = src -> start ; end = src -> end ; } ssgBase *ssgTimedSelector::clone ( int clone_flags ) { ssgTimedSelector *b = new ssgTimedSelector ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgTimedSelector::ssgTimedSelector ( int max_kids ) : ssgSelector ( max_kids ) { type = ssgTypeTimedSelector () ; select ( 1 ) ; running = SSG_ANIM_STOP ; mode = SSG_ANIM_SHUTTLE ; start_time = pause_time = 0.0 ; loop_time = 1.0 ; times = new float [ max_kids ] ; for ( int i = 0 ; i < max_kids ; i++ ) times [ i ] = 1.0f ; curr = start = end = 0 ; time_mode = SSG_ANIM_FRAME ; ck.reset() ; } void ssgTimedSelector::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { compute_loop_time () ; selectStep ( getStep () ) ; ssgSelector::cull ( f, m, test_needed ) ; } void ssgTimedSelector::hot ( sgVec3 sp, sgMat4 m, int test_needed ) { selectStep ( getStep () ) ; ssgSelector::hot ( sp, m, test_needed ) ; } void ssgTimedSelector::los ( sgVec3 sp, sgMat4 m, int test_needed ) { selectStep ( getStep () ) ; ssgSelector::los ( sp, m, test_needed ) ; } void ssgTimedSelector::isect ( sgSphere *sp, sgMat4 m, int test_needed ) { selectStep ( getStep () ) ; ssgSelector::isect ( sp, m, test_needed ) ; } int ssgTimedSelector::getStep () { double t = get_time () ; if ( running == SSG_ANIM_STOP || running == SSG_ANIM_PAUSE ) return curr ; /* SSG_ANIM_START */ t -= start_time ; /* t is time since start of run */ if ( mode == SSG_ANIM_ONESHOT ) { if ( t >= loop_time ) { running = SSG_ANIM_STOP ; return end ; } } else if ( mode == SSG_ANIM_SHUTTLE ) { /* Compute time since start of this loop */ t = t - floor ( t / loop_time ) * loop_time ; } else if ( mode == SSG_ANIM_SWING ) { /* Compute time since start of this swing loop */ t = t - floor ( t / (2.0 * loop_time) ) * (2.0 * loop_time) ; /* Are we on the reverse part of the loop? */ if ( t >= loop_time ) t = 2.0 * loop_time - t ; } int k ; for ( k = start ; t > 0.0 && k <= end ; k++ ) t -= (double) times [ k ] ; //DaveM: i removed this line because, in shuttle mode, start plays twice k-- ; if ( k < start ) k = start ; if ( k > end ) k = end ; curr = k ; return curr ; } ssgTimedSelector::~ssgTimedSelector (void) { delete [] times ; } int ssgTimedSelector::load ( FILE *fd ) { _ssgReadInt ( fd, (int *) & running ) ; _ssgReadInt ( fd, (int *) & mode ) ; // _ssgReadDouble( fd, & start_time ) ; // _ssgReadDouble( fd, & pause_time ) ; // _ssgReadDouble( fd, & loop_time ) ; _ssgReadInt ( fd, & max_kids ) ; delete [] times ; times = new float [ max_kids ] ; _ssgReadFloat ( fd, max_kids, times ) ; _ssgReadInt ( fd, & curr ) ; _ssgReadInt ( fd, & start ) ; _ssgReadInt ( fd, & end ) ; _ssgReadInt ( fd, (int *) & time_mode ) ; return ssgSelector::load(fd) ; } int ssgTimedSelector::save ( FILE *fd ) { _ssgWriteInt ( fd, (int) running ) ; _ssgWriteInt ( fd, (int) mode ) ; // _ssgWriteFloat ( fd, start_time ) ; // _ssgWriteFloat ( fd, pause_time ) ; // _ssgWriteFloat ( fd, loop_time ) ; _ssgWriteInt ( fd, max_kids ) ; _ssgWriteFloat ( fd, max_kids, times ) ; _ssgWriteInt ( fd, curr ) ; _ssgWriteInt ( fd, start ) ; _ssgWriteInt ( fd, end ) ; _ssgWriteInt ( fd, (int) time_mode ) ; return ssgSelector::save(fd) ; } plib-1.8.5/src/ssg/ssgStats.cxx0000644000175000001440000000537410765364437013342 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgStats.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" int stats_num_vertices = 0 ; int stats_isect_triangles = 0 ; int stats_isect_test = 0 ; int stats_cull_test = 0 ; int stats_bind_textures = 0 ; int stats_num_leaves = 0 ; int stats_hot_triangles = 0 ; int stats_hot_test = 0 ; int stats_hot_no_trav = 0 ; int stats_hot_radius_reject=0 ; int stats_hot_triv_accept = 0 ; int stats_hot_straddle = 0 ; int stats_los_triangles = 0 ; int stats_los_test = 0 ; int stats_los_no_trav = 0 ; int stats_los_radius_reject=0 ; int stats_los_triv_accept = 0 ; int stats_los_straddle = 0 ; static char stats_string [ 1024 ] ; char *ssgShowStats () { sprintf ( stats_string, "V=%4d, L=%3d H=%3d IS=%3d IT=%3d HT=%3d CT=%3d BT=%3d\n", stats_num_vertices , stats_num_leaves , stats_hot_triangles , stats_isect_triangles, stats_isect_test , stats_hot_test , stats_cull_test , stats_bind_textures ) ; /* sprintf ( stats_string, "Tri=%d, Tst=%d NoTr=%d Rej=%d Acp=%d Str=%d\n", stats_hot_triangles , stats_hot_test , stats_hot_no_trav , stats_hot_radius_reject, stats_hot_triv_accept , stats_hot_straddle ) ; */ stats_num_vertices = 0 ; stats_num_leaves = 0 ; stats_isect_triangles = 0 ; stats_isect_test = 0 ; stats_cull_test = 0 ; stats_bind_textures = 0 ; stats_hot_triangles = 0 ; stats_hot_test = 0 ; stats_hot_no_trav = 0 ; stats_hot_radius_reject=0 ; stats_hot_triv_accept = 0 ; stats_hot_straddle = 0 ; stats_los_triangles = 0 ; stats_los_test = 0 ; stats_los_no_trav = 0 ; stats_los_radius_reject=0 ; stats_los_triv_accept = 0 ; stats_los_straddle = 0 ; return stats_string ; } plib-1.8.5/src/ssg/ssg.dsp0000644000175000001440000002254410765364437012305 00000000000000# Microsoft Developer Studio Project File - Name="ssg" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=ssg - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "ssg.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "ssg.mak" CFG="ssg - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "ssg - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "ssg - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "ssg - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\sg" /I "..\util" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "PROXY_TEXTURES_ARE_NOT_BROKEN" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy ssg.h ..\..\ssg.h copy ssgconf.h ..\..\ssgconf.h copy ssgMSFSPalette.h ..\..\ssgMSFSPalette.h copy ssgKeyFlier.h ..\..\ssgKeyFlier.h # End Special Build Tool !ELSEIF "$(CFG)" == "ssg - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\sg" /I "..\util" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "PROXY_TEXTURES_ARE_NOT_BROKEN" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\ssg_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy ssg.h ..\..\ssg.h copy ssgconf.h ..\..\ssgconf.h copy ssgMSFSPalette.h ..\..\ssgMSFSPalette.h copy ssgKeyFlier.h ..\..\ssgKeyFlier.h # End Special Build Tool !ENDIF # Begin Target # Name "ssg - Win32 Release" # Name "ssg - Win32 Debug" # Begin Source File SOURCE=.\ssg.cxx # End Source File # Begin Source File SOURCE=.\ssg.h # End Source File # Begin Source File SOURCE=.\ssg3ds.h # End Source File # Begin Source File SOURCE=.\ssgAnimation.cxx # End Source File # Begin Source File SOURCE=.\ssgAnimTransform.cxx # End Source File # Begin Source File SOURCE=.\ssgAxisTransform.cxx # End Source File # Begin Source File SOURCE=.\ssgBase.cxx # End Source File # Begin Source File SOURCE=.\ssgBaseTransform.cxx # End Source File # Begin Source File SOURCE=.\ssgBranch.cxx # End Source File # Begin Source File SOURCE=.\ssgconf.h # End Source File # Begin Source File SOURCE=.\ssgContext.cxx # End Source File # Begin Source File SOURCE=.\ssgCutout.cxx # End Source File # Begin Source File SOURCE=.\ssgDList.cxx # End Source File # Begin Source File SOURCE=.\ssgEntity.cxx # End Source File # Begin Source File SOURCE=.\ssgInvisible.cxx # End Source File # Begin Source File SOURCE=.\ssgIO.cxx # End Source File # Begin Source File SOURCE=.\ssgIsect.cxx # End Source File # Begin Source File SOURCE=.\ssgKeyFlier.h # End Source File # Begin Source File SOURCE=.\ssgLeaf.cxx # End Source File # Begin Source File SOURCE=.\ssgList.cxx # End Source File # Begin Source File SOURCE=.\ssgLoad.cxx # End Source File # Begin Source File SOURCE=.\ssgLoad3ds.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadAC.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadASC.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadASE.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadATG.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadBMP.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadDOF.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadDXF.cxx # End Source File # Begin Source File SOURCE=.\ssgLoaderWriterStuff.cxx # End Source File # Begin Source File SOURCE=.\ssgLoaderWriterStuff.h # End Source File # Begin Source File SOURCE=.\ssgLoadFLT.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadIV.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadM.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadMD2.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadMDL.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadMDL.h # End Source File # Begin Source File SOURCE=.\ssgLoadMDL_BGLTexture.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadOBJ.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadOFF.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadPCX.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadPNG.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadSGI.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadSSG.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadStrip.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadTexture.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadTGA.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadTRI.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadVRML.h # End Source File # Begin Source File SOURCE=.\ssgLoadVRML1.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadX.cxx # End Source File # Begin Source File SOURCE=.\ssgLoadXPlaneObj.cxx # End Source File # Begin Source File SOURCE=.\ssgLocal.h # End Source File # Begin Source File SOURCE=.\ssgMSFSPalette.h # End Source File # Begin Source File SOURCE=.\ssgOptimiser.cxx # End Source File # Begin Source File SOURCE=.\ssgParser.cxx # End Source File # Begin Source File SOURCE=.\ssgParser.h # End Source File # Begin Source File SOURCE=.\ssgRangeSelector.cxx # End Source File # Begin Source File SOURCE=.\ssgRoot.cxx # End Source File # Begin Source File SOURCE=.\ssgSave3ds.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveAC.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveASC.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveASE.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveATG.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveDXF.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveFLT.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveIV.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveM.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveOBJ.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveOFF.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveQHI.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveTRI.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveVRML1.cxx # End Source File # Begin Source File SOURCE=.\ssgSaveX.cxx # End Source File # Begin Source File SOURCE=.\ssgSelector.cxx # End Source File # Begin Source File SOURCE=.\ssgSimpleList.cxx # End Source File # Begin Source File SOURCE=.\ssgSimpleState.cxx # End Source File # Begin Source File SOURCE=.\ssgState.cxx # End Source File # Begin Source File SOURCE=.\ssgStateSelector.cxx # End Source File # Begin Source File SOURCE=.\ssgStateTables.cxx # End Source File # Begin Source File SOURCE=.\ssgStatistics.cxx # End Source File # Begin Source File SOURCE=.\ssgStats.cxx # End Source File # Begin Source File SOURCE=.\ssgTexTrans.cxx # End Source File # Begin Source File SOURCE=.\ssgTexture.cxx # End Source File # Begin Source File SOURCE=.\ssgTransform.cxx # End Source File # Begin Source File SOURCE=.\ssgTween.cxx # End Source File # Begin Source File SOURCE=.\ssgTweenController.cxx # End Source File # Begin Source File SOURCE=.\ssgVertSplitter.cxx # End Source File # Begin Source File SOURCE=.\ssgVertSplitter.h # End Source File # Begin Source File SOURCE=.\ssgVTable.cxx # End Source File # Begin Source File SOURCE=.\ssgVtxArray.cxx # End Source File # Begin Source File SOURCE=.\ssgVtxTable.cxx # End Source File # End Target # End Project plib-1.8.5/src/ssg/ssgState.cxx0000644000175000001440000000630010765364437013312 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgState.cxx 1810 2003-11-20 14:01:05Z stromberg $ */ #include "ssgLocal.h" static ssgStateCallback _ssgPendingPostDrawCB = NULL ; static ssgState *_ssgPreviousState = NULL ; void ssgState::preApply () { if ( _ssgPendingPostDrawCB ) (*_ssgPendingPostDrawCB)(_ssgPreviousState) ; if ( preApplyCB ) (*preApplyCB)(this) ; } void ssgState::preDraw () { if ( preDrawCB ) { (*preDrawCB)(this) ; _ssgPendingPostDrawCB = postDrawCB ; _ssgPreviousState = this ; } } void _ssgStartOfFrameInit () { _ssgPendingPostDrawCB = NULL ; _ssgPreviousState = NULL ; } void _ssgEndOfFrameCleanup () { if ( _ssgPendingPostDrawCB ) (*_ssgPendingPostDrawCB)(_ssgPreviousState) ; _ssgPendingPostDrawCB = NULL ; _ssgPreviousState = NULL ; } void ssgState::copy_from ( ssgState *src, int clone_flags ) { ssgBase::copy_from ( src, clone_flags ) ; setExternalPropertyIndex ( src -> getExternalPropertyIndex () ) ; if ( src -> isTranslucent () ) setTranslucent () ; else setOpaque () ; setStateCallback( SSG_CALLBACK_PREDRAW, src->getStateCallback( SSG_CALLBACK_PREDRAW ) ); setStateCallback( SSG_CALLBACK_POSTDRAW, src->getStateCallback( SSG_CALLBACK_POSTDRAW ) ); setStateCallback( SSG_CALLBACK_PREAPPLY, src->getStateCallback( SSG_CALLBACK_PREAPPLY ) ); } ssgState::ssgState (void) { type = ssgTypeState () ; preApplyCB = NULL ; preDrawCB = NULL ; postDrawCB = NULL ; setOpaque () ; setExternalPropertyIndex ( 0 ) ; } ssgState::~ssgState (void) { if ( _ssgPreviousState == this ) { _ssgPendingPostDrawCB = NULL ; _ssgPreviousState = NULL ; } } void ssgState::print ( FILE *fd, char *indent, int how_much ) { ssgBase::print ( fd, indent, how_much ) ; if ( how_much < 2 ) return; fprintf ( fd, "%s Translucent = %s\n", indent, translucent?"True":"False"); fprintf ( fd, "%s ExternalProp = %d\n", indent, external_property_index ) ; } int ssgState::load ( FILE *fd ) { _ssgReadInt ( fd, & translucent ) ; _ssgReadInt ( fd, & external_property_index ) ; preApplyCB = NULL ; preDrawCB = NULL ; postDrawCB = NULL ; return ssgBase::load ( fd ) ; } int ssgState::save ( FILE *fd ) { _ssgWriteInt ( fd, translucent ) ; _ssgWriteInt ( fd, external_property_index ) ; return ssgBase::save ( fd ) ; } plib-1.8.5/src/ssg/Makefile.am0000644000175000001440000000323110765364437013025 00000000000000if BUILD_SSG lib_LIBRARIES = libplibssg.a include_HEADERS = ssg.h ssgconf.h ssgMSFSPalette.h ssgKeyFlier.h pcx.h libplibssg_a_SOURCES = ssg.cxx ssgAnimation.cxx ssgBase.cxx \ ssgBaseTransform.cxx ssgBranch.cxx ssgContext.cxx ssgCutout.cxx \ ssgDList.cxx ssgEntity.cxx ssgIsect.cxx ssgLeaf.cxx ssgList.cxx \ ssgLoadDOF.cxx ssgLoadAC.cxx \ ssgLocal.h ssgOptimiser.cxx ssgRoot.cxx ssgSaveAC.cxx \ ssgSelector.cxx ssgSimpleState.cxx ssgState.cxx ssgStateTables.cxx \ ssgStats.cxx ssgTween.cxx ssgTweenController.cxx \ ssgTexTrans.cxx ssgTexture.cxx ssgTransform.cxx \ ssgStateSelector.cxx ssgRangeSelector.cxx ssgLoadTexture.cxx \ ssgLoadBMP.cxx ssgLoadSGI.cxx ssgLoadPNG.cxx ssgLoadTGA.cxx \ ssgLoadPCX.cxx ssgInvisible.cxx ssgLoadSSG.cxx ssgVTable.cxx \ ssgSimpleList.cxx ssgVtxTable.cxx ssgIO.cxx ssgLoad3ds.cxx \ ssgSaveASE.cxx ssgLoadASE.cxx ssgParser.cxx ssgParser.h \ ssgLoadDXF.cxx ssgSaveDXF.cxx ssgLoadTRI.cxx ssgSaveTRI.cxx \ ssgLoadOBJ.cxx ssgSaveOBJ.cxx ssgVtxArray.cxx ssgLoadMD2.cxx \ ssgLoadMDL.cxx ssgLoadX.cxx ssgSaveX.cxx ssgLoaderWriterStuff.cxx \ ssgLoadFLT.cxx ssgLoadM.cxx ssgSaveM.cxx ssgLoadStrip.cxx \ ssgLoadOFF.cxx ssgSaveOFF.cxx ssgSaveQHI.cxx ssgLoadVRML1.cxx \ ssgSaveVRML1.cxx ssgLoaderWriterStuff.h ssgMSFSPalette.h ssg3ds.h \ ssgLoadMDL.h ssgSave3ds.cxx ssgAxisTransform.cxx ssgLoadATG.cxx \ ssgSaveFLT.cxx ssgSaveATG.cxx ssgLoadIV.cxx ssgLoad.cxx ssgLoadVRML.h \ ssgLoadMDL_BGLTexture.cxx ssgLoadXPlaneObj.cxx ssgLoadASC.cxx ssgSaveASC.cxx \ ssgSaveIV.cxx ssgAnimTransform.cxx\ ssgVertSplitter.h ssgVertSplitter.cxx ssgStatistics.cxx INCLUDES = -I$(top_srcdir)/src/sg -I$(top_srcdir)/src/util endif EXTRA_DIST = ssg.dsp plib-1.8.5/src/ssg/ssgBranch.cxx0000644000175000001440000003743610765364437013445 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgBranch.cxx 1860 2004-02-16 20:51:12Z stromberg $ */ #include "ssgLocal.h" void ssgBranch::copy_from ( ssgBranch *src, int clone_flags ) { ssgEntity::copy_from ( src, clone_flags ) ; for ( int i = 0 ; i < src -> getNumKids () ; i++ ) { ssgEntity *k = src -> getKid ( i ) ; if ( k != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) ) addKid ( (ssgEntity *)( k -> clone ( clone_flags )) ) ; else addKid ( k ) ; } } ssgBase *ssgBranch::clone ( int clone_flags ) { ssgBranch *b = new ssgBranch ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBranch::ssgBranch (void) { type = ssgTypeBranch () ; } ssgBranch::~ssgBranch (void) { removeAllKids () ; } void ssgBranch::zeroSpareRecursive () { zeroSpare () ; for ( ssgEntity *k = getKid ( 0 ) ; k != NULL ; k = getNextKid () ) k -> zeroSpareRecursive () ; } void ssgBranch::recalcBSphere (void) { emptyBSphere () ; for ( ssgEntity *k = getKid ( 0 ) ; k != NULL ; k = getNextKid () ) extendBSphere ( k -> getBSphere () ) ; bsphere_is_invalid = FALSE ; } void ssgBranch::addKid ( ssgEntity *entity ) { kids. addEntity ( entity ) ; entity -> addParent ( this ) ; dirtyBSphere () ; } void ssgBranch::removeKid ( int n ) { ssgEntity *k = kids.getEntity ( n ) ; if ( k != NULL ) { k -> removeParent ( this ) ; kids.removeEntity ( n ) ; dirtyBSphere () ; } } void ssgBranch::removeKid ( ssgEntity *entity ) { removeKid( searchForKid( entity ) ); } void ssgBranch::removeAllKids (void) { for ( int k = getNumKids() - 1; k >= 0; --k ) { removeKid ( k ) ; } } void ssgBranch::replaceKid ( int n, ssgEntity *new_entity ) { if ( n >= 0 && n < getNumKids () ) { getKid ( n ) -> removeParent ( this ) ; kids.replaceEntity ( n, new_entity ) ; new_entity -> addParent ( this ) ; dirtyBSphere () ; } } void ssgBranch::replaceKid ( ssgEntity *old_entity, ssgEntity *new_entity ) { replaceKid ( searchForKid( old_entity ), new_entity ) ; } void ssgBranch::print ( FILE *fd, char *indent, int how_much ) { ssgEntity::print ( fd, indent, how_much ) ; fprintf ( fd, "%s Num Kids=%d\n", indent, getNumKids() ) ; if ( getNumParents() != getRef() ) ulSetError ( UL_WARNING, "Ref count doesn't tally with parent count" ) ; if ( how_much > 1 ) { if ( bsphere.isEmpty() ) fprintf ( fd, "%s BSphere is Empty.\n", indent ) ; else fprintf ( fd, "%s BSphere R=%g, C=(%g,%g,%g)\n", indent, bsphere.getRadius(), bsphere.getCenter()[0], bsphere.getCenter()[1], bsphere.getCenter()[2] ) ; } char in [ 100 ] ; sprintf ( in, "%s ", indent ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> print ( fd, in, how_much ) ; } void ssgBranch::getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_verts ) { int nb, nl, nt, nv ; *num_branches = 1 ; /* this! */ *num_leaves = 0 ; *num_tris = 0 ; *num_verts = 0 ; for ( int i = 0 ; i < getNumKids () ; i++ ) { ssgEntity *e = getKid ( i ) ; e -> getStats ( & nb, & nl, & nt, & nv ) ; *num_branches += nb ; *num_leaves += nl ; *num_tris += nt ; *num_verts += nv ; } } ssgEntity *ssgBranch::getByName ( char *match ) { if ( getName() != NULL && strcmp ( getName(), match ) == 0 ) return this ; /* Otherwise check the kids for a match */ for ( ssgEntity* k = getKid ( 0 ) ; k != NULL ; k = getNextKid() ) { ssgEntity *e = k -> getByName ( match ) ; if ( e != NULL ) return e ; } return NULL ; } ssgEntity *ssgBranch::getByPath ( char *path ) { /* Ignore leading '/' */ if ( *path == '/' ) ++path ; char *n = getName () ; /* If this node has no name then pass the request down the tree */ if ( n == NULL ) { for ( ssgEntity* k = getKid ( 0 ) ; k != NULL ; k = getNextKid () ) { ssgEntity *e = k -> getByPath ( path ) ; if ( e != NULL ) return e ; } return NULL ; } /* If this node does have a name - but it doesn't match the next part of the path then punt. */ unsigned int l = strlen ( n ) ; if ( strlen ( path ) < l || strncmp ( n, path, l ) != 0 ) return NULL ; /* If the first part of the path is this ssgBranch, we may have a winner. */ char c = path [ l ] ; /* If we reached the end of the path - we win! */ if ( c == '\0' ) return this ; if ( c == '/' ) { /* If the path continues, try to follow the path to the kids */ for ( ssgEntity* k = getKid ( 0 ) ; k != NULL ; k = getNextKid () ) { ssgEntity *e = k -> getByPath ( path + l ) ; if ( e != NULL ) return e ; } } return NULL ; } void ssgBranch::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) ) return ; int cull_result = cull_test ( f, m, test_needed ) ; if ( cull_result == SSG_OUTSIDE ) return ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> cull ( f, m, cull_result != SSG_INSIDE ) ; postTravTests ( SSGTRAV_CULL ) ; } void ssgBranch::hot ( sgVec3 s, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) ) return ; int hot_result = hot_test ( s, m, test_needed ) ; if ( hot_result == SSG_OUTSIDE ) return ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> hot ( s, m, hot_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_HOT ) ; } void ssgBranch::los ( sgVec3 s, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) ) return ; int los_result = los_test ( s, m, test_needed ) ; if ( los_result == SSG_OUTSIDE ) return ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> los ( s, m, los_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_LOS) ; } void ssgBranch::isect ( sgSphere *s, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) ) return ; int isect_result = isect_test ( s, m, test_needed ) ; if ( isect_result == SSG_OUTSIDE ) return ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> isect ( s, m, isect_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_ISECT ) ; } int ssgBranch::load ( FILE *fd ) { int nkids ; _ssgReadInt ( fd, & nkids ) ; if ( ! ssgEntity::load ( fd ) ) return FALSE ; for ( int i = 0 ; i < nkids ; i++ ) { ssgEntity *kid ; if ( ! _ssgLoadObject ( fd, (ssgBase **) &kid, ssgTypeEntity () ) ) return FALSE ; addKid ( kid ) ; } return TRUE ; } int ssgBranch::save ( FILE *fd ) { _ssgWriteInt ( fd, getNumKids() ) ; if ( ! ssgEntity::save ( fd ) ) return FALSE ; for ( int i = 0 ; i < getNumKids() ; i++ ) { if ( ! _ssgSaveObject ( fd, getKid ( i ) ) ) return FALSE ; } return TRUE ; } // ----------------------- code by W.K for merging hierarchy nodes ------------------------------ // #define VERBOSE int maxTriangles = 100; // Thats a nice value for handling MDL files for BoB. // You might want to assign another value, possibly -1 before calling mergeHNodes int maxVertices = 195; // see maxTriangles static int noOfMergedNodes; // number of merged nodes void AddLeafToTriangles(ssgVtxArray *pSrc , ssgVtxArray *pDest) // pDest must be of type GL_TRIANGLES // So, this function adds the contents of a leaf to a GL_TRIANGLES node. { // Add vertices and keep track of old to new indexes if(pSrc->getNumTriangles()==0) return; // wk 14.7.2002 int * aiOld2NewIndex = new int[pSrc->getNumVertices()]; int iSrc; // iDest; for(iSrc = 0; iSrc < pSrc->getNumVertices(); iSrc++) { float * pfSrc = pSrc->getVertex(iSrc); int bFound = FALSE; /* test for(iDest = 0; iDest < pDest->getNumVertices(); iDest++) { float * pfDest = pDest->getVertex(iDest); #define MYABS(x) ((x>0)?(x):(-(x))) if (MYABS(pfSrc[0]-pfDest[0])+MYABS(pfSrc[1]-pfDest[1])+ MYABS(pfSrc[2]-pfDest[2]) < 0.0001) { bFound = TRUE; aiOld2NewIndex[iSrc] = iDest; } }*/ if(!bFound) { aiOld2NewIndex[iSrc] = pDest->getNumVertices(); pDest->vertices->add(pfSrc); float * f = pSrc->getNormal(iSrc); if (f) pDest->normals->add(f); else { pDest->normals->add(_ssgNormalUp); } f = pSrc->getTexCoord(iSrc); if (f) pDest->texcoords->add(f); else { pDest->texcoords->add(_ssgTexCoord00); } // assert(pSrc->colours->getNum()==0); } } // Add faces pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(0)]); pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(1)]); pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(2)]); if(pSrc->getGLtype()==GL_TRIANGLE_FAN) { for(iSrc=1;iSrcgetNumTriangles();iSrc++) { // add 0, i+1, i+2 pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(0)]); pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(iSrc+1)]); pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(iSrc+2)]); } } else { assert(pSrc->getGLtype()==GL_TRIANGLES); for(iSrc=1;iSrcgetNumTriangles();iSrc++) { // add 0, i+1, i+2 pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(iSrc*3)]); pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(iSrc*3+1)]); pDest->addIndex(aiOld2NewIndex[*pSrc->getIndex(iSrc*3+2)]); } } // State pDest->setState(pSrc ->getState()); delete aiOld2NewIndex ; } void recursiveMergeHNodes ( ssgEntity *root, int delta ) // This is the recursive part of "mergeHNodes". // Walks the scene graph and looks for nodes to merge. // Uses AddLeafToTriangles for the actual merging { if ( root == NULL ) return ; if ( root -> isAKindOf ( ssgTypeBranch() ) ) { // see whether we can merge some of the kids ssgBranch *b = (ssgBranch *) root ; int i1, // loop var. oldnk=b -> getNumKids (), oldi1=-1 ; // for debug purpose only i1 = 0 ; while(i1 < b -> getNumKids () ) { // check that each loop increases i1 or decreases b -> getNumKids () if(!((i1>oldi1) || (oldnk>b ->getNumKids ()))) break; assert((i1>oldi1) || (oldnk>b ->getNumKids ())); oldi1=i1; oldnk=b ->getNumKids (); ssgEntity * pThis = b -> getKid ( i1 ) ; if ( pThis -> isAKindOf ( ssgTypeBranch() ) ) { recursiveMergeHNodes ( pThis, delta ); // recursively go deeper into the scene graph i1++; } else if(( pThis -> isAKindOf ( ssgTypeLeaf() ) ) && (i1+delta < b -> getNumKids ())) { ssgEntity * pOther = b -> getKid ( i1+delta ); if( pOther -> isAKindOf ( ssgTypeLeaf() ) ) { ssgLeaf *l1 = (ssgLeaf *)pThis, *l2 = (ssgLeaf *)pOther; // now: l1 = kid at i1, l2 = kid at i1+delta if ( (l1->getState() == l2->getState()) && ((maxTriangles < 0) || (l1->getNumTriangles()+l2->getNumTriangles()getNumVertices()+l2->getNumVertices()getPrintableName(), l2->getPrintableName())) ) { if (((l1->getGLtype() == GL_TRIANGLE_FAN) || (l1->getGLtype() == GL_TRIANGLES)) && ((l2->getGLtype() == GL_TRIANGLE_FAN) || (l2->getGLtype() == GL_TRIANGLES))) { // For using MDL files, these are all the types that we need ... if (l1->isA(ssgTypeVtxTable())) { l1 = ((ssgVtxTable *)l1)->getAs_ssgVtxArray(); // Kludge: mem leak b->replaceKid ( i1, l1 ) ; } if (l2->isA(ssgTypeVtxTable())) { l2 = ((ssgVtxTable *)l2)->getAs_ssgVtxArray(); // Kludge: mem leak b->replaceKid ( i1+delta, l2 ) ; } assert(l1 -> isAKindOf ( ssgTypeVtxArray() )); assert(l2 -> isAKindOf ( ssgTypeVtxArray() )); if((l1->getNumTriangles()+l2->getNumTriangles())<1300) // ??? wk kludge { #ifdef VERBOSE printf("I do sthg :-) %d\n", noOfMergedNodes++); #else noOfMergedNodes++; #endif if(l1->getGLtype() == GL_TRIANGLE_FAN) // convert to GL_TRIANGLES { ssgVtxArray * pNewArray = new ssgVtxArray(GL_TRIANGLES, new ssgVertexArray(), new ssgNormalArray(), new ssgTexCoordArray(), new ssgColourArray(), new ssgIndexArray()); AddLeafToTriangles((ssgVtxArray *)l1, pNewArray); pNewArray->setName(l1->getPrintableName()); assert(l1==b->getKid(i1)); b->removeKid(i1); b->addKid(pNewArray); pNewArray->dirtyBSphere (); l1 = pNewArray; } // l1 is of type GL_TRIANGLES now. { //ssgEntity *t= b->getKid(i1+delta); //assert(l2==t); } AddLeafToTriangles((ssgVtxArray *)l2, (ssgVtxArray *)l1); l1->dirtyBSphere (); l2->dirtyBSphere (); // unnessesary ? b->removeKid(l2); // kid(i1+delta) changed because of remove!?! i1+delta); } } else { i1++; printf("wrong types: %ld, %ld, num Trias: %ld, %ld\n", (long)l1->getGLtype(), (long)l1->getGLtype(), (long)l1->getNumTriangles(), (long)l2->getNumTriangles()); } } else i1++; } else i1++; } else i1++; } /* int i1=0; for ( i = 0 ; i < b -> getNumKids () ; i++ ) { ssgEntity * pThis = b -> getKid ( i1 ) ; if ( pThis -> isAKindOf ( ssgTypeBranch() ) ) { recursiveMergeHNodes ( pThis ); i1++; } else { assert( pThis -> isAKindOf ( ssgTypeLeaf() ) ); ssgLeaf *l1 = (ssgLeaf *)pThis; assert(l1 -> isAKindOf ( ssgTypeVtxArray() )); static int noOfMergedNodes=0; printf("I could do sthg :-) %d\n", noOfMergedNodes++); assert(l1->getGLtype() == GL_TRIANGLE_FAN); // convert to GL_TRIANGLES ssgVtxArray * pNewArray = new ssgVtxArray(GL_TRIANGLES, new ssgVertexArray(), new ssgNormalArray(), new ssgTexCoordArray(), new ssgColourArray(), new ssgIndexArray()); AddLeafToTriangles((ssgVtxArray *)l1, pNewArray); b->removeKid(i1); pNewArray->dirtyBSphere (); b->addKid(pNewArray); pNewArray->setName("meins!"); } } */ } } void ssgBranch::mergeHNodes() // merges hierarchy nodes if (not iff :-/): // a) Both have the same state // b) the same name // c) the result would not have more than maxTriangles triangles (if maxTriangles is negative, this is not checked). // d) the result would not have more than maxVertices vertices (if maxVertices is negative, this is not checked). // e) both are of type GL_TRIANGLE_FAN or GL_TRIANGLES { int deltas[] = { 1 ,2 ,1 ,3 ,2 ,1 ,2 ,4 ,2 ,1 ,5 ,1 ,2 ,6 ,2 ,1 ,2 ,7 ,2 ,1 ,2 ,1 ,8 ,1 ,2 ,1 ,2 ,9 ,2 ,1 ,2 ,1, 10 ,1 ,2 ,1 ,2 ,11 ,1 ,12 ,1 ,2 ,13 ,1 ,2 ,14 ,2 ,1 ,1 ,15 ,1 ,16 ,1 ,17 ,2 ,1 ,18 ,1 ,22 ,2 ,25 , 2 ,1 ,30 ,2 ,1 ,2 ,1 ,13 ,2 ,1 ,2 ,1 }; noOfMergedNodes = 0; for(unsigned i=0; i < sizeof(deltas)/sizeof(int); i++) { recursiveMergeHNodes ( this, deltas[i] ); #ifdef VERBOSE printf("############################################### ^%d\n". deltas[i]); #endif } printf("%d nodes were merged!\n", noOfMergedNodes); } plib-1.8.5/src/ssg/ssgStateTables.cxx0000644000175000001440000002233110765364437014447 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgStateTables.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" /* Well, it would be nice to say that these tables were automatically generated - but they weren't. So, there is some particularly nasty Macro-processing going on to save my poor aching fingers. */ #define E0 { if ( ! _ssgCurrentContext->textureOverridden ()) glEnable ( GL_TEXTURE_2D ) ; } #define E1 { if ( ! _ssgCurrentContext->cullfaceOverridden()) glEnable ( GL_CULL_FACE ) ; } #define E2 glEnable ( GL_COLOR_MATERIAL ) ; #define E3 glEnable ( GL_BLEND ) ; #define E4 glEnable ( GL_ALPHA_TEST ) ; #define E5 glEnable ( GL_LIGHTING ) ; #define D0 glDisable ( GL_TEXTURE_2D ) ; #define D1 glDisable ( GL_CULL_FACE ) ; #define D2 glDisable ( GL_COLOR_MATERIAL ) ; #define D3 glDisable ( GL_BLEND ) ; #define D4 glDisable ( GL_ALPHA_TEST ) ; #define D5 glDisable ( GL_LIGHTING ) ; /* Do any combination of useful glEnable/glDisable commands */ static void enable_00 () { } static void enable_01 () { E0 } static void enable_02 () { E1 } static void enable_03 () { E0 E1 } static void enable_04 () { E2 } static void enable_05 () { E0 E2 } static void enable_06 () { E1 E2 } static void enable_07 () { E0 E1 E2 } static void enable_08 () { E3 } static void enable_09 () { E0 E3 } static void enable_10 () { E1 E3 } static void enable_11 () { E0 E1 E3 } static void enable_12 () { E2 E3 } static void enable_13 () { E0 E2 E3 } static void enable_14 () { E1 E2 E3 } static void enable_15 () { E0 E1 E2 E3 } static void enable_16 () { E4 } static void enable_17 () { E0 E4 } static void enable_18 () { E1 E4 } static void enable_19 () { E0 E1 E4 } static void enable_20 () { E2 E4 } static void enable_21 () { E0 E2 E4 } static void enable_22 () { E1 E2 E4 } static void enable_23 () { E0 E1 E2 E4 } static void enable_24 () { E3 E4 } static void enable_25 () { E0 E3 E4 } static void enable_26 () { E1 E3 E4 } static void enable_27 () { E0 E1 E3 E4 } static void enable_28 () { E2 E3 E4 } static void enable_29 () { E0 E2 E3 E4 } static void enable_30 () { E1 E2 E3 E4 } static void enable_31 () { E0 E1 E2 E3 E4 } static void enable_32 () { E5 } static void enable_33 () { E0 E5 } static void enable_34 () { E1 E5 } static void enable_35 () { E0 E1 E5 } static void enable_36 () { E2 E5 } static void enable_37 () { E0 E2 E5 } static void enable_38 () { E1 E2 E5 } static void enable_39 () { E0 E1 E2 E5 } static void enable_40 () { E3 E5 } static void enable_41 () { E0 E3 E5 } static void enable_42 () { E1 E3 E5 } static void enable_43 () { E0 E1 E3 E5 } static void enable_44 () { E2 E3 E5 } static void enable_45 () { E0 E2 E3 E5 } static void enable_46 () { E1 E2 E3 E5 } static void enable_47 () { E0 E1 E2 E3 E5 } static void enable_48 () { E4 E5 } static void enable_49 () { E0 E4 E5 } static void enable_50 () { E1 E4 E5 } static void enable_51 () { E0 E1 E4 E5 } static void enable_52 () { E2 E4 E5 } static void enable_53 () { E0 E2 E4 E5 } static void enable_54 () { E1 E2 E4 E5 } static void enable_55 () { E0 E1 E2 E4 E5 } static void enable_56 () { E3 E4 E5 } static void enable_57 () { E0 E3 E4 E5 } static void enable_58 () { E1 E3 E4 E5 } static void enable_59 () { E0 E1 E3 E4 E5 } static void enable_60 () { E2 E3 E4 E5 } static void enable_61 () { E0 E2 E3 E4 E5 } static void enable_62 () { E1 E2 E3 E4 E5 } static void enable_63 () { E0 E1 E2 E3 E4 E5 } static void disable_00 () { } static void disable_01 () { D0 } static void disable_02 () { D1 } static void disable_03 () { D0 D1 } static void disable_04 () { D2 } static void disable_05 () { D0 D2 } static void disable_06 () { D1 D2 } static void disable_07 () { D0 D1 D2 } static void disable_08 () { D3 } static void disable_09 () { D0 D3 } static void disable_10 () { D1 D3 } static void disable_11 () { D0 D1 D3 } static void disable_12 () { D2 D3 } static void disable_13 () { D0 D2 D3 } static void disable_14 () { D1 D2 D3 } static void disable_15 () { D0 D1 D2 D3 } static void disable_16 () { D4 } static void disable_17 () { D0 D4 } static void disable_18 () { D1 D4 } static void disable_19 () { D0 D1 D4 } static void disable_20 () { D2 D4 } static void disable_21 () { D0 D2 D4 } static void disable_22 () { D1 D2 D4 } static void disable_23 () { D0 D1 D2 D4 } static void disable_24 () { D3 D4 } static void disable_25 () { D0 D3 D4 } static void disable_26 () { D1 D3 D4 } static void disable_27 () { D0 D1 D3 D4 } static void disable_28 () { D2 D3 D4 } static void disable_29 () { D0 D2 D3 D4 } static void disable_30 () { D1 D2 D3 D4 } static void disable_31 () { D0 D1 D2 D3 D4 } static void disable_32 () { D5 } static void disable_33 () { D0 D5 } static void disable_34 () { D1 D5 } static void disable_35 () { D0 D1 D5 } static void disable_36 () { D2 D5 } static void disable_37 () { D0 D2 D5 } static void disable_38 () { D1 D2 D5 } static void disable_39 () { D0 D1 D2 D5 } static void disable_40 () { D3 D5 } static void disable_41 () { D0 D3 D5 } static void disable_42 () { D1 D3 D5 } static void disable_43 () { D0 D1 D3 D5 } static void disable_44 () { D2 D3 D5 } static void disable_45 () { D0 D2 D3 D5 } static void disable_46 () { D1 D2 D3 D5 } static void disable_47 () { D0 D1 D2 D3 D5 } static void disable_48 () { D4 D5 } static void disable_49 () { D0 D4 D5 } static void disable_50 () { D1 D4 D5 } static void disable_51 () { D0 D1 D4 D5 } static void disable_52 () { D2 D4 D5 } static void disable_53 () { D0 D2 D4 D5 } static void disable_54 () { D1 D2 D4 D5 } static void disable_55 () { D0 D1 D2 D4 D5 } static void disable_56 () { D3 D4 D5 } static void disable_57 () { D0 D3 D4 D5 } static void disable_58 () { D1 D3 D4 D5 } static void disable_59 () { D0 D1 D3 D4 D5 } static void disable_60 () { D2 D3 D4 D5 } static void disable_61 () { D0 D2 D3 D4 D5 } static void disable_62 () { D1 D2 D3 D4 D5 } static void disable_63 () { D0 D1 D2 D3 D4 D5 } void (*__ssgEnableTable[64])() = { enable_00, enable_01, enable_02, enable_03, enable_04, enable_05, enable_06, enable_07, enable_08, enable_09, enable_10, enable_11, enable_12, enable_13, enable_14, enable_15, enable_16, enable_17, enable_18, enable_19, enable_20, enable_21, enable_22, enable_23, enable_24, enable_25, enable_26, enable_27, enable_28, enable_29, enable_30, enable_31, enable_32, enable_33, enable_34, enable_35, enable_36, enable_37, enable_38, enable_39, enable_40, enable_41, enable_42, enable_43, enable_44, enable_45, enable_46, enable_47, enable_48, enable_49, enable_50, enable_51, enable_52, enable_53, enable_54, enable_55, enable_56, enable_57, enable_58, enable_59, enable_60, enable_61, enable_62, enable_63 } ; void (*__ssgDisableTable[64])() = { disable_00, disable_01, disable_02, disable_03, disable_04, disable_05, disable_06, disable_07, disable_08, disable_09, disable_10, disable_11, disable_12, disable_13, disable_14, disable_15, disable_16, disable_17, disable_18, disable_19, disable_20, disable_21, disable_22, disable_23, disable_24, disable_25, disable_26, disable_27, disable_28, disable_29, disable_30, disable_31, disable_32, disable_33, disable_34, disable_35, disable_36, disable_37, disable_38, disable_39, disable_40, disable_41, disable_42, disable_43, disable_44, disable_45, disable_46, disable_47, disable_48, disable_49, disable_50, disable_51, disable_52, disable_53, disable_54, disable_55, disable_56, disable_57, disable_58, disable_59, disable_60, disable_61, disable_62, disable_63 } ; plib-1.8.5/src/ssg/ssgRoot.cxx0000644000175000001440000000267210765364437013165 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgRoot.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgRoot::copy_from ( ssgRoot *src, int clone_flags ) { ssgBranch::copy_from ( src, clone_flags ) ; } ssgBase *ssgRoot::clone ( int clone_flags ) { ssgRoot *b = new ssgRoot ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgRoot::ssgRoot (void) { type = ssgTypeRoot () ; } ssgRoot::~ssgRoot (void) { } int ssgRoot::load ( FILE *fd ) { return ssgBranch::load(fd) ; } int ssgRoot::save ( FILE *fd ) { return ssgBranch::save(fd) ; } plib-1.8.5/src/ssg/ssgVTable.cxx0000644000175000001440000004770210765364437013422 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgVTable.cxx 1938 2004-06-24 16:30:55Z sjbaker $ */ #include "ssgLocal.h" void ssgVTable::copy_from ( ssgVTable *src, int clone_flags ) { ssgLeaf::copy_from ( src, clone_flags ) ; gltype = src -> getPrimitiveType () ; indexed = src -> isIndexed () ; num_vertices = src -> getNumVertices () ; num_normals = src -> getNumNormals () ; num_colours = src -> getNumColours () ; num_texcoords = src -> getNumTexCoords () ; /* I should probably copy these arrays if SSG_CLONE_GEOMETRY is set - but life is short and ssgVTable is obsolete - and the inability to free the space that would create was the main reason to obsolete ssgVTable. */ src -> getVertexList ( (void **) & vertices , & v_index ) ; src -> getNormalList ( (void **) & normals , & n_index ) ; src -> getTexCoordList ( (void **) & texcoords, & t_index ) ; src -> getColourList ( (void **) & colours , & c_index ) ; recalcBSphere () ; } ssgBase *ssgVTable::clone ( int clone_flags ) { ssgVTable *b = new ssgVTable ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgVTable::ssgVTable () { type = ssgTypeVTable () ; gltype = GL_POINTS ; indexed = FALSE ; num_vertices = 0 ; v_index = NULL ; vertices = NULL ; num_normals = 0 ; n_index = NULL ; normals = NULL ; num_texcoords = 0 ; t_index = NULL ; texcoords = NULL ; num_colours = 0 ; c_index = NULL ; colours = NULL ; } ssgVTable::ssgVTable ( GLenum ty, int nv, unsigned short *vi, sgVec3 *vl, int nn, unsigned short *ni, sgVec3 *nl, int nt, unsigned short *ti, sgVec2 *tl, int nc, unsigned short *ci, sgVec4 *cl ) { type = ssgTypeVTable () ; gltype = ty ; indexed = TRUE ; num_vertices = nv ; v_index = vi ; vertices = vl ; num_normals = nn ; n_index = ni ; normals = nl ; num_texcoords = nt ; t_index = ti ; texcoords = tl ; num_colours = nc ; c_index = ci ; colours = cl ; recalcBSphere () ; } ssgVTable::ssgVTable ( GLenum ty, int nv, sgVec3 *vl, int nn, sgVec3 *nl, int nt, sgVec2 *tl, int nc, sgVec4 *cl ) { gltype = ty ; type = ssgTypeVTable () ; indexed = FALSE ; num_vertices = nv ; vertices = vl ; num_normals = nn ; normals = nl ; num_texcoords = nt ; texcoords = tl ; num_colours = nc ; colours = cl ; recalcBSphere () ; } ssgVTable::~ssgVTable () { } void ssgVTable::getTriangle ( int n, short *v1, short *v2, short *v3 ) { switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : *v1 = 0 ; *v2 = n+1 ; *v3 = n+2 ; return ; case GL_TRIANGLES : *v1 = n*3 ; *v2 = n*3+1 ; *v3 = n*3+2 ; return ; case GL_TRIANGLE_STRIP : case GL_QUAD_STRIP : if ( n & 1 ) { *v3 = n ; *v2 = n+1 ; *v1 = n+2 ; } else { *v1 = n ; *v2 = n+1 ; *v3 = n+2 ; } return ; case GL_QUADS : *v1 = (n/2)*4 + (n&1) + 0 ; *v2 = (n/2)*4 + (n&1) + 1 ; *v3 = (n/2)*4 + (n&1) + 2 ; return ; default : return ; } } int ssgVTable::getNumTriangles () { switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : return getNumVertices() - 2 ; case GL_TRIANGLES : return getNumVertices() / 3 ; case GL_TRIANGLE_STRIP : return getNumVertices() - 2 ; case GL_QUADS : return ( getNumVertices() / 4 ) * 2 ; case GL_QUAD_STRIP : return ( ( getNumVertices() - 2 ) / 2 ) * 2 ; default : break ; } return 0 ; } int ssgVTable::getNumLines () { switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : case GL_TRIANGLES : case GL_TRIANGLE_STRIP : case GL_QUADS : case GL_QUAD_STRIP : case GL_POINTS : return 0; case GL_LINES : // wk: FIXME: check the 3 following formulas. I don't have an OpenGL bokk at hand currently :-( return getNumVertices()/2; case GL_LINE_LOOP : return getNumVertices(); case GL_LINE_STRIP : return getNumVertices()-1; default : break ; } assert(false); /* Should never get here */ return 0 ; } void ssgVTable::getLine ( int n, short *v1, short *v2 ) { assert( n>=0 ); switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : case GL_TRIANGLES : case GL_TRIANGLE_STRIP : case GL_QUADS : case GL_QUAD_STRIP : case GL_POINTS : assert(false); case GL_LINES : // wk: FIXME: check the 3 following formulas. I don't have an OpenGL bokk at hand currently :-( assert ( 2*n+1 < getNumVertices() ); *v1 = 2*n; *v2 = 2*n+1 ; return ; case GL_LINE_LOOP : assert ( n < getNumVertices() ); *v1 = n; if ( n == getNumVertices()-1 ) *v2 = 0; else *v2 = n+1; return ; case GL_LINE_STRIP : assert ( n < getNumVertices()-1 ); *v1 = n; *v2 = n+1; return; default : break ; } assert(false); /* Should never get here */ return ; } void ssgVTable::transform ( const sgMat4 m ) { int i ; for ( i = 0 ; i < num_vertices ; i++ ) sgXformPnt3 ( vertices[i], vertices[i], m ) ; for ( i = 0 ; i < num_normals ; i++ ) sgXformVec3 ( normals[i], normals[i], m ) ; recalcBSphere () ; } void ssgVTable::recalcBSphere () { emptyBSphere () ; bbox . empty () ; int i ; if ( indexed ) for ( i = 0 ; i < num_vertices ; i++ ) bbox . extend ( vertices [ v_index [ i ] ] ) ; else for ( i = 0 ; i < num_vertices ; i++ ) bbox . extend ( vertices [ i ] ) ; extendBSphere ( & bbox ) ; dirtyBSphere () ; /* Cause parents to redo their bspheres */ bsphere_is_invalid = FALSE ; } void ssgVTable::draw () { if ( ! preDraw () ) return ; if ( _ssgCurrentContext-> stateOverridden () ) _ssgCurrentContext -> overriddenState () -> apply () ; else if ( hasState () ) getState () -> apply () ; stats_num_leaves++ ; stats_num_vertices += num_vertices ; #ifdef _SSG_USE_DLIST if ( dlist ) glCallList ( dlist ) ; else #endif draw_geometry () ; if ( postDrawCB != NULL ) (*postDrawCB)(this) ; } void ssgVTable::drawHighlight ( sgVec4 /* colour */, int /* vertex id */ ) { } void ssgVTable::drawHighlight ( sgVec4 /* colour */ ) { } void ssgVTable::pick ( int baseName ) { int i ; glPushName ( baseName ) ; if ( indexed ) { glBegin ( gltype ) ; for ( i = 0 ; i < num_vertices ; i++ ) glVertex3fv( vertices [ v_index [ i ]] ) ; glEnd () ; /* Then test each vertex in turn */ for ( i = 0 ; i < num_vertices ; i++ ) { glLoadName ( baseName + i + 1 ) ; glBegin ( GL_POINTS ) ; glVertex3fv( vertices [ v_index [ i ]] ) ; glEnd () ; } } else { glBegin ( gltype ) ; for ( i = 0 ; i < num_vertices ; i++ ) { glLoadName ( baseName + i + 1 ) ; glVertex3fv( vertices [ i ] ) ; } glEnd () ; /* Then test each vertex in turn */ for ( i = 0 ; i < num_vertices ; i++ ) { glLoadName ( baseName + i + 1 ) ; glBegin ( GL_POINTS ) ; glVertex3fv( vertices [ i ] ) ; glEnd () ; } } glPopName () ; } void ssgVTable::draw_geometry () { _ssgCurrStatistics . bumpVertexCount ( num_vertices ) ; _ssgCurrStatistics . bumpLeafCount ( 1 ) ; if ( indexed ) { glBegin ( gltype ) ; if ( num_colours == 0 ) glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ; if ( num_colours == 1 ) glColor4fv ( colours [ c_index [ 0 ]] ) ; if ( num_normals == 1 ) glNormal3fv ( normals [ n_index [ 0 ]] ) ; for ( int i = 0 ; i < num_vertices ; i++ ) { if ( num_colours > 1 ) glColor4fv ( colours [ c_index [ i ]] ) ; if ( num_normals > 1 ) glNormal3fv ( normals [ n_index [ i ]] ) ; if ( num_texcoords > 1 ) glTexCoord2fv ( texcoords [ t_index [ i ]] ) ; glVertex3fv ( vertices [ v_index [ i ]] ) ; } glEnd () ; } else { glBegin ( gltype ) ; if ( num_colours == 0 ) glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ; if ( num_colours == 1 ) glColor4fv ( colours [ 0 ] ) ; if ( num_normals == 1 ) glNormal3fv ( normals [ 0 ] ) ; for ( int i = 0 ; i < num_vertices ; i++ ) { if ( num_colours > 1 ) glColor4fv ( colours [ i ] ) ; if ( num_normals > 1 ) glNormal3fv ( normals [ i ] ) ; if ( num_texcoords > 1 ) glTexCoord2fv ( texcoords [ i ] ) ; glVertex3fv ( vertices [ i ] ) ; } glEnd () ; } } void ssgVTable::hot_triangles ( sgVec3 s, sgMat4 m, int /* test_needed */ ) { int nt = getNumTriangles () ; stats_hot_triangles += nt ; for ( int i = 0 ; i < nt ; i++ ) { short v1, v2, v3 ; sgVec3 vv1, vv2, vv3 ; sgVec4 plane ; if ( _ssgBackFaceCollisions ) getTriangle ( i, &v1, &v3, &v2 ) ; else getTriangle ( i, &v1, &v2, &v3 ) ; sgXformPnt3 ( vv1, getVertex(v1), m ) ; sgXformPnt3 ( vv2, getVertex(v2), m ) ; sgXformPnt3 ( vv3, getVertex(v3), m ) ; /* Does the X/Y coordinate lie outside the triangle's bbox, or does the Z coordinate lie beneath the bbox ? */ if ( ( s[0] < vv1[0] && s[0] < vv2[0] && s[0] < vv3[0] ) || ( s[1] < vv1[1] && s[1] < vv2[1] && s[1] < vv3[1] ) || ( s[0] > vv1[0] && s[0] > vv2[0] && s[0] > vv3[0] ) || ( s[1] > vv1[1] && s[1] > vv2[1] && s[1] > vv3[1] ) || ( s[2] < vv1[2] && s[2] < vv2[2] && s[2] < vv3[2] ) ) continue ; sgMakePlane ( plane, vv1, vv2, vv3 ) ; if ( _ssgIsHotTest ) { /* No HOT from upside-down or vertical triangles */ if ( getCullFace() && plane [ 2 ] <= 0 ) continue ; /* Find the point vertically below the text point as it crosses the plane of the polygon */ float z = sgHeightOfPlaneVec2 ( plane, s ) ; /* No HOT from below the triangle */ if ( z > s[2] ) continue ; /* Outside the vertical extent of the triangle? */ if ( ( z < vv1[2] && z < vv2[2] && z < vv3[2] ) || ( z > vv1[2] && z > vv2[2] && z > vv3[2] ) ) continue ; } /* Now it gets messy - the isect point is inside the bbox of the triangle - but that's not enough. Is it inside the triangle itself? */ float e1 = s [0] * vv1[1] - s [1] * vv1[0] ; float e2 = s [0] * vv2[1] - s [1] * vv2[0] ; float e3 = s [0] * vv3[1] - s [1] * vv3[0] ; float ep1 = vv1[0] * vv2[1] - vv1[1] * vv2[0] ; float ep2 = vv2[0] * vv3[1] - vv2[1] * vv3[0] ; float ep3 = vv3[0] * vv1[1] - vv3[1] * vv1[0] ; float ap = (float) fabs ( ep1 + ep2 + ep3 ) ; float ai = (float) ( fabs ( e1 + ep1 - e2 ) + fabs ( e2 + ep2 - e3 ) + fabs ( e3 + ep3 - e1 ) ) ; if ( ai > ap * 1.01 ) continue ; _ssgAddHit ( this, i, m, plane ) ; } } void ssgVTable::los_triangles ( sgVec3 s, sgMat4 m, int /* test_needed */ ) { int nt = getNumTriangles () ; stats_los_triangles += nt ; for ( int i = 0 ; i < nt ; i++ ) { short v1, v2, v3 ; sgVec3 vv1, vv2, vv3 ; sgVec4 plane ; SGfloat edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; SGfloat det,inv_det; SGfloat /*t,*/u,v; if ( _ssgBackFaceCollisions ) getTriangle ( i, &v1, &v3, &v2 ) ; else getTriangle ( i, &v1, &v2, &v3 ) ; sgXformPnt3 ( vv1, getVertex(v1), m ) ; sgXformPnt3 ( vv2, getVertex(v2), m ) ; sgXformPnt3 ( vv3, getVertex(v3), m ) ; sgVec3 cam; cam[0] = m[0][3]; cam[1] = m[1][3]; cam[2] = m[2][3]; //if ( _ssgIsLosTest ) //{ /* find vectors for two edges sharing vert0 */ sgSubVec3(edge1, vv2, vv1); sgSubVec3(edge2, vv3, vv1); /* begin calculating determinant - also used to calculate U parameter */ sgVectorProductVec3(pvec, s, edge2); /* if determinant is near zero, ray lies in plane of triangle */ det = sgScalarProductVec3(edge1, pvec); if (det > -0.0000001 && det < 0.0000001) continue; inv_det = (float)1.0 / det; /* calculate distance from vert0 to ray origin */ sgSubVec3(tvec, cam, vv1); /* calculate U parameter and test bounds */ u = sgScalarProductVec3(tvec, pvec) * inv_det; if (u < 0.0 || u > 1.0) continue; /* prepare to test V parameter */ sgVectorProductVec3(qvec, tvec, edge1); /* calculate V parameter and test bounds */ v = sgScalarProductVec3(s, qvec) * inv_det; if (v < 0.0 || u + v > 1.0) continue; /* calculate t, ray intersects triangle */ //t = sgScalarProductVec3(edge2, qvec) * inv_det; //} sgMakePlane ( plane, vv1, vv2, vv3 ) ; _ssgAddHit ( this, i, m, plane ) ; } } void ssgVTable::isect_triangles ( sgSphere *s, sgMat4 m, int test_needed ) { int nt = getNumTriangles () ; stats_isect_triangles += nt ; for ( int i = 0 ; i < nt ; i++ ) { short v1, v2, v3 ; sgVec3 vv1, vv2, vv3 ; sgVec4 plane ; if ( _ssgBackFaceCollisions ) getTriangle ( i, &v1, &v3, &v2 ) ; else getTriangle ( i, &v1, &v2, &v3 ) ; sgXformPnt3 ( vv1, getVertex(v1), m ) ; sgXformPnt3 ( vv2, getVertex(v2), m ) ; sgXformPnt3 ( vv3, getVertex(v3), m ) ; sgMakePlane ( plane, vv1, vv2, vv3 ) ; if ( ! test_needed ) { _ssgAddHit ( this, i, m, plane ) ; continue ; } float dp = (float) fabs ( sgDistToPlaneVec3 ( plane, s->getCenter() ) ) ; if ( dp > s->getRadius() ) continue ; /* The BSphere touches the plane containing the triangle - but does it actually touch the triangle itself? Let's erect some vertical walls around the triangle. */ /* Construct a 'wall' as a plane through two vertices and a third vertex made by adding the surface normal to the first of those two vertices. */ sgVec3 vvX ; sgVec4 planeX ; sgAddVec3 ( vvX, plane, vv1 ) ; sgMakePlane ( planeX, vv1, vv2, vvX ) ; float dp1 = sgDistToPlaneVec3 ( planeX, s->getCenter() ) ; if ( dp1 > s->getRadius() ) continue ; sgAddVec3 ( vvX, plane, vv2 ) ; sgMakePlane ( planeX, vv2, vv3, vvX ) ; float dp2 = sgDistToPlaneVec3 ( planeX, s->getCenter() ) ; if ( dp2 > s->getRadius() ) continue ; sgAddVec3 ( vvX, plane, vv3 ) ; sgMakePlane ( planeX, vv3, vv1, vvX ) ; float dp3 = sgDistToPlaneVec3 ( planeX, s->getCenter() ) ; if ( dp3 > s->getRadius() ) continue ; /* OK, so we now know that the sphere intersects the plane of the triangle and is not more than one radius outside the walls. However, you can still get close enough to the wall and to the triangle itself and *still* not intersect the triangle itself. However, if the center is inside the triangle then we don't need that costly test. */ if ( dp1 <= 0 && dp2 <= 0 && dp3 <= 0 ) { _ssgAddHit ( this, i, m, plane ) ; continue ; } /* ...now we really need that costly set of tests... If the sphere penetrates the plane of the triangle and the plane of the wall, then we can use pythagoras to determine if the sphere actually intersects that edge between the wall and the triangle. if ( dp_sqd + dp1_sqd > radius_sqd ) ...in! else ...out! */ float r2 = s->getRadius() * s->getRadius() - dp * dp ; if ( dp1 * dp1 <= r2 || dp2 * dp2 <= r2 || dp3 * dp3 <= r2 ) { _ssgAddHit ( this, i, m, plane ) ; continue ; } } } void ssgVTable::print ( FILE *fd, char *indent, int how_much ) { ssgLeaf::print ( fd, indent, how_much ) ; } int ssgVTable::load ( FILE *fd ) { sgVec3 temp; _ssgReadVec3 ( fd, temp ); bbox.setMin( temp ) ; _ssgReadVec3 ( fd, temp ); bbox.setMax( temp ) ; _ssgReadInt ( fd, &indexed ) ; _ssgReadInt ( fd, (int *)(&gltype) ) ; _ssgReadInt ( fd, &num_vertices ) ; _ssgReadInt ( fd, &num_normals ) ; _ssgReadInt ( fd, &num_texcoords) ; _ssgReadInt ( fd, &num_colours ) ; int i ; int max ; /* Vertices */ if ( indexed ) { v_index = new unsigned short [ num_vertices ] ; _ssgReadUShort ( fd, num_vertices, v_index ) ; max = 0 ; for ( i = 0 ; i < num_vertices ; i++ ) if ( v_index [ i ] > max ) max = v_index[i] ; } else max = num_vertices ; vertices = new sgVec3 [ max ] ; _ssgReadFloat ( fd, max * 3, (float *) vertices ) ; /* Normals */ if ( indexed ) { n_index = new unsigned short [ num_normals ] ; _ssgReadUShort ( fd, num_normals, n_index ) ; max = 0 ; for ( i = 0 ; i < num_normals ; i++ ) if ( n_index [ i ] > max ) max = n_index[i] ; } else max = num_normals ; normals = new sgVec3 [ max ] ; _ssgReadFloat ( fd, max * 3, (float *) normals ) ; /* Texture Coordinates */ if ( indexed ) { t_index = new unsigned short [ num_texcoords ] ; _ssgReadUShort ( fd, num_texcoords, t_index ) ; max = 0 ; for ( i = 0 ; i < num_texcoords ; i++ ) if ( t_index [ i ] > max ) max = t_index[i] ; } else max = num_texcoords ; texcoords = new sgVec2 [ max ] ; _ssgReadFloat ( fd, max * 2, (float *) texcoords ) ; /* Colours */ if ( indexed ) { c_index = new unsigned short [ num_colours ] ; _ssgReadUShort ( fd, num_colours, c_index ) ; max = 0 ; for ( i = 0 ; i < num_colours ; i++ ) if ( c_index [ i ] > max ) max = c_index[i] ; } else max = num_colours ; colours = new sgVec4 [ max ] ; _ssgReadFloat ( fd, max * 4, (float *) colours ) ; return ssgLeaf::load(fd) ; } int ssgVTable::save ( FILE *fd ) { _ssgWriteVec3 ( fd, bbox.getMin() ) ; _ssgWriteVec3 ( fd, bbox.getMax() ) ; _ssgWriteInt ( fd, indexed ) ; _ssgWriteInt ( fd, (int) gltype ) ; _ssgWriteInt ( fd, num_vertices ) ; _ssgWriteInt ( fd, num_normals ) ; _ssgWriteInt ( fd, num_texcoords) ; _ssgWriteInt ( fd, num_colours ) ; int i ; int max ; /* Vertices */ if ( indexed ) { max = 0 ; for ( i = 0 ; i < num_vertices ; i++ ) if ( v_index [ i ] > max ) max = v_index[i] ; _ssgWriteUShort ( fd, num_vertices, v_index ) ; } else max = num_vertices ; _ssgWriteFloat ( fd, max * 3, (float *)vertices ) ; /* Normals */ if ( indexed ) { max = 0 ; for ( i = 0 ; i < num_normals ; i++ ) if ( n_index [ i ] > max ) max = n_index[i] ; _ssgWriteUShort ( fd, num_normals, n_index ) ; } else max = num_normals ; _ssgWriteFloat ( fd, max * 3, (float *)normals ) ; /* Texture Coordinates */ if ( indexed ) { max = 0 ; for ( i = 0 ; i < num_texcoords ; i++ ) if ( t_index [ i ] > max ) max = t_index[i] ; _ssgWriteUShort ( fd, num_texcoords, t_index ) ; } else max = num_texcoords ; _ssgWriteFloat ( fd, max * 2, (float *)texcoords ) ; /* Colours */ if ( indexed ) { max = 0 ; for ( i = 0 ; i < num_colours ; i++ ) if ( c_index [ i ] > max ) max = c_index[i] ; _ssgWriteUShort ( fd, num_colours, c_index ) ; } else max = num_colours ; _ssgWriteFloat ( fd, max * 4, (float *)colours ) ; return ssgLeaf::save(fd) ; } plib-1.8.5/src/ssg/ssg3ds.h0000644000175000001440000000711010765364437012350 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssg3ds.h 2108 2006-12-11 20:42:05Z fayjf $ */ /******************************************************* ** ssg3ds.h ** * Common data for ssgLoad3ds.cxx and ssgSave3ds.cxx *******************************************************/ // 3ds chunk identifiers static const int CHUNK_VERSION = 0x0002; static const int CHUNK_RGB1 = 0x0010; // 3 floats of RGB static const int CHUNK_RGB2 = 0x0011; // 3 bytes of RGB static const int CHUNK_RGB3 = 0x0012; // 3 bytes of RGB (gamma) static const int CHUNK_AMOUNT = 0x0030; static const int CHUNK_MAIN = 0x4D4D; static const int CHUNK_OBJMESH = 0x3D3D; static const int CHUNK_ONEUNIT = 0x0100; static const int CHUNK_BKGCOLOR = 0x1200; static const int CHUNK_AMBCOLOR = 0x2100; static const int CHUNK_OBJBLOCK = 0x4000; static const int CHUNK_TRIMESH = 0x4100; static const int CHUNK_VERTLIST = 0x4110; static const int CHUNK_FACELIST = 0x4120; static const int CHUNK_FACEMAT = 0x4130; static const int CHUNK_MAPLIST = 0x4140; static const int CHUNK_SMOOLIST = 0x4150; static const int CHUNK_TRMATRIX = 0x4160; static const int CHUNK_LIGHT = 0x4600; static const int CHUNK_SPOTLIGHT = 0x4610; static const int CHUNK_CAMERA = 0x4700; static const int CHUNK_MATERIAL = 0xAFFF; static const int CHUNK_MATNAME = 0xA000; static const int CHUNK_AMBIENT = 0xA010; static const int CHUNK_DIFFUSE = 0xA020; static const int CHUNK_SPECULAR = 0xA030; static const int CHUNK_SHININESS = 0xA040; static const int CHUNK_SHINE_STRENGTH = 0xA041; static const int CHUNK_TRANSPARENCY = 0xA050; static const int CHUNK_TRANSP_FALLOFF = 0xA052; static const int CHUNK_DOUBLESIDED = 0xA081; static const int CHUNK_TEXTURE = 0xA200; static const int CHUNK_BUMPMAP = 0xA230; static const int CHUNK_MAPFILENAME = 0xA300; static const int CHUNK_MAPOPTIONS = 0xA351; static const int CHUNK_MAP_VSCALE = 0xA354; static const int CHUNK_MAP_USCALE = 0xA356; static const int CHUNK_MAP_UOFFST = 0xA358; static const int CHUNK_MAP_VOFFST = 0xA35A; static const int CHUNK_KEYFRAMER = 0xB000; static const int CHUNK_FRAMES = 0xB008; static const int CHUNK_KEYFRAME_MESH = 0xB002; static const int CHUNK_FRAME_OBJNAME = 0xB010; static const int CHUNK_FRAME_DUMMYNAME = 0xB011; static const int CHUNK_FRAME_PIVOT = 0xB013; static const int CHUNK_FRAME_POSITION = 0xB020; static const int CHUNK_FRAME_ROTATION = 0xB021; static const int CHUNK_FRAME_SCALE = 0xB022; static const int CHUNK_FRAME_HIERARCHY = 0xB030; plib-1.8.5/src/ssg/ssgLoadPCX.cxx0000644000175000001440000001364610765364437013477 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 2001 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadPCX.cxx 1963 2004-09-26 09:27:28Z bram $ */ //=========================================================================== // // File: ssgLoadPCX.cxx // // Created: 12.12.2003 // // Author: Wolfram Kuss // // Revision: $Id: ssgLoadPCX.cxx 1963 2004-09-26 09:27:28Z bram $ // // Description: Loads PCX texture files. Only 8 bit indexed for now. // // //=========================================================================== #include "ssgLocal.h" typedef unsigned char UByte,*UByteP; #include "pcx.h" #ifdef SSG_LOAD_PCX_SUPPORTED int ReadFileIntoBuffer(const char *fname, UByte *&buffer, UByte *&bufferorig, unsigned long &file_length) // Opens the file, allocates buffer of correct size to hold the file, reads it, closes it { // **** open file **** FILE *tfile; if ( (tfile = fopen(fname, "rb")) == NULL) { ulSetError( UL_WARNING, "ssgLoadTexture: Failed to open file '%s' for reading.", fname ); return false ; } // **** allocate buffer, read file into it and close file **** fseek(tfile, 0, SEEK_END); file_length = ftell(tfile); fseek(tfile, 0, SEEK_SET); buffer = new UByte[file_length]; bufferorig = buffer; fread(buffer, file_length, 1, tfile); fclose(tfile); return true; } bool ssgLoadPCX ( const char *fname, ssgTextureInfo* info ) { UByte *buffer, *bufferorig; unsigned long file_length; if(!ReadFileIntoBuffer(fname, buffer, bufferorig, file_length)) return false ; // **** "read" header and "analyse" it **** pcxHeaderType *ppcxHeader = (pcxHeaderType *) buffer; buffer += sizeof(pcxHeaderType); short width = ppcxHeader->xmax-ppcxHeader->x+1; short height = ppcxHeader->ymax-ppcxHeader->y+1; //p->isMasked = ((p->resOfRowanTexture & 0x200) != 0) ? 1 : 0; if ( info != NULL ) { info -> width = width ; info -> height = height ; info -> depth = 4 ; info -> alpha = TRUE ; //I think we have to set it to true always, since we always generate 4 bytes per pixel } // **** read body´; Do error checking **** long size = ((long)width)*height; UByte *pAlfa = NULL, * pBody = new UByte [size]; // 1 byte per texel UByte * pBodyorig = pBody; if(!ReadPCXBody(buffer, ppcxHeader, pBody)) // writes to pBody, which must have been allocated { delete [] buffer; delete [] pBody; ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - unsupported or broken PCX texture file", fname ) ; return false ; } if(*buffer++ != 12) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - PCX files needs a '12' byte", fname ) ; return false ; } assert(bufferorig + file_length - 768 == buffer); // starting at "buffer", you can find the palette, 256 entrys with 3 bytes each // only true for version 5 (and possible later versions)= // start alfa handling // PCX does not allow alfa, so to enable alfa, you need two files :-(, // one for the body, for example abc.pcx and one for the alfa component, for example abc_trans.pcx if(fname[strlen(fname)-4]=='.') { char *t, *s = new char[strlen(fname)+15]; strcpy(s, fname); t=&(s[strlen(s)-4]); strcpy(t, "_trans.pcx"); if(ulFileExists(s)) { UByte *alfaBuffer, *alfaBufferorig; if(!ReadFileIntoBuffer(s, alfaBuffer, alfaBufferorig, file_length)) return false ; // **** "read" header and "analyse" it **** ppcxHeader = (pcxHeaderType *) alfaBuffer; alfaBuffer += sizeof(pcxHeaderType); if(width != ppcxHeader->xmax-ppcxHeader->x+1) ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - Width does not agree to 'body' width, so alfa is ignored", s ) ; else { if (height != ppcxHeader->ymax-ppcxHeader->y+1) ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - Height does not agree to 'body' height, so alfa is ignored", s ) ; else { // **** read body´; Do error checking **** pAlfa = new UByte [size]; // 1 byte per texel if(!ReadPCXBody(alfaBuffer, ppcxHeader, pAlfa)) // writes to pBody, which must have been allocated { delete [] buffer; delete [] pAlfa; ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - unsupported or broken PCX texture file", fname ) ; return false ; } } } } } // end alfa handling UByte *texels = new UByte [size * 4]; // 4 bytes per texel int c = 0; int iRunningIndex = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { UByte a = pAlfa?pAlfa[iRunningIndex]:255; UByte b = pBody[iRunningIndex++]; texels[c++] = buffer[b*3 ]; texels[c++] = buffer[b*3 + 1]; texels[c++] = buffer[b*3 + 2]; texels[c++] = a; } } delete [] pBodyorig; delete [] bufferorig; if (pAlfa) delete [] pAlfa; return ssgMakeMipMaps ( texels, width, height, 4 ) ; } #else bool ssgLoadPCX ( const char *fname, ssgTextureInfo* info ) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - PCX texture support not configured", fname ) ; return false ; } #endif plib-1.8.5/src/ssg/ssgLoad3ds.cxx0000644000175000001440000011307010765364437013526 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoad3ds.cxx 2110 2006-12-12 15:43:45Z fayjf $ */ /******************************************************* ** ssgLoad3ds.cxx ** ** Written by Per Liedman (liedman@home.se) ** Last updated: 2001-02-09 ** ** This was written to be a part of Stephen J Bakers ** PLIB (http://plib.sourceforge.net) *******************************************************/ /* KNOWN ISSUES: * Some models (one of the test cases) gets turned "inside out" - obviously the triangle winding has been reversed so that all triangles that should be culled are shown and vice versa. I don't know where this information can be found in the file. * Models that uses double-sided materials sometimes look strange. My approach to double sided materials is to add a copy of each triangle with the winding reversed and also negate the normals...this seems to *almost* work. * The transformation matrix in the 3DS files is still a mystery to me - whatever I do with it seems to make things worse than ignoring it, although that doesn't work perfect either. I've taken a look at other loaders, and it seems that no one really knows what to do with them. */ #define USE_VTXARRAYS const int maxFacesPerLeaf = 10922; // = 32768 / 3 #include "ssgLocal.h" #include "ssg3ds.h" #define MAX_MATERIALS 512 #define PARSE_OK 1 #define PARSE_ERROR 0 #define CHUNK_HEADER_SIZE (2 + 4) #define IS_DOUBLESIDED 1 /* Define DEBUG if you want debug output (this might be a nice way of looking at the structure of a 3DS file). */ //#define DEBUG 1 #ifdef DEBUG #define DEBUGPRINT(f, x, y, z) ulSetError(UL_DEBUG, f, debug_indent, x, y, z) #else #define DEBUGPRINT(f, x, y, z) #endif #ifdef DEBUG static char debug_indent[256]; #endif /* this is the minimum value of the dot product for to faces if their normals should be smoothed, if they don't use smooth groups. */ // Until we are able to route such param through the LoaderOptions mechanism, // make it globally accessible /*static const*/ float _ssg_smooth_threshold = 0.8f; // parsing functions for chunks that need separate treatment. static int parse_material( unsigned int length); static int parse_objblock( unsigned int length); static int parse_rgb1( unsigned int length); static int parse_rgb2( unsigned int length); static int parse_material_name( unsigned int length); static int parse_ambient( unsigned int length); static int parse_diffuse( unsigned int length); static int parse_specular( unsigned int length); static int parse_shininess( unsigned int length); static int parse_transparency( unsigned int length); static int parse_doublesided( unsigned int length); static int parse_vert_list( unsigned int length); static int parse_face_list( unsigned int length); static int parse_map_list( unsigned int length); static int parse_tra_matrix( unsigned int length); static int parse_trimesh( unsigned int length); static int parse_smooth_list( unsigned int length); static int parse_face_materials( unsigned int length); static int parse_mapname( unsigned int length); static int parse_mapoptions( unsigned int length); static int parse_uscale( unsigned int length); static int parse_vscale( unsigned int length); static int parse_uoffst( unsigned int length); static int parse_voffst( unsigned int length); static int parse_oneunit( unsigned int length); static int parse_version( unsigned int length); static int parse_frame ( unsigned int length); static int parse_frame_objname ( unsigned int length); static int parse_frame_hierarchy( unsigned int length); static int identify_face_materials( unsigned int length ); static int parse_frame_dummyname( unsigned int length ); /* _ssg3dsChunk defines how a certain chunk is handled when encountered - what subchunks it might have and what parse function should be used for it. */ struct _ssg3dsChunk { unsigned short id; _ssg3dsChunk *subchunks; int (*parse_func) ( unsigned int ); }; // following arrays define the structure of the chunks in the 3ds file. static _ssg3dsChunk FaceListDataChunks[] = { { CHUNK_SMOOLIST, NULL, parse_smooth_list }, { CHUNK_FACEMAT, NULL, identify_face_materials }, { 0, NULL, NULL } }; static _ssg3dsChunk FaceListChunks[] = { { CHUNK_FACEMAT, NULL, parse_face_materials }, { 0, NULL, NULL } }; static _ssg3dsChunk TriMeshDataChunks[] = { { CHUNK_VERTLIST, NULL, parse_vert_list }, { CHUNK_MAPLIST, NULL, parse_map_list }, { 0, NULL, NULL } }; /* these chunks have to be known *before* we call parse_face_list (see parse_trimesh for more info) */ static _ssg3dsChunk TriMeshChunks[] = { { CHUNK_FACELIST, FaceListChunks, parse_face_list }, { CHUNK_TRMATRIX, NULL, parse_tra_matrix }, { 0, NULL, NULL } }; static _ssg3dsChunk ObjBlockChunks[] = { { CHUNK_TRIMESH, TriMeshChunks, parse_trimesh }, { 0, NULL, NULL } }; static _ssg3dsChunk TextureChunks[] = { { CHUNK_MAPFILENAME, NULL, parse_mapname }, { CHUNK_MAP_USCALE, NULL, parse_uscale }, { CHUNK_MAP_VSCALE, NULL, parse_vscale }, { CHUNK_MAP_UOFFST, NULL, parse_uoffst }, { CHUNK_MAP_VOFFST, NULL, parse_voffst }, { CHUNK_MAPOPTIONS, NULL, parse_mapoptions }, { 0, NULL, NULL } }; static _ssg3dsChunk MaterialColourChunks[] = { { CHUNK_RGB1, NULL, parse_rgb1 }, { CHUNK_RGB2, NULL, parse_rgb2 }, { CHUNK_RGB3, NULL, parse_rgb2 }, { 0, NULL, NULL } }; static _ssg3dsChunk MaterialChunks[] = { { CHUNK_MATNAME, NULL, parse_material_name }, { CHUNK_AMBIENT, MaterialColourChunks, parse_ambient }, { CHUNK_DIFFUSE, MaterialColourChunks, parse_diffuse }, { CHUNK_SPECULAR, MaterialColourChunks, parse_specular}, { CHUNK_SHINE_STRENGTH, NULL, parse_shininess }, { CHUNK_TRANSPARENCY, NULL, parse_transparency }, { CHUNK_TEXTURE, TextureChunks, NULL }, { CHUNK_DOUBLESIDED, NULL, parse_doublesided }, { 0, NULL, NULL } }; static _ssg3dsChunk ObjMeshChunks[] = { { CHUNK_MATERIAL, MaterialChunks, parse_material }, { CHUNK_OBJBLOCK, ObjBlockChunks, parse_objblock }, { CHUNK_ONEUNIT, NULL, parse_oneunit }, { 0, NULL, NULL } }; static _ssg3dsChunk FrameChunks[] = { { CHUNK_FRAME_OBJNAME , NULL, parse_frame_objname }, { CHUNK_FRAME_HIERARCHY, NULL, parse_frame_hierarchy }, { CHUNK_FRAME_DUMMYNAME, NULL, parse_frame_dummyname }, { 0, NULL, NULL } }; static _ssg3dsChunk KeyframerChunks[] = { { CHUNK_FRAMES , NULL , parse_frame }, { CHUNK_KEYFRAME_MESH, FrameChunks, NULL }, { 0, NULL, NULL } }; static _ssg3dsChunk MainChunks[] = { { CHUNK_OBJMESH, ObjMeshChunks , NULL }, { CHUNK_KEYFRAMER, KeyframerChunks, NULL }, { CHUNK_VERSION, NULL, parse_version }, { 0, NULL, NULL } }; static _ssg3dsChunk TopChunk[] = { { CHUNK_MAIN, MainChunks, NULL }, { 0, NULL, NULL } }; /* The material properties are temporarily stored in this structure before creating ssgSimpleStates out of them. */ struct _3dsMat { char *name ; int flags; sgVec3 colour[4]; float shi, alpha; char *tex_name; sgVec2 tex_scale, tex_offset; bool wrap_s, wrap_t; }; /* These are the indices used for identifying the materials colour-properties: */ #define _3DSMAT_AMB 0 #define _3DSMAT_DIF 1 #define _3DSMAT_EMI 2 #define _3DSMAT_SPE 3 /* Some 3ds files does not have any materials defined. This material is used in that case: */ static _3dsMat default_material= { "ssgLoad3ds default material", 0, { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, }, 0.0f, 1.0f, NULL, {1.0f, 1.0f}, {0.0f, 0.0f}, false, false }; /* A _ssg3dsStructureNode holds a mesh or a transformation node. All geometry is collected into structure nodes before actually being assembled into the scene-graph, since the hierarchy information is at the end of the 3ds file. */ struct _ssg3dsStructureNode { _ssg3dsStructureNode() { id = -1; object = NULL; has_been_used = false; next = NULL; } short id; ssgBranch *object; bool has_been_used; _ssg3dsStructureNode *next; }; static _ssg3dsStructureNode *findStructureNode( char *name ); static _ssg3dsStructureNode *findStructureNode( short id ); static int parse_chunks( _ssg3dsChunk *chunk_list, unsigned int length); static void add_leaf( _3dsMat *material, int listed_faces, unsigned short *face_indices ); /* Each vertex in a mesh has a face list associated with it, which contains all faces that use this vertex. This list is used when smoothing normals, since the adjacent faces of each vertex is needed. */ struct _ssg3dsFaceList { int face_index; _ssg3dsFaceList *next; }; static _ssg3dsFaceList *addFaceListEntry( _ssg3dsFaceList *face_list, int face_index ) { _ssg3dsFaceList *new_entry = new _ssg3dsFaceList; new_entry -> face_index = face_index; new_entry -> next = face_list; return new_entry; } static void freeFaceList( _ssg3dsFaceList *face_list ) { for (_ssg3dsFaceList *i = face_list, *temp = NULL; i != NULL; i = temp) { temp = i -> next; delete i; } } // globals static FILE *model; static int num_objects, num_materials, num_textures; static int double_sided; // is there some double sided material? static ssgBranch *top_object, *current_branch; static ssgLoaderOptions* current_options = NULL ; static _3dsMat **materials, *current_material; static unsigned short *vertex_index, *normal_index, num_vertices, num_faces; static unsigned int *smooth_list; static _ssg3dsFaceList **face_lists; static ssgTransform *current_transform, *last_dummy_object; static sgVec3 *vertex_list; static sgVec3 *face_normals, *vertex_normals; static sgVec2 *texcrd_list; static int smooth_found, facemat_found; static int colour_mode; static _ssg3dsStructureNode *object_list = NULL; static short current_structure_id = -1; static short dummy_id = 0; static short last_id = 0; /* flag to control whether to use smooting groups found in the file or not */ // Until we are able to route such param through the LoaderOptions mechanism, // make it globally accessible int _3DS_use_smoothing_groups = 0; // convenient functions static unsigned char get_byte() { unsigned char b; fread( &b, 1, 1, model ); return b; } /* NOTE: This string has to be freed by the caller Also note: You can't fetch strings longer than 256 characters! */ static char* get_string() { char *s = new char[256], read; int c = 0; while ( (read = getc(model)) != 0 ) { if (c < 255) s[c++] = read; } s[c] = 0; return s; } //========================================================== // STRUCTURE NODE FUNCTIONS static _ssg3dsStructureNode *findStructureNode( char *name ) { for ( _ssg3dsStructureNode *n = object_list; n != NULL; n = n->next ) { if ( strcmp( n->object->getName(), name ) == 0 ) { return n; } } return NULL; } static _ssg3dsStructureNode *findStructureNode( short id ) { for ( _ssg3dsStructureNode *n = object_list; n != NULL; n = n->next ) { if ( n->id == id ) { return n; } } return NULL; } static void addStructureNode( _ssg3dsStructureNode *node ) { if (object_list == NULL) { object_list = node; } else { node -> next = object_list; object_list = node; } } //========================================================== // MATERIAL PARSERS static int parse_mapname( unsigned int length ) { current_material->tex_name = get_string(); DEBUGPRINT("%sMap name: %s %s%s", current_material->tex_name, "", ""); return PARSE_OK; } static int parse_mapoptions( unsigned int length ) { unsigned short value = ulEndianReadLittle16(model); // bit 4: 0=tile (default), 1=do not tile (a single bit for both u and v) current_material->wrap_s = current_material->wrap_t = ((value & 0x10) == 0); DEBUGPRINT("%sMap options (wrap): %c %s%s", (current_material->wrap_s)?'Y':'N', "", ""); return PARSE_OK; } static int parse_uscale( unsigned int length ) { current_material->tex_scale[1] = ulEndianReadLittleFloat(model); DEBUGPRINT("%sU-scale: %.3f %s%s", current_material->tex_scale[1], "", ""); return PARSE_OK; } static int parse_vscale( unsigned int length ) { current_material->tex_scale[0] = ulEndianReadLittleFloat(model); DEBUGPRINT("%sV-scale: %.3f %s%s", current_material->tex_scale[0], "", ""); return PARSE_OK; } static int parse_uoffst( unsigned int length ) { current_material->tex_offset[1] = ulEndianReadLittleFloat(model); DEBUGPRINT("%sU-offset: %.3f %s%s", current_material->tex_offset[1], "", ""); return PARSE_OK; } static int parse_voffst( unsigned int length ) { current_material->tex_offset[0] = ulEndianReadLittleFloat(model); DEBUGPRINT("%sV-offset: %.3f %s%s", current_material->tex_offset[0], "", ""); return PARSE_OK; } static int parse_material( unsigned int length ) { materials[num_materials] = current_material = new _3dsMat; current_material->flags = 0; current_material->tex_name = NULL; num_materials++; /* set default value for material colours (taken from glMaterial man page) */ sgSetVec3(current_material -> colour[_3DSMAT_AMB], 0.2f, 0.2f, 0.2f ); sgSetVec3(current_material -> colour[_3DSMAT_DIF], 0.8f, 0.8f, 0.8f ); sgSetVec3(current_material -> colour[_3DSMAT_SPE], 0.0f, 0.0f, 0.0f ); sgSetVec3(current_material -> colour[_3DSMAT_EMI], 0.0f, 0.0f, 0.0f ); current_material -> shi = 0.0f; current_material -> alpha = 1.0f; /* set up texture info */ sgSetVec2(current_material -> tex_scale , 1.0f, 1.0f); sgSetVec2(current_material -> tex_offset, 0.0f, 0.0f); current_material -> wrap_s = current_material -> wrap_t = true; DEBUGPRINT("%sNew material found.%s%s%s", "", "", ""); return PARSE_OK; } static int parse_material_name( unsigned int length ) { current_material -> name = get_string(); DEBUGPRINT("%sMaterial name:%s%s%s", current_material->name, "", ""); return PARSE_OK; } static int parse_rgb1( unsigned int length ) { float r, g, b; r = ulEndianReadLittleFloat(model); g = ulEndianReadLittleFloat(model); b = ulEndianReadLittleFloat(model); DEBUGPRINT("%sColour: R:%.2f, G:%.2f, B:%.2f", r, g, b); sgSetVec3(current_material->colour[colour_mode], r, g, b); return PARSE_OK; } static int parse_rgb2( unsigned int length ) { float r, g, b; r = (float)get_byte() / 255.0f; g = (float)get_byte() / 255.0f; b = (float)get_byte() / 255.0f; DEBUGPRINT("%sColour: R:%.2f, G:%.2f, B:%.2f", r, g, b); sgSetVec3(current_material->colour[colour_mode], r, g, b); return PARSE_OK; } static int parse_ambient( unsigned int length ) { colour_mode = _3DSMAT_AMB; DEBUGPRINT("%sAmbient colour%s%s%s", "", "", ""); return PARSE_OK; } static int parse_diffuse( unsigned int length ) { colour_mode = _3DSMAT_DIF; DEBUGPRINT("%sDiffuse colour%s%s%s", "", "", ""); return PARSE_OK; } static int parse_specular( unsigned int length ) { colour_mode = _3DSMAT_SPE; DEBUGPRINT("%sSpecular colour%s%s%s", "", "", ""); return PARSE_OK; } static int parse_shininess( unsigned int length ) { // this chunk contains a percentage chunk, // so just read that chunks header ulEndianReadLittle16(model); ulEndianReadLittle32(model); current_material -> shi = (float)ulEndianReadLittle16(model) * 128.0f / 100.0f; DEBUGPRINT("%sShininess:%.1f%s%s", current_material->shi, "", ""); return PARSE_OK; } static int parse_transparency( unsigned int length ) { // this chunk contains a percentage chunk, // so just read that chunks header ulEndianReadLittle16(model); ulEndianReadLittle32(model); current_material->alpha = 1.0f - (float)ulEndianReadLittle16(model) / 100.0f; DEBUGPRINT("%sAlpha:%.1f%s%s", current_material->alpha, "", ""); return PARSE_OK; } static int parse_doublesided( unsigned int length ) { double_sided = current_material->flags |= IS_DOUBLESIDED; DEBUGPRINT("%sMaterial is double sided.%s%s%s", "", "", ""); return PARSE_OK; } static ssgSimpleState *get_state( _3dsMat *mat ) { if ( mat -> name != NULL ) { ssgSimpleState *st = current_options -> createSimpleState ( mat -> name ) ; if ( st != NULL ) return st ; } ssgSimpleState *st = new ssgSimpleState () ; st -> setName( mat -> name ); st -> setMaterial ( GL_AMBIENT, mat->colour[_3DSMAT_AMB][0], mat->colour[_3DSMAT_AMB][1], mat->colour[_3DSMAT_AMB][2], mat->alpha ) ; st -> setMaterial ( GL_DIFFUSE, mat->colour[_3DSMAT_DIF][0], mat->colour[_3DSMAT_DIF][1], mat->colour[_3DSMAT_DIF][2], mat->alpha ) ; st -> setMaterial ( GL_SPECULAR, mat->colour[_3DSMAT_SPE][0], mat->colour[_3DSMAT_SPE][1], mat->colour[_3DSMAT_SPE][2], mat->alpha ) ; st -> setMaterial ( GL_EMISSION, mat->colour[_3DSMAT_EMI][0], mat->colour[_3DSMAT_EMI][1], mat->colour[_3DSMAT_EMI][2], mat->alpha ) ; st -> setShininess( mat -> shi ) ; st -> disable ( GL_COLOR_MATERIAL ) ; st -> enable ( GL_LIGHTING ) ; st -> setShadeModel ( GL_SMOOTH ) ; if ( mat -> alpha < 0.99f ) { st -> disable ( GL_ALPHA_TEST ) ; st -> enable ( GL_BLEND ) ; st -> setTranslucent () ; } else { st -> disable ( GL_BLEND ) ; st -> setOpaque () ; } if (mat -> tex_name != NULL) { st -> setTexture( current_options -> createTexture(mat->tex_name, mat->wrap_s, mat->wrap_t) ) ; st -> enable( GL_TEXTURE_2D ); } else { st -> disable( GL_TEXTURE_2D ); } // don't show specular if exponent is 0, more info at: // http://sf.net/mailarchive/forum.php?thread_id=6481452&forum_id=4479 if ( ! mat->shi ) st -> setMaterial ( GL_SPECULAR, 0,0,0,1 ); return st ; } //========================================================== // TRIMESH PARSERS static void free_trimesh() { DEBUGPRINT("%sFreeing trimesh object%s%s%s", "","",""); if (vertex_list) delete [] vertex_list; if (face_normals) delete [] face_normals; if (vertex_normals) delete [] vertex_normals; if (texcrd_list) delete [] texcrd_list; if (smooth_list) delete [] smooth_list; if (vertex_index) delete [] vertex_index; if (face_lists) { for (int i = 0; i < num_vertices; i++) { freeFaceList( face_lists[i] ); } delete [] face_lists; } vertex_list = NULL; face_normals = NULL; vertex_normals = NULL; texcrd_list = NULL; smooth_list = NULL; vertex_index = NULL; face_lists = NULL; } static int parse_trimesh( unsigned int length ) { free_trimesh(); #if 0 current_transform = new ssgTransform(); current_branch -> addKid( current_transform ); #else // avoid introducing a useless ssgTransform current_transform = (ssgTransform*) current_branch; #endif /* Before we parse CHUNK_FACEMAT, we have to know vertices and texture coordinates. To ensure this, we make a special pass of the Trimesh chunks, just extracting this information. This is kind of a kludge, but it was the easiest way to solve this problem */ DEBUGPRINT("%sPrescanning sub-chunks for vertices and texture coords." \ "%s%s%s", "","",""); #ifdef DEBUG strcat(debug_indent, " "); #endif unsigned long p = ftell(model); int parse_ok = parse_chunks( TriMeshDataChunks, length ); fseek(model, p, SEEK_SET); #ifdef DEBUG debug_indent[strlen(debug_indent)-4] = 0; #endif DEBUGPRINT("%sDone prescanning.%s%s%s", "","",""); return parse_ok; } static int parse_vert_list( unsigned int length ) { num_vertices = ulEndianReadLittle16(model); vertex_list = new sgVec3[num_vertices]; face_lists = new _ssg3dsFaceList*[num_vertices]; DEBUGPRINT("%sReading %d vertices.%s%s", num_vertices, "", ""); for (int i = 0; i < num_vertices; i++) { vertex_list[i][0] = ulEndianReadLittleFloat(model); vertex_list[i][1] = ulEndianReadLittleFloat(model); vertex_list[i][2] = ulEndianReadLittleFloat(model); face_lists [i] = NULL; } return PARSE_OK; } static int parse_smooth_list( unsigned int length ) { int i; smooth_found = TRUE; smooth_list = new unsigned int[num_faces]; DEBUGPRINT("%sReading smoothlist%s%s%s", "", "", ""); for (i = 0; i < num_faces; i++) smooth_list[i] = ulEndianReadLittle32(model); return PARSE_OK; } static void smooth_normals( int use_smooth_list ) { for (int i = 0; i < num_faces; i++) { for (int j = 0; j < 3; j++) { int nindex = i * 3 +j; int vindex = vertex_index[ nindex ]; sgCopyVec3( vertex_normals[nindex], face_normals[i] ); // find all faces containing vertex vindex for ( _ssg3dsFaceList *l = face_lists[vindex]; l != NULL; l = l->next ) { int findex = l -> face_index; if ( findex != i ) { int should_smooth; if (use_smooth_list) { should_smooth = (smooth_list[i] & smooth_list[findex]); } else { float scalar = sgScalarProductVec3( face_normals[i], face_normals[findex] ); should_smooth = ( scalar > _ssg_smooth_threshold ); } if (should_smooth) { sgAddVec3( vertex_normals[nindex], face_normals[findex] ); } } } sgNormaliseVec3( vertex_normals[nindex] ); } } } static int identify_face_materials( unsigned int length ) { facemat_found = TRUE; DEBUGPRINT("%sFace materials found.%s%s%s", "","",""); fseek( model, length, SEEK_CUR ); return PARSE_OK; } static int parse_face_list( unsigned int length ) { int i; num_faces = ulEndianReadLittle16(model); DEBUGPRINT("%sReading %d faces.%s%s", num_faces, "", ""); vertex_index = new unsigned short[num_faces*3]; face_normals = new sgVec3[num_faces]; vertex_normals = new sgVec3[num_faces * 3]; for (i = 0; i < num_faces; i++) { int v1 = ulEndianReadLittle16(model); int v2 = ulEndianReadLittle16(model); int v3 = ulEndianReadLittle16(model); vertex_index[i*3 ] = v1; vertex_index[i*3 + 1] = v2; vertex_index[i*3 + 2] = v3; face_lists[ v1 ] = addFaceListEntry( face_lists[ v1 ], i ); face_lists[ v2 ] = addFaceListEntry( face_lists[ v2 ], i ); face_lists[ v3 ] = addFaceListEntry( face_lists[ v3 ], i ); unsigned short flags = ulEndianReadLittle16(model); if (flags & 7 == 0) { // Triangle vertices order should be swapped unsigned short tmp = vertex_index[i*3 + 1]; vertex_index[i*3 + 1] = vertex_index[i*3 + 2]; vertex_index[i*3 + 2] = tmp; } sgMakeNormal( face_normals[i], vertex_list[vertex_index[i*3 ]], vertex_list[vertex_index[i*3 + 1]], vertex_list[vertex_index[i*3 + 2]] ); } /* this is a special "hack" for the face list chunk because we HAVE to know the smooth list (if there is one) before building the ssgVtxTable objects, this parsing has to be done first...*ugh*/ smooth_found = FALSE; facemat_found = FALSE; DEBUGPRINT("%sPrescanning sub-chunks for smooth list...%s%s%s", "","",""); #ifdef DEBUG strcat(debug_indent, " "); #endif unsigned long p = ftell(model); parse_chunks( FaceListDataChunks, length - (2 + 8*num_faces) ); fseek(model, p, SEEK_SET); #ifdef DEBUG debug_indent[strlen(debug_indent)-4] = 0; #endif DEBUGPRINT("%sDone prescanning.%s%s%s", "","",""); /* now apply correct smoothing. If smooth list has been found, use it, otherwise use threshold value. */ smooth_normals( _3DS_use_smoothing_groups && smooth_found ); if (!facemat_found) { DEBUGPRINT("%sNo CHUNK_FACEMAT found. Adding default faces of material " \ "\"%s\"%s%s.", materials[0]->name, "", ""); unsigned short *face_indices = new unsigned short[num_faces]; for (i = 0; i < num_faces; i++) { face_indices[i] = i; } #if 0 add_leaf(materials[0], num_faces, face_indices); #else if( num_faces > maxFacesPerLeaf ) { float num_objs = (float)num_faces / maxFacesPerLeaf; int int_num_objs = int(num_objs); ulSetError( UL_DEBUG, "\tgeometry objects '%s' split into %d leaves", current_branch->getName(), num_objs > int_num_objs ? int_num_objs+1 : int_num_objs); } for ( int il = 0; il < num_faces; il += maxFacesPerLeaf ) { add_leaf(materials[0], ulMin(num_faces-il,maxFacesPerLeaf), &face_indices[il]); } #endif } return PARSE_OK; } static int parse_map_list( unsigned int length ) { unsigned short num_v = ulEndianReadLittle16(model); texcrd_list = new sgVec2[num_v]; DEBUGPRINT("%sReading %d texture coords.%s%s", num_v, "", ""); for (int i = 0; i < num_v; i++) { texcrd_list[i][0] = ulEndianReadLittleFloat(model); texcrd_list[i][1] = ulEndianReadLittleFloat(model); } return PARSE_OK; } static int parse_tra_matrix( unsigned int length ) { sgMat4 m; sgMakeIdentMat4( m ); DEBUGPRINT("%sReading transformation matrix.%s%s%s", "","",""); /* Strange things seems to be going on with the local coordinate system in 3ds - I have commented this out, but things seems to work better without it (which is odd).*/ int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 3; j++) { m[j][i] = ulEndianReadLittleFloat(model); } } #if 0 m[3][3] = 1.0f; sgTransposeNegateMat4( m ); #ifdef DEBUG for (int a = 0; a < 4; a++) { fputs(debug_indent, stderr); for (int b = 0; b < 4; b++) { fprintf(stderr, "%.2f\t", m[b][a]); } putc('\n', stderr); } #endif // current_transform -> setTransform( m ); #endif return PARSE_OK; } static void add_leaf( _3dsMat *material, int listed_faces, unsigned short *face_indices ) { int is_ds = material->flags & IS_DOUBLESIDED; int has_texture = material->tex_name != NULL; ssgVertexArray *vertices = new ssgVertexArray(); ssgNormalArray *normals = new ssgNormalArray(); ssgTexCoordArray *texcrds = NULL; #ifdef USE_VTXARRAYS ssgIndexArray* indices = new ssgIndexArray(); #endif if (has_texture) { if (texcrd_list == NULL) { ulSetError(UL_WARNING, "ssgLoad3ds: Texture coords missing."); } else { texcrds = new ssgTexCoordArray(); } } int tri_idx = 0; for (int i = 0; i < listed_faces; i++) { unsigned short faceindex = face_indices[i]; int v1 = faceindex * 3, v2 = faceindex * 3 + 1, v3 = faceindex * 3 + 2; #ifdef USE_VTXARRAYS indices->add( tri_idx++ ); indices->add( tri_idx++ ); indices->add( tri_idx++ ); #endif vertices->add( vertex_list[ vertex_index[v1] ] ); vertices->add( vertex_list[ vertex_index[v2] ] ); vertices->add( vertex_list[ vertex_index[v3] ] ); normals ->add( vertex_normals[ v1 ] ); normals ->add( vertex_normals[ v2 ] ); normals ->add( vertex_normals[ v3 ] ); if (has_texture && texcrd_list != NULL) { int num_texcrds = 3; sgVec2 _texcrds[6]; sgCopyVec2( _texcrds[0], texcrd_list[ vertex_index[v1] ] ); sgCopyVec2( _texcrds[1], texcrd_list[ vertex_index[v2] ] ); sgCopyVec2( _texcrds[2], texcrd_list[ vertex_index[v3] ] ); if (is_ds) { num_texcrds = 6; sgCopyVec2( _texcrds[3], texcrd_list[ vertex_index[v1] ] ); sgCopyVec2( _texcrds[4], texcrd_list[ vertex_index[v3] ] ); sgCopyVec2( _texcrds[5], texcrd_list[ vertex_index[v2] ] ); } for (int j = 0; j < num_texcrds; j++) { _texcrds[j][0] *= material->tex_scale[0]; _texcrds[j][1] *= material->tex_scale[1]; sgAddVec2( _texcrds[j], material->tex_offset ); texcrds->add( _texcrds[j] ); } } if (is_ds) { sgVec3 n[3]; /* we have to use the *negated* normals for back faces */ vertices->add( vertex_list[ vertex_index[v1] ] ); vertices->add( vertex_list[ vertex_index[v3] ] ); vertices->add( vertex_list[ vertex_index[v2] ] ); sgCopyVec3( n[0], vertex_normals[v1] ); sgCopyVec3( n[1], vertex_normals[v3] ); sgCopyVec3( n[2], vertex_normals[v2] ); for (int j = 0; j < 3; j++) { sgNegateVec3( n[j] ); normals->add( n[j] ); } #ifdef USE_VTXARRAYS indices->add( tri_idx++ ); indices->add( tri_idx++ ); indices->add( tri_idx++ ); #endif } } #ifdef USE_VTXARRAYS ssgVtxArray* vtab = new ssgVtxArray ( GL_TRIANGLES, vertices, normals, texcrds, NULL, indices ); #else ssgVtxTable* vtab = new ssgVtxTable ( GL_TRIANGLES, vertices, normals, texcrds, NULL ) ; #endif vtab -> setState ( get_state( material ) ) ; vtab -> setCullFace ( TRUE ) ; ssgLeaf* leaf = current_options -> createLeaf ( vtab, 0 ) ; if ( leaf ) current_transform -> addKid( leaf ); } static int parse_face_materials( unsigned int length ) { int mat_num; char *mat_name = get_string(); _3dsMat *material = NULL; // find the material for (mat_num = 0; mat_num < num_materials; mat_num++) { if ( strcmp( mat_name, materials[mat_num]->name ) == 0 ) { material = materials[mat_num]; break; } } if (material == NULL) { ulSetError(UL_WARNING, "ssgLoad3ds: Undefined reference to material " \ "\"%s\" found.", mat_name); return PARSE_ERROR; } unsigned short listed_faces = ulEndianReadLittle16(model); DEBUGPRINT("%sFaces of \"%s\" list with %d faces.%s", mat_name, listed_faces, ""); delete mat_name; // no longer needed unsigned short *face_indices = new unsigned short[listed_faces]; for (int i = 0; i < listed_faces; i++) { face_indices[i] = ulEndianReadLittle16(model); } #if 0 add_leaf(material, listed_faces, face_indices); #else if( listed_faces > maxFacesPerLeaf ) { float num_objs = (float)listed_faces / maxFacesPerLeaf; int int_num_objs = int(num_objs); ulSetError( UL_DEBUG, "\tgeometry objects '%s' split into %d leaves", current_branch->getName(), num_objs > int_num_objs ? int_num_objs+1 : int_num_objs); } for ( int il = 0; il < listed_faces; il += maxFacesPerLeaf ) { add_leaf(material, ulMin(listed_faces-il,maxFacesPerLeaf), &face_indices[il]); } #endif delete [] face_indices; return PARSE_OK; } //========================================================== // OBJBLOCK PARSER static int parse_objblock( unsigned int length ) { char *object_name = get_string(); current_branch = new ssgTransform; current_branch -> setName( object_name ); _ssg3dsStructureNode *object_node = new _ssg3dsStructureNode; object_node -> object = current_branch; addStructureNode( object_node ); DEBUGPRINT("%sObject block \"%s\"%s%s", object_name, "", ""); delete object_name; return PARSE_OK; } static int parse_oneunit( unsigned int length ) { #ifdef DEBUG float oneunit = ulEndianReadLittleFloat(model); DEBUGPRINT("%sOne unit: %.3f%s%s", oneunit, "", ""); #else ulEndianReadLittleFloat(model) ; #endif return PARSE_OK; } static int parse_version( unsigned int length ) { #ifdef DEBUG unsigned int version = ulEndianReadLittle32(model); DEBUGPRINT("%s3DS Version: %d%s%s", version, "", ""); #else ulEndianReadLittle32(model) ; #endif return PARSE_OK; } //========================================================== // KEYFRAME CHUNK PARSER static int parse_frame( unsigned int length ) { // this chunk is not used for anything right now #ifdef DEBUG DEBUGPRINT("%sFrame start: %d, end: %d%s", ulEndianReadLittle32(model), ulEndianReadLittle32(model), ""); #else ulEndianReadLittle32(model); ulEndianReadLittle32(model); #endif return PARSE_OK; } static int parse_frame_dummyname( unsigned int length ) { char *dummyname = get_string(); if ( last_dummy_object != (ssgTransform*)NULL ) last_dummy_object->setName( dummyname ); delete dummyname; return PARSE_OK; } static int parse_frame_objname( unsigned int length ) { /* This chunk defines a hierarchy elements name and its parent object's identifier. This function assumes that the hierarchy is defined from root to leaf, i.e. a nodes parent must have been declared before the node itself is declared. */ char *objname = get_string(), dummyname[255]; ulEndianReadLittle16(model); ulEndianReadLittle16(model); short parent_id = ulEndianReadLittle16(model); int dummy = 0; DEBUGPRINT("%sObject name: %s, parent: %d%s", objname, parent_id, ""); if ( strcmp(objname,"$$$DUMMY") == 0 ) { sprintf( dummyname, "%s_%d", objname, dummy_id++ ); objname = dummyname; dummy = 1; } _ssg3dsStructureNode *current_structure_node = findStructureNode( objname ); if ( current_structure_node == NULL ) { current_structure_node = new _ssg3dsStructureNode; current_structure_node -> object = last_dummy_object = new ssgTransform; current_structure_node -> object -> setName( objname ); addStructureNode( current_structure_node ); } if ( current_structure_id >= 0 ) { current_structure_node -> id = current_structure_id; current_structure_id = -1; } else current_structure_node -> id = last_id++; if ( parent_id != -1 ) { _ssg3dsStructureNode *parent = findStructureNode( parent_id ); if (parent == NULL) { ulSetError( UL_WARNING, "ssgLoad3ds: Hierarchy entry \"%d\" does "\ "not match any defined objects.", parent_id ); } else { parent -> object -> addKid( current_structure_node -> object ); current_structure_node -> has_been_used = true; } } else { top_object -> addKid( current_structure_node -> object ); current_structure_node -> has_been_used = true; } if ( !dummy ) delete objname; return PARSE_OK; } static int parse_frame_hierarchy( unsigned int length ) { current_structure_id = ulEndianReadLittle16(model); DEBUGPRINT("%sThis object's hierarchy id: %d.%s%s", current_structure_id, "", ""); return PARSE_OK; } //========================================================== // GENERAL CHUNK PARSER static int parse_chunks( _ssg3dsChunk *chunk_list, unsigned int length ) { int parse_ok = PARSE_OK; unsigned short id; unsigned int sub_length; unsigned int p = 0; _ssg3dsChunk *t; while (parse_ok && p < length) { id = ulEndianReadLittle16(model); sub_length = ulEndianReadLittle32(model); if (p + sub_length > length) { ulSetError(UL_WARNING, "ssgLoad3ds: Illegal chunk %X of length %i. " \ "Chunk is longer than parent chunk.", (int)id, sub_length); return PARSE_ERROR; } p += sub_length; sub_length -= CHUNK_HEADER_SIZE; for (t = chunk_list; t->id != 0 && t->id != id; t++); if (t->id == id) { DEBUGPRINT("%sFound chunk %X of length %d%s (known)", id, sub_length,""); // this is a known chunk // do chunk-specific parsing if available unsigned long cp = ftell(model); if (t->parse_func) parse_ok = t->parse_func( sub_length ); #ifdef DEBUG strcat(debug_indent, " "); #endif // if chunk can have subchunks, parse these if (t->subchunks && parse_ok) { parse_ok = parse_chunks( t->subchunks, sub_length - (ftell(model)-cp) ); } #ifdef DEBUG debug_indent[strlen(debug_indent)-4] = 0; #endif } else { DEBUGPRINT("%sFound chunk %X of length %d%s (unknown)", id, sub_length,""); fseek( model, sub_length, SEEK_CUR ); } } return parse_ok; } ssgEntity *ssgLoad3ds( const char *filename, const ssgLoaderOptions* options ) { int i; ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; char filepath [ 1024 ] ; current_options -> makeModelPath ( filepath, filename ) ; model = fopen ( filepath, "rb" ); if ( model == NULL ) { ulSetError(UL_WARNING, "ssgLoad3ds: Failed to open '%s' for reading", filepath ) ; return NULL ; } fseek(model, 0, SEEK_END); unsigned long size = ftell(model); rewind(model); current_structure_id = -1; dummy_id = last_id = 0; last_dummy_object = (ssgTransform*)NULL; num_objects = num_materials = num_textures = 0; object_list = NULL; vertex_list = NULL; texcrd_list = NULL; face_normals = NULL; face_lists = NULL; vertex_index = normal_index = NULL; top_object = new ssgBranch(); // initialize some storage room for materials // (ok, could be implemented as linked list, but...well I'm lazy) materials = new _3dsMat*[MAX_MATERIALS]; // strange enough, the 3ds file does not have to include any materials, // in which case we will use this one. materials[0] = & default_material; parse_chunks( TopChunk, size ); fclose(model); // clean up the materials array for (i = 0; i < num_materials; i++) { if (materials[i] -> name != NULL) { delete [] materials[i] -> name; } if (materials[i] -> tex_name != NULL) { delete [] materials[i] -> tex_name; } delete materials[i]; } for ( _ssg3dsStructureNode *n = object_list, *temp; n != NULL; n = temp ) { if ( !n -> has_been_used ) { top_object -> addKid( n -> object ); } temp = n -> next; delete n; } delete [] materials; free_trimesh(); return top_object; } plib-1.8.5/src/ssg/ssgLoadIV.cxx0000644000175000001440000002612310765364437013355 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 William Lachance, Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "ssgLocal.h" #include "ssgParser.h" #include "ssgLoaderWriterStuff.h" #include "ssgLoadVRML.h" static _ssgParserSpec parser_spec = { "\r\n\t, ", // delim_chars_skipable 0, // delim_chars_non_skipable NULL, // pre_processor "{[", // open_brace_chars "}]", // close_brace_chars '"', // quote_char '#', // comment_char 0 // comment_string }; static ssgLoaderOptions* currentOptions = NULL ; static _nodeIndex *definedNodes = NULL; static bool iv_parseSeparator( ssgBranch *parentBranch, _traversalState *parentData, char *defName ); static bool iv_parseSwitch( ssgBranch *parentBranch, _traversalState *parentData, char *defName ); static bool iv_parseIndexedFaceSet( ssgBranch *parentBranch, _traversalState *parentData, char *defName ); static bool iv_parseTexture2( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); static _parseTag ivTags [] = { { "Separator", iv_parseSeparator }, { "Switch", iv_parseSwitch }, { "IndexedFaceSet", iv_parseIndexedFaceSet }, { "Coordinate3", vrml1_parseCoordinate3 }, { "TextureCoordinate2", vrml1_parseTextureCoordinate2 }, { "Texture2", iv_parseTexture2 }, { "ShapeHints", vrml1_parseShapeHints }, { "MatrixTransform", vrml1_parseMatrixTransform }, { "Scale", vrml1_parseScale }, { "Rotation", vrml1_parseRotation }, { "Translation", vrml1_parseTranslation }, { NULL, NULL }, }; ssgEntity *ssgLoadIV( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; currentOptions = ssgGetCurrentOptions () ; if ( !vrmlParser.openFile( fname, &parser_spec ) ) { ulSetError ( UL_WARNING, "ssgLoadIV: Failed to open '%s' for reading", fname ) ; return 0; } definedNodes = new _nodeIndex(); // check for a valid header header char *token; if( !(token = vrmlParser.getRawLine()) ) return 0; if( strstr( token, "#Inventor V2.1 ascii" ) == NULL ) // should we handle different flavours of inventor? { ulSetError ( UL_WARNING, "ssgLoadIV: valid iv header not found" ); return 0; } // creating a root node.. ssgBranch *rootBranch = new ssgBranch(); vrmlParser.expectNextToken( "Separator" ); if( !iv_parseSeparator( rootBranch, NULL, NULL ) ) { ulSetError ( UL_WARNING, "ssgLoadVRML: Failed to extract valid object(s) from %s", fname ) ; delete( rootBranch ); delete( definedNodes ); return NULL ; } vrmlParser.closeFile(); delete( definedNodes ); return rootBranch ; } static bool iv_parseSeparator( ssgBranch *parentBranch, _traversalState *parentData, char *defName ) { char *childDefName = NULL; char *token; vrmlParser.expectNextToken( "{" ); // create a branch for this node ssgBranch *currentBranch = new ssgBranch(); if( defName != NULL ) { currentBranch->setName( defName ); definedNodes->insert( currentBranch ); } _traversalState *currentData; if( parentData == NULL ) currentData = new _traversalState(); else currentData = parentData->clone(); token = vrmlParser.getNextToken( NULL ); while( strcmp( token, "}" ) ) { int i=0; bool tokenFound = FALSE; while( ivTags[i].token != NULL && !tokenFound ) { if( !strcmp( token, ivTags[i].token ) ) { if( !(ivTags[i].func( currentBranch, currentData, childDefName ) ) ) { delete( currentBranch ); delete( currentData ); return FALSE; } tokenFound = TRUE; } i++; } if( !tokenFound ) parseUnidentified(); token = vrmlParser.getNextToken( NULL ); } parentBranch->addKid( currentBranch ); delete( currentData ); // delete the currentData structure (we may use its content, but not its form) return TRUE; } static bool iv_parseSwitch( ssgBranch *parentBranch, _traversalState *parentData, char *defName ) // UNSUPPORTED BEHAVIOUR: does not do a check for a whichChild parameter. Assumes that a switch // "hides" all of its children. { char *childDefName = NULL; char *token; vrmlParser.expectNextToken( "{" ); // create a branch for this node ssgBranch *currentBranch = new ssgSelector(); ((ssgSelector *)currentBranch)->select( 0 ); // fixme: allow for children to be traversed if( defName != NULL ) { currentBranch->setName( defName ); definedNodes->insert( currentBranch ); } _traversalState *currentData; if( parentData == NULL ) currentData = new _traversalState(); else currentData = parentData->clone(); token = vrmlParser.getNextToken( NULL ); while( strcmp( token, "}" ) ) { int i=0; bool tokenFound = FALSE; while( ivTags[i].token != NULL && !tokenFound ) { if( !strcmp( token, ivTags[i].token ) ) { if( !(ivTags[i].func( currentBranch, currentData, childDefName ) ) ) { delete( currentBranch ); delete( currentData ); return FALSE; } tokenFound = TRUE; } i++; } if( !tokenFound ) parseUnidentified(); token = vrmlParser.getNextToken( NULL ); } parentBranch->addKid( currentBranch ); delete( currentData ); // delete the currentData structure (we may use its content, but not its form) return TRUE; } static bool iv_parseIndexedFaceSet( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { char *token; bool texCoordIndexGiven = FALSE; ssgBranch *currentBranch = new ssgBranch(); if( defName != NULL ) { currentBranch->setName( defName ); definedNodes->insert( currentBranch ); } ssgLoaderWriterMesh *loaderMesh = new ssgLoaderWriterMesh(); loaderMesh->createFaces(); loaderMesh->setVertices( currentData->getVertices() ); if( currentData->getTexture() != NULL && currentData->getTextureCoordinates() != NULL ) loaderMesh->createPerFaceAndVertexTextureCoordinates2(); vrmlParser.expectNextToken("{"); token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "}" ) ) { if( !strcmp( token, "coordIndex" ) ) { vrmlParser.expectNextToken("coordIndex"); if( !vrml1_parseCoordIndex( loaderMesh, currentData ) ) { delete( loaderMesh ); return FALSE; } } else if( !strcmp( token, "textureCoordIndex" ) ) { texCoordIndexGiven = TRUE; vrmlParser.expectNextToken("textureCoordIndex"); if( !vrml1_parseTextureCoordIndex( loaderMesh, currentData ) ) { delete( loaderMesh ); return FALSE; } } else token = vrmlParser.getNextToken( NULL ); token = vrmlParser.peekAtNextToken( NULL ); } //ulSetError(UL_DEBUG, "Level: %i. Found %i faces here.\n", vrmlParser.level, numFaces); vrmlParser.expectNextToken( "}" ); // ------------------------------------------------------- // add the face set to ssg // ------------------------------------------------------- // kludge. We need a state for addToSSG: ssgSimpleState * ss = new ssgSimpleState () ; // (0) ? ss -> setMaterial ( GL_AMBIENT, 0.5, 0.5, 0.5, 1.0); ss -> setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0) ; // 0.8, 0.8, 1.0, 1.0f ss -> setMaterial ( GL_SPECULAR, 1.0, 1.0, 1.0, 1.0); ss -> setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 1.0); ss -> setShininess ( 20 ) ; // Fixme, NIV14: Is that correct? // ------------------------------------------------------- // texturing stuff // ------------------------------------------------------- // todo: give an implicit mapping if texture coordinates are not given // todo: add support for per-vertex texturing if( currentData->getTexture() != NULL && currentData->getTextureCoordinates() != NULL && texCoordIndexGiven ) { ss -> setTexture ( currentData->getTexture() ); ss -> enable( GL_TEXTURE_2D ); } else ss -> disable( GL_TEXTURE_2D ); ss -> disable ( GL_COLOR_MATERIAL ) ; //ss -> enable ( GL_COLOR_MATERIAL ) ; //ss -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; ss -> enable ( GL_LIGHTING ) ; ss -> setShadeModel ( GL_SMOOTH ) ; ss ->disable(GL_ALPHA_TEST); //needed? ss -> disable ( GL_BLEND ) ; ss -> setOpaque () ; if( !currentData->getEnableCullFace() ) ss->disable( GL_CULL_FACE ); if( !loaderMesh->checkMe() ) { delete( loaderMesh ); return FALSE; } if( currentData->getTransform() != NULL ) { currentBranch->addKid( currentData->getTransform() ); // FIXME: in case we're reusing transforms, perhaps they should be reinstanced? (currently we don't allow this) loaderMesh->addToSSG( ss, currentOptions, currentData->getTransform() ); } else loaderMesh->addToSSG( ss, currentOptions, currentBranch ); parentBranch->addKid( currentBranch ); return TRUE; } static bool iv_parseTexture2( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { char *token; char *fileName = NULL; bool wrapU = FALSE, wrapV = FALSE; vrmlParser.expectNextToken("{"); token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "}" ) ) { if( !strcmp( token, "filename") ) { vrmlParser.expectNextToken("filename"); if( !vrmlParser.getNextString( token, NULL ) ) return FALSE; fileName = ulStrDup ( token ) ; } else if( !strcmp( token, "wrapS") ) { vrmlParser.expectNextToken("wrapS"); token = vrmlParser.getNextToken( NULL ); if( !strcmp( token, "REPEAT") ) wrapU = TRUE; } else if( !strcmp( token, "wrapT") ) { vrmlParser.expectNextToken("wrapT"); token = vrmlParser.getNextToken( NULL ); if( !strcmp( token, "REPEAT") ) wrapV = TRUE; } else token = vrmlParser.getNextToken( NULL ); token = vrmlParser.peekAtNextToken( NULL ); } if( fileName == NULL ) return FALSE; //ssgTexture *currentTexture = new ssgTexture( fileName, wrapU, wrapV ); ssgTexture *currentTexture = currentOptions -> createTexture ( fileName, wrapU, wrapV ); currentData->setTexture( currentTexture ); vrmlParser.expectNextToken("}"); delete [] fileName; return TRUE; } plib-1.8.5/src/ssg/ssgLoadTRI.cxx0000644000175000001440000000652410765364437013500 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadTRI.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ // // TRI ( AC3D triangle file ) import for SSG/PLIB // Written by Dave McClurg (dpm@efn.org) in March-2000 // #include "ssgLocal.h" #define MAX_TRI 100000 struct triData { sgVec3 v[3] ; int color ; } ; /******************************************************************************/ ssgEntity *ssgLoadTRI ( const char *fname, const ssgLoaderOptions* options ) /******************************************************************************/ /* Purpose: reads an AC3D triangle file. Example: Each line contains 9 floating point values and a 1 hex value for color. the 9 floating point values represent 3 vertices of a triangle the color format is 0xRRGGBB (eg 0xffffff is white) 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0xffffff */ { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; const ssgLoaderOptions* current_options = ssgGetCurrentOptions () ; //open the file char filename [ 1024 ] ; current_options -> makeModelPath ( filename, fname ) ; FILE *loader_fd = fopen ( filename, "ra" ) ; if ( loader_fd == NULL ) { ulSetError ( UL_WARNING, "ssgLoadTRI: Failed to open '%s' for reading", filename ) ; return NULL ; } //read the data triData* tri = new triData [ MAX_TRI ] ; int num_tri = 0 ; char buffer [ 1024 ] ; while ( fgets ( buffer, 1024, loader_fd ) != NULL ) { float coord [9] ; int color ; if ( sscanf ( buffer, "%e %e %e %e %e %e %e %e %e %d", &coord[0], &coord[1], &coord[2], &coord[3], &coord[4], &coord[5], &coord[6], &coord[7], &coord[8], &color ) != 10 ) { ulSetError ( UL_WARNING, "ssgLoadTRI: Can't parse triangle: %s", buffer ) ; } else if ( num_tri < MAX_TRI ) { float* cp = coord; for ( int i=0; i<3; i++ ) for ( int j=0; j<3; j++ ) tri[ num_tri ].v[ i ][ j ] = *cp++; tri[ num_tri ].color = color ; num_tri ++ ; } else { break; } } fclose ( loader_fd ) ; ssgBranch* current_branch = NULL ; if ( num_tri ) { ssgVertexArray* vlist = new ssgVertexArray ( num_tri * 3 ) ; for ( int i=0; i add ( tri[ i ].v[ j ] ) ; ssgVtxTable *vtab = new ssgVtxTable ( GL_TRIANGLES, vlist, 0, 0, 0 ); current_branch = new ssgTransform () ; current_branch -> addKid ( vtab ) ; } delete[] tri ; return current_branch ; } plib-1.8.5/src/ssg/ssgSaveASE.cxx0000644000175000001440000002435410765364437013472 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveASE.cxx 1957 2004-09-13 12:11:56Z wolfram_kuss $ */ // // ASE ( 3DSMAX ASCII EXPORT Version 2.00 ) export for SSG/PLIB // Written by Dave McClurg (dpm@efn.org) in Feb-2000 // #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" static FILE *save_fd ; static ssgSimpleStateArray gSSL; static void save_state ( ssgSimpleState* st, int istate ) { float* amb = st -> getMaterial ( GL_AMBIENT ) ; float* diff = st -> getMaterial ( GL_DIFFUSE ) ; float* spec = st -> getMaterial ( GL_SPECULAR ) ; float shine = st -> getShininess () ; float trans = st -> isTranslucent () ? 1.0f : 0.0f ; fprintf ( save_fd, " *MATERIAL %d {\n", istate ); fprintf ( save_fd, " *MATERIAL_NAME \"Material #%d\"\n", istate ); fprintf ( save_fd, " *MATERIAL_CLASS \"Standard\"\n" ); fprintf ( save_fd, " *MATERIAL_AMBIENT %f %f %f\n", amb[0], amb[1], amb[2] ) ; fprintf ( save_fd, " *MATERIAL_DIFFUSE %f %f %f\n", diff[0], diff[1], diff[2] ) ; fprintf ( save_fd, " *MATERIAL_SPECULAR %f %f %f\n", spec[0], spec[1], spec[2] ) ; fprintf ( save_fd, " *MATERIAL_SHINE %f\n", shine ) ; fprintf ( save_fd, " *MATERIAL_SHINESTRENGTH %f\n", shine ) ; fprintf ( save_fd, " *MATERIAL_TRANSPARENCY %f\n", trans ) ; fprintf ( save_fd, " *MATERIAL_WIRESIZE 1.0000\n" ); fprintf ( save_fd, " *MATERIAL_SHADING Blinn\n" ); fprintf ( save_fd, " *MATERIAL_XP_FALLOFF 0.0000\n" ); fprintf ( save_fd, " *MATERIAL_SELFILLUM 0.0000\n" ); fprintf ( save_fd, " *MATERIAL_TWOSIDED\n" ); fprintf ( save_fd, " *MATERIAL_FALLOFF In\n" ); fprintf ( save_fd, " *MATERIAL_SOFTEN\n" ); fprintf ( save_fd, " *MATERIAL_XP_TYPE Filter\n" ) ; if ( st -> isEnabled ( GL_TEXTURE_2D ) ) { const char* tfname = st -> getTextureFilename() ; fprintf ( save_fd, " *MAP_DIFFUSE {\n" ); fprintf ( save_fd, " *MAP_NAME \"Map #%d\"\n", istate ) ; fprintf ( save_fd, " *MAP_CLASS \"Bitmap\"\n" ) ; fprintf ( save_fd, " *MAP_SUBNO 1\n" ) ; fprintf ( save_fd, " *MAP_AMOUNT 1.0000\n" ) ; fprintf ( save_fd, " *BITMAP \"%s\"\n", tfname ) ; fprintf ( save_fd, " *MAP_TYPE Spherical\n" ) ; fprintf ( save_fd, " *UVW_U_OFFSET 0.0000\n" ) ; fprintf ( save_fd, " *UVW_V_OFFSET 0.0000\n" ) ; fprintf ( save_fd, " *UVW_U_TILING 1.0000\n" ) ; fprintf ( save_fd, " *UVW_V_TILING 1.0000\n" ) ; fprintf ( save_fd, " *UVW_ANGLE 0.0000\n" ) ; fprintf ( save_fd, " *UVW_BLUR 1.0000\n" ) ; fprintf ( save_fd, " *UVW_BLUR_OFFSET 0.0000\n" ) ; fprintf ( save_fd, " *UVW_NOUSE_AMT 1.0000\n" ) ; fprintf ( save_fd, " *UVW_NOISE_SIZE 1.0000\n" ) ; fprintf ( save_fd, " *UVW_NOISE_LEVEL 1\n" ) ; fprintf ( save_fd, " *UVW_NOISE_PHASE 0.0000\n" ) ; fprintf ( save_fd, " *BITMAP_FILTER Pyramidal\n" ) ; fprintf ( save_fd, " }\n" ); } fprintf ( save_fd, " }\n" ); } static void save_states () { fprintf ( save_fd, "*MATERIAL_LIST {\n" ) ; fprintf ( save_fd, " *MATERIAL_COUNT %d\n", gSSL.getNum() ) ; for ( int i=0; i < gSSL.getNum(); i++ ) save_state ( gSSL.get(i) , i ) ; fprintf ( save_fd, "}\n" ); } static void save_vtx_table ( ssgVtxTable *vt ) { GLenum mode = vt -> getPrimitiveType () ; if ( mode != GL_TRIANGLES && mode != GL_TRIANGLE_FAN && mode != GL_TRIANGLE_STRIP ) { //only triangle export return; } const char* name = vt->getPrintableName() ; int j ; int istate = gSSL.findIndex ( (ssgSimpleState*)vt->getState () ) ; ssgSimpleState* st = ( istate != -1 )? gSSL.get( istate ): 0; /* Begin the big geometry block. */ fprintf ( save_fd, "*GEOMOBJECT {\n" ); fprintf ( save_fd, " *NODE_NAME \"%s\"\n", name ); /* Sub block NODE_TM: */ fprintf ( save_fd, " *NODE_TM {\n" ); fprintf ( save_fd, " *NODE_NAME \"%s\"\n", name ); fprintf ( save_fd, " *INHERIT_POS 0 0 0\n" ); fprintf ( save_fd, " *INHERIT_ROT 0 0 0\n" ); fprintf ( save_fd, " *INHERIT_SCL 0 0 0\n" ); fprintf ( save_fd, " *TM_ROW0 1.0000 0.0000 0.0000\n" ); fprintf ( save_fd, " *TM_ROW1 0.0000 1.0000 0.0000\n" ); fprintf ( save_fd, " *TM_ROW2 0.0000 0.0000 1.0000\n" ); fprintf ( save_fd, " *TM_ROW3 0.0000 0.0000 0.0000\n" ); fprintf ( save_fd, " *TM_POS 0.0000 0.0000 0.0000\n" ); fprintf ( save_fd, " *TM_ROTAXIS 0.0000 0.0000 0.0000\n" ); fprintf ( save_fd, " *TM_ROTANGLE 0.0000\n" ); fprintf ( save_fd, " *TM_SCALE 1.0000 1.0000 1.0000\n" ); fprintf ( save_fd, " *TM_SCALEAXIS 0.0000 0.0000 0.0000\n" ); fprintf ( save_fd, " *TM_SCALEAXISANG 0.0000\n" ); fprintf ( save_fd, " }\n" ); /* Sub block MESH: Items */ int num_vert = vt -> getNumVertices () ; int num_face = vt -> getNumTriangles () ; fprintf ( save_fd, " *MESH {\n" ); fprintf ( save_fd, " *TIMEVALUE 0\n" ); fprintf ( save_fd, " *MESH_NUMVERTEX %d\n", num_vert ); fprintf ( save_fd, " *MESH_NUMFACES %d\n", num_face ); /* Sub sub block MESH_VERTEX_LIST */ fprintf ( save_fd, " *MESH_VERTEX_LIST {\n" ); for ( j = 0; j < num_vert; j++ ) { sgVec3 v; sgCopyVec3 ( v, vt->getVertex ( j ) ) ; fprintf ( save_fd, " *MESH_VERTEX %d %f %f %f\n", j, v[0], v[1], v[2] ); } fprintf ( save_fd, " }\n" ); /* Sub sub block MESH_FACE_LIST Items MESH_FACE */ fprintf ( save_fd, " *MESH_FACE_LIST {\n" ); for ( j = 0; j < num_face; j++ ) { short i1,i2,i3; vt -> getTriangle ( j, &i1, &i2, &i3 ) ; fprintf ( save_fd, " *MESH_FACE %d: A: %d B: %d C: %d", j, i1, i2, i3 ); fprintf ( save_fd, " AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING *MESH_MTLID 1\n" ); } fprintf ( save_fd, " }\n" ); /* Item MESH_NUMTVERTEX. */ if ( st && st -> isEnabled ( GL_TEXTURE_2D ) && vt -> getNumTexCoords () == num_vert ) { fprintf ( save_fd, " *MESH_NUMTVERTEX %d\n", num_vert ); fprintf ( save_fd, " *MESH_TVERTLIST {\n" ); for ( j = 0; j < num_vert; j++ ) { sgVec2 tv ; sgCopyVec2 ( tv, vt->getTexCoord ( j ) ) ; fprintf ( save_fd, " *MESH_TVERT %d %f %f %f\n", j, tv[0], 1.0f - tv[1], 1.0f ); } fprintf ( save_fd, " }\n" ); fprintf ( save_fd, " *MESH_NUMTVFACES %d\n", num_face ); fprintf ( save_fd, " *MESH_TFACELIST {\n" ); for ( j = 0; j < num_face; j++ ) { short i1,i2,i3; vt -> getTriangle ( j, &i1, &i2, &i3 ) ; fprintf ( save_fd, " *MESH_TFACE %d %d %d %d\n", j, i1, i2, i3 ); } fprintf ( save_fd, " }\n" ); } else { fprintf ( save_fd, " *MESH_NUMTVERTEX 0\n" ); } fprintf ( save_fd, "done\n" ) ; fflush ( save_fd ) ; /* Item NUMCVERTEX. */ fprintf ( save_fd, " *MESH_NUMCVERTEX 0\n" ); #if 0 /* Sub block MESH_NORMALS Items MESH_FACENORMAL, MESH_VERTEXNORMAL (repeated) */ fprintf ( save_fd, " *MESH_NORMALS {\n" ); for ( j = 0; j < num_face; j++ ) { fprintf ( save_fd, " *MESH_FACENORMAL %d %f %f %f\n", iface, face_normal[0][j], face_normal[1][j], face_normal[2][j] ); for ( ivert = 0; ivert < face_order[j]; ivert++ ) { fprintf ( save_fd, " *MESH_VERTEXNORMAL %d %f %f %f\n", face[ivert][iface], vertex_normal[0][ivert][iface], vertex_normal[1][ivert][j], vertex_normal[2][ivert][j] ); } } fprintf ( save_fd, " }\n" ); #endif /* Close the MESH object. */ fprintf ( save_fd, " }\n" ); /* A few closing parameters. */ fprintf ( save_fd, " *PROP_MOTIONBLUR 0\n" ); fprintf ( save_fd, " *PROP_CASTSHADOW 1\n" ); fprintf ( save_fd, " *PROP_RECVSHADOW 1\n" ); if ( st ) fprintf ( save_fd, " *MATERIAL_REF %d\n", gSSL.findIndex ( st ) ); /* Close the GEOM object. */ fprintf ( save_fd, "}\n" ); } static void save_geom ( ssgEntity *e ) { if ( e -> isAKindOf ( ssgTypeBranch() ) ) { ssgBranch *br = (ssgBranch *) e ; if ( br -> isAKindOf ( ssgTypeSelector() ) ) { for ( int i = 0 ; i < br -> getNumKids () ; i++ ) save_geom ( br -> getKid ( i ) ) ; } else { for ( int i = 0 ; i < br -> getNumKids () ; i++ ) save_geom ( br -> getKid ( i ) ) ; } } else if ( e -> isAKindOf ( ssgTypeVtxTable() ) ) { ssgVtxTable *vt = (ssgVtxTable *) e ; save_vtx_table ( vt ) ; } } int ssgSaveASE ( FILE* fileout, ssgEntity *ent ) { save_fd = fileout ; /* Write the header. */ fprintf ( save_fd, "*3DSMAX_ASCIIEXPORT 200\n" ); fprintf ( save_fd, "*COMMENT \"created by SSG.\"\n" ); /* Write the scene block. */ fprintf ( save_fd, "*SCENE {\n" ); fprintf ( save_fd, " *SCENE_FILENAME \"\"\n" ); fprintf ( save_fd, " *SCENE_FIRSTFRAME 0\n" ); fprintf ( save_fd, " *SCENE_LASTFRAME 100\n" ); fprintf ( save_fd, " *SCENE_FRAMESPEED 30\n" ); fprintf ( save_fd, " *SCENE_TICKSPERFRAME 160\n" ); fprintf ( save_fd, " *SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000\n" ); fprintf ( save_fd, " *SCENE_AMBIENT_STATIC 0.0431 0.0431 0.0431\n" ); fprintf ( save_fd, "}\n" ); gSSL.collect ( ent ) ; save_states () ; save_geom ( ent ) ; gSSL.removeAll(); fflush ( save_fd ) ; return TRUE ; } int ssgSaveASE ( const char *filename, ssgEntity *ent ) { save_fd = fopen ( filename, "wa" ) ; if ( save_fd == NULL ) { ulSetError ( UL_WARNING, "ssgSaveASE: Failed to open '%s' for writing", filename ) ; return FALSE ; } int result = ssgSaveASE ( save_fd, ent ) ; fclose ( save_fd ) ; return result ; } plib-1.8.5/src/ssg/ssgLoadATG.cxx0000644000175000001440000003653010765364437013455 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadATG.cxx 1970 2004-10-04 08:11:26Z wolfram_kuss $ */ /* .scenery loader for SSG/PLIB ATG = ascii Terra Gear Written by Wolfram Kuss (Wolfram.Kuss@t-online.de) in May 2001 */ /* General info on working with FG scenery files: If you want to add stuff to the scenery think about adding it via the *.ind files. Editing the scenery manually is always "dangerous", since your effort is lost the next time the scenery is re-generated. ssgLoadATG and ssgSaveATG are not finished at all and there are some known bugs: - texture coordinate reading doesn't work 100%, writing is not implemented yet. - Only faces with "f". TriStrips ("ts") and TriFans ("tf") not yet supported. First of all, make sure the FG textures are in your texture path. If your FG is in, then add C:/FG/Textures/$(...) to the string in viewer.setTexturePath in .ppe_rc. If you run PPE, it will tell you where you .pee_rc is (and create one if you don't have one). As an example, say you want to add a tower to the airport KLVK. It goes something like this: 1. Unzip KLVK.gz, you get a file KLVK. 2. delete KLVK.gz or move it away so that it isn't used anymore. 3. Rename KLVK to KLV.atg. PLIB finds out the fileformat via the extension, so PLIB can't handle files without extension. 4. Go into PPE (or another PLIB based program :-)) and load KLVK.atg. 5. Say "make everything visible". You can look at it from all sides via the middle mouse button and move the camery via the numKeyPad. For more, see the PPE docu. 6. Now, using some magic like a future PPE-version, add whatever you want to add. I tried this and by coding a few small functions, have succeeded partly. Some hints: Pressing "w" gets you into a mode where you can get the 3D coordinates of stuff. What I want to add is centred around 0,0,0, so writing a small, but non-trivial :-( translateAllVertices, moved the other object that I load via "merge". The next problem is that the tile is not axisparalell, so you have to rotate what you loaded a certain way. 7. Save the tile as KLVK.atg 8. From the original KLVK, get the line with "# gbs..." and copy it to KLVK.atg 9. Rename KLVK.atg to KLVK. You can now view it in FG by going to this airport. The texture coords will be broken (see above). */ #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" #include "ssgParser.h" extern sgVec4 currentDiffuse; static /* const */ ssgLoaderOptions* current_options = NULL ; static class ssgTexCoordArray *linearListTCPFAV=NULL; // TCPFAV = TextureCoordinatesPerFaceAndVertex static _ssgParserSpec parser_spec = { "\r\n\t ", // delim_chars_skipable NULL, // delim_chars_non_skipable NULL, // pre_processor NULL, // open_brace_chars NULL, // close_brace_chars '"', // quote_char. not used for scenery 0, // comment_char # is handled in this module, since it may contain // important info like the name of the material or the gbs NULL // comment_string } ; static _ssgParser parser; static ssgBranch* top_branch; static int Ascii2Int(int &retVal, const char *token, const char* name ) // returns TRUE on success { char *endptr; retVal = int(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { parser.error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } #define MAX_NO_VERTICES_PER_FACE 10000 static class ssgLoaderWriterMesh _theMesh; static int _ssgNoFaces, _ssgNoVertices, _ssgNoVertexNormals, _ssgNoVertexTC; //lint !e551 static char * _current_usemtl = NULL, * _last_usemtl = NULL; static int _current_material_index = -1; static double _ssg_gbs_x = 0.0, _ssg_gbs_y = 0.0, _ssg_gbs_z = 1.0, _ssg_gbs_r = 0.0; void ssgGetValuesFromLastATGFile(double *x, double *y, double *z, double *r) // These values are the values from the "# gbs" line from the last loaded // ATG file, or 0, 0, 1, 0 if there is no ATG file with a # gbs line loaded yet // The values are the vector from the centre of the earth to the tile and // a radius. { *x = _ssg_gbs_x; *y = _ssg_gbs_y; *z = _ssg_gbs_z; *r = _ssg_gbs_r; } static char* parser_getLine() // replaces parser.getLine, but handles '#' // Some "comment lines" starting with '#' have important info like material/texture name inside // if this function finds a #-line with a materialname, it sets _current_usemtl { char *token; token = parser.getLine(0); if ( token == NULL ) return NULL; while ( token[0] == '#' ) { char * token0 = parser.parseToken( 0 ); if ( ulStrEqual ("usemtl" , token0)) // name has to be 0 { char * usemtl = parser.parseToken( 0 ); if ( usemtl != NULL) if ( 0 != usemtl[0] ) { if ( _current_usemtl != NULL ) delete [] _current_usemtl ; _current_usemtl = ulStrDup ( usemtl ) ; } } //# gbs -2710586.16105 -4275323.15743 3867065.62925 7623.60 else if ( ulStrEqual ("gbs" , token0)) // name has to be 0 { char * temp; temp = parser.parseToken( 0 ); _ssg_gbs_x = atof (temp); temp = parser.parseToken( 0 ); _ssg_gbs_y = atof (temp); temp = parser.parseToken( 0 ); _ssg_gbs_z = atof (temp); temp = parser.parseToken( 0 ); _ssg_gbs_r = atof (temp); } token = parser.getLine(0); if ( token == NULL ) return NULL; } return token; } static int reduce_numbers; // some ATG files (from BTG converted ones?) have vertex coordinates that include gbs, for example // 2713547.89986. Others have coordinates excluding gbs, for example 2961.50684 // I need to reduce the big numbers beacuse float a,b; a-b is dangerous if a large and b small. // Therefore I reduce the numbers by gbs while I have vertex coords and gbs as double and add it back in using double in PPE static int parse() { // ************* Init ************************ char* token; _ssgNoFaces= 0; _ssgNoVertices = 0; _ssgNoVertexNormals = 0; _ssgNoVertexTC = 0; _theMesh.reInit (); _theMesh.createVertices(); _theMesh.createFaces(); _theMesh.createPerFaceAndVertexTextureCoordinates2(); _theMesh.createMaterials(); _theMesh.createMaterialIndices() ; token = parser_getLine(); if ( token == NULL ) { parser.error("The file seems to be empty"); return FALSE; } // ****** read vertices ************ int first = TRUE; while ( 0 == strcmp( token, "v") ) { double vx, vy, vz; if (! parser.parseDouble( vx, "vertex.x") ) return FALSE; if (! parser.parseDouble( vy, "vertex.y") ) return FALSE; if (! parser.parseDouble( vz, "vertex.z") ) return FALSE; if (first) { first = FALSE; #ifndef ABS #define ABS(x) (((x)>0)?(x):-(x)) #endif // Mega-kludge: reduce_numbers = (ABS(vx)>50000); } if (reduce_numbers) { assert( _ssg_gbs_x != 0.0); // kludge vx += _ssg_gbs_x; vy += _ssg_gbs_y; vz += _ssg_gbs_z; } sgVec3 vert; sgSetVec3( vert, (float) vx, (float) vy, (float) vz); _theMesh.addVertex(vert); // add to mesh _ssgNoVertices++; token = parser_getLine(); if ( token == NULL ) { parser.error("There are only vertices in the scenery, no faces"); return FALSE; } } // ****** read vertex normals ************ while ( 0 == strcmp( token, "vn") ) { sgVec3 vert_norm; if (! parser.parseFloat( vert_norm[0], "vertex normal.x") ) return FALSE; if (! parser.parseFloat( vert_norm[1], "vertex normal.y") ) return FALSE; if (! parser.parseFloat( vert_norm[2], "vertex normal.z") ) return FALSE; //_theMesh.addVertex(vert); _ssgNoVertexNormals++; token = parser_getLine(); if ( token == NULL ) { parser.error("There are only vertices in the scenery, no faces"); return FALSE; } } /*if ( _ssgNoVertexNormals != _ssgNoVertices) { parser.error("The number of vertex normals and vertices doesn't match"); return FALSE; }*/ // ***************** read texture coords. ********************** // this format has a "linear" list of texture coords, that is indexed from the faces. while ( 0 == strcmp( token, "vt") ) { sgVec2 vert_tc; if (! parser.parseFloat( vert_tc[0], "vertex texture.x") ) return FALSE; if (! parser.parseFloat( vert_tc[1], "vertex texture.y") ) return FALSE; linearListTCPFAV->add(vert_tc); _ssgNoVertexTC++; token = parser_getLine(); if ( token == NULL ) { parser.error("There are only vertices in the scenery, no faces"); return FALSE; } } /*if ( _ssgNoVertexTC != _ssgNoVertices) { parser.error("The number of texture coords and vertices doesn't match"); return FALSE; }*/ // ********* Read Faces ********** int aiVertices[MAX_NO_VERTICES_PER_FACE], aiTCs[MAX_NO_VERTICES_PER_FACE]; unsigned int nNoOfVerticesForThisFace; while ( 0 == strcmp( token, "f") ) { char *ptr, buffer[1024], *ptr2Slash; if ( !ulStrEqual (_current_usemtl, _last_usemtl)) // ***************+ material has changed. *********** { // bring _last_usemtl up to date if ( _last_usemtl != NULL ) delete [] _last_usemtl; _last_usemtl= ulStrDup ( _current_usemtl ) ; // create SimpleState ssgSimpleState * currentState = new ssgSimpleState () ; // (0) ? currentState -> setMaterial ( GL_AMBIENT, 0.5, 0.5, 0.5, 1.0); currentState -> setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0) ; // 0.8, 0.8, 1.0, 1.0f currentState -> setMaterial ( GL_SPECULAR, 1.0, 1.0, 1.0, 1.0); currentState -> setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 1.0); currentState -> setShininess ( 20 ) ; // Fixme, NIV14: Is that correct? currentState -> disable ( GL_COLOR_MATERIAL ) ; //currentState -> enable ( GL_COLOR_MATERIAL ) ; //currentState -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; currentState -> enable ( GL_LIGHTING ) ; currentState -> setShadeModel ( GL_SMOOTH ) ; currentState ->disable(GL_ALPHA_TEST); //needed? /* if ( currentDiffuse[3] > 0.0f ) { currentState -> disable ( GL_ALPHA_TEST ) ; currentState -> enable ( GL_BLEND ) ; currentState -> setTranslucent () ; } else */ { currentState -> disable ( GL_BLEND ) ; currentState -> setOpaque () ; } currentState -> disable( GL_TEXTURE_2D ); // if (textured) { char * fileName = new char [ strlen ( _current_usemtl ) + 5 ] ; assert( fileName != NULL ); strcpy ( fileName, _current_usemtl ) ; strcat( fileName, ".rgb" ); currentState -> setTexture( current_options -> createTexture( fileName ) ); delete [] fileName; currentState -> enable( GL_TEXTURE_2D ); } // add SimpleState _theMesh.addMaterial( ¤tState ); // bring _current_material_index up to date _current_material_index ++; } // if new material // ************* parse vertex and TC indices of this face ****************** nNoOfVerticesForThisFace = 0; ptr = parser.parseToken( "vertex index"); while ( ptr != NULL ) { strncpy(buffer, ptr, 1024); ptr2Slash = strchr(buffer, '/'); if ( ptr2Slash != NULL) { *ptr2Slash = 0; ptr2Slash++; if ( ! Ascii2Int( aiTCs[ nNoOfVerticesForThisFace ], ptr2Slash, "texture coord. index")) return FALSE; } else aiTCs[ nNoOfVerticesForThisFace ]=0; if ( ! Ascii2Int( aiVertices[ nNoOfVerticesForThisFace ], buffer, "vertex index")) return FALSE; nNoOfVerticesForThisFace++; assert(nNoOfVerticesForThisFaceref(); for(j=0;j<3;j++) { if ( ! linearListTCPFAV->get(aiTCs[l*3+j]) ) { parser.error("Internal error while reading *.atg-file: aiTCs[j] == NULL \n"); return FALSE; } sca->add(linearListTCPFAV->get(aiTCs[l*3+j])); } // ****** add face to mesh ***** _theMesh.addPerFaceAndVertexTextureCoordinate2( &sca ) ; int carray[3]; carray[0]=aiVertices[3*l+0]; carray[1]=aiVertices[3*l+1]; carray[2]=aiVertices[3*l+2]; _theMesh.addFaceFromIntegerArray(3, carray); _theMesh.addMaterialIndex ( _current_material_index ) ; } #else unsigned int j; ssgTexCoordArray * sca = new ssgTexCoordArray (nNoOfVerticesForThisFace); sca->ref(); for(j=0;jget(aiTCs[j]) ) { parser.error("Internal error while reading *.atg-file: aiTCs[j] == NULL \n"); return FALSE; } sca->add(linearListTCPFAV->get(aiTCs[j])); } // ****** add face to mesh ***** _theMesh.addPerFaceAndVertexTextureCoordinate2 ( &sca ) ; _theMesh.addFaceFromIntegerArray(nNoOfVerticesForThisFace, aiVertices); _theMesh.addMaterialIndex ( _current_material_index ) ; #endif token = parser_getLine(); if ( token == NULL ) break; } // ******* end of reading faces ***** if ( token != NULL ) ulSetError ( UL_WARNING, "f expected, got %s\n", token); if (! parser.eof ) ulSetError ( UL_WARNING, "Warning: no eof\n"); // kludge. We need a state for add2SSG: ssgSimpleState * ss = new ssgSimpleState () ; // (0) ? ss -> setMaterial ( GL_AMBIENT, 0.5, 0.5, 0.5, 1.0); ss -> setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0) ; // 0.8, 0.8, 1.0, 1.0f ss -> setMaterial ( GL_SPECULAR, 1.0, 1.0, 1.0, 1.0); ss -> setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 1.0); ss -> setShininess ( 20 ) ; // Fixme, NIV14: Is that correct? ss -> disable ( GL_COLOR_MATERIAL ) ; //ss -> enable ( GL_COLOR_MATERIAL ) ; //ss -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; ss -> enable ( GL_LIGHTING ) ; ss -> setShadeModel ( GL_SMOOTH ) ; ss ->disable(GL_ALPHA_TEST); //needed? ss -> disable ( GL_BLEND ) ; ss -> setOpaque () ; ss -> disable( GL_TEXTURE_2D ); _theMesh.checkMe(); //lint !e534 // For debug _theMesh.addToSSG( ss, // super kludge. NIV135 current_options, top_branch); return TRUE ; } ssgEntity *ssgLoadATG ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; top_branch = new ssgBranch ; _current_usemtl = NULL; _last_usemtl = NULL; _current_material_index = -1; if ( !parser.openFile( fname, &parser_spec )) { delete top_branch ; return 0; } linearListTCPFAV=new ssgTexCoordArray(); if ( !parse() ) { delete linearListTCPFAV; delete top_branch ; top_branch = 0 ; } delete linearListTCPFAV; // parse_free(); parser.closeFile(); return top_branch ; } plib-1.8.5/src/ssg/ssgLoadBMP.cxx0000644000175000001440000002314610765364437013457 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadBMP.cxx 2109 2006-12-12 15:29:22Z fayjf $ */ #include "ssgLocal.h" #ifdef SSG_LOAD_BMP_SUPPORTED static FILE *curr_image_fd ; static char curr_image_fname [ 512 ] ; static int isSwapped ; static void swab_short ( unsigned short *x ) { if ( isSwapped ) *x = (( *x >> 8 ) & 0x00FF ) | (( *x << 8 ) & 0xFF00 ) ; } static void swab_int ( unsigned int *x ) { if ( isSwapped ) *x = (( *x >> 24 ) & 0x000000FF ) | (( *x >> 8 ) & 0x0000FF00 ) | (( *x << 8 ) & 0x00FF0000 ) | (( *x << 24 ) & 0xFF000000 ) ; } /*static void swab_int_array ( int *x, int leng ) { if ( ! isSwapped ) return ; for ( int i = 0 ; i < leng ; i++ ) { *x = (( *x >> 24 ) & 0x000000FF ) | (( *x >> 8 ) & 0x0000FF00 ) | (( *x << 8 ) & 0x00FF0000 ) | (( *x << 24 ) & 0xFF000000 ) ; x++ ; } }*/ static unsigned char readByte () { unsigned char x ; fread ( & x, sizeof(unsigned char), 1, curr_image_fd ) ; return x ; } static unsigned short readShort () { unsigned short x ; fread ( & x, sizeof(unsigned short), 1, curr_image_fd ) ; swab_short ( & x ) ; return x ; } static unsigned int readInt () { unsigned int x ; fread ( & x, sizeof(unsigned int), 1, curr_image_fd ) ; swab_int ( & x ) ; return x ; } /* Original source for BMP loader kindly donated by "Sean L. Palmer" */ struct BMPHeader { unsigned short FileType ; unsigned int FileSize ; unsigned short Reserved1 ; unsigned short Reserved2 ; unsigned int OffBits ; unsigned int Size ; unsigned int Width ; unsigned int Height ; unsigned short Planes ; unsigned short BitCount ; unsigned int Compression ; unsigned int SizeImage ; unsigned int XPelsPerMeter ; unsigned int YPelsPerMeter ; unsigned int ClrUsed ; unsigned int ClrImportant ; } ; struct RGBA { unsigned char r,g,b,a ; } ; bool ssgLoadBMP ( const char *fname, ssgTextureInfo* info ) { int w, h, bpp ; int index=0; bool old_format = false; RGBA pal [ 256 ] ; BMPHeader bmphdr ; /* Open file & get size */ strcpy ( curr_image_fname, fname ) ; if ( ( curr_image_fd = fopen ( curr_image_fname, "rb" ) ) == NULL ) { char *p = strrchr(curr_image_fname,'_'); if (p != 0) { *p = '\0'; p++; index = atoi (p); old_format = true; if ( ( curr_image_fd = fopen(curr_image_fname, "rb")) == NULL) { perror ( "ssgLoadTexture" ) ; ulSetError( UL_WARNING, "ssgLoadTexture: Failed to load '%s' for reading.", curr_image_fname ); return false ; } p--; *p = '_'; } else { perror ( "ssgLoadTexture" ) ; ulSetError( UL_WARNING, "ssgLoadTexture: Failed to open '%s' for reading.", curr_image_fname ); return false ; } } /* Load the BMP piecemeal to avoid struct packing issues */ isSwapped = FALSE ; bmphdr.FileType = readShort () ; if ( bmphdr.FileType == ((int)'B' + ((int)'M'<<8)) ) isSwapped = FALSE ; else if ( bmphdr.FileType == ((int)'M' + ((int)'B'<<8)) ) isSwapped = TRUE ; else { ulSetError ( UL_WARNING, "%s: Unrecognised magic number 0x%04x", curr_image_fname, bmphdr.FileType ) ; return false ; } bmphdr.FileSize = readInt () ; bmphdr.Reserved1 = readShort () ; bmphdr.Reserved2 = readShort () ; bmphdr.OffBits = readInt () ; bmphdr.Size = readInt () ; bmphdr.Width = readInt () ; bmphdr.Height = readInt () ; bmphdr.Planes = readShort () ; bmphdr.BitCount = readShort () ; bmphdr.Compression = readInt () ; bmphdr.SizeImage = readInt () ; bmphdr.XPelsPerMeter = readInt () ; bmphdr.YPelsPerMeter = readInt () ; bmphdr.ClrUsed = readInt () ; bmphdr.ClrImportant = readInt () ; w = bmphdr.Width ; h = bmphdr.Height ; bpp = bmphdr.Planes * bmphdr.BitCount ; bool top_down = false ; if ( h < 0 ) { top_down = true ; h = -1 * h ; } #ifdef PRINT_BMP_HEADER_DEBUG ulSetError ( UL_DEBUG, "Filetype %04x", bmphdr.FileType ) ; ulSetError ( UL_DEBUG, "Filesize %08x", bmphdr.FileSize ) ; ulSetError ( UL_DEBUG, "R1 %04x", bmphdr.Reserved1 ) ; ulSetError ( UL_DEBUG, "R2 %04x", bmphdr.Reserved2 ) ; ulSetError ( UL_DEBUG, "Offbits %08x", bmphdr.OffBits ) ; ulSetError ( UL_DEBUG, "Size %08x", bmphdr.Size ) ; ulSetError ( UL_DEBUG, "Width %08x", bmphdr.Width ) ; ulSetError ( UL_DEBUG, "Height %08x", bmphdr.Height ) ; ulSetError ( UL_DEBUG, "Planes %04x", bmphdr.Planes ) ; ulSetError ( UL_DEBUG, "Bitcount %04x", bmphdr.BitCount ) ; ulSetError ( UL_DEBUG, "Compression %08x", bmphdr.Compression ) ; ulSetError ( UL_DEBUG, "SizeImage %08x", bmphdr.SizeImage ) ; ulSetError ( UL_DEBUG, "XPelsPerMeter %08x", bmphdr.XPelsPerMeter ) ; ulSetError ( UL_DEBUG, "YPelsPerMeter %08x", bmphdr.YPelsPerMeter ) ; ulSetError ( UL_DEBUG, "ClrUsed %08x", bmphdr.ClrUsed ) ; ulSetError ( UL_DEBUG, "ClrImportant %08x", bmphdr.ClrImportant ) ; #endif int isMonochrome = TRUE ; int isOpaque = TRUE ; if ( bpp <= 8 ) { for ( int i = 0 ; i < 256 ; i++ ) { pal[i].b = readByte () ; pal[i].g = readByte () ; pal[i].r = readByte () ; /* According to BMP specs, this fourth value is not really alpha value but just a filler byte, so it is ignored for now. */ pal[i].a = readByte () ; if (old_format == true) { pal[i].a = (i= 0 ; y-- ) { GLubyte *row_ptr ; if ( top_down ) { /* store flipped image */ row_ptr = &data [ y * row_size ] ; } else { /* store without flipping */ row_ptr = &data [ ( h - ( y + 1 ) ) * row_size ] ; } if ( fread ( row_ptr, 1, row_size, curr_image_fd ) != (unsigned)row_size ) { ulSetError ( UL_WARNING, "Premature EOF in '%s'", curr_image_fname ) ; return false ; } } } fclose ( curr_image_fd ) ; GLubyte *image ; int z ; if ( bpp == 8 ) { int i ; // check for diffrent alpha values in the bitmap // assume blending if that's the case for ( i = 1 ; i < w * h ; i++ ) { if (pal[data[i]].a != pal[data[i-1]].a) { isOpaque = FALSE ; break; } } if ( isMonochrome ) z = isOpaque ? 1 : 2 ; else z = isOpaque ? 3 : 4 ; image = new GLubyte [ w * h * z ] ; for ( i = 0 ; i < w * h ; i++ ) switch ( z ) { case 1 : image [ i ] = pal[data[i]].r ; break ; case 2 : image [ i*2 ] = pal[data[i]].r ; image [ i*2 + 1 ] = pal[data[i]].a ; break ; case 3 : image [ i*3 ] = pal[data[i]].r ; image [ i*3 + 1 ] = pal[data[i]].g ; image [ i*3 + 2 ] = pal[data[i]].b ; break ; case 4 : image [ i*4 ] = pal[data[i]].r ; image [ i*4 + 1 ] = pal[data[i]].g ; image [ i*4 + 2 ] = pal[data[i]].b ; image [ i*4 + 3 ] = pal[data[i]].a ; break ; default : break ; } delete [] data ; } else if ( bpp == 24 ) { z = 3 ; image = data ; /* BGR --> RGB */ for ( int i = 0 ; i < w * h ; i++ ) { GLubyte tmp = image [ 3 * i ] ; image [ 3 * i ] = image [ 3 * i + 2 ]; image [ 3 * i + 2 ] = tmp ; } } else if ( bpp == 32 ) { z = 4 ; image = data ; /* BGRA --> RGBA */ for ( int i = 0 ; i < w * h ; i++ ) { GLubyte tmp = image [ 4 * i ] ; image [ 4 * i ] = image [ 4 * i + 2 ]; image [ 4 * i + 2 ] = tmp ; } } else { ulSetError ( UL_WARNING, "ssgLoadTexture: Can't load %d bpp BMP textures.", bpp ) ; return false ; } if ( info != NULL ) { info -> width = w ; info -> height = h ; info -> depth = z ; info -> alpha = ( isOpaque == FALSE ) ; } return ssgMakeMipMaps ( image, w, h, z ) ; } #else bool ssgLoadBMP ( const char *fname, ssgTextureInfo* info ) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - BMP support not configured", fname ) ; return false ; } #endif plib-1.8.5/src/ssg/ssgLoadVRML1.cxx0000644000175000001440000006656210765364437013713 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 William Lachance, Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ // ssgLoadVRML1: loads vrml1 files into the scenegraph // Written by William Lachance (wlach@interlog.com) // known bugs/limitations: // - implicit texture mapping is not supported // - explicit normal definitions not supported (they are calculated automatically) // - only a very small subset of the inventor spec is supported // - there is no support for primitives (cubes, spheres, cylinders, or cones) // - no support for materials // - no support for weblinks in vrml(well, this isn't much of a tragedy) :-) // .. // this loader borrows, to some extent, from the previous vrml file loader: // - array based token identification // - flipping the axises so that z is up #include "ssgLocal.h" #include "ssgParser.h" #include "ssgLoaderWriterStuff.h" #include "ssgLoadVRML.h" static _ssgParserSpec parser_spec = { "\r\n\t, ", // delim_chars_skipable 0, // delim_chars_non_skipable NULL, // pre_processor "{[", // open_brace_chars "}]", // close_brace_chars '"', // quote_char '#', // comment_char 0 // comment_string }; _ssgParser vrmlParser; static ssgLoaderOptions* currentOptions = NULL ; static _nodeIndex *definedNodes = NULL; static bool vrml1_parseSeparator( ssgBranch *parentBranch, _traversalState *parentData, char *defName ); static bool vrml1_parseSwitch( ssgBranch *parentBranch, _traversalState *parentData, char *defName ); static bool vrml1_parseIndexedFaceSet( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); static bool vrml1_parseTexture2( ssgBranch *parentBranch, _traversalState *currentData, char *defName ); static _parseTag vrmlTags [] = { { "Separator", vrml1_parseSeparator }, { "Switch", vrml1_parseSwitch }, { "IndexedFaceSet", vrml1_parseIndexedFaceSet }, { "Coordinate3", vrml1_parseCoordinate3 }, { "TextureCoordinate2", vrml1_parseTextureCoordinate2 }, { "Texture2", vrml1_parseTexture2 }, { "ShapeHints", vrml1_parseShapeHints }, { "MatrixTransform", vrml1_parseMatrixTransform }, { "Scale", vrml1_parseScale }, { "Rotation", vrml1_parseRotation }, { "Translation", vrml1_parseTranslation }, { NULL, NULL }, }; ssgEntity *ssgLoadVRML1( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; currentOptions = ssgGetCurrentOptions () ; if ( !vrmlParser.openFile( fname, &parser_spec ) ) { ulSetError ( UL_WARNING, "ssgLoadVRML1: Failed to open '%s' for reading", fname ) ; return 0; } definedNodes = new _nodeIndex(); // check for a valid header header char *token; if( !(token = vrmlParser.getRawLine()) ) return 0; if( strstr( token, "#VRML V1.0 ascii" ) == NULL ) { ulSetError ( UL_WARNING, "ssgLoadVRML1: valid vrml1 header not found" ); return 0; } // creating a root node.. (a transform that changes Zup with Yup) ssgBranch *rootTransform = new ssgTransform(); sgCoord *tmpCoord = new sgCoord(); sgSetCoord( tmpCoord, 0.0f, 0.0f, 0.0f, 0.0f, 90.0f, 0.0f ); ((ssgTransform *)rootTransform)->setTransform( tmpCoord ); vrmlParser.expectNextToken( "Separator" ); if( !vrml1_parseSeparator( (ssgBranch *)rootTransform, NULL, NULL ) ) { ulSetError ( UL_WARNING, "ssgLoadVRML: Failed to extract valid object(s) from %s", fname ) ; delete( definedNodes ); delete( rootTransform ); return NULL ; } vrmlParser.closeFile(); delete( definedNodes ); return (ssgBranch *)rootTransform; } static bool vrml1_parseSeparator( ssgBranch *parentBranch, _traversalState *parentData, char *defName ) { char *childDefName = NULL; char *token; vrmlParser.expectNextToken( "{" ); // create a branch for this node ssgBranch *currentBranch = new ssgBranch(); if( defName != NULL ) { currentBranch->setName( defName ); definedNodes->insert( currentBranch ); } _traversalState *currentData; if( parentData == NULL ) currentData = new _traversalState(); else currentData = parentData->clone(); token = vrmlParser.getNextToken( NULL ); while( strcmp( token, "}" ) ) { if( !strcmp( token, "DEF" ) ) { token = vrmlParser.getNextToken( NULL ); ulSetError(UL_DEBUG, "DEF: Found an object definition %s.", token); childDefName = new char[50]; strncpy( childDefName, token, 50); } else if( !strcmp( token, "USE" ) ) { token = vrmlParser.getNextToken( NULL ); ulSetError(UL_DEBUG, "USE: Found a use directive %s.", token); if( !vrml1_parseUseDirective( currentBranch, currentData, token, childDefName ) ) { delete( currentBranch ); delete( currentData ); if( childDefName != NULL ) delete [] childDefName; return FALSE; } } else { int i=0; bool tokenFound = FALSE; while( vrmlTags[i].token != NULL && !tokenFound ) { if( !strcmp( token, vrmlTags[i].token ) ) { if( !(vrmlTags[i].func( currentBranch, currentData, childDefName ) ) ) { delete( currentBranch ); delete( currentData ); if( childDefName != NULL ) delete [] childDefName; return FALSE; } tokenFound = TRUE; } i++; } if( !tokenFound ) parseUnidentified(); } token = vrmlParser.getNextToken( NULL ); } parentBranch->addKid( currentBranch ); // delete the currentData structure (we may use its content, but not its form) delete( currentData ); return TRUE; } static bool vrml1_parseSwitch( ssgBranch *parentBranch, _traversalState *parentData, char *defName ) // UNSUPPORTED BEHAVIOUR: does not do a check for a whichChild parameter. Assumes that a switch // "hides" all of its children. { char *childDefName = NULL; char *token; vrmlParser.expectNextToken( "{" ); // create a branch for this node ssgBranch *currentBranch = new ssgSelector(); ((ssgSelector *)currentBranch)->select( 0 ); // fixme: allow for children to be traversed if( defName != NULL ) { currentBranch->setName( defName ); definedNodes->insert( currentBranch ); } _traversalState *currentData; if( parentData == NULL ) currentData = new _traversalState(); else currentData = parentData->clone(); token = vrmlParser.getNextToken( NULL ); while( strcmp( token, "}" ) ) { if( !strcmp( token, "DEF" ) ) { token = vrmlParser.getNextToken( NULL ); ulSetError(UL_DEBUG, "DEF: Found an object definition %s.", token); if( childDefName != NULL ) delete [] childDefName; childDefName = ulStrDup ( token ) ; } else if( !strcmp( token, "USE" ) ) { token = vrmlParser.getNextToken( NULL ); ulSetError(UL_DEBUG, "USE: Found a use directive %s.", token); if( !vrml1_parseUseDirective( currentBranch, currentData, token, childDefName ) ) { delete( currentBranch ); delete( currentData ); if( childDefName != NULL ) delete [] childDefName; return FALSE; } } else { int i=0; bool tokenFound = FALSE; while( vrmlTags[i].token != NULL && !tokenFound ) { if( !strcmp( token, vrmlTags[i].token ) ) { if( !(vrmlTags[i].func( currentBranch, currentData, childDefName ) ) ) { delete( currentBranch ); delete( currentData ); if( childDefName != NULL ) delete [] childDefName; return FALSE; } tokenFound = TRUE; } i++; } if( !tokenFound ) parseUnidentified(); } token = vrmlParser.getNextToken( NULL ); } parentBranch->addKid( currentBranch ); delete( currentData ); // delete the currentData structure (we may use its content, but not its form) return TRUE; } // parseVec: tries to parse a vec (of vSize), returns true if successful, false otherwise bool parseVec( SGfloat *v, int vSize ) { for( int i=0; iadd( index ); else return NULL; token = vrmlParser.peekAtNextToken( NULL ); } vrmlParser.expectNextToken( "-1" ); // we have to reverse vertex ordering if vertices are in clockwise order if( currentData->getFrontFace() == GL_CW ) { // so return something else that goes in reverse order ssgIndexArray *reversedIndexArray = new ssgIndexArray( indexArray->getNum() ); for( int i=(indexArray->getNum()-1); i>=0; i-- ) { int newIndex = (int)*indexArray->get( i ); reversedIndexArray->add( newIndex ); } delete( indexArray ); return reversedIndexArray; } return indexArray; } // parseCoordinate3: parses a list of 3d coordinates, adds them to the current // vertice array bool vrml1_parseCoordinate3( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { char *token; int numVertices = 0; // Ok, now we can allocate a new vertex table //ssgVertexArray *currentVertices = new ssgVertexArray(); ssgVertexArray *currentVertices = new ssgVertexArray(); if( defName != NULL ) { currentVertices->setName( defName ); definedNodes->insert( currentVertices ); } vrmlParser.expectNextToken("{"); vrmlParser.expectNextToken("point"); // an array? most likely.. token = vrmlParser.peekAtNextToken( NULL ); if( !strcmp( token, "[" ) ) { vrmlParser.expectNextToken("["); // begin parsing vertices token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "]" ) ) { sgVec3 v; if( ! parseVec( v, 3 ) ) return FALSE; numVertices++; currentVertices->add( v ); token = vrmlParser.peekAtNextToken( NULL ); } vrmlParser.expectNextToken("]"); } // otherwise it must be a singular value else { sgVec3 v; if( ! parseVec( v, 3 ) ) return FALSE; numVertices++; currentVertices->add( v ); } ulSetError(UL_DEBUG, "Level: %i. Found %i vertices here.", vrmlParser.level, numVertices); vrmlParser.expectNextToken("}"); currentData->setVertices( currentVertices ); return TRUE; } bool vrml1_parseTextureCoordinate2( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { char *token; int numTextureCoordinates = 0; ssgTexCoordArray *currentTextureCoordinates = new ssgTexCoordArray(); if( defName != NULL ) { currentTextureCoordinates->setName( defName ); definedNodes->insert( currentTextureCoordinates ); } vrmlParser.expectNextToken("{"); vrmlParser.expectNextToken("point"); // an array? most likely.. token = vrmlParser.peekAtNextToken( NULL ); if( !strcmp( token, "[" ) ) { vrmlParser.expectNextToken("["); // begin parsing TexCoords token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "]" ) ) { sgVec2 v; if( ! parseVec( v, 2 ) ) return FALSE; numTextureCoordinates++; currentTextureCoordinates->add( v ); token = vrmlParser.peekAtNextToken( NULL ); } vrmlParser.expectNextToken("]"); } // otherwise it must be a singular value else { sgVec2 v; if( ! parseVec( v, 2 ) ) return FALSE; numTextureCoordinates++; currentTextureCoordinates->add( v ); } ulSetError(UL_DEBUG, "Level: %i. Found %i TexCoords here.", vrmlParser.level, numTextureCoordinates); vrmlParser.expectNextToken("}"); currentData->setTextureCoordinates( currentTextureCoordinates ); return TRUE; } static bool vrml1_parseIndexedFaceSet( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { char *token; bool texCoordIndexGiven = FALSE; ssgBranch *currentBranch = new ssgBranch(); if( defName != NULL ) { currentBranch->setName( defName ); definedNodes->insert( currentBranch ); } ssgLoaderWriterMesh *loaderMesh = new ssgLoaderWriterMesh(); loaderMesh->createFaces(); loaderMesh->setVertices( currentData->getVertices() ); if( currentData->getTexture() != NULL && currentData->getTextureCoordinates() != NULL ) loaderMesh->createPerFaceAndVertexTextureCoordinates2(); vrmlParser.expectNextToken("{"); token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "}" ) ) { if( !strcmp( token, "coordIndex" ) ) { vrmlParser.expectNextToken("coordIndex"); if( !vrml1_parseCoordIndex( loaderMesh, currentData ) ) { delete( currentBranch ); delete( loaderMesh ); return FALSE; } } else if( !strcmp( token, "textureCoordIndex" ) ) { texCoordIndexGiven = TRUE; vrmlParser.expectNextToken("textureCoordIndex"); if( !vrml1_parseTextureCoordIndex( loaderMesh, currentData ) ) { delete( currentBranch ); delete( loaderMesh ); return FALSE; } } else token = vrmlParser.getNextToken( NULL ); token = vrmlParser.peekAtNextToken( NULL ); } //ulSetError(UL_DEBUG, "Level: %i. Found %i faces here.", vrmlParser.level, numFaces); vrmlParser.expectNextToken( "}" ); // ------------------------------------------------------- // add the face set to ssg // ------------------------------------------------------- // kludge. We need a state for addToSSG: ssgSimpleState * ss = new ssgSimpleState () ; // (0) ? ss -> setMaterial ( GL_AMBIENT, 0.5, 0.5, 0.5, 1.0); ss -> setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0) ; // 0.8, 0.8, 1.0, 1.0f ss -> setMaterial ( GL_SPECULAR, 1.0, 1.0, 1.0, 1.0); ss -> setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 1.0); ss -> setShininess ( 20 ) ; // Fixme, NIV14: Is that correct? // ------------------------------------------------------- // texturing stuff // ------------------------------------------------------- // todo: give an implicit mapping if texture coordinates are not given // todo: add support for per-vertex texturing if( currentData->getTexture() != NULL && currentData->getTextureCoordinates() != NULL && texCoordIndexGiven ) { ss -> setTexture ( currentData->getTexture() ); ss -> enable( GL_TEXTURE_2D ); } else ss -> disable( GL_TEXTURE_2D ); ss -> disable ( GL_COLOR_MATERIAL ) ; //ss -> enable ( GL_COLOR_MATERIAL ) ; //ss -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; ss -> enable ( GL_LIGHTING ) ; ss -> setShadeModel ( GL_SMOOTH ) ; ss ->disable(GL_ALPHA_TEST); //needed? ss -> disable ( GL_BLEND ) ; ss -> setOpaque () ; if( !currentData->getEnableCullFace() ) ss->disable( GL_CULL_FACE ); if( !loaderMesh->checkMe() ) { delete( currentBranch ); delete( loaderMesh ); return FALSE; } if( currentData->getTransform() != NULL ) { currentBranch->addKid( currentData->getTransform() ); // FIXME: in case we're reusing transforms, perhaps they should be reinstanced? (currently we don't allow transforms to be defed) loaderMesh->addToSSG( ss, currentOptions, currentData->getTransform() ); } else loaderMesh->addToSSG( ss, currentOptions, currentBranch ); parentBranch->addKid( currentBranch ); delete( loaderMesh ); return TRUE; } static bool vrml1_parseTexture2( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { char *token; char *fileName = NULL; bool wrapU = FALSE, wrapV = FALSE; vrmlParser.expectNextToken("{"); token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "}" ) ) { if( !strcmp( token, "filename") ) { vrmlParser.expectNextToken("filename"); token = vrmlParser.getNextToken( NULL ); fileName = new char[ strlen( token ) + 1]; strcpy( fileName, token ); } else if( !strcmp( token, "wrapS") ) { vrmlParser.expectNextToken("wrapS"); token = vrmlParser.getNextToken( NULL ); if( !strcmp( token, "REPEAT") ) wrapU = TRUE; } else if( !strcmp( token, "wrapT") ) { vrmlParser.expectNextToken("wrapT"); token = vrmlParser.getNextToken( NULL ); if( !strcmp( token, "REPEAT") ) wrapV = TRUE; } else token = vrmlParser.getNextToken( NULL ); token = vrmlParser.peekAtNextToken( NULL ); } if( fileName == NULL ) return FALSE; //ssgTexture *currentTexture = new ssgTexture( fileName, wrapU, wrapV ); ssgTexture *currentTexture = currentOptions -> createTexture ( fileName, wrapU, wrapV ); currentData->setTexture( currentTexture ); vrmlParser.expectNextToken("}"); delete [] fileName; return TRUE; } bool vrml1_parseShapeHints( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { char *token; vrmlParser.expectNextToken("{"); token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "}" ) ) { if( !strcmp( token, "vertexOrdering") ) { vrmlParser.expectNextToken("vertexOrdering"); token = vrmlParser.getNextToken( NULL ); if( !strcmp( token, "CLOCKWISE") ) { currentData->setEnableCullFace( TRUE ); currentData->setFrontFace( GL_CW ); } else if( !strcmp( token, "COUNTERCLOCKWISE") ) { currentData->setEnableCullFace( TRUE ); currentData->setFrontFace( GL_CCW ); } else if( !strcmp( token, "UNKNOWN_ORDERING") ) currentData->setEnableCullFace( FALSE ); else { ulSetError ( UL_WARNING, "ssgLoadVRML: invalid vertex ordering directive" ) ; return FALSE; } } else token = vrmlParser.getNextToken( NULL ); token = vrmlParser.peekAtNextToken( NULL ); } vrmlParser.expectNextToken("}"); return TRUE; } bool vrml1_parseMatrixTransform( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { ssgTransform *currentTransform = new ssgTransform(); sgMat4 transformMat; vrmlParser.expectNextToken("{"); vrmlParser.expectNextToken("matrix"); for( unsigned int i=0; i<4; i++ ) for( unsigned int j=0; j<4; j++ ) { if( !vrmlParser.getNextFloat( transformMat[i][j], NULL ) ) { ulSetError ( UL_WARNING, "ssgLoadVRML: Expected a float for a matrix, didn't get it." ) ; return FALSE; } } vrmlParser.expectNextToken("}"); currentTransform->setTransform( transformMat ); applyTransform( currentTransform, currentData ); //ulSetError(UL_DEBUG, "Found a Matrix Transform (%f, %f, %f %f), (%f, %f, %f %f), (%f, %f, %f %f), (%f, %f, %f %f)", xForm[0][0], xForm[1][0], xForm[2][0], xForm[3][0], // xForm[0][1], xForm[1][1], xForm[2][1], xForm[3][1], // xForm[0][2], xForm[1][2], xForm[2][2], xForm[3][2], // xForm[0][3], xForm[1][3], xForm[2][3], xForm[3][3] ); return TRUE; } bool vrml1_parseScale( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { ssgTransform *currentTransform = new ssgTransform(); sgVec3 scaleFactor; sgCoord moveFactor; sgZeroCoord( &moveFactor ); vrmlParser.expectNextToken("{"); vrmlParser.expectNextToken("scaleFactor"); if( !parseVec( scaleFactor, 3 ) ) return FALSE; vrmlParser.expectNextToken("}"); currentTransform->setTransform( &moveFactor, scaleFactor[0], scaleFactor[1], scaleFactor[2] ); applyTransform( currentTransform, currentData ); ulSetError(UL_DEBUG, "Found a scale transform: %f %f %f", scaleFactor[0], scaleFactor[1], scaleFactor[2] ); return TRUE; } bool vrml1_parseRotation( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { ssgTransform *currentTransform = new ssgTransform(); sgVec3 axis; SGfloat angle; sgMat4 rotation; vrmlParser.expectNextToken("{"); vrmlParser.expectNextToken("rotation"); if( !parseVec( axis, 3 ) ) return FALSE; if( !vrmlParser.getNextFloat( angle, NULL ) ) return FALSE; vrmlParser.expectNextToken("}"); angle *= SG_RADIANS_TO_DEGREES; sgMakeRotMat4( rotation, angle, axis ) ; currentTransform->setTransform( rotation ); applyTransform( currentTransform, currentData ); ulSetError(UL_DEBUG, "Found a rotation: %f %f %f %f", axis[0], axis[1], axis[2], angle ); return TRUE; } bool vrml1_parseTranslation( ssgBranch *parentBranch, _traversalState *currentData, char *defName ) { ssgTransform *currentTransform = new ssgTransform(); sgVec3 transform; vrmlParser.expectNextToken("{"); vrmlParser.expectNextToken("translation"); if( !parseVec( transform, 3 ) ) return FALSE; vrmlParser.expectNextToken("}"); currentTransform->setTransform( transform ); applyTransform( currentTransform, currentData ); ulSetError(UL_DEBUG, "Found a translation: %f %f %f", transform[0], transform[1], transform[2] ); return TRUE; } bool vrml1_parseUseDirective( ssgBranch *parentBranch, _traversalState *currentData, char *useName, char *defName ) { // find the node within the list of defined nodes ssgBase *node = definedNodes->extract( useName ); if( node==NULL ) return TRUE; if( node->isA( ssgTypeBranch() ) ) { ssgBranch *currentBranch = NULL; if( currentData->getTransform() != NULL ) { currentBranch = currentData->getTransform(); currentBranch->addKid( (ssgEntity *)node ); } else currentBranch = (ssgBranch *)node; parentBranch->addKid( currentBranch ); return TRUE; } return TRUE; } // parseUnidentified: A node that we either don't support or isn't part of the // VRML/IV spec. Just skip it. bool parseUnidentified() { char *token; int startLevel = vrmlParser.level; int currentLevel = startLevel + 1; vrmlParser.expectNextToken("{"); while( currentLevel != startLevel ) { token = vrmlParser.getNextToken( NULL ); if( !strcmp( token, "{" ) ) currentLevel++; else if( !strcmp( token, "}" ) ) currentLevel--; } return TRUE; } void applyTransform( ssgTransform *currentTransform, _traversalState *currentData ) { if( currentData->getTransform() == NULL ) currentData->setTransform( currentTransform ); else { ssgTransform *newTransform = new ssgTransform(); mergeTransformNodes( newTransform, currentTransform, currentData->getTransform() ); // this will have to be changed when we allow use declarations on transforms delete( currentTransform ); currentData->setTransform( newTransform ); } } bool vrml1_parseCoordIndex( ssgLoaderWriterMesh *loaderMesh, _traversalState *currentData ) { char *token = vrmlParser.peekAtNextToken( NULL ); int numFaces = 0; // an array? most likely.. if( !strcmp( token, "[" ) ) { vrmlParser.expectNextToken("["); token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "]" ) ) { ssgIndexArray *currentFaceIndices = parseIndexArray( currentData ); if( currentFaceIndices == NULL ) { ulSetError ( UL_WARNING, "ssgLoadVRML1: invalid index list" ) ; return FALSE; } loaderMesh->addFace( (ssgIndexArray **) ¤tFaceIndices ); //ulSetError(UL_DEBUG, "Level: %i. Added a face with %i vertices", vrmlParser.level, numVerticesInFace ); numFaces++; token = vrmlParser.peekAtNextToken( NULL ); } vrmlParser.expectNextToken( "]" ); } // otherwise a single point else { ssgIndexArray *currentFaceIndices = parseIndexArray( currentData ); if( currentFaceIndices == NULL ) { ulSetError ( UL_WARNING, "ssgLoadVRML1: invalid index list" ) ; return FALSE; } loaderMesh->addFace( (ssgIndexArray **) ¤tFaceIndices ); numFaces++; vrmlParser.expectNextToken( "-1" ); } return TRUE; } bool vrml1_parseTextureCoordIndex( ssgLoaderWriterMesh *loaderMesh, _traversalState *currentData ) { char *token = vrmlParser.peekAtNextToken( NULL ); // an array? most likely.. if( !strcmp( token, "[" ) ) { vrmlParser.expectNextToken("["); token = vrmlParser.peekAtNextToken( NULL ); while( strcmp( token, "]" ) ) { ssgIndexArray *currentTextureCoordinateIndices = parseIndexArray( currentData ); if( currentTextureCoordinateIndices == NULL ) return FALSE; ssgTexCoordArray *currentPerFaceAndVertexTextureCoordinateList = new ssgTexCoordArray( currentTextureCoordinateIndices->getNum() ); for( int i=0; igetNum(); i++ ) currentPerFaceAndVertexTextureCoordinateList->add( (currentData->getTextureCoordinates())->get( (unsigned int)*currentTextureCoordinateIndices->get( i ) ) ); loaderMesh->addPerFaceAndVertexTextureCoordinate2( (ssgTexCoordArray **) ¤tPerFaceAndVertexTextureCoordinateList ); delete( currentTextureCoordinateIndices ); //ulSetError(UL_DEBUG, "Level: %i. Added a face with %i vertices", vrmlParser.level, numVerticesInFace ); token = vrmlParser.peekAtNextToken( NULL ); } vrmlParser.expectNextToken( "]" ); } // otherwise a single point else { ssgIndexArray *currentTextureCoordinateIndices = parseIndexArray( currentData ); if( currentTextureCoordinateIndices == NULL ) return FALSE; ssgTexCoordArray *currentPerFaceAndVertexTextureCoordinateList = new ssgTexCoordArray( currentTextureCoordinateIndices->getNum() ); for( int i=0; igetNum(); i++ ) currentPerFaceAndVertexTextureCoordinateList->add( (currentData->getTextureCoordinates())->get( (unsigned int)*currentTextureCoordinateIndices->get( i ) ) ); loaderMesh->addPerFaceAndVertexTextureCoordinate2( (ssgTexCoordArray **) ¤tPerFaceAndVertexTextureCoordinateList ); delete( currentTextureCoordinateIndices ); //ulSetError(UL_DEBUG, "Level: %i. Added a face with %i vertices", vrmlParser.level, numVerticesInFace ); } return TRUE; } void mergeTransformNodes( ssgTransform *newTransform, ssgTransform *oldTransform1, ssgTransform *oldTransform2 ) { sgMat4 oldTransformMat1; sgMat4 oldTransformMat2; sgMat4 newTransformMat; oldTransform1->getTransform( oldTransformMat1 ); oldTransform2->getTransform( oldTransformMat2 ); sgMultMat4( newTransformMat, oldTransformMat1, oldTransformMat2 ) ; newTransform->setTransform( newTransformMat ); } plib-1.8.5/src/ssg/ssgSimpleState.cxx0000644000175000001440000004672410765364437014502 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSimpleState.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" void ssgSimpleState::copy_from ( ssgSimpleState *src, int clone_flags ) { ssgState::copy_from ( src, clone_flags ) ; ssgTexture *tex = src -> getTexture () ; ssgDeRefDelete(texture); if ( tex != NULL && ( clone_flags & SSG_CLONE_TEXTURE ) ) texture = (ssgTexture *)( tex -> clone ( clone_flags ) ) ; else texture = tex ; if (texture != NULL) texture->ref(); dont_care = src -> dont_care ; enables = src -> enables ; colour_material_mode = src -> colour_material_mode ; sgCopyVec4 ( specular_colour, src -> specular_colour ) ; sgCopyVec4 ( emission_colour, src -> emission_colour ) ; sgCopyVec4 ( ambient_colour, src -> ambient_colour ) ; sgCopyVec4 ( diffuse_colour, src -> diffuse_colour ) ; shade_model = src -> shade_model ; shininess = src -> shininess ; alpha_clamp = src -> alpha_clamp ; } ssgBase *ssgSimpleState::clone ( int clone_flags ) { ssgSimpleState *b = new ssgSimpleState ; b -> copy_from ( this, clone_flags ) ; return b ; } void _ssgForceLineState () { _ssgCurrentContext->getState()->enables &= ~((1<getState()->enables & 0x3F ; (*(__ssgDisableTable[turn_off]))() ; _ssgCurrentContext->getState()->enables &= ~turn_off ; if ( ~ dont_care & ( (1<getState()->colour_material_mode != colour_material_mode ) { glColorMaterial ( GL_FRONT_AND_BACK, (GLenum) colour_material_mode ) ; _ssgCurrentContext->getState()->colour_material_mode = colour_material_mode ; indeterminate |= _ssgCurrentContext->getState()->enables & (1<getState()->specular_colour, -1.0f, -1.0f, -1.0f ) ; sgSetVec3 ( _ssgCurrentContext->getState()->emission_colour, -1.0f, -1.0f, -1.0f ) ; sgSetVec3 ( _ssgCurrentContext->getState()->ambient_colour, -1.0f, -1.0f, -1.0f ) ; sgSetVec4 ( _ssgCurrentContext->getState()->diffuse_colour, -1.0f, -1.0f, -1.0f, -1.0f ) ; } } if ( ~ dont_care & ( (1<getState()->shininess != shininess ) { glMaterialf ( GL_FRONT_AND_BACK, GL_SHININESS, shininess ) ; _ssgCurrentContext->getState()->shininess = shininess ; } if ( ( ~ dont_care & (1<getState()->specular_colour, specular_colour ) ) { glMaterialfv ( GL_FRONT_AND_BACK, GL_SPECULAR, specular_colour ) ; sgCopyVec3 ( _ssgCurrentContext->getState()->specular_colour, specular_colour ) ; } if ( ( ~ dont_care & (1<getState()->emission_colour, emission_colour ) ) { glMaterialfv ( GL_FRONT_AND_BACK, GL_EMISSION, emission_colour ) ; sgCopyVec3 ( _ssgCurrentContext->getState()->emission_colour, emission_colour ) ; } if ( ( ~ dont_care & (1<getState()->ambient_colour, ambient_colour ) ) { glMaterialfv ( GL_FRONT_AND_BACK, GL_AMBIENT, ambient_colour ) ; sgCopyVec3 ( _ssgCurrentContext->getState()->ambient_colour, ambient_colour ) ; } if ( ( ~ dont_care & (1<getState()->diffuse_colour, diffuse_colour ) ) { glMaterialfv ( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse_colour ) ; sgCopyVec4 ( _ssgCurrentContext->getState()->diffuse_colour, diffuse_colour ) ; } } if ( ( ~ dont_care & (1<getState()->getTexture() != getTexture() ) { stats_bind_textures++ ; #ifdef GL_VERSION_1_1 glBindTexture ( GL_TEXTURE_2D, getTextureHandle() ) ; #else /* For ancient SGI machines */ glBindTextureEXT ( GL_TEXTURE_2D, getTextureHandle() ) ; #endif _ssgCurrentContext->getState()->setTexture ( getTexture () ) ; } if ( ( ~ dont_care & (1<getState()->shade_model != shade_model ) { glShadeModel ( shade_model ) ; _ssgCurrentContext->getState()->shade_model = shade_model ; } if ( ( ~ dont_care & (1<getState()->alpha_clamp != alpha_clamp ) { glAlphaFunc ( GL_GREATER, alpha_clamp ) ; _ssgCurrentContext->getState()->alpha_clamp = alpha_clamp ; } int turn_on = ~dont_care & enables & ~_ssgCurrentContext->getState()->enables & 0x3F ; (*(__ssgEnableTable [turn_on ]))() ; _ssgCurrentContext->getState()->enables |= turn_on ; preDraw () ; } void ssgSimpleState::force (void) { preApply () ; int turn_off = ~dont_care & ~enables & 0x3F ; (*(__ssgDisableTable[turn_off]))() ; _ssgCurrentContext->getState()->enables &= ~turn_off ; /* invalidate the material colours, since we do not know what the current mode is */ sgSetVec3 ( _ssgCurrentContext->getState()->specular_colour, -1.0f, -1.0f, -1.0f ) ; sgSetVec3 ( _ssgCurrentContext->getState()->emission_colour, -1.0f, -1.0f, -1.0f ) ; sgSetVec3 ( _ssgCurrentContext->getState()->ambient_colour, -1.0f, -1.0f, -1.0f ) ; sgSetVec4 ( _ssgCurrentContext->getState()->diffuse_colour, -1.0f, -1.0f, -1.0f, -1.0f ) ; if ( ~ dont_care & ( (1<getState()->colour_material_mode = colour_material_mode ; } if ( ~ dont_care & (1<getState()->shininess = shininess ; } if ( ~ dont_care & (1<getState()->diffuse_colour, diffuse_colour ) ; } if ( ~ dont_care & (1<getState()->emission_colour, emission_colour ) ; } if ( ~ dont_care & (1<getState()->ambient_colour, ambient_colour ) ; } if ( ~ dont_care & (1<getState()->specular_colour, specular_colour ) ; } } if ( ~ dont_care & (1<getState()->setTexture ( getTexture () ) ; } if ( ~ dont_care & (1<getState()->shade_model = shade_model ; } if ( ~ dont_care & (1<getState()->alpha_clamp = alpha_clamp ; } int turn_on = ~dont_care & enables & 0x3F ; (*(__ssgEnableTable [turn_on ]))() ; _ssgCurrentContext->getState()->enables |= turn_on ; preDraw () ; } int ssgSimpleState::isEnabled ( GLenum mode ) { switch ( mode ) { case GL_TEXTURE_2D : return enables & (1< ref () ; return ssgState::load(fd) ; } int ssgSimpleState::save ( FILE *fd ) { _ssgWriteInt ( fd, dont_care ) ; _ssgWriteInt ( fd, enables ) ; _ssgWriteInt ( fd, colour_material_mode ) ; _ssgWriteVec4 ( fd, specular_colour ) ; _ssgWriteVec4 ( fd, emission_colour ) ; _ssgWriteVec4 ( fd, ambient_colour ) ; _ssgWriteVec4 ( fd, diffuse_colour ) ; _ssgWriteInt ( fd, (int) shade_model ) ; _ssgWriteFloat ( fd, shininess ) ; _ssgWriteFloat ( fd, alpha_clamp ) ; if ( ! _ssgSaveObject ( fd, texture ) ) return FALSE ; return ssgState::save(fd) ; } /* wk: not implemented yet Is ssgSimpleState the right place to do this? use gkGetTexParamiv or so. int ssgSimpleState::getWrapU() { int wrapu = TRUE, wrapv = TRUE ; if ( filename == NULL ) return TRUE; if ( filename[0] == 0 ) return TRUE; GLuint texture_handle = getTextureHandle () ; } */ static void printStateString ( FILE *fd, unsigned int bits ) { if ( bits & (1<" : getTextureFilename() ) ; fprintf ( fd, "%s Shade Model = %d\n", indent, shade_model ) ; fprintf ( fd, "%s Shininess = %f\n", indent, shininess ) ; fprintf ( fd, "%s AlphaClamp = %f\n", indent, alpha_clamp ) ; fprintf ( fd, "%s ColourMatMode= %s\n", indent, (colour_material_mode == GL_AMBIENT) ? "GL_AMBIENT" : (colour_material_mode == GL_DIFFUSE) ? "GL_DIFFUSE" : (colour_material_mode == GL_AMBIENT_AND_DIFFUSE) ? "GL_AMBIENT_AND_DIFFUSE" : (colour_material_mode == GL_SPECULAR) ? "GL_SPECULAR" : (colour_material_mode == GL_EMISSION) ? "GL_EMISSION" : "?????" ) ; fprintf ( fd, "%s Ambient : (%f,%f,%f,%f)\n", indent, ambient_colour[0], ambient_colour[1], ambient_colour[2], ambient_colour[3] ) ; fprintf ( fd, "%s Diffuse : (%f,%f,%f,%f)\n", indent, diffuse_colour[0], diffuse_colour[1], diffuse_colour[2], diffuse_colour[3] ) ; fprintf ( fd, "%s Specular : (%f,%f,%f,%f)\n", indent, specular_colour[0], specular_colour[1], specular_colour[2], specular_colour[3] ) ; fprintf ( fd, "%s Emission : (%f,%f,%f,%f)\n", indent, emission_colour[0], emission_colour[1], emission_colour[2], emission_colour[3] ) ; } // *********************************************************************** // ******************** class ssgSimpleStateArray ************************ // *********************************************************************** int ssgSimpleStateArray::findIndex ( ssgSimpleState* st ) { for ( int i = 0; i < getNum (); i++ ) if ( get (i) == st ) return i ; return -1 ; } void ssgSimpleStateArray::collect ( ssgEntity *e ) { removeAll () ; collect_recursive (e); } void ssgSimpleStateArray::collect_recursive ( ssgEntity *e ) { if ( e -> isAKindOf ( ssgTypeBranch() ) ) { ssgBranch *br = (ssgBranch *) e ; for ( int i = 0 ; i < br -> getNumKids () ; i++ ) collect_recursive ( br -> getKid ( i ) ) ; } else if ( e -> isAKindOf ( ssgTypeVtxTable() ) ) { ssgVtxTable* vt = (ssgVtxTable *) e ; ssgState* st = vt -> getState () ; if ( st && st -> isAKindOf ( ssgTypeSimpleState() ) ) { ssgSimpleState* ss = (ssgSimpleState*) vt -> getState () ; if ( findIndex ( ss ) == -1 ) add ( ss ) ; } } } void ssgSimpleStateArray::add ( ssgSimpleState* ss ) { if ( ss ) { ss -> ref () ; raw_add ( (char *) &ss ) ; } } void ssgSimpleStateArray::removeAll () { for ( int i = 0; i < getNum (); i++ ) ssgDeRefDelete ( get (i) ) ; ssgSimpleList::removeAll () ; } ssgSimpleState* ssgSimpleStateArray::findMatch ( ssgSimpleState* st ) { if ( st == NULL ) return NULL ; for ( int i = 0; i < getNum (); i++ ) { ssgSimpleState *st2 = get (i) ; if ( st == st2 ) return NULL ; //same pointer -- don't change state if ( st->isEnabled ( GL_TEXTURE_2D ) != st2->isEnabled ( GL_TEXTURE_2D ) ) continue ; if ( st->isEnabled ( GL_TEXTURE_2D ) && st -> getTextureHandle () != st2 -> getTextureHandle () ) continue ; if ( st->getCareAbout (SSG_GL_SPECULAR) != st2->getCareAbout (SSG_GL_SPECULAR) || st->getCareAbout (SSG_GL_EMISSION) != st2->getCareAbout (SSG_GL_EMISSION) || st->getCareAbout (SSG_GL_AMBIENT) != st2->getCareAbout (SSG_GL_AMBIENT) || st->getCareAbout (SSG_GL_DIFFUSE) != st2->getCareAbout (SSG_GL_DIFFUSE) ) continue ; if ( ! st->getCareAbout (SSG_GL_SPECULAR) && ! sgEqualVec4 ( st->getMaterial (GL_SPECULAR), st2->getMaterial (GL_SPECULAR) ) ) continue ; if ( ! st->getCareAbout (SSG_GL_EMISSION) && ! sgEqualVec4 ( st->getMaterial (GL_EMISSION), st2->getMaterial (GL_EMISSION) ) ) continue ; if ( ! st->getCareAbout (SSG_GL_AMBIENT) && ! sgEqualVec4 ( st->getMaterial (GL_AMBIENT), st2->getMaterial (GL_AMBIENT) ) ) continue ; if ( ! st->getCareAbout (SSG_GL_DIFFUSE) && ! sgEqualVec4 ( st->getMaterial (GL_DIFFUSE), st2->getMaterial (GL_DIFFUSE) ) ) continue ; if ( st -> isTranslucent () != st2 -> isTranslucent () || st -> getShininess () != st2 -> getShininess () ) continue ; return st2 ; } return NULL ; } plib-1.8.5/src/ssg/ssg.cxx0000644000175000001440000004327410765364437012324 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssg.cxx 2125 2007-09-29 17:20:40Z fayjf $ */ #define _UL_GENERATE_CODE_ #include "ssgLocal.h" #if defined(UL_MACINTOSH) # include #elif defined(UL_MAC_OSX) # include #elif defined(UL_WIN32) /* Nothing */ #else # include #endif static bool glIsValidContext ( void ) { #if defined(CONSOLE) return true ; #elif defined(UL_WIN32) return ( wglGetCurrentContext () != NULL ) ; #elif defined(UL_MACINTOSH) return ( aglGetCurrentContext () != NULL ) ; #elif defined(UL_MAC_OSX) return ( CGLGetCurrentContext () != NULL ) ; #else return ( glXGetCurrentContext () != NULL ) ; #endif } sgMat4 _ssgOpenGLAxisSwapMatrix = { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, -1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f } } ; sgVec3 _ssgVertex000 = { 0.0f, 0.0f, 0.0f } ; sgVec4 _ssgColourWhite = { 1.0f, 1.0f, 1.0f, 1.0f } ; sgVec3 _ssgNormalUp = { 0.0f, 0.0f, 1.0f } ; sgVec2 _ssgTexCoord00 = { 0.0f, 0.0f } ; short _ssgIndex0 = 0; bool _ssgBackFaceCollisions = false ; void ssgSetBackFaceCollisions ( bool b ) { _ssgBackFaceCollisions = b ; } static ssgLight _ssgLights [ 8 ] ; static int _ssgFrameCounter = 0 ; int ssgGetFrameCounter () { return _ssgFrameCounter ; } void ssgSetFrameCounter ( int fc ) { _ssgFrameCounter = fc ; } const char *ssgGetVersion () { #ifdef VERSION return VERSION ; #else return "Unknown" ; #endif } void ssgDeRefDelete ( ssgBase *s ) { if ( s == NULL ) return ; s -> deRef () ; if ( s -> getRef () <= 0 ) delete s ; } void ssgDelete ( ssgBranch *br ) { if ( br == NULL ) return ; br -> removeAllKids () ; delete br ; } ssgLight *ssgGetLight ( int i ) { return &_ssgLights [ i ] ; } void ssgInit () { if ( ! glIsValidContext () ) { ulSetError ( UL_FATAL, "ssgInit called without a valid OpenGL context."); } ssgTexturePath ( "." ) ; ssgModelPath ( "." ) ; _ssgLights [ 0 ] . setID ( 0 ) ; _ssgLights [ 0 ] . on () ; for ( int i = 1 ; i < 8 ; i++ ) { _ssgLights [ i ] . setID ( i ) ; _ssgLights [ i ] . off () ; } new ssgContext ; /* Sets the current context with defaults */ ssgAddModelFormat ( ".ssg", ssgLoadSSG , ssgSaveSSG ) ; ssgAddModelFormat ( ".3ds", ssgLoad3ds , ssgSave3ds ) ; ssgAddModelFormat ( ".ac" , ssgLoadAC3D , ssgSaveAC ) ; ssgAddModelFormat ( ".ase", ssgLoadASE , ssgSaveASE ) ; ssgAddModelFormat ( ".dof", ssgLoadDOF , NULL ) ; ssgAddModelFormat ( ".dxf", ssgLoadDXF , ssgSaveDXF ) ; ssgAddModelFormat ( ".obj", ssgLoadOBJ , ssgSaveOBJ ) ; ssgAddModelFormat ( ".tri", ssgLoadTRI , ssgSaveTRI ) ; ssgAddModelFormat ( ".md2", ssgLoadMD2 , NULL ) ; ssgAddModelFormat ( ".x" , ssgLoadX , ssgSaveX ) ; ssgAddModelFormat ( ".flt", ssgLoadFLT , ssgSaveFLT ) ; ssgAddModelFormat ( ".strip", ssgLoadStrip, NULL ) ; ssgAddModelFormat ( ".m" , ssgLoadM , ssgSaveM ) ; ssgAddModelFormat ( ".off" , ssgLoadOFF , ssgSaveOFF ) ; ssgAddModelFormat ( ".atg" , ssgLoadATG , ssgSaveATG ) ; ssgAddModelFormat ( ".qhi" , NULL , ssgSaveQHI ) ; ssgAddModelFormat ( ".wrl", ssgLoadVRML1, ssgSaveVRML1 ) ; ssgAddModelFormat ( ".iv", ssgLoadIV , ssgSaveIV ) ; ssgAddModelFormat ( ".asc", ssgLoadASC , ssgSaveASC ) ; //ssgAddModelFormat ( ".pov", NULL , ssgSavePOV ) ; #ifdef SSG_LOAD_MDL_SUPPORTED ssgAddModelFormat ( ".mdl", ssgLoadMDL , NULL ) ; #endif #ifdef SSG_LOAD_TGA_SUPPORTED ssgAddTextureFormat ( ".tga" , ssgLoadTGA ) ; #endif #ifdef SSG_LOAD_BMP_SUPPORTED ssgAddTextureFormat ( ".bmp" , ssgLoadBMP ) ; #endif #ifdef SSG_LOAD_PNG_SUPPORTED ssgAddTextureFormat ( ".png" , ssgLoadPNG ) ; #endif #ifdef SSG_LOAD_PCX_SUPPORTED ssgAddTextureFormat ( ".pcx" , ssgLoadPCX ) ; #endif #ifdef SSG_LOAD_SGI_SUPPORTED ssgAddTextureFormat ( ".rgb" , ssgLoadSGI ) ; ssgAddTextureFormat ( ".rgba" , ssgLoadSGI ) ; ssgAddTextureFormat ( ".int" , ssgLoadSGI ) ; ssgAddTextureFormat ( ".inta" , ssgLoadSGI ) ; ssgAddTextureFormat ( ".bw" , ssgLoadSGI ) ; #endif #if defined(SSG_LOAD_MDL_SUPPORTED) || defined(SSG_LOAD_MDL_BGL_TEXTURE_SUPPORTED) ssgAddTextureFormat ( ".0af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".1af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".2af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".3af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".4af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".5af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".6af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".7af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".8af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".9af" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".aaf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".baf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".caf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".daf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".eaf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".faf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".gaf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".haf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".iaf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".jaf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".kaf" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".pat" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".r8" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".naz" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".ktx" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".oav" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".sky" , ssgLoadMDLTexture ) ; ssgAddTextureFormat ( ".ngt" , ssgLoadMDLTexture ) ; #endif #ifdef SSG_LOAD_XPL_SUPPORTED ssgAddModelFormat ( ".xpl", ssgLoadXPlaneOBJ , NULL ) ; #endif } void ssgCullAndPick ( ssgBranch *r, sgVec2 botleft, sgVec2 topright ) { if ( _ssgCurrentContext == NULL ) { ulSetError ( UL_FATAL, "ssg: No Current Context: Did you forgot to call ssgInit()?" ) ; } ssgForceBasicState () ; GLint vp [ 4 ] ; sgVec4 viewport ; sgMat4 mat ; float w = (topright[0] - botleft[0]) ; float h = (topright[1] - botleft[1]) ; float x = (botleft[0] + topright[0]) / 2.0f ; float y = (botleft[1] + topright[1]) / 2.0f ; glGetIntegerv ( GL_VIEWPORT, vp ) ; sgSetVec4 ( viewport, (float)vp[0], (float)vp[1], (float)vp[2], (float)vp[3] ) ; sgMakePickMatrix ( mat, x, y, w, h, viewport ) ; glMatrixMode ( GL_PROJECTION ) ; glLoadIdentity () ; glMultMatrixf ( (float *) mat ) ; _ssgCurrentContext->pushProjectionMatrix () ; glMatrixMode ( GL_MODELVIEW ) ; glLoadIdentity () ; int i ; for ( i = 0 ; i < 8 ; i++ ) if ( _ssgLights [ i ] . isHeadlight () ) _ssgLights [ i ] . setup () ; _ssgCurrentContext->loadModelviewMatrix () ; for ( i = 0 ; i < 8 ; i++ ) if ( ! _ssgLights [ i ] . isHeadlight () ) _ssgLights [ i ] . setup () ; _ssgCurrentContext->cull(r) ; _ssgDrawDList () ; glMatrixMode ( GL_MODELVIEW ) ; glLoadIdentity () ; } void ssgCullAndDraw ( ssgBranch *r ) { if ( _ssgCurrentContext == NULL ) { ulSetError ( UL_FATAL, "ssg: No Current Context: Did you forgot to call ssgInit()?" ) ; } _ssgStartOfFrameInit () ; ssgForceBasicState () ; glMatrixMode ( GL_PROJECTION ) ; _ssgCurrentContext->loadProjectionMatrix () ; glMatrixMode ( GL_MODELVIEW ) ; glLoadIdentity () ; int i ; for ( i = 0 ; i < 8 ; i++ ) if ( _ssgLights [ i ] . isHeadlight () ) _ssgLights [ i ] . setup () ; _ssgCurrentContext->loadModelviewMatrix () ; _ssgCurrentContext->applyClipPlanes () ; for ( i = 0 ; i < 8 ; i++ ) if ( ! _ssgLights [ i ] . isHeadlight () ) _ssgLights [ i ] . setup () ; _ssgCurrentContext->cull(r) ; _ssgDrawDList () ; _ssgCurrentContext->removeClipPlanes () ; glMatrixMode ( GL_MODELVIEW ) ; glLoadIdentity () ; _ssgEndOfFrameCleanup () ; _ssgFrameCounter++ ; } const char *ssgAxisTransform::getTypeName (void) { return "ssgAxisTransform" ; } const char *ssgBase ::getTypeName (void) { return "ssgBase" ; } const char *ssgTexture ::getTypeName (void) { return "ssgTexture" ; } const char *ssgState ::getTypeName (void) { return "ssgState" ; } const char *ssgSimpleState ::getTypeName (void) { return "ssgSimpleState" ; } const char *ssgStateSelector::getTypeName (void) { return "ssgStateSelector" ; } const char *ssgEntity ::getTypeName (void) { return "ssgEntity" ; } const char *ssgLeaf ::getTypeName (void) { return "ssgLeaf" ; } const char *ssgVTable ::getTypeName (void) { return "ssgVTable" ; } const char *ssgVtxTable ::getTypeName (void) { return "ssgVtxTable" ; } const char *ssgVtxArray ::getTypeName (void) { return "ssgVtxArray" ; } const char *ssgBranch ::getTypeName (void) { return "ssgBranch" ; } const char *ssgSelector ::getTypeName (void) { return "ssgSelector" ; } const char *ssgRangeSelector::getTypeName (void) { return "ssgRangeSelector" ; } const char *ssgTimedSelector::getTypeName (void) { return "ssgTimedSelector" ; } const char *ssgBaseTransform::getTypeName (void) { return "ssgBaseTransform" ; } const char *ssgTransform ::getTypeName (void) { return "ssgTransform" ; } const char *ssgTexTrans ::getTypeName (void) { return "ssgTexTrans" ; } const char *ssgCutout ::getTypeName (void) { return "ssgCutout" ; } const char *ssgRoot ::getTypeName (void) { return "ssgRoot" ; } const char *ssgSimpleList ::getTypeName (void) { return "ssgSimpleList" ; } const char *ssgColourArray ::getTypeName (void) { return "ssgColourArray" ; } const char *ssgIndexArray ::getTypeName (void) { return "ssgIndexArray" ; } const char *ssgTransformArray::getTypeName (void) { return "ssgTransformArray" ; } const char *ssgTexCoordArray::getTypeName (void) { return "ssgTexCoordArray" ; } const char *ssgVertexArray ::getTypeName (void) { return "ssgVertexArray" ; } const char *ssgNormalArray ::getTypeName (void) { return "ssgNormalArray" ; } const char *ssgInterleavedArray::getTypeName (void) { return "ssgInterleavedArray"; } static ssgBase *createBase () { return new ssgBase ; } //static ssgBase *createEntity () { return new ssgEntity ; } //static ssgBase *createLeaf () { return new ssgLeaf ; } static ssgBase *createVTable () { return new ssgVTable ; } static ssgBase *createVtxTable () { return new ssgVtxTable ; } static ssgBase *createVtxArray () { return new ssgVtxArray ; } static ssgBase *createTween () { return new ssgTween ; } static ssgBase *createBranch () { return new ssgBranch ; } //static ssgBase *createBaseTransform () { return new ssgBaseTransform ; } static ssgBase *createTransform () { return new ssgTransform ; } static ssgBase *createTexTrans () { return new ssgTexTrans ; } static ssgBase *createAnimTransform() { return new ssgAnimTransform ; } static ssgBase *createAxisTransform() { return new ssgAxisTransform ; } static ssgBase *createSelector () { return new ssgSelector ; } static ssgBase *createRangeSelector () { return new ssgRangeSelector ; } static ssgBase *createTimedSelector () { return new ssgTimedSelector ; } static ssgBase *createTweenController () { return new ssgTweenController ; } static ssgBase *createRoot () { return new ssgRoot ; } static ssgBase *createCutout () { return new ssgCutout ; } static ssgBase *createInvisible () { return new ssgInvisible ; } //static ssgBase *createState () { return new ssgState ; } static ssgBase *createSimpleState () { return new ssgSimpleState ; } static ssgBase *createStateSelector () { return new ssgStateSelector ; } static ssgBase *createSimpleList () { return new ssgSimpleList ; } static ssgBase *createVertexArray () { return new ssgVertexArray ; } static ssgBase *createNormalArray () { return new ssgNormalArray ; } static ssgBase *createTexCoordArray () { return new ssgTexCoordArray ; } static ssgBase *createColourArray () { return new ssgColourArray ; } static ssgBase *createIndexArray () { return new ssgIndexArray ; } static ssgBase *createTransformArray () { return new ssgTransformArray ; } static ssgBase *createInterleavedArray () { return new ssgInterleavedArray ; } static ssgBase *createTexture () { return new ssgTexture ; } static struct { int type ; ssgBase * ( *func ) () ; } table[256] = { { ssgTypeBase () , createBase }, //{ ssgTypeEntity () , createEntity }, //{ ssgTypeLeaf () , createLeaf }, { ssgTypeVTable () , createVTable }, { ssgTypeVtxTable () , createVtxTable }, { ssgTypeVtxArray () , createVtxArray }, { ssgTypeTween () , createTween }, { ssgTypeBranch () , createBranch }, //{ ssgTypeBaseTransform () , createBaseTransform }, { ssgTypeTransform () , createTransform }, { ssgTypeAnimTransform () , createAnimTransform }, { ssgTypeTexTrans () , createTexTrans }, { ssgTypeAxisTransform () , createAxisTransform }, { ssgTypeSelector () , createSelector }, { ssgTypeRangeSelector () , createRangeSelector }, { ssgTypeTimedSelector () , createTimedSelector }, { ssgTypeTweenController () , createTweenController }, { ssgTypeRoot () , createRoot }, { ssgTypeCutout () , createCutout }, { ssgTypeInvisible () , createInvisible }, //{ ssgTypeState () , createState }, { ssgTypeSimpleState () , createSimpleState }, { ssgTypeStateSelector () , createStateSelector }, { ssgTypeSimpleList () , createSimpleList }, { ssgTypeVertexArray () , createVertexArray }, { ssgTypeNormalArray () , createNormalArray }, { ssgTypeTexCoordArray () , createTexCoordArray }, { ssgTypeColourArray () , createColourArray }, { ssgTypeIndexArray () , createIndexArray }, { ssgTypeTransformArray () , createTransformArray }, { ssgTypeInterleavedArray () , createInterleavedArray }, { ssgTypeTexture () , createTexture }, { 0, NULL } }; void ssgRegisterType ( int type, ssgBase * ( *func ) () ) { if ( type == 0 || func == NULL ) { ulSetError ( UL_WARNING, "ssgRegisterType: Bad arguments (type %#x, func %p).", type, func ) ; return ; } int i ; for ( i = 0 ; table[i].type != 0 && table[i].type != type ; i++ ) ; if ( table[i].type == type && table[i].func != func ) ulSetError ( UL_WARNING, "ssgRegisterType: Type %#x redefined differently.", type ) ; table[i].type = type ; table[i].func = func ; } ssgBase *ssgCreateOfType ( int type ) { // XXX linear search int i ; for ( i = 0 ; table[i].type != 0 && table[i].type != type ; i++ ) ; if ( table[i].type == 0 ) { ulSetError ( UL_WARNING, "ssgCreateOfType: Unrecognized type %#x.", type ) ; return NULL ; } ssgBase *obj = (*table[i].func) () ; if ( obj == NULL ) ulSetError ( UL_WARNING, "ssgCreateOfType: Got null object for type %#x.", type ) ; else if ( obj -> getType () != type ) ulSetError ( UL_WARNING, "ssgCreateOfType: Created object has wrong type %#x (%s), expected %#x.", obj -> getType (), obj -> getTypeName (), type ) ; return obj ; } static bool ssgSearchExtensionString(char *extString, char *extName) { // Returns GL_TRUE if the *extName string appears in the *extString string, // surrounded by white spaces, or GL_FALSE otherwise. char *p, *end; int n, extNameLen; if ( ( extString == NULL ) || ( extName == NULL ) ) return false; extNameLen = strlen ( extName ); p = extString; end = p + strlen ( p ); while ( p < end ) { n = strcspn ( p, " " ); if ( ( extNameLen == n ) && ( strncmp ( extName, p, n ) == 0 ) ) return GL_TRUE; p += (n + 1); } return GL_FALSE; } bool ssgIsExtensionSupported(char *extName) { // Returns GL_TRUE if the OpenGL Extension whose name is *extName // is supported by the system, or GL_FALSE otherwise. // The *extName string must follow the OpenGL extensions naming scheme // (ie: "GL_type_extension", like GL_EXT_convolution) return ssgSearchExtensionString ( (char *)glGetString(GL_EXTENSIONS), extName ); } plib-1.8.5/src/ssg/ssgContext.cxx0000644000175000001440000001516110765364437013663 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgContext.cxx 1736 2002-12-02 15:04:06Z sjbaker $ */ #include "ssgLocal.h" ssgContext *_ssgCurrentContext = NULL ; ssgContext::~ssgContext () { if ( isCurrent() ) _ssgCurrentContext = NULL ; //~~ T.G. was ordinary delete before - must be derefed ssgDeRefDelete ( currentState ); ssgDeRefDelete ( basicState ); delete frustum ; } ssgContext::ssgContext () { makeCurrent () ; currentState = NULL ; basicState = NULL ; //orthographic = FALSE ; cullFace = TRUE ; ovTexture = FALSE ; ovCullface = FALSE ; ovState = NULL ; sgCopyMat4 ( cameraMatrix, _ssgOpenGLAxisSwapMatrix ) ; frustum = new sgFrustum ; frustum -> setNearFar ( 1.0, 10000.0 ) ; frustum -> setFOV ( 60.0, 45.0 ) ; currentState = new ssgSimpleState ( 1 ) ; currentState -> ref(); //~~ T.G. basicState = new ssgSimpleState ( 0 ) ; basicState -> ref(); //~~ T.G. currentState -> force () ; /* The order of the two following lines is essential. setTexture(NULL) currently sets the TEXTURE bit in dont_care... not the desired effect here. /PL */ basicState->setTexture ( (ssgTexture*) NULL ) ; basicState->dont_care = 0 ; basicState->colour_material_mode = GL_AMBIENT_AND_DIFFUSE ; sgSetVec4(basicState->specular_colour,1.0f,1.0f,1.0f,1.0f); sgSetVec4(basicState->emission_colour,0.0f,0.0f,0.0f,1.0f); sgSetVec4(basicState->ambient_colour, 1.0f,1.0f,1.0f,1.0f); sgSetVec4(basicState->diffuse_colour, 1.0f,1.0f,1.0f,1.0f); basicState->shade_model = GL_SMOOTH ; basicState->shininess = 0.0f ; basicState->alpha_clamp = 0.01f ; for ( int i = 0 ; i < 6 ; i++ ) sgSetVec4 ( clipPlane[i], 0, 0, 1, 0 ) ; enabledClipPlanes = 0 ; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } int ssgContext::isCurrent () { return _ssgCurrentContext == this ; } void ssgContext::forceBasicState () { if ( ! ovCullface ) glEnable ( GL_CULL_FACE ) ; cullFace = TRUE ; if ( ovState != NULL ) ovState -> force () ; else basicState -> force () ; } void ssgContext::makeCurrent () { _ssgCurrentContext = this ; } void ssgContext::getCameraPosition ( sgVec3 pos ) { sgCopyVec3 ( pos, cameraMatrix [ 3 ] ) ; } void ssgContext::overrideState ( ssgState *s ) { ovState = s ; } void ssgContext::overrideTexture ( int on_off ) { ovTexture = on_off ; } void ssgContext::overrideCullface ( int on_off ) { ovCullface = on_off ; } void ssgContext::setFrustum ( float l, float r, float b, float t, float n, float f ) { frustum -> setFrustum ( l, r, b, t, n, f ) ; } void ssgContext::setOrtho ( float l, float r, float b, float t, float n, float f ) { frustum -> setOrtho ( l, r, b, t, n, f ) ; } void ssgContext::getNearFar ( float *n, float *f ) { frustum -> getNearFar ( n, f ) ; } void ssgContext::getFOV ( float *w, float *h ) { frustum -> getFOV ( w, h ) ; } void ssgContext::setNearFar ( float n, float f ) { frustum -> setNearFar ( n, f ) ; } void ssgContext::getOrtho ( float *w, float *h ) { frustum -> getOrtho ( w, h ) ; } void ssgContext::setOrtho ( float w, float h ) { frustum -> setOrtho ( w, h ) ; } void ssgContext::setFOV ( float w, float h ) { frustum -> setFOV ( w, h ) ; } void ssgContext::setCamera ( sgMat4 mat ) { sgMat4 viewmat ; sgTransposeNegateMat4 ( viewmat, mat ) ; sgCopyMat4 ( cameraMatrix, _ssgOpenGLAxisSwapMatrix ) ; sgPreMultMat4 ( cameraMatrix, viewmat ) ; } void ssgContext::setCamera ( const sgCoord *coord ) { sgMat4 viewmat, mat ; sgMakeCoordMat4 ( mat, coord ) ; sgTransposeNegateMat4 ( viewmat, mat ) ; sgCopyMat4 ( cameraMatrix, _ssgOpenGLAxisSwapMatrix ) ; sgPreMultMat4 ( cameraMatrix, viewmat ) ; } void ssgContext::setCameraLookAt ( const sgVec3 eye, const sgVec3 center, const sgVec3 up ) { sgMat4 mat ; sgMakeLookAtMat4 ( mat, eye, center, up ) ; setCamera ( mat ) ; } void ssgContext::setCameraLookAt ( const sgVec3 eye, const sgVec3 center ) { sgVec3 up ; sgSetVec3 ( up, 0.0f, 0.0f, 1.0f ) ; sgMat4 mat ; sgMakeLookAtMat4 ( mat, eye, center, up ) ; setCamera ( mat ) ; } void ssgContext::loadProjectionMatrix() { glLoadIdentity () ; pushProjectionMatrix () ; } void ssgContext::pushProjectionMatrix () { pushProjectionMatrix ( frustum ) ; } void ssgContext::pushProjectionMatrix ( sgFrustum *f ) { if ( f -> isOrtho() ) glOrtho ( f -> getLeft() , f -> getRight(), f -> getBot () , f -> getTop (), f -> getNear() , f -> getFar () ) ; else glFrustum ( f -> getLeft() , f -> getRight(), f -> getBot () , f -> getTop (), f -> getNear() , f -> getFar () ) ; } void ssgContext::getProjectionMatrix ( sgMat4 dst ) { frustum -> getMat4 ( dst ) ; } void ssgContext::getModelviewMatrix ( sgMat4 dst ) { sgCopyMat4 ( dst, cameraMatrix ) ; } void ssgContext::loadModelviewMatrix () { glLoadMatrixf ( (float *) cameraMatrix ) ; } void ssgContext::loadModelviewMatrix ( sgMat4 mat ) { glLoadMatrixf ( (float *) mat ) ; } void ssgContext::cull ( ssgBranch *r ) { r -> cull ( frustum, cameraMatrix, TRUE ) ; } void ssgContext::removeClipPlanes () { for ( int i = 0 ; i < 6 ; i++ ) glDisable ( (GLenum)( GL_CLIP_PLANE0 + i) ) ; } void ssgContext::applyClipPlanes () { if ( enabledClipPlanes == 0 ) return ; for ( int i = 0 ; i < 6 ; i++ ) { if ( enabledClipPlanes & (1< #include "ssgLocal.h" struct FLT_texture { char fname [ 200 ] ; /* 200 is the OpenFlight limit - don't increase it! */ } ; struct FLT_vertex { sgVec3 vert ; sgVec3 norm ; sgVec4 col ; sgVec2 tex ; } ; static ulList *texList = NULL ; static ulList *vtxList = NULL ; static FILE *save_fd = NULL ; static int max_bank = 1 ; static int curr_bank = 0 ; static int addToTexturePool ( char *tex ) { int max = texList -> getNumEntities () ; for ( int p = strlen(tex) ; p >= 0 ; p-- ) if ( tex[p] == '/' ) { tex = & tex[p+1] ; break ; } for ( int i = 0 ; i < max ; i++ ) { FLT_texture *target = (FLT_texture *)( texList -> getEntity ( i ) ) ; if ( strcmp ( target->fname, tex ) == 0 ) return i ; } FLT_texture *add = new FLT_texture ; strncpy ( add->fname, tex, 199 ) ; texList -> addEntity ( add ) ; return max ; } static int addToVertexPool ( FLT_vertex *vert ) { int max = vtxList -> getNumEntities () ; for ( int i = 0 ; i < max ; i++ ) { FLT_vertex *target = (FLT_vertex *)( vtxList -> getEntity ( i ) ) ; if ( memcmp ( target, vert, sizeof ( FLT_vertex ) ) == 0 ) return i ; } FLT_vertex *add = new FLT_vertex ; *add = *vert ; vtxList -> addEntity ( add ) ; return max ; } static int writeChar ( char val ) { fwrite ( & val, sizeof(char), 1, save_fd ) ; return sizeof(char) ; } static int writeShort ( short val ) { writeChar ( (val >> 8) & 0xFF ) ; writeChar ( val & 0xFF ) ; return sizeof(short) ; } static int writeInt( int val ) { writeChar ( (val >> 24) & 0xFF ) ; writeChar ( (val >> 16) & 0xFF ) ; writeChar ( (val >> 8 ) & 0xFF ) ; writeChar ( val & 0xFF ) ; return sizeof(int) ; } static void swabInt ( int *x ) { unsigned int t = (unsigned int) *x ; *x = ((t & 0x000000FF) << 24) | ((t & 0x0000FF00) << 8) | ((t & 0x00FF0000) >> 8) | ((t & 0xFF000000) >> 24) ; } static void swabFloat ( float *x ) { int *a = (int *) x ; swabInt ( a ) ; } static void swabDouble ( double *x ) { int *a = (int *) x ; int *b = a+1 ; swabInt ( a ) ; swabInt ( b ) ; *a = *a ^ *b ; *b = *a ^ *b ; *a = *a ^ *b ; } static int writeFloat ( float val ) { if ( ulIsLittleEndian ) swabFloat ( & val ) ; fwrite ( & val, sizeof(float), 1, save_fd ) ; return sizeof(float) ; } static int writeDouble( double val ) { if ( ulIsLittleEndian ) swabDouble ( & val ) ; fwrite ( & val, sizeof(double), 1, save_fd ) ; return sizeof(double) ; } static int writeString( char *str, int slen ) { fwrite ( str, sizeof(char), slen, save_fd ) ; return slen ; } static void writeHeader () { int len = 0; len += writeShort ( 1 ) ; len += writeShort ( 2+2+8+4+4+32+2+2+2+2+2+1+1+4+4+ 4+4+4+4+4+4+4+4+4+4+4+4+4+2+2+ 4+8+8+8+8+2+2+4+4+2+2+2+2+4+8+ 8+8+8+8+8+8+8+2+2+2+2+2+2+2+2+ 4+2+2+2+8+8+2+2 ) ; len += writeString( " ", 8 ) ; /* ID */ len += writeInt ( 1570 ) ; /* Format Rev level 15.70 */ len += writeInt ( 0 ) ; /* Edit rev level */ len += writeString( "Unknown Date. ", 32 ) ; /* Date/Time */ len += writeShort ( 0 ) ; /* Next Group Node */ len += writeShort ( 0 ) ; /* Next LOD Node */ len += writeShort ( 0 ) ; /* Next Object Node */ len += writeShort ( 0 ) ; /* Next Face node */ len += writeShort ( 1 ) ; /* Unit multiplier */ len += writeChar ( 0 ) ; /* Unit type Meters */ len += writeChar ( 0 ) ; /* TexWhite */ len += writeInt ( 0 ) ; /* Flags */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Projection Type */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeShort ( 0 ) ; /* Next DOF node */ len += writeShort ( 1 ) ; /* Vertex storage type (DOUBLE!) */ len += writeInt ( 100 ) ; /* Database Origin */ len += writeDouble( 0 ) ; /* SW DB X */ len += writeDouble( 0 ) ; /* SW DB Y */ len += writeDouble( 0 ) ; /* Delta X */ len += writeDouble( 0 ) ; /* Delta Y */ len += writeShort ( 0 ) ; /* Next Sound node */ len += writeShort ( 0 ) ; /* Next Path node */ len += writeInt ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Reserved */ len += writeShort ( 0 ) ; /* Next Clip node */ len += writeShort ( 0 ) ; /* Next Text node */ len += writeShort ( 0 ) ; /* Next BSP node */ len += writeShort ( 0 ) ; /* Next Switch node */ len += writeInt ( 0 ) ; /* Reserved */ len += writeDouble( 0 ) ; /* SW Corner lat */ len += writeDouble( 0 ) ; /* SW Corner lon */ len += writeDouble( 0 ) ; /* NE Corner lat */ len += writeDouble( 0 ) ; /* NE Corner lon */ len += writeDouble( 0 ) ; /* Org Lat */ len += writeDouble( 0 ) ; /* Org Lon */ len += writeDouble( 0 ) ; /* Lambert upper lat */ len += writeDouble( 0 ) ; /* Lambert upper lon */ len += writeShort ( 0 ) ; /* Next Light source */ len += writeShort ( 0 ) ; /* Next Light Point */ len += writeShort ( 0 ) ; /* Next Road */ len += writeShort ( 0 ) ; /* Next CAT */ len += writeShort ( 0 ) ; /* Reserved */ len += writeShort ( 0 ) ; /* Reserved */ len += writeShort ( 0 ) ; /* Reserved */ len += writeShort ( 0 ) ; /* Reserved */ len += writeInt ( 0 ) ; /* Earth Ellipsoidal model (==WGS84) */ len += writeShort ( 0 ) ; /* Next Adaptive node */ len += writeShort ( 0 ) ; /* Next Curve node */ len += writeShort ( 0 ) ; /* Reserved */ len += writeDouble( 0 ) ; /* Delta Z to place */ len += writeDouble( 0 ) ; /* Radius Z to place */ len += writeShort ( 0 ) ; /* Next Mesh node */ len += writeShort ( 0 ) ; /* Reserved */ } static void writePush () { writeShort ( 10 ) ; writeShort ( 4 ) ; } static void writePop () { writeShort ( 11 ) ; writeShort ( 4 ) ; } static void writeObject () { writeShort ( 4 ) ; writeShort ( 2+2+8+4+2+2+2+2+2+2 ) ; static int next_name = 0 ; char name [ 8 ] ; sprintf ( name, "O%d", next_name++ ) ; writeString ( name, 8 ) ; /* Name */ writeInt ( 0x00000000 ) ; /* Flags */ writeShort ( 0 ) ; /* Relative Priority */ writeShort ( 0 ) ; /* Transparency (1-Alpha) */ writeShort ( 0 ) ; /* Special ID 1 */ writeShort ( 0 ) ; /* Special ID 2 */ writeShort ( 0 ) ; /* Significance */ writeShort ( 0 ) ; /* Layer */ } static void writeFace ( ssgLeaf *leaf, int isLine ) { writeShort ( 5 ) ; writeShort ( 2+2+8+4+2+1+1+2+2+1+1+2+2+2+2+2+4+2+1+1+ 4+1+1+2+4+4+4+2+2+4+4+2+2 ) ; static int next_name = 0 ; char name [ 8 ] ; sprintf ( name, "F%d", next_name++ ) ; writeString ( name, 8 ) ; /* Name */ writeInt ( 0 ) ; /* IR color code */ writeShort ( 0 ) ; /* Relative Priority */ writeChar ( isLine ? 2 : 0 ) ; /* Draw Type */ writeChar ( 0 ) ; /* Texture-White */ writeShort ( 0 ) ; /* Color name index */ writeShort ( 0 ) ; /* Alternate Color name index */ writeChar ( 0 ) ; writeChar ( 0 ) ; /* Billboard */ writeShort (-1 ) ; /* Detail Texture */ ssgSimpleState *s = (ssgSimpleState *)( leaf -> getState () ) ; if ( s != NULL && s -> getTextureFilename () != NULL ) writeShort ( addToTexturePool ( s -> getTextureFilename () ) ) ; else writeShort (-1 ) ; /* No Texture */ writeShort (-1 ) ; /* Material */ writeShort ( 0 ) ;/* XXXX */ /* SMC */ writeShort ( 0 ) ; /* DFAD FID */ writeInt ( 0 ) ; /* IR Material Code */ writeShort ( 0 ) ; /* Transparent */ writeChar ( 0 ) ; /* LOD generation control */ writeChar ( 0 ) ; /* Line Style */ writeInt ( 0x60000000 ) ; /* Flags == No Colour */ writeChar ( 3 ) ; /* Light mode == Use Vertex colour & Normal */ writeChar ( 0 ) ; writeShort ( 0 ) ; writeInt ( 0 ) ; writeInt ( 0xFFFFFFFF ) ; /* Packed Color */ writeInt ( 0xFFFFFFFF ) ; /* Packed Alt Color */ writeShort ( 0 ) ; /* Texture mapping index */ writeShort ( 0 ) ; writeInt ( 0 ) ; /* Primary Color Index */ writeInt ( 0 ) ; /* Secondary Color Index */ writeShort ( 0 ) ; writeShort ( 0 ) ; } static void writeLeaf ( ssgLeaf *leaf ) { int i ; writeObject () ; writePush () ; for ( i = 0 ; i < leaf -> getNumLines () ; i++ ) { writeFace ( leaf, TRUE ) ; writePush () ; writeShort ( 72 ) ; /* Vertex List */ writeShort ( 2+2+4*2 ) ; short vv [ 2 ] ; leaf -> getLine ( i, &vv[0], &vv[1] ) ; for ( int j = 0 ; j < 2 ; j++ ) { FLT_vertex vert ; sgCopyVec3 ( vert.vert, leaf -> getVertex ( vv[j] ) ) ; sgCopyVec3 ( vert.norm, leaf -> getNormal ( vv[j] ) ) ; sgCopyVec4 ( vert.col , leaf -> getColour ( vv[j] ) ) ; sgCopyVec2 ( vert.tex , leaf -> getTexCoord ( vv[j] ) ) ; writeInt ( addToVertexPool ( & vert ) * 60 + 8 ) ; } writePop () ; } for ( i = 0 ; i < leaf -> getNumTriangles () ; i++ ) { writeFace ( leaf, FALSE ) ; writePush () ; writeShort ( 72 ) ; /* Vertex List */ writeShort ( 2+2+4*3 ) ; short vv [ 3 ] ; leaf -> getTriangle ( i, &vv[0], &vv[1], &vv[2] ) ; for ( int j = 0 ; j < 3 ; j++ ) { FLT_vertex vert ; sgCopyVec3 ( vert.vert, leaf -> getVertex ( vv[j] ) ) ; sgCopyVec3 ( vert.norm, leaf -> getNormal ( vv[j] ) ) ; sgCopyVec4 ( vert.col , leaf -> getColour ( vv[j] ) ) ; sgCopyVec2 ( vert.tex , leaf -> getTexCoord ( vv[j] ) ) ; writeInt ( addToVertexPool ( & vert ) * 60 + 8 ) ; } writePop () ; } writePop () ; } static void writeAnimationGroup () { writeShort ( 2 ) ; writeShort ( 2+2+8+2+2+4+2+2+2+1+1+4 ) ; writeString ( "Animate", 8 ) ; /* Name */ writeShort ( 0 ) ; /* Relative Priority */ writeShort ( 0 ) ; writeInt ( 0x40000000 ) ; /* Flags = Animate forwards */ writeShort ( 100 ) ;/* Special ID 1 */ writeShort ( 0 ) ; /* Special ID 2 */ writeShort ( 0 ) ; /* Significance */ writeChar ( 0 ) ; /* Layer */ writeChar ( 0 ) ; writeInt ( 0 ) ; } static void writeVanillaGroup () { writeShort ( 2 ) ; writeShort ( 2+2+8+2+2+4+2+2+2+1+1+4 ) ; static int next_name = 0 ; char name [ 8 ] ; sprintf ( name, "Q%d", next_name++ ) ; writeString ( name, 8 ) ; /* Name */ writeShort ( 0 ) ; /* Relative Priority */ writeShort ( 0 ) ; writeInt ( 0 ) ; /* Flags */ writeShort ( 0 ) ; /* Special ID 1 */ writeShort ( 0 ) ; /* Special ID 2 */ writeShort ( 0 ) ; /* Significance */ writeChar ( 0 ) ; /* Layer */ writeChar ( 0 ) ; writeInt ( 0 ) ; } static void writeGroup ( ssgBranch *bra ) { writeShort ( 2 ) ; writeShort ( 2+2+8+2+2+4+2+2+2+1+1+4 ) ; static int next_name = 0 ; char name [ 8 ] ; sprintf ( name, "G%d", next_name++ ) ; writeString ( name, 8 ) ; /* Name */ writeShort ( 0 ) ; /* Relative Priority */ writeShort ( 0 ) ; writeInt ( 0 ) ; /* Flags */ writeShort ( 0 ) ; /* Special ID 1 */ writeShort ( 0 ) ; /* Special ID 2 */ writeShort ( 0 ) ; /* Significance */ writeChar ( 0 ) ; /* Layer */ writeChar ( 0 ) ; writeInt ( 0 ) ; } static void writeEntity ( ssgEntity *ent ) { if ( ent == NULL ) return ; if ( ! ent -> isAKindOf ( ssgTypeBranch () ) ) { if ( ent -> isAKindOf ( ssgTypeTween () ) ) ((ssgTween *)ent) -> setBank ( curr_bank ) ; writeLeaf ( (ssgLeaf *)ent ) ; if ( ent -> isAKindOf ( ssgTypeTween () ) ) ((ssgTween *)ent) -> setBank ( 0 ) ; return ; } if ( ((ssgBranch *)ent) -> getNumKids() == 0 ) return ; writeGroup ( (ssgBranch *)ent ) ; writePush () ; for ( int i = 0 ; i < ((ssgBranch *)ent) -> getNumKids() ; i++ ) writeEntity ( ((ssgBranch *)ent) -> getKid ( i ) ) ; writePop () ; } static void collectPalettesFromLeaf ( ssgLeaf *leaf ) { ssgSimpleState *s = (ssgSimpleState *)( leaf -> getState () ) ; if ( s != NULL && s -> getTextureFilename () != NULL ) addToTexturePool ( s -> getTextureFilename () ) ; if ( leaf -> isAKindOf ( ssgTypeTween () ) ) { ssgTween *t = (ssgTween *) leaf ; if ( t -> getNumBanks () > max_bank ) max_bank = t -> getNumBanks () ; for ( int i = 0 ; i < t->getNumBanks() ; i++ ) { t -> setBank ( i ) ; for ( int i = 0 ; i < t -> getNumVertices () ; i++ ) { FLT_vertex vert ; sgCopyVec3 ( vert.vert, t -> getVertex ( i ) ) ; sgCopyVec3 ( vert.norm, t -> getNormal ( i ) ) ; sgCopyVec4 ( vert.col , t -> getColour ( i ) ) ; sgCopyVec2 ( vert.tex , t -> getTexCoord ( i ) ) ; addToVertexPool ( & vert ) ; } } t -> setBank ( 0 ) ; } for ( int i = 0 ; i < leaf -> getNumVertices () ; i++ ) { FLT_vertex vert ; sgCopyVec3 ( vert.vert, leaf -> getVertex ( i ) ) ; sgCopyVec3 ( vert.norm, leaf -> getNormal ( i ) ) ; sgCopyVec4 ( vert.col , leaf -> getColour ( i ) ) ; sgCopyVec2 ( vert.tex , leaf -> getTexCoord ( i ) ) ; addToVertexPool ( & vert ) ; } } static void collectPalettes ( ssgEntity *ent ) { if ( ent == NULL ) return ; if ( ! ent -> isAKindOf ( ssgTypeBranch () ) ) { collectPalettesFromLeaf ( (ssgLeaf *)ent ) ; return ; } for ( int i = 0 ; i < ((ssgBranch *)ent) -> getNumKids() ; i++ ) collectPalettes ( ((ssgBranch *)ent) -> getKid ( i ) ) ; } static void writePalettes ( ssgEntity *root ) { int i ; max_bank = 1 ; collectPalettes ( root ) ; for ( i = 0 ; i < texList -> getNumEntities () ; i++ ) { writeShort ( 64 ) ; /* Texture Palette */ writeShort ( 2+2+200+4+4+4 ) ; writeString ( ((FLT_texture *)(texList -> getEntity ( i )))->fname, 200 ) ; writeInt ( i ) ; writeInt ( i % 16 ) ; writeInt ( i / 16 ) ; } writeShort ( 67 ) ; /* Vertex Palette header. */ writeShort ( 2+2+4 ) ; writeInt ( 2+2+4 + ( 2+2+2+2+8+8+8+4*3+4*2+4+4 ) * vtxList -> getNumEntities () ) ; for ( i = 0 ; i < vtxList -> getNumEntities () ; i++ ) { FLT_vertex *vv = (FLT_vertex *)(vtxList -> getEntity ( i )) ; writeShort ( 70 ) ; /* Vertex Palette with Normal and Texture */ writeShort ( 2+2+2+2+8+8+8+4*3+4*2+4+4 ) ; writeShort ( 0 ) ; /* Colour name index */ writeShort ( 0x1000 ) ; /* Flags == Use Packed Colour */ writeDouble ( vv -> vert [ 0 ] ) ; writeDouble ( vv -> vert [ 1 ] ) ; writeDouble ( vv -> vert [ 2 ] ) ; writeFloat ( vv -> norm [ 0 ] ) ; writeFloat ( vv -> norm [ 1 ] ) ; writeFloat ( vv -> norm [ 2 ] ) ; writeFloat ( vv -> tex [ 0 ] ) ; writeFloat ( vv -> tex [ 1 ] ) ; writeInt ( ( (int) ( vv -> col [ 3 ] * 255.0f ) << 24 ) + ( (int) ( vv -> col [ 2 ] * 255.0f ) << 16 ) + ( (int) ( vv -> col [ 1 ] * 255.0f ) << 8 ) + ( (int) ( vv -> col [ 0 ] * 255.0f ) << 0 ) ) ; writeInt ( 0 ) ; } } int ssgSaveFLT ( const char *fname, ssgEntity *root ) { if ( ( save_fd = fopen ( fname, "wb") ) == NULL ) { fprintf ( stderr, "Could not open file '%s' for writing.\n", fname ) ; return FALSE ; } writeHeader () ; if ( texList == NULL ) texList = new ulList ( 20 ) ; if ( vtxList == NULL ) vtxList = new ulList ( 200 ) ; writePalettes ( root ) ; writePush () ; writeVanillaGroup () ; writePush () ; if ( max_bank > 1 ) { writeAnimationGroup () ; writePush () ; } for ( int i = 0 ; i < max_bank ; i++ ) { curr_bank = i ; writeEntity ( root ) ; } if ( max_bank > 1 ) writePop () ; writePop () ; writePop () ; fclose ( save_fd ) ; /* Cleanup */ // This block is commented out because it // seems to screw things up elsewhere. // However, it needs to be there to avoid // a memory leak. // !! DEBUG ME!! #ifdef PREVENT_MEMORY_LEAK int max, i ; max = texList -> getNumEntities () ; for ( i = 0 ; i < max ; i++ ) delete (FLT_texture *) texList -> getEntity ( i ) ; delete texList ; max = vtxList -> getNumEntities () ; for ( i = 0 ; i < max ; i++ ) delete (FLT_vertex *) vtxList -> getEntity ( i ) ; delete vtxList ; #endif return TRUE ; } plib-1.8.5/src/ssg/ssgLoadDOF.cxx0000644000175000001440000003634710765364437013460 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2003 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadDOF.cxx 1748 2003-01-29 19:33:41Z sjbaker $ */ #include "ssgLocal.h" static ssgLoaderOptions* current_options = NULL ; struct _NameValuePair { char *name ; int value ; } ; #define TOKEN_DOF1 1 #define TOKEN_EDOF 2 #define TOKEN_MATS 3 #define TOKEN_GEOB 4 #define TOKEN_MAT0 5 #define TOKEN_GOB1 6 #define TOKEN_MHDR 7 #define TOKEN_MCOL 8 #define TOKEN_MUVW 9 #define TOKEN_MTRA 10 #define TOKEN_MTEX 11 #define TOKEN_MSUB 12 #define TOKEN_MEND 13 #define TOKEN_GHDR 14 #define TOKEN_INDI 15 #define TOKEN_VERT 16 #define TOKEN_TVER 17 #define TOKEN_NORM 18 #define TOKEN_BRST 19 #define TOKEN_GEND 20 #define TOKEN_ILLEGAL 998 #define TOKEN_EOF 999 static _NameValuePair tags [] = { { "DOF1", TOKEN_DOF1 }, { "EDOF", TOKEN_EDOF }, { "MATS", TOKEN_MATS }, { "GEOB", TOKEN_GEOB }, { "MAT0", TOKEN_MAT0 }, { "GOB1", TOKEN_GOB1 }, { "MHDR", TOKEN_MHDR }, { "MCOL", TOKEN_MCOL }, { "MUVW", TOKEN_MUVW }, { "MTRA", TOKEN_MTRA }, { "MTEX", TOKEN_MTEX }, { "MSUB", TOKEN_MSUB }, { "MEND", TOKEN_MEND }, { "GHDR", TOKEN_GHDR }, { "INDI", TOKEN_INDI }, { "VERT", TOKEN_VERT }, { "TVER", TOKEN_TVER }, { "NORM", TOKEN_NORM }, { "BRST", TOKEN_BRST }, { "GEND", TOKEN_GEND }, { NULL, 0 } } ; struct dofMaterial { char *name ; char *className ; sgVec4 ambient ; sgVec4 diffuse ; sgVec4 specular ; sgVec4 emission ; float shininess ; float uvwUoffset ; float uvwVoffset ; float uvwUtiling ; float uvwVtiling ; float uvwAngle ; float uvwBlur ; float uvwBlurOffset ; float transparency ; /* Unused */ int blendMode ; /* 0 == No blend, 1 == BLEND_SRC_ALPHA, 2 == BLEND_CONST (unused) */ int textures ; char **mapName ; int subMaterials ; /* Should be zero */ dofMaterial *MAT0 ; /* Should be unused */ ssgSimpleState *ssg_material ; } ; static ulList *materials ; static int getToken ( FILE *fd ) { char s [ 5 ] ; if ( fread ( s, 1, 4, fd ) != 4 ) return TOKEN_EOF ; s [ 4 ] = '\0' ; for ( int i = 0 ; tags [ i ] . name != 0 ; i++ ) if ( strcmp ( tags[i].name, s ) == 0 ) return tags[i].value ; ulSetError ( UL_WARNING, "Illegal token '%s'", s ) ; return TOKEN_ILLEGAL ; } static short getShort ( FILE *fd ) { short val ; if ( fread ( & val, sizeof(short), 1, fd ) != 1 ) return 0 ; val = ulEndianLittle16 ( (unsigned short) val ) ; return val ; } static void getColour ( FILE *fd, float *colour ) { if ( fread ( colour, sizeof(float), 4, fd ) != 4 ) return ; ulEndianLittleArrayFloat ( colour, 4 ) ; } static float getFloat ( FILE *fd ) { float val ; if ( fread ( & val, sizeof(float), 1, fd ) != 1 ) return 0 ; val = ulEndianLittleFloat ( val ) ; return val ; } static int getInteger ( FILE *fd ) { int val ; if ( fread ( & val, sizeof(int), 1, fd ) != 1 ) return 0 ; val = ulEndianLittle32 ( (unsigned int) val ) ; return val ; } static int getLength ( FILE *fd ) { return getInteger ( fd ) ; } static int getTokenAndLength ( FILE *fd, int *len ) { int tok = getToken ( fd ) ; if ( tok == TOKEN_EOF ) { *len = 0 ; return tok ; } *len = getLength ( fd ) ; return tok ; } static char *getQString ( FILE *fd, int *l ) { short len = getShort ( fd ) ; (*l) -= len + sizeof ( short ) ; char *res = new char [ len + 1 ] ; fread ( res, sizeof(char), len, fd ) ; res [ len ] = '\0' ; return res ; } static void getMAT0 ( FILE *fd ) { dofMaterial *mat = new dofMaterial ; mat -> ssg_material = new ssgSimpleState () ; materials -> addEntity ( mat ) ; while ( 1 ) { int len ; switch ( getToken ( fd ) ) { case TOKEN_MHDR : { len = getLength ( fd ) ; mat -> name = getQString ( fd, &len ) ; mat -> className = getQString ( fd, &len ) ; fprintf ( stderr, "MAT0: Name='%s', className='%s'\n", mat -> name, mat -> className ) ; } break ; case TOKEN_MTEX : { len = getLength ( fd ) ; mat -> textures = getInteger ( fd ) ; len -= sizeof ( int ) ; mat -> mapName = new char * [ mat -> textures ] ; for ( int i = 0 ; i < mat -> textures ; i++ ) mat -> mapName [ i ] = getQString ( fd, & len ) ; } break ; case TOKEN_MCOL : { len = getLength ( fd ) ; getColour ( fd, mat -> ambient ) ; getColour ( fd, mat -> diffuse ) ; getColour ( fd, mat -> specular ) ; getColour ( fd, mat -> emission ) ; mat -> shininess = getFloat ( fd ) ; len -= 17 * sizeof(float) ; } break ; case TOKEN_MUVW : len = getLength ( fd ) ; mat -> uvwUoffset = getFloat ( fd ) ; mat -> uvwVoffset = getFloat ( fd ) ; mat -> uvwUtiling = getFloat ( fd ) ; mat -> uvwVtiling = getFloat ( fd ) ; mat -> uvwAngle = getFloat ( fd ) ; mat -> uvwBlur = getFloat ( fd ) ; mat -> uvwBlurOffset = getFloat ( fd ) ; len -= 7 * sizeof(float) ; break ; case TOKEN_MTRA : len = getLength ( fd ) ; mat -> transparency = getFloat ( fd ) ; mat -> blendMode = getInteger ( fd ) ; len -= sizeof(float) + sizeof(int) ; break ; case TOKEN_MSUB : { len = getLength ( fd ) ; mat -> subMaterials = getInteger ( fd ) ; if ( mat -> subMaterials != 0 ) ulSetError ( UL_WARNING, "ssgLoadDOF: Sub-Materials are not supported." ) ; len -= sizeof ( int ) ; } break ; case TOKEN_MEND : { ssgSimpleState *m = mat -> ssg_material ; if ( mat -> textures > 0 ) { m -> enable ( GL_TEXTURE_2D ) ; m -> setTexture ( mat -> mapName[0] ) ; } else m -> disable ( GL_TEXTURE_2D ) ; m -> disable ( GL_COLOR_MATERIAL ) ; m -> setMaterial ( GL_AMBIENT , mat -> ambient ) ; m -> setMaterial ( GL_DIFFUSE , mat -> diffuse ) ; m -> setMaterial ( GL_SPECULAR, mat -> specular ) ; m -> setMaterial ( GL_EMISSION, mat -> emission ) ; m -> setShininess ( mat -> shininess ) ; } return ; case TOKEN_EOF : return ; default : { ulSetError ( UL_WARNING, "ssgLoadDOF: Material contains an unrecognised token?!?" ) ; len = getLength ( fd ) ; } break ; } for ( int i = 0 ; i < len ; i++ ) getc ( fd ) ; } } static void getMaterials ( FILE *fd, int howMany ) { ulSetError ( UL_WARNING, "Getting %d materials", howMany ) ; for ( int i = 0 ; i < howMany ; i++ ) { int len ; switch ( getToken ( fd ) ) { case TOKEN_MAT0 : len = getLength ( fd ) ; getMAT0 ( fd ) ; break ; case TOKEN_EOF : return ; default : { ulSetError ( UL_WARNING, "ssgLoadDOF: Material contains an unrecognised token?!?" ) ; len = getLength ( fd ) ; for ( int i = 0 ; i < len ; i++ ) getc ( fd ) ; } return ; } } } static ssgEntity *getGOB1 ( FILE *fd ) { int flags = 0 ; int paintflags = 0 ; int materialRef = 0 ; int indices = 0 ; short *index = NULL ; int vertices = 0 ; float *vertex = NULL ; int tvertices = 0 ; float *tvertex = NULL ; int normals = 0 ; float *normal = NULL ; int bursts = 0 ; int *burstStart = NULL ; int *burstCount = NULL ; int *burstMtlID = NULL ; int *burstVperP = NULL ; while ( 1 ) { int len ; switch ( getToken ( fd ) ) { case TOKEN_GHDR : { len = getLength ( fd ) ; flags = getInteger ( fd ) ; paintflags = getInteger ( fd ) ; materialRef = getInteger ( fd ) ; len -= 3 * sizeof ( int ) ; } break ; case TOKEN_INDI : { len = getLength ( fd ) ; indices = getInteger ( fd ) ; index = new short [ indices ] ; fread ( index, sizeof(short), indices, fd ) ; ulEndianLittleArray16 ( (unsigned short *) index, indices ) ; len -= sizeof(int) + sizeof(short) * indices ; } break ; case TOKEN_VERT : { len = getLength ( fd ) ; vertices = getInteger ( fd ) ; vertex = new float [ vertices * 3 ] ; fread ( vertex, sizeof(float), vertices * 3, fd ) ; ulEndianLittleArrayFloat ( vertex, vertices * 3 ) ; len -= sizeof(int) + sizeof(float) * vertices * 3 ; } break ; case TOKEN_TVER : { len = getLength ( fd ) ; tvertices = getInteger ( fd ) ; tvertex = new float [ tvertices * 2 ] ; fread ( tvertex, sizeof(float), tvertices * 2, fd ) ; ulEndianLittleArrayFloat ( tvertex, tvertices * 2 ) ; len -= sizeof(int) + sizeof(float) * tvertices * 2 ; } break ; case TOKEN_NORM : { len = getLength ( fd ) ; normals = getInteger ( fd ) ; normal = new float [ normals * 3 ] ; fread ( normal, sizeof(float), normals * 3, fd ) ; ulEndianLittleArrayFloat ( normal, normals * 3 ) ; len -= sizeof(int) + sizeof(float) * normals * 3 ; } break ; case TOKEN_BRST : { len = getLength ( fd ) ; bursts = getInteger ( fd ) ; burstStart = new int [ bursts ] ; burstCount = new int [ bursts ] ; burstMtlID = new int [ bursts ] ; burstVperP = new int [ bursts ] ; fread ( burstStart, sizeof(int), bursts, fd ) ; fread ( burstCount, sizeof(int), bursts, fd ) ; fread ( burstMtlID, sizeof(int), bursts, fd ) ; fread ( burstVperP, sizeof(int), bursts, fd ) ; ulEndianLittleArray32 ( (unsigned int *) burstStart, bursts ) ; ulEndianLittleArray32 ( (unsigned int *) burstCount, bursts ) ; ulEndianLittleArray32 ( (unsigned int *) burstMtlID, bursts ) ; ulEndianLittleArray32 ( (unsigned int *) burstVperP, bursts ) ; len -= sizeof(int) + sizeof(int) * bursts * 4 ; } break ; case TOKEN_GEND : { float *colours = new float [ vertices * 4 ] ; for ( int i = 0 ; i < vertices ; i++ ) { colours [ i*4 + 0 ] = 0.5f ; colours [ i*4 + 1 ] = 0.5f ; colours [ i*4 + 2 ] = 0.5f ; colours [ i*4 + 3 ] = 1.0f ; float tmp ; tmp = vertex [ i*3 + 1 ] ; vertex [ i*3 + 1 ] = -vertex [ i*3 + 2 ] ; vertex [ i*3 + 2 ] = tmp ; tmp = normal [ i*3 + 1 ] ; normal [ i*3 + 1 ] = -normal [ i*3 + 2 ] ; normal [ i*3 + 2 ] = tmp ; } ssgVertexArray *vx = new ssgVertexArray ( vertices , (sgVec3 *) vertex ) ; ssgColourArray *co = new ssgColourArray ( vertices , (sgVec4 *) colours ) ; ssgNormalArray *nm = new ssgNormalArray ( normals , (sgVec3 *) normal ) ; ssgTexCoordArray *tx = new ssgTexCoordArray ( tvertices, (sgVec2 *) tvertex ) ; ssgIndexArray *ix = new ssgIndexArray ( indices , index ) ; ssgVtxArray *va = new ssgVtxArray ( GL_TRIANGLES, vx, nm, tx, co, ix ) ; va -> setState ( ( (dofMaterial *) ( materials -> getEntity ( materialRef ) ) ) -> ssg_material ) ; delete [] burstStart ; delete [] burstCount ; delete [] burstMtlID ; delete [] burstVperP ; return va ; } case TOKEN_EOF : return NULL ; default : { ulSetError ( UL_WARNING, "ssgLoadDOF: GOB1 contains an unrecognised token?!?" ) ; len = getLength ( fd ) ; } break ; } for ( int i = 0 ; i < len ; i++ ) getc ( fd ) ; } } static ssgBranch *getGeode ( FILE *fd, int howMany ) { ssgBranch *br = new ssgBranch () ; ulSetError ( UL_WARNING, "Getting %d geodes", howMany ) ; for ( int i = 0 ; i < howMany ; i++ ) { int len ; switch ( getToken ( fd ) ) { case TOKEN_GOB1 : len = getLength ( fd ) ; br -> addKid ( getGOB1 ( fd ) ) ; break ; case TOKEN_EOF : return br ; default : { ulSetError ( UL_WARNING, "ssgLoadDOF: Geode contains an unrecognised token?!?" ) ; len = getLength ( fd ) ; for ( int i = 0 ; i < len ; i++ ) getc ( fd ) ; } return br ; } } return br ; } static void cleanUp () { for ( int i = 0 ; i < materials -> getNumEntities () ; i++ ) delete (dofMaterial *) ( materials -> getEntity ( i ) ) ; delete materials ; } ssgEntity *ssgLoadDOF ( const char *fname, const ssgLoaderOptions* options ) { ssgBranch *model ; ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; char filename [ 1024 ] ; current_options -> makeModelPath ( filename, fname ) ; FILE *fd = fopen ( filename, "ra" ) ; if ( fd == NULL ) { ulSetError ( UL_WARNING, "ssgLoadDOF: Failed to open '%s' for reading", filename ) ; return NULL ; } int len ; if ( getTokenAndLength ( fd, &len ) != TOKEN_DOF1 ) { ulSetError ( UL_WARNING, "ssgLoadDOF: '%s' does not start with 'DOF1'?!?", filename ) ; return NULL ; } materials = new ulList () ; model = new ssgBranch () ; while ( 1 ) { switch ( getToken ( fd ) ) { case TOKEN_MATS : getLength ( fd ) ; getMaterials ( fd, getInteger ( fd ) ) ; break ; case TOKEN_GEOB : getLength ( fd ) ; model -> addKid ( getGeode ( fd, getInteger ( fd ) ) ) ; break ; case TOKEN_EDOF : cleanUp () ; return model ; case TOKEN_EOF : cleanUp () ; return NULL ; default : ulSetError ( UL_WARNING, "ssgLoadDOF: '%s' contains an unrecognised token?!?", filename ) ; cleanUp () ; return NULL ; } } } plib-1.8.5/src/ssg/ssgLoadSGI.cxx0000644000175000001440000003107010765364437013456 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadSGI.cxx 2081 2006-04-16 17:45:33Z bram $ */ #include "ssgLocal.h" /* Some magic constants in the file header. */ #define SGI_IMG_MAGIC 0x01DA #define SGI_IMG_SWABBED_MAGIC 0xDA01 /* This is how it appears on a PC */ #define SGI_IMG_VERBATIM 0 #define SGI_IMG_RLE 1 class ssgSGIHeader { public: /* Yuk! Need to hide some of this public stuff! */ unsigned short magic ; int max ; int min ; int colormap ; char type ; char bpp ; unsigned int *start ; int *leng ; unsigned short dim ; unsigned short xsize ; unsigned short ysize ; unsigned short zsize ; int tablen ; /* added by J. Nathan Matias */ FILE *image_fd; char image_fname [ 512 ]; int isSwapped; unsigned char *rle_temp; bool loadSGI_bool; ssgSGIHeader () ; ssgSGIHeader(const char *fname, ssgTextureInfo* info ); ~ssgSGIHeader () ; bool openFile(const char *fname); void makeConsistant () ; void getRow ( unsigned char *buf, int y, int z ) ; void getPlane ( unsigned char *buf, int z ) ; void getImage ( unsigned char *buf ) ; void readHeader () ; protected: void swab_short ( unsigned short *x ); void swab_int ( unsigned int *x ); void swab_int_array ( int *x, int leng ); unsigned char readByte (); unsigned short readShort (); unsigned int readInt (); } ; #ifdef SSG_LOAD_SGI_SUPPORTED void ssgSGIHeader::makeConsistant () { /* Sanity checks - and a workaround for buggy RGB files generated by the MultiGen Paint program because it will sometimes get confused about the way to represent maps with more than one component. eg Y > 1, Number of dimensions == 1 Z > 1, Number of dimensions == 2 */ if ( ysize > 1 && dim < 2 ) dim = 2 ; if ( zsize > 1 && dim < 3 ) dim = 3 ; if ( dim < 1 ) ysize = 1 ; if ( dim < 2 ) zsize = 1 ; if ( dim > 3 ) dim = 3 ; if ( zsize < 1 && ysize == 1 ) dim = 1 ; if ( zsize < 1 && ysize != 1 ) dim = 2 ; if ( zsize >= 1 ) dim = 3 ; /* A very few SGI image files have 2 bytes per component - this library cannot deal with those kinds of files. */ if ( bpp == 2 ) { ulSetError ( UL_FATAL, "ssgLoadTexture: Can't work with SGI images with %d bpp", bpp ) ; } bpp = 1 ; min = 0 ; max = 255 ; magic = SGI_IMG_MAGIC ; colormap = 0 ; } void ssgSGIHeader::swab_short ( unsigned short *x ) { if ( isSwapped ) *x = (( *x >> 8 ) & 0x00FF ) | (( *x << 8 ) & 0xFF00 ) ; } void ssgSGIHeader::swab_int ( unsigned int *x ) { if ( isSwapped ) *x = (( *x >> 24 ) & 0x000000FF ) | (( *x >> 8 ) & 0x0000FF00 ) | (( *x << 8 ) & 0x00FF0000 ) | (( *x << 24 ) & 0xFF000000 ) ; } void ssgSGIHeader::swab_int_array ( int *x, int leng ) { if ( ! isSwapped ) return ; for ( int i = 0 ; i < leng ; i++ ) { *x = (( *x >> 24 ) & 0x000000FF ) | (( *x >> 8 ) & 0x0000FF00 ) | (( *x << 8 ) & 0x00FF0000 ) | (( *x << 24 ) & 0xFF000000 ) ; x++ ; } } unsigned char ssgSGIHeader::readByte () { unsigned char x ; fread ( & x, sizeof(unsigned char), 1, image_fd ) ; return x ; } unsigned short ssgSGIHeader::readShort () { unsigned short x ; fread ( & x, sizeof(unsigned short), 1, image_fd ) ; swab_short ( & x ) ; return x ; } unsigned int ssgSGIHeader::readInt () { unsigned int x ; fread ( & x, sizeof(unsigned int), 1, image_fd ) ; swab_int ( & x ) ; return x ; } void ssgSGIHeader::getRow ( unsigned char *buf, int y, int z ) { if ( y >= ysize ) y = ysize - 1 ; if ( z >= zsize ) z = zsize - 1 ; fseek ( image_fd, start [ z * ysize + y ], SEEK_SET ) ; if ( type == SGI_IMG_RLE ) { unsigned char *tmpp = rle_temp ; unsigned char *bufp = buf ; int length = leng [ z * ysize + y ]; fread ( rle_temp, 1, length, image_fd ) ; unsigned char pixel, count ; while ( tmpp < rle_temp + length ) { pixel = *tmpp++ ; count = ( pixel & 0x7f ) ; if ( count == 0 ) break ; if ( pixel & 0x80 ) { while ( count-- ) *bufp++ = *tmpp++ ; } else { pixel = *tmpp++ ; while ( count-- ) *bufp++ = pixel ; } } } else fread ( buf, 1, xsize, image_fd ) ; } void ssgSGIHeader::getPlane ( unsigned char *buf, int z ) { if ( image_fd == NULL ) return ; if ( z >= zsize ) z = zsize - 1 ; for ( int y = 0 ; y < ysize ; y++ ) getRow ( & buf [ y * xsize ], y, z ) ; } void ssgSGIHeader::getImage ( unsigned char *buf ) { if ( image_fd == NULL ) return ; for ( int y = 0 ; y < ysize ; y++ ) for ( int z = 0 ; z < zsize ; z++ ) getRow ( & buf [ ( z * ysize + y ) * xsize ], y, z ) ; } ssgSGIHeader::ssgSGIHeader () { dim = 0 ; start = NULL ; leng = NULL ; rle_temp = NULL ; image_fd = NULL ; } ssgSGIHeader::ssgSGIHeader ( const char *fname, ssgTextureInfo* info ) { ssgSGIHeader *sgihdr = this ; start = NULL ; leng = NULL ; rle_temp = NULL ; bool success=openFile(fname); if ( !success ) { loadSGI_bool = false ; return ; } GLubyte *image = new GLubyte [ sgihdr->xsize * sgihdr->ysize * sgihdr->zsize ] ; GLubyte *ptr = image ; unsigned char *rbuf = new unsigned char [ sgihdr->xsize ] ; unsigned char *gbuf = (sgihdr->zsize>1) ? new unsigned char [ sgihdr->xsize ] : (unsigned char *) NULL ; unsigned char *bbuf = (sgihdr->zsize>2) ? new unsigned char [ sgihdr->xsize ] : (unsigned char *) NULL ; unsigned char *abuf = (sgihdr->zsize>3) ? new unsigned char [ sgihdr->xsize ] : (unsigned char *) NULL ; for ( int y = 0 ; y < sgihdr->ysize ; y++ ) { int x ; switch ( sgihdr->zsize ) { case 1 : sgihdr->getRow ( rbuf, y, 0 ) ; for ( x = 0 ; x < sgihdr->xsize ; x++ ) *ptr++ = rbuf [ x ] ; break ; case 2 : sgihdr->getRow ( rbuf, y, 0 ) ; sgihdr->getRow ( gbuf, y, 1 ) ; for ( x = 0 ; x < sgihdr->xsize ; x++ ) { *ptr++ = rbuf [ x ] ; *ptr++ = gbuf [ x ] ; } break ; case 3 : sgihdr->getRow ( rbuf, y, 0 ) ; sgihdr->getRow ( gbuf, y, 1 ) ; sgihdr->getRow ( bbuf, y, 2 ) ; for ( x = 0 ; x < sgihdr->xsize ; x++ ) { *ptr++ = rbuf [ x ] ; *ptr++ = gbuf [ x ] ; *ptr++ = bbuf [ x ] ; } break ; case 4 : sgihdr->getRow ( rbuf, y, 0 ) ; sgihdr->getRow ( gbuf, y, 1 ) ; sgihdr->getRow ( bbuf, y, 2 ) ; sgihdr->getRow ( abuf, y, 3 ) ; for ( x = 0 ; x < sgihdr->xsize ; x++ ) { *ptr++ = rbuf [ x ] ; *ptr++ = gbuf [ x ] ; *ptr++ = bbuf [ x ] ; *ptr++ = abuf [ x ] ; } break ; } } fclose ( image_fd ) ; image_fd = NULL ; delete [] rbuf ; delete [] gbuf ; delete [] bbuf ; delete [] abuf ; if ( info != NULL ) { info -> width = sgihdr->xsize ; info -> height = sgihdr->ysize ; info -> depth = sgihdr->zsize ; info -> alpha = ( sgihdr->zsize == 2 || sgihdr->zsize == 4 ) ; } bool result = ssgMakeMipMaps ( image, sgihdr->xsize, sgihdr->ysize, sgihdr->zsize ) ; loadSGI_bool= result ; } ssgSGIHeader::~ssgSGIHeader() { if (start != NULL) delete [] start; if (leng != NULL) delete [] leng; if (image_fd != NULL) fclose(image_fd); if (rle_temp != NULL) delete [] rle_temp; } void ssgSGIHeader::readHeader () { isSwapped = FALSE ; magic = readShort () ; if ( magic != SGI_IMG_MAGIC && magic != SGI_IMG_SWABBED_MAGIC ) { ulSetError ( UL_FATAL, "%s: Unrecognised magic number 0x%04x", image_fname, magic ) ; } if ( magic == SGI_IMG_SWABBED_MAGIC ) { isSwapped = TRUE ; swab_short ( & magic ) ; } type = readByte () ; bpp = readByte () ; dim = readShort () ; /* This is a backstop test - if for some reason the magic number isn't swabbed, this test will still catch a swabbed file. Of course images with more than 256 dimensions are not catered for :-) */ if ( dim > 255 ) { ulSetError ( UL_WARNING, "%s: Bad swabbing?!?", image_fname ) ; isSwapped = ! isSwapped ; swab_short ( & dim ) ; magic = SGI_IMG_MAGIC ; } xsize = readShort () ; ysize = readShort () ; zsize = readShort () ; min = readInt () ; max = readInt () ; readInt () ; /* Dummy field */ int i ; for ( i = 0 ; i < 80 ; i++ ) readByte () ; /* Name field */ colormap = readInt () ; for ( i = 0 ; i < 404 ; i++ ) readByte () ; /* Dummy field */ makeConsistant () ; tablen = ysize * zsize ; start = new unsigned int [ tablen ] ; leng = new int [ tablen ] ; } bool ssgSGIHeader::openFile(const char *fname) { ssgSGIHeader *sgihdr=this; strcpy ( image_fname, fname ) ; image_fd = fopen ( image_fname, "rb" ) ; if ( image_fd == NULL ) { /* perror ( "ssgLoadTexture" ) ;*/ ulSetError ( UL_WARNING, "ssgSGIHeader::: Failed to open '%s' for reading.", image_fname ) ; return false ; } sgihdr -> readHeader () ; if ( sgihdr -> type == SGI_IMG_RLE ) { fread ( sgihdr->start, sizeof (unsigned int), sgihdr->tablen, image_fd ) ; fread ( sgihdr->leng , sizeof (int), sgihdr->tablen, image_fd ) ; swab_int_array ( (int *) sgihdr->start, sgihdr->tablen ) ; swab_int_array ( (int *) sgihdr->leng , sgihdr->tablen ) ; int maxlen = 0 ; for ( int i = 0 ; i < sgihdr->tablen ; i++ ) if ( sgihdr->leng [ i ] > maxlen ) maxlen = sgihdr->leng [ i ] ; rle_temp = new unsigned char [ maxlen ] ; } else { rle_temp = NULL ; for ( int i = 0 ; i < sgihdr->zsize ; i++ ) for ( int j = 0 ; j < sgihdr->ysize ; j++ ) { sgihdr->start [ i * sgihdr->ysize + j ] = sgihdr->xsize * ( i * sgihdr->ysize + j ) + 512 ; sgihdr->leng [ i * sgihdr->ysize + j ] = sgihdr->xsize ; } } if ( sgihdr->zsize <= 0 || sgihdr->zsize > 4 ) { ulSetError ( UL_FATAL, "ssgLoadTexture: '%s' is corrupted.", image_fname ) ; } return true ; } //wrapper function that does the same job as the previous one //except we now have a better architecture bool ssgLoadSGI ( const char *fname, ssgTextureInfo* info ) { ssgSGIHeader *sgihdr=new ssgSGIHeader( fname, info); bool returnval=sgihdr->loadSGI_bool; delete sgihdr; return returnval; } #else /*if there's no SGI support, allow things to compile, but print an error*/ ssgSGIHeader::ssgSGIHeader() { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - SGI support not configured", fname ) ; return; } ssgSGIHeader::ssgSGIHeader(const char *fname, ssgTextureInfo* info ) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - SGI support not configured", fname ) ; return; } void SGIHeader::makeConsistant (){return;} void SGIHeader::getRow ( unsigned char *buf, int y, int z ) {return;} void SGIHeader::getPlane ( unsigned char *buf, int z ) {return;} void SGIHeader::getImage ( unsigned char *buf ) {return;} void SGIHeader::readHeader () {return;} void SGIHeader::swab_short ( unsigned short *x ){return;} void SGIHeader::swab_int ( unsigned int *x ){return;} void SGIHeader::swab_int_array ( int *x, int leng ){return;} unsigned char SGIHeader::readByte (){return;} unsigned short SGIHeader::readShort (){return;} unsigned int SGIHeader::readInt (){return;} bool ssgLoadSGI ( const char *fname, ssgTextureInfo* info ) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - SGI support not configured", fname ) ; return false ; } #endif plib-1.8.5/src/ssg/ssgLoadStrip.cxx0000644000175000001440000000714110765364437014137 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadStrip.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgLocal.h" static ssgLoaderOptions* current_options; ssgEntity* ssgLoadStrip( const char* fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; char filename [ 1024 ] ; current_options -> makeModelPath ( filename, fname ) ; FILE* model_file = fopen(filename, "r"); if (model_file == NULL) { ulSetError(UL_WARNING, "ssgLoadStrip: Couldn't open file '%s'.", filename); return NULL; } ssgSimpleState* state = new ssgSimpleState(); state->setOpaque(); state->disable(GL_BLEND); state->disable(GL_ALPHA_TEST); state->disable(GL_TEXTURE_2D); state->enable(GL_COLOR_MATERIAL); state->enable(GL_LIGHTING); state->setShadeModel(GL_SMOOTH); state->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.0f, 1.0f); state->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.0f, 1.0f); state->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f); state->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f); state->setShininess(50); int i; int num_vertices = ulEndianReadLittle32(model_file); ssgBranch* model = new ssgBranch(); ssgVertexArray* vertices = new ssgVertexArray(); ssgNormalArray* normals = new ssgNormalArray(); for (i = 0; i < num_vertices; i++) { sgVec3 new_vec; int j; for (j = 0; j < 3; j++) { new_vec[j] = ulEndianReadLittleFloat(model_file); } vertices->add(new_vec); for (j = 0; j < 3; j++) { new_vec[j] = ulEndianReadLittleFloat(model_file); } normals->add(new_vec); } int num_strips = ulEndianReadLittle32(model_file); for (i = 0; i < num_strips; i++) { int num_indices = ulEndianReadLittle32(model_file); ssgIndexArray* strip_indices = new ssgIndexArray(num_indices); for (int j = 0; j < num_indices; j++) { strip_indices->add( ulEndianReadLittle16(model_file) ); } ssgVtxArray* varr = new ssgVtxArray( GL_TRIANGLE_STRIP, vertices, normals, NULL, NULL, strip_indices ); varr->setState( state ); varr->setCullFace( TRUE ); ssgLeaf* leaf = current_options->createLeaf(varr, NULL); model->addKid(leaf); } int num_indices = ulEndianReadLittle32(model_file); ssgIndexArray* indices = new ssgIndexArray(num_indices); for (i = 0; i < num_indices; i++) { indices->add( ulEndianReadLittle16(model_file) ); } ssgVtxArray* varr = new ssgVtxArray( GL_TRIANGLES, vertices, normals, NULL, NULL, indices ); varr->setState( state ); varr->setCullFace( TRUE ); ssgLeaf* leaf = current_options->createLeaf(varr, NULL); model->addKid(leaf); return model; } plib-1.8.5/src/ssg/ssg.h0000644000175000001440000024035210765364437011745 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssg.h 2126 2007-10-02 00:49:30Z fayjf $ */ #ifndef _INCLUDED_SSG_H_ #define _INCLUDED_SSG_H_ #include #include "sg.h" #ifdef UL_MAC_OSX # include #else # include #endif #include "ssgconf.h" #ifndef _SSG_PUBLIC #define _SSG_PUBLIC protected #endif extern int sgebug ; enum ssgCullResult { SSG_OUTSIDE = SG_OUTSIDE, SSG_INSIDE = SG_INSIDE, SSG_STRADDLE = SG_STRADDLE } ; #define SSG_MAXPATH 50 #define SSGTRAV_CULL 1 #define SSGTRAV_ISECT 2 #define SSGTRAV_HOT 4 #define SSGTRAV_LOS 8 class ssgList ; class ssgKidList ; class ssgBase ; class ssgEntity ; class ssgLeaf ; class ssgVTable ; class ssgVtxTable ; class ssgVtxArray ; class ssgTween ; class ssgBranch ; class ssgInvisible ; class ssgBaseTransform ; class ssgTransform ; class ssgTexTrans ; class ssgCutout ; class ssgSelector ; class ssgRangeSelector ; class ssgTimedSelector ; class ssgTweenController ; class ssgRoot ; void ssgDeRefDelete ( ssgBase *br ) ; /* Think twice before assigning new type bits, it is rather complicated. Perhaps some kind of automatic assignment would be good? */ #define _SSG_BACKWARDS_REFERENCE 0x0000000 /* For SSG format files */ #define _SSG_TYPE_BASE 0x00000001 /* ssgEntities */ #define _SSG_TYPE_ENTITY 0x00000002 #define _SSG_TYPE_LEAF 0x00000020 #define _SSG_TYPE_VTABLE 0x00000080 #define _SSG_TYPE_VTXTABLE 0x00000100 #define _SSG_TYPE_VTXARRAY 0x00000200 #define _SSG_TYPE_BRANCH 0x00000040 #define _SSG_TYPE_BASETRANSFORM 0x00000080 #define _SSG_TYPE_TRANSFORM 0x00001000 #define _SSG_TYPE_TEXTRANS 0x00002000 #define _SSG_TYPE_AXISTRANSFORM 0x00004000 #define _SSG_TYPE_ANIMTRANSFORM 0x00008000 #define _SSG_TYPE_SELECTOR 0x00000100 #define _SSG_TYPE_RANGESELECTOR 0x00001000 #define _SSG_TYPE_TIMEDSELECTOR 0x00002000 #define _SSG_TYPE_TWEEN 0x00008000 #define _SSG_TYPE_TWEENCONTROLLER 0x00010000 #define _SSG_TYPE_ROOT 0x00000200 #define _SSG_TYPE_CUTOUT 0x00000400 #define _SSG_TYPE_INVISIBLE 0x00000800 /* ssgStates */ #define _SSG_TYPE_STATE 0x00000004 #define _SSG_TYPE_SIMPLESTATE 0x00000020 #define _SSG_TYPE_STATESELECTOR 0x00000040 /* ssgSimpleLists */ #define _SSG_TYPE_SIMPLELIST 0x00000008 #define _SSG_TYPE_VERTEXARRAY 0x00000020 #define _SSG_TYPE_NORMALARRAY 0x00000040 #define _SSG_TYPE_TEXCOORDARRAY 0x00000080 #define _SSG_TYPE_COLOURARRAY 0x00000100 #define _SSG_TYPE_INDEXARRAY 0x00000200 #define _SSG_TYPE_TRANSFORMARRAY 0x00000400 #define _SSG_TYPE_INTERLEAVEDARRAY 0x00000800 /* ssgTextures */ #define _SSG_TYPE_TEXTURE 0x00000010 #define SSG_FILE_VERSION 0x01 #define SSG_FILE_MAGIC_NUMBER (('S'<<24)+('S'<<16)+('G'<<8)+SSG_FILE_VERSION) inline int ssgTypeBase () { return _SSG_TYPE_BASE ; } inline int ssgTypeEntity () { return _SSG_TYPE_ENTITY | ssgTypeBase () ; } inline int ssgTypeLeaf () { return _SSG_TYPE_LEAF | ssgTypeEntity () ; } inline int ssgTypeVTable () { return _SSG_TYPE_VTABLE | ssgTypeLeaf () ; } inline int ssgTypeVtxTable () { return _SSG_TYPE_VTXTABLE | ssgTypeLeaf () ; } inline int ssgTypeVtxArray () { return _SSG_TYPE_VTXARRAY | ssgTypeVtxTable() ; } inline int ssgTypeTween () { return _SSG_TYPE_TWEEN | ssgTypeVtxTable() ; } inline int ssgTypeBranch () { return _SSG_TYPE_BRANCH | ssgTypeEntity () ; } inline int ssgTypeTweenController(){ return _SSG_TYPE_TWEENCONTROLLER | ssgTypeBranch() ; } inline int ssgTypeBaseTransform() { return _SSG_TYPE_BASETRANSFORM | ssgTypeBranch () ; } inline int ssgTypeTransform () { return _SSG_TYPE_TRANSFORM | ssgTypeBaseTransform () ; } inline int ssgTypeAnimTransform() { return _SSG_TYPE_ANIMTRANSFORM | ssgTypeTransform () ; } inline int ssgTypeTexTrans () { return _SSG_TYPE_TEXTRANS | ssgTypeBaseTransform () ; } inline int ssgTypeAxisTransform() { return _SSG_TYPE_AXISTRANSFORM | ssgTypeTransform () ; } inline int ssgTypeSelector () { return _SSG_TYPE_SELECTOR | ssgTypeBranch () ; } inline int ssgTypeRangeSelector() { return _SSG_TYPE_RANGESELECTOR | ssgTypeSelector () ; } inline int ssgTypeTimedSelector() { return _SSG_TYPE_TIMEDSELECTOR | ssgTypeSelector () ; } inline int ssgTypeRoot () { return _SSG_TYPE_ROOT | ssgTypeBranch () ; } inline int ssgTypeCutout () { return _SSG_TYPE_CUTOUT | ssgTypeBranch () ; } inline int ssgTypeInvisible () { return _SSG_TYPE_INVISIBLE | ssgTypeBranch () ; } inline int ssgTypeState () { return _SSG_TYPE_STATE | ssgTypeBase () ; } inline int ssgTypeSimpleState () { return _SSG_TYPE_SIMPLESTATE | ssgTypeState () ; } inline int ssgTypeStateSelector() { return _SSG_TYPE_STATESELECTOR | ssgTypeSimpleState () ; } inline int ssgTypeSimpleList () { return _SSG_TYPE_SIMPLELIST | ssgTypeBase () ; } inline int ssgTypeVertexArray () { return _SSG_TYPE_VERTEXARRAY | ssgTypeSimpleList () ; } inline int ssgTypeNormalArray () { return _SSG_TYPE_NORMALARRAY | ssgTypeSimpleList () ; } inline int ssgTypeTexCoordArray() { return _SSG_TYPE_TEXCOORDARRAY | ssgTypeSimpleList () ; } inline int ssgTypeColourArray () { return _SSG_TYPE_COLOURARRAY | ssgTypeSimpleList () ; } inline int ssgTypeIndexArray () { return _SSG_TYPE_INDEXARRAY | ssgTypeSimpleList () ; } inline int ssgTypeTransformArray() { return _SSG_TYPE_TRANSFORMARRAY | ssgTypeSimpleList () ; } inline int ssgTypeInterleavedArray() { return _SSG_TYPE_INTERLEAVEDARRAY | ssgTypeSimpleList () ; } inline int ssgTypeTexture () { return _SSG_TYPE_TEXTURE | ssgTypeBase () ; } /* It's critical that these numbers don't change without some pretty pressing need because significant change to ssgSimpleState.cxx and ssgStateTables.cxx would be needed. */ #define SSG_GL_TEXTURE_EN 0 #define SSG_GL_CULL_FACE_EN 1 #define SSG_GL_COLOR_MATERIAL_EN 2 #define SSG_GL_BLEND_EN 3 #define SSG_GL_ALPHA_TEST_EN 4 #define SSG_GL_LIGHTING_EN 5 #define SSG_GL_TEXTURE 6 #define SSG_GL_COLOR_MATERIAL 7 #define SSG_GL_DIFFUSE 8 #define SSG_GL_AMBIENT 9 #define SSG_GL_SPECULAR 10 #define SSG_GL_EMISSION 11 #define SSG_GL_SHININESS 12 #define SSG_GL_ALPHA_TEST 13 #define SSG_GL_SHADE_MODEL 14 #define SSG_CLONE_RECURSIVE 1 #define SSG_CLONE_GEOMETRY 2 #define SSG_CLONE_USERDATA 4 #define SSG_CLONE_STATE 8 #define SSG_CLONE_STATE_RECURSIVE 16 #define SSG_CLONE_TEXTURE 32 int ssgGetFrameCounter () ; void ssgSetFrameCounter ( int fc ) ; // Returns GL_TRUE if the OpenGL Extension whose name is *extName // is supported by the system, or GL_FALSE otherwise. bool ssgIsExtensionSupported(char *extName); class ssgList { protected: unsigned int total ; /* The total number of entities in the list */ unsigned int limit ; /* The current limit on number of entities */ unsigned int next ; /* The next entity when we are doing getNext ops */ ssgEntity **entity_list ; /* The list. */ void sizeChk (void) ; public: ssgList ( int init_max = 1 ) ; virtual ~ssgList (void) ; ssgEntity *getEntity ( unsigned int n ) { next = n + 1 ; return ( n >= total ) ? (ssgEntity *) NULL : entity_list [ n ] ; } virtual void addEntity ( ssgEntity *entity ) ; virtual void removeEntity ( unsigned int n ) ; void removeAllEntities () ; void removeEntity ( ssgEntity *entity ) { removeEntity ( searchForEntity ( entity ) ) ; } virtual void replaceEntity ( unsigned int n, ssgEntity *new_entity ) ; void replaceEntity ( ssgEntity *old_entity, ssgEntity *new_entity ) { replaceEntity ( searchForEntity ( old_entity ), new_entity ) ; } int getNumEntities (void) { return total ; } ssgEntity *getNextEntity (void) { return getEntity ( next ) ; } int searchForEntity ( ssgEntity *entity ) ; } ; class ssgKidList : public ssgList { public: ssgKidList ( int init_max = 1 ) ; virtual ~ssgKidList (void) ; void addEntity ( ssgEntity *entity ) ; void removeEntity ( unsigned int n ) ; void removeEntity ( ssgEntity *entity ) { removeEntity ( searchForEntity ( entity ) ) ; } void replaceEntity ( unsigned int n, ssgEntity *new_entity ) ; void replaceEntity ( ssgEntity *old_entity, ssgEntity *new_entity ) { replaceEntity ( searchForEntity ( old_entity ), new_entity ) ; } } ; class ssgBase { int refc ; /* The number of references to this node */ int unique ; /* A unique number for this node */ protected : int type ; int spare ; /* This spare field is used in a bunch of short-term hacks */ char *name ; ssgBase *user_data ; virtual void copy_from ( ssgBase *src, int clone_flags ) ; public: void *operator new ( size_t size ) ; void operator delete ( void *ptr ) ; void deadBeefCheck () { assert ( type != (int) 0xDeadBeef ) ; } virtual void zeroSpareRecursive (); virtual void zeroSpare () ; virtual void incSpare () ; virtual void setSpare ( int ss ) ; virtual int getSpare () ; int getUnique () { return unique ; } ssgBase (void) ; virtual ~ssgBase (void) ; void ref () { refc++ ; } void deRef () { assert ( refc > 0 ) ; refc-- ; } int getRef() { return refc ; } virtual ssgBase *clone ( int clone_flags = 0 ) ; /* Type checking mechanism */ virtual const char *getTypeName(void) ; int getType (void) { return type ; } int isA ( int ty ) { return getType() == ty ; } int isAKindOf ( int ty ) { return ( getType() & ty ) == ty ; } virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; ssgBase *getUserData () { return user_data ; } void setUserData ( ssgBase *s ) { ssgDeRefDelete ( user_data ) ; user_data = s ; if ( s != NULL ) s -> ref () ; } void setName ( const char *nm ) ; char *getName () { return name ; } const char *getPrintableName () { return (name == NULL) ? "NoName" : name ; } } ; class ssgSimpleList : public ssgBase { protected: unsigned int total ; /* The total number of things in the list */ unsigned int limit ; /* The current limit on number of things */ unsigned int size_of ; /* The size of each thing */ char *list ; /* The list. */ bool own_mem ; /* Do we own the list memory ? */ void sizeChk ( unsigned int n ) { if ( (total+n) > limit ) { if ( ! own_mem ) ulSetError( UL_FATAL, "ssgSimpleList: Cannot resize array." ); /* how big should we make the list? */ limit += limit ; /* double it */ if ( limit <= 0 ) limit = 3; if ( (total+n) > limit ) limit = (total+n) ; /* re-allocate the list */ char *nlist = new char [ limit * size_of ] ; memmove ( nlist, list, total * size_of ) ; delete [] list ; list = nlist ; } } virtual void copy_from ( ssgSimpleList *src, int clone_flags ) ; _SSG_PUBLIC: ssgSimpleList () { type = ssgTypeSimpleList () ; limit = 0 ; size_of = 0 ; total = 0 ; list = NULL ; own_mem = true ; } public: ssgSimpleList ( int sz, int init = 3, char* things = 0 ) { type = ssgTypeSimpleList () ; limit = init ; size_of = sz ; if ( things ) { total = init ; list = things ; own_mem = false ; } else { total = 0 ; list = new char [ limit * size_of ] ; own_mem = true ; } } virtual ssgBase *clone ( int clone_flags = 0 ) ; virtual ~ssgSimpleList (void) { if ( own_mem ) delete [] list ; list = NULL ; } ; char *raw_get ( unsigned int n ) { return ( n >= total ) ? ((char *) 0) : & list [ n * size_of ] ; } void raw_add ( char *thing ) { sizeChk ( 1 ) ; memcpy ( & list [ size_of * total++ ], thing, size_of ) ; } ; void raw_add ( char *things, unsigned int n ) { sizeChk ( n ) ; memcpy ( & list [ size_of * total ], things, size_of * n ) ; total += n ; } void raw_set ( char *thing, unsigned int n ) { memcpy ( & list [ size_of * n ], thing, size_of ) ; } ; void removeLast () { if ( total > 0 ) total-- ; } void removeAll () { if ( own_mem ) delete [] list ; list = NULL ; limit = total = 0 ; } int compare(ssgSimpleList *other, int print_result=TRUE); int getSizeOf (void) { return size_of ; } int getNum (void) { return total ; } void rawSetNum ( unsigned int n ) /* Better know what you're doing!! */ { total = n ; } void setNum ( unsigned int n ) { if ( total < n ) { sizeChk ( n ) ; memset ( & list [ size_of * total ], 0, size_of * (n-total) ) ; total = n ; } } virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual const char *getTypeName(void) ; } ; class ssgVertexArray : public ssgSimpleList { public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgVertexArray ( int init = 3, sgVec3* things = 0 ) : ssgSimpleList ( sizeof(sgVec3), init, (char*)things ) { type = ssgTypeVertexArray () ; } float *get ( unsigned int n ) { return (float *) raw_get ( n ) ; } void add ( sgVec3 thing ) { raw_add ( (char *) thing ) ; } ; void set ( sgVec3 thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ; void set ( float x, float y, float z, unsigned int n ) { sgVec3 tmp = { x, y, z } ; raw_set ( (char *) tmp, n ) ; } ; void add ( float x, float y, float z ) { sgVec3 tmp = { x, y, z } ; raw_add ( (char *) tmp ) ; } ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual const char *getTypeName(void) ; } ; class ssgNormalArray : public ssgSimpleList { public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgNormalArray ( int init = 3, sgVec3* things = 0 ) : ssgSimpleList ( sizeof(sgVec3), init, (char*)things ) { type = ssgTypeNormalArray () ; } float *get ( unsigned int n ) { return (float *) raw_get ( n ) ; } void add ( sgVec3 thing ) { raw_add ( (char *) thing ) ; } ; void set ( sgVec3 thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ; void set ( float x, float y, float z, unsigned int n ) { sgVec3 tmp = { x, y, z } ; raw_set ( (char *) tmp, n ) ; } ; void add ( float x, float y, float z ) { sgVec3 tmp = { x, y, z } ; raw_add ( (char *) tmp ) ; } ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual const char *getTypeName(void) ; } ; class ssgTexCoordArray : public ssgSimpleList { public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgTexCoordArray ( int init = 3, sgVec2* things = 0 ) : ssgSimpleList ( sizeof(sgVec2), init, (char*)things ) { type = ssgTypeTexCoordArray () ; } float *get ( unsigned int n ) { return (float *) raw_get ( n ) ; } void add ( sgVec2 thing ) { raw_add ( (char *) thing ) ; } ; void set ( sgVec2 thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ; void set ( float u, float v, unsigned int n ) { sgVec2 tmp = { u, v } ; raw_set ( (char *) tmp, n ) ; } ; void add ( float u, float v ) { sgVec2 tmp = { u, v } ; raw_add ( (char *) tmp ) ; } ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual const char *getTypeName(void) ; } ; class ssgColourArray : public ssgSimpleList { public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgColourArray ( int init = 3, sgVec4* things = 0 ) : ssgSimpleList ( sizeof(sgVec4), init, (char*)things ) { type = ssgTypeColourArray () ; } float *get ( unsigned int n ) { return (float *) raw_get ( n ) ; } void add ( sgVec4 thing ) { raw_add ( (char *) thing ) ; } ; void set ( sgVec4 thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ; void set ( float r, float g, float b, float a, unsigned int n ) { sgVec4 tmp = { r,g,b,a } ; raw_set ( (char *) tmp, n ) ; } ; void add ( float r, float g, float b, float a ) { sgVec4 tmp = { r,g,b,a } ; raw_add ( (char *) tmp ) ; } ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual const char *getTypeName(void) ; } ; class ssgIndexArray : public ssgSimpleList { public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgIndexArray ( int init = 3, short* things = 0 ) : ssgSimpleList ( sizeof(short), init, (char*)things ) { type = ssgTypeIndexArray () ; } virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; short *get ( unsigned int n ) { return (short *) raw_get ( n ) ; } void add ( short thing ) { raw_add ( (char *) &thing ) ; } ; void set ( short thing, unsigned int n ) { raw_set ( (char *) &thing, n ) ; } ; virtual const char *getTypeName(void) ; } ; class ssgTransformArray : public ssgSimpleList { public: int selection ; /* used to remember last transform selected */ ssgTransformArray ( int init = 3, sgMat4* things = 0 ) : ssgSimpleList ( sizeof(sgMat4), init, (char*)things ) { type = ssgTypeTransformArray () ; selection = 0 ; } sgMat4 *get ( unsigned int n ) { return (sgMat4 *) raw_get ( n ) ; } void add ( sgMat4 thing ) { raw_add ( (char *) thing ) ; } ; virtual const char *getTypeName(void) ; } ; class ssgTexture ; class ssgTextureArray : private ssgSimpleList { public: ssgTextureArray ( int init = 3 ) : ssgSimpleList ( sizeof(ssgTexture*), init ) { //type = ssgTypeTextureArray () ; } int getNum (void) { return total ; } ssgTexture* get ( unsigned int n ) { return *( (ssgTexture**) raw_get ( n ) ) ; } void add ( ssgTexture* thing ) ; void removeAll () ; ssgTexture* findByFilename ( const char* fname ) ; } ; class ssgSimpleState ; class ssgSimpleStateArray : private ssgSimpleList { void collect_recursive ( ssgEntity *e ); public: ssgSimpleStateArray ( int init = 3 ) : ssgSimpleList ( sizeof(ssgSimpleState*), init ) { //type = ssgTypeSimpleStateArray () ; } int getNum (void) { return total ; } ssgSimpleState* get ( unsigned int n ) { assert(n getHandle () ; return 0 ; } virtual char *getTextureFilename(void) { if ( texture != NULL ) return texture -> getFilename () ; return NULL ; } virtual ssgTexture* getTexture (void) { return texture ; } virtual void setTexture ( ssgTexture *tex ) { ssgDeRefDelete ( texture ) ; texture = tex ; if ( texture != NULL ) { care_about ( SSG_GL_TEXTURE ) ; texture -> ref () ; } else { dont_care_about ( SSG_GL_TEXTURE ) ; } } virtual void setTexture ( const char *fname, int _wrapu = TRUE, int _wrapv = TRUE, int _mipmap = TRUE ) { mipmap = _mipmap ; setTexture ( new ssgTexture ( fname, _wrapu, _wrapv, mipmap ) ) ; } /* WARNING - THIS FORM OF setTexture IS DEPRECATED BECAUSE IT PREVENTS ssgSave FROM SAVING THE TEXTURE FILENAME and it LEAKS texture handles! */ virtual void setTexture ( GLuint tex ) { if ( !texture ) setTexture ( new ssgTexture ) ; texture -> setHandle ( tex ) ; texture -> setFilename ( NULL ) ; } virtual void setTextureFilename ( const char *fname ) { if ( !texture ) setTexture ( new ssgTexture ) ; texture -> setFilename ( fname ) ; } virtual GLenum getColourMaterial () { return (GLenum) colour_material_mode ; } virtual void setColourMaterial ( GLenum which ) { colour_material_mode = (int) which ; care_about ( SSG_GL_COLOR_MATERIAL ) ; } virtual void setMaterial ( GLenum which, float r, float g, float b, float a = 1.0f ) { sgVec4 rgba ; sgSetVec4 ( rgba, r, g, b, a ) ; setMaterial ( which, rgba ) ; } virtual void setMaterial ( GLenum which, sgVec4 rgba ) { switch ( which ) { case GL_EMISSION : sgCopyVec4 ( emission_colour, rgba ) ; care_about ( SSG_GL_EMISSION ) ; break ; case GL_SPECULAR : sgCopyVec4 ( specular_colour, rgba ) ; care_about ( SSG_GL_SPECULAR ) ; break ; case GL_AMBIENT : sgCopyVec4 ( ambient_colour , rgba ) ; care_about ( SSG_GL_AMBIENT ) ; break ; case GL_DIFFUSE : sgCopyVec4 ( diffuse_colour , rgba ) ; care_about ( SSG_GL_DIFFUSE ) ; break ; case GL_AMBIENT_AND_DIFFUSE : // in compliance with glMaterial sgCopyVec4 ( ambient_colour , rgba ) ; sgCopyVec4 ( diffuse_colour , rgba ) ; care_about ( SSG_GL_AMBIENT | SSG_GL_DIFFUSE ) ; break ; default : break ; } } virtual float *getMaterial ( GLenum which ) { switch ( which ) { case GL_EMISSION : return emission_colour ; case GL_SPECULAR : return specular_colour ; case GL_AMBIENT : return ambient_colour ; case GL_DIFFUSE : return diffuse_colour ; default: break ; } return NULL ; } virtual float getShininess (void) { return shininess ; } virtual void setShininess ( float sh ) { care_about ( SSG_GL_SHININESS ) ; shininess = sh ; } virtual void setShadeModel ( GLenum model ) { care_about ( SSG_GL_SHADE_MODEL ) ; shade_model = model ; } virtual void setAlphaClamp ( float clamp ) { care_about ( SSG_GL_ALPHA_TEST ) ; alpha_clamp = clamp ; } /*int getWrapU(); int getWrapV();*/ virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; class ssgStateSelector : public ssgSimpleState { int nstates ; int selection ; _SSG_PUBLIC: ssgSimpleState **statelist ; protected: virtual void copy_from ( ssgStateSelector *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgStateSelector () ; ssgStateSelector ( int ns ) ; virtual ~ssgStateSelector (void) ; virtual const char *getTypeName(void) ; int getNumSteps ( void ) { return nstates ; } void selectStep ( unsigned int s ) ; unsigned int getSelectStep (void) ; ssgSimpleState *getCurrentStep (void) ; void setStep ( int i, ssgSimpleState *step ) ; ssgSimpleState *getStep ( int i ) ; virtual int isTranslucent (void) ; virtual void setTranslucent (void) ; virtual void setOpaque (void) ; void force (void) ; void apply (void) ; void care_about ( int mode ) ; void dont_care_about ( int mode ) ; int isEnabled ( GLenum mode ) ; void disable ( GLenum mode ) ; void enable ( GLenum mode ) ; char *getTextureFilename(void) ; void setTextureFilename(char *fname) ; void setTexture ( char *fname, int _wrapu = TRUE, int _wrapv = TRUE, int _mipmap = TRUE ) ; GLuint getTextureHandle (void) ; void setTexture ( ssgTexture *tex ) ; /* WARNING - THIS FORM OF setTexture IS DEPRECATED BECAUSE IT PREVENTS ssgSave FROM SAVING THE TEXTURE FILENAME and LEAKS texture handles! */ void setTexture ( GLuint tex ) ; void setColourMaterial(GLenum which); void setMaterial ( GLenum which, float r, float g, float b, float a = 1.0f ) ; void setMaterial ( GLenum which, sgVec4 rgba ) ; float *getMaterial ( GLenum which ) ; float getShininess (void) ; void setShininess ( float sh ) ; void setShadeModel ( GLenum model ) ; void setAlphaClamp ( float clamp ) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; struct ssgEntityBinding { ssgEntity **entity ; char *nameOrPath ; } ; class ssgEntity : public ssgBase { ssgList parents ; int traversal_mask ; ssgTravCallback preTravCB ; ssgTravCallback postTravCB ; protected: sgSphere bsphere ; int bsphere_is_invalid ; void emptyBSphere () { bsphere.empty () ; } void visualiseBSphere () ; void extendBSphere ( sgSphere *s ) { bsphere.extend ( s ) ; } void extendBSphere ( sgBox *b ) { bsphere.extend ( b ) ; } void extendBSphere ( sgVec3 v ) { bsphere.extend ( v ) ; } virtual ssgCullResult cull_test ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual ssgCullResult isect_test ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual ssgCullResult hot_test ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual ssgCullResult los_test ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void copy_from ( ssgEntity *src, int clone_flags ) ; public: ssgEntity (void) ; virtual ~ssgEntity (void) ; int getTraversalMask () { return traversal_mask ;} void setTraversalMask ( int t ) { traversal_mask = t ; } void setTraversalMaskBits ( int t ) { traversal_mask |= t ; } void clrTraversalMaskBits ( int t ) { traversal_mask &= ~t ; } ssgTravCallback getTravCallback ( int cb_type ) { return ( cb_type == SSG_CALLBACK_PRETRAV ) ? preTravCB : postTravCB ; } void setTravCallback ( int cb_type, ssgTravCallback cb ) { if ( cb_type == SSG_CALLBACK_PRETRAV ) preTravCB = cb ; else postTravCB = cb ; } int preTravTests ( int *test_needed, int which ) ; void postTravTests ( int which ) ; virtual void getNetTransform ( sgMat4 xform ) ; virtual void getLastNetTransform ( sgMat4 xform ) ; /* for backward compatibility */ virtual ssgCallback getCallback ( int cb_type ) ; virtual void setCallback ( int cb_type, ssgCallback cb ) ; virtual ssgEntity* getByName ( char *nm ) ; virtual ssgEntity* getByPath ( char *path ) ; int bindEntities ( ssgEntityBinding *bind ) ; virtual void recalcBSphere (void) = 0 ; int isDirtyBSphere (void) { return bsphere_is_invalid ; } void dirtyBSphere () ; sgSphere *getBSphere () { if ( isDirtyBSphere () ) recalcBSphere () ; return & bsphere ; } virtual int getNumKids (void) { return 0 ; } int getNumParents () { return parents.getNumEntities () ; } ssgBranch *getParent ( int p ) { return (ssgBranch *) parents.getEntity ( p ) ; } ssgBranch *getNextParent () { return (ssgBranch *) parents.getNextEntity () ; } void addParent ( ssgEntity *entity ) { parents.addEntity ( entity ) ; } void removeParent ( ssgEntity *entity ) { parents.removeEntity ( entity ) ; } virtual const char *getTypeName(void) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) = 0 ; virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) = 0 ; virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) = 0 ; virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) = 0 ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) = 0 ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; class ssgLeaf : public ssgEntity { int cull_face ; ssgState *state ; protected: GLenum gltype ; ssgCallback preDrawCB ; ssgCallback postDrawCB ; #ifdef _SSG_USE_DLIST GLuint dlist ; #endif virtual void draw_geometry () = 0 ; int preDraw () ; virtual void copy_from ( ssgLeaf *src, int clone_flags ) ; public: ssgLeaf (void) ; virtual ~ssgLeaf (void) ; virtual void drawHighlight ( sgVec4 colour ) = 0 ; virtual void drawHighlight ( sgVec4 colour, int i ) = 0 ; virtual void pick ( int baseName ) = 0 ; #ifdef _SSG_USE_DLIST void makeDList () ; void deleteDList () ; GLuint getDListIndex () { return dlist ; } #endif int getExternalPropertyIndex () { return state ? state->getExternalPropertyIndex() : 0 ; } int isTranslucent () { return state ? state->isTranslucent() : FALSE ; } int hasState () { return state != NULL ; } ssgState *getState () { return state ; } void setState ( ssgState *st ); //~~ T.G. Body extended & moved into CXX file virtual ssgCallback getCallback ( int cb_type ) { return ( cb_type == SSG_CALLBACK_PREDRAW ) ? preDrawCB : postDrawCB ; } virtual void setCallback ( int cb_type, ssgCallback cb ) { if ( cb_type == SSG_CALLBACK_PREDRAW ) preDrawCB = cb ; else postDrawCB = cb ; } virtual void setPrimitiveType ( GLenum ty ) { gltype = ty ; } virtual GLenum getPrimitiveType () { return gltype ; } /* For backwards compatibility only -- DEPRECATED */ GLenum getGLtype () { return getPrimitiveType() ; } virtual int getNumVertices () { return 0 ; } virtual int getNumNormals () { return 0 ; } virtual int getNumColours () { return 0 ; } virtual int getNumTexCoords () { return 0 ; } virtual float *getVertex ( int i ) = 0 ; virtual float *getNormal ( int i ) = 0 ; virtual float *getColour ( int i ) = 0 ; virtual float *getTexCoord ( int i ) = 0 ; virtual int getNumTriangles () = 0 ; virtual void getTriangle ( int n, short *v1, short *v2, short *v3 ) = 0 ; virtual int getNumLines () = 0 ; virtual void getLine ( int n, short *v1, short *v2 ) = 0 ; virtual void transform ( const sgMat4 m ) = 0 ; void setCullFace ( int cf ) { cull_face = cf ; } int getCullFace () { return cull_face ; } virtual void recalcBSphere () = 0 ; virtual const char *getTypeName(void) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void isect_triangles ( sgSphere *s, sgMat4 m, int test_needed ) = 0 ; virtual void hot_triangles ( sgVec3 s, sgMat4 m, int test_needed ) = 0 ; virtual void los_triangles ( sgVec3 s, sgMat4 m, int test_needed ) = 0 ; virtual void draw () = 0 ; } ; extern sgVec3 _ssgVertex000 ; extern sgVec4 _ssgColourWhite ; extern sgVec3 _ssgNormalUp ; extern sgVec2 _ssgTexCoord00 ; extern short _ssgIndex0 ; extern float _ssgGlobTime ; // used by ssgAnimTransform. Has to be set by the appliation! class ssgVTable : public ssgLeaf { protected: sgBox bbox ; int indexed ; sgVec3 *vertices ; int num_vertices ; unsigned short *v_index ; sgVec3 *normals ; int num_normals ; unsigned short *n_index ; sgVec2 *texcoords ; int num_texcoords ; unsigned short *t_index ; sgVec4 *colours ; int num_colours ; unsigned short *c_index ; virtual void draw_geometry () ; virtual void copy_from ( ssgVTable *src, int clone_flags ) ; _SSG_PUBLIC: int isIndexed () { return indexed ; } public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgVTable () ; ssgVTable ( GLenum ty, int nv, unsigned short *vi, sgVec3 *vl, int nn, unsigned short *ni, sgVec3 *nl, int nt, unsigned short *ti, sgVec2 *tl, int nc, unsigned short *ci, sgVec4 *cl ) ; ssgVTable ( GLenum ty, int nv, sgVec3 *vl, int nn, sgVec3 *nl, int nt, sgVec2 *tl, int nc, sgVec4 *cl ) ; virtual void drawHighlight ( sgVec4 colour ) ; virtual void drawHighlight ( sgVec4 colour, int i ) ; virtual void pick ( int baseName ) ; virtual void transform ( const sgMat4 m ) ; int getNumVertices () { return num_vertices ; } int getNumNormals () { return num_normals ; } int getNumColours () { return num_colours ; } int getNumTexCoords () { return num_texcoords ; } int getNumTriangles () ; void getTriangle ( int n, short *v1, short *v2, short *v3 ) ; int getNumLines () ; void getLine ( int n, short *v1, short *v2 ) ; void getColourList ( void **list, unsigned short **idx ) { *list = colours ; *idx = c_index ; } void getTexCoordList ( void **list, unsigned short **idx ) { *list = texcoords ; *idx = t_index ; } void getNormalList ( void **list, unsigned short **idx ) { *list = normals ; *idx = n_index ; } void getVertexList ( void **list, unsigned short **idx ) { *list = vertices ; *idx = v_index ; } float *getVertex (int i){ if(i>=num_vertices)i=num_vertices-1; return (num_vertices<=0) ? _ssgVertex000 : ((indexed)?vertices [v_index[i]]:vertices [i]);} float *getColour (int i){ if(i>=num_colours)i=num_colours-1; return (num_colours<=0) ? _ssgColourWhite : ((indexed)?colours [c_index[i]]:colours [i]);} float *getNormal (int i){ if(i>=num_normals)i=num_normals-1; return (num_normals<=0) ? _ssgNormalUp : ((indexed)?normals [n_index[i]]:normals [i]);} float *getTexCoord(int i){ if(i>=num_texcoords)i=num_texcoords-1; return (num_texcoords<=0) ? _ssgTexCoord00 : ((indexed)?texcoords[t_index[i]]:texcoords[i]);} virtual ~ssgVTable (void) ; virtual const char *getTypeName(void) ; virtual void recalcBSphere () ; virtual void draw () ; virtual void isect_triangles ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot_triangles ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los_triangles ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; class ssgVtxTable : public ssgLeaf { protected: sgBox bbox ; virtual void draw_geometry () ; virtual void copy_from ( ssgVtxTable *src, int clone_flags ) ; _SSG_PUBLIC: ssgVertexArray *vertices ; ssgNormalArray *normals ; ssgTexCoordArray *texcoords ; ssgColourArray *colours ; public: int compare(ssgVtxTable *other, int print_result=TRUE); virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgVtxTable () ; ssgVtxTable ( GLenum ty, ssgVertexArray *vl, ssgNormalArray *nl, ssgTexCoordArray *tl, ssgColourArray *cl ) ; void textureMe(float uP, float vP) { texcoords = new ssgTexCoordArray; for(int i=vertices->getNum()-1; i>=0; i--) { sgVec2 v; v[0] = uP; v[1] = vP; texcoords->add(v); } } virtual void drawHighlight ( sgVec4 colour ) ; virtual void drawHighlight ( sgVec4 colour, int i ) ; virtual void pick ( int baseName ) ; virtual void transform ( const sgMat4 m ) ; ssgVertexArray *getVertices () { return vertices ; } ssgNormalArray *getNormals () { return normals ; } ssgTexCoordArray *getTexCoords () { return texcoords ; } ssgColourArray *getColours () { return colours ; } virtual void setVertices ( ssgVertexArray *vl ) ; virtual void setNormals ( ssgNormalArray *nl ) ; virtual void setTexCoords ( ssgTexCoordArray *tl ) ; virtual void setColours ( ssgColourArray *cl ) ; int getNumVertices () { return vertices -> getNum () ; } int getNumNormals () { return normals -> getNum () ; } int getNumColours () { return colours -> getNum () ; } int getNumTexCoords () { return texcoords -> getNum () ; } /* Don't call this unless you know what you are doing!! */ void rawSetNumVertices ( unsigned int n ) { vertices -> rawSetNum ( n ) ; } int getNumTriangles () ; void getTriangle ( int n, short *v1, short *v2, short *v3 ) ; int getNumLines () ; void getLine ( int n, short *v1, short *v2 ) ; void getVertexList ( void **list ) { *list = vertices -> get ( 0 ) ; } void getNormalList ( void **list ) { *list = normals -> get ( 0 ) ; } void getTexCoordList ( void **list ) { *list = texcoords -> get ( 0 ) ; } void getColourList ( void **list ) { *list = colours -> get ( 0 ) ; } float *getVertex (int i){ int nv=getNumVertices(); if(i>=nv)i=nv-1; return (nv<=0) ? _ssgVertex000:vertices->get(i);} float *getNormal (int i){ int nn=getNumNormals(); if(i>=nn)i=nn-1; return (nn<=0) ? _ssgNormalUp:normals->get(i);} float *getTexCoord(int i){ int nc=getNumTexCoords(); if(i>=nc)i=nc-1; return (nc<=0) ? _ssgTexCoord00:texcoords->get(i);} float *getColour (int i){ int nc=getNumColours(); if(i>=nc)i=nc-1; return (nc<=0) ? _ssgColourWhite:colours->get(i);} ssgVtxArray *getAs_ssgVtxArray (); virtual ~ssgVtxTable (void) ; virtual const char *getTypeName(void) ; virtual void recalcBSphere () ; virtual void draw () ; virtual void isect_triangles ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot_triangles ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los_triangles ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2); virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; class ssgTween : public ssgVtxTable { virtual void copy_from ( ssgTween *src, int clone_flags ) ; void init () ; protected: _SSG_PUBLIC: int curr_bank ; ssgVertexArray *render_vertices ; ssgNormalArray *render_normals ; ssgTexCoordArray *render_texcoords ; ssgColourArray *render_colours ; ulList *banked_vertices ; ulList *banked_normals ; ulList *banked_texcoords ; ulList *banked_colours ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgTween () ; ssgTween ( GLenum ty ) ; virtual void setVertices ( ssgVertexArray *vl ) ; virtual void setNormals ( ssgNormalArray *nl ) ; virtual void setTexCoords ( ssgTexCoordArray *tl ) ; virtual void setColours ( ssgColourArray *cl ) ; virtual void recalcBSphere () ; virtual void draw () ; virtual void transform ( const sgMat4 m ) ; virtual const char *getTypeName(void) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2); virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; int getNumBanks () { return banked_vertices -> getNumEntities () ; } int newBank ( ssgVertexArray *vl, ssgNormalArray *nl, ssgTexCoordArray *tl, ssgColourArray *cl ) ; int newBank ( int newVertices , int newNormals, int newTexCoords, int newColours ) ; void setBank ( int bank ) ; virtual ~ssgTween (void) ; } ; class ssgVtxArray : public ssgVtxTable { protected: ssgIndexArray *indices; virtual void draw_geometry () ; virtual void copy_from ( ssgVtxArray *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgVtxArray () ; ssgVtxArray ( GLenum ty, ssgVertexArray *vl, ssgNormalArray *nl, ssgTexCoordArray *tl, ssgColourArray *cl, ssgIndexArray *il ) ; virtual void drawHighlight ( sgVec4 colour ) ; virtual void drawHighlight ( sgVec4 colour, int i ) ; virtual void pick ( int baseName ) ; void setIndices ( ssgIndexArray *il ) ; void addIndex ( short i) { indices->add(i); } int getNumIndices () { return indices -> getNum () ; } int getNumTriangles () ; void getTriangle ( int n, short *v1, short *v2, short *v3 ) ; int getNumLines () ; void getLine ( int n, short *v1, short *v2 ) ; void getIndexList ( void **list ) { *list = indices -> get ( 0 ) ; } short *getIndex (int i){ int ni=getNumIndices();if(i>=ni)i=ni-1; return (ni<=0) ? &_ssgIndex0 : indices->get(i);} void removeUnusedVertices(); virtual ~ssgVtxArray (void) ; virtual const char *getTypeName(void) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; // class ssgVtxInterleavedArray class ssgBranch : public ssgEntity { ssgKidList kids ; protected: virtual void copy_from ( ssgBranch *src, int clone_flags ) ; public: virtual void zeroSpareRecursive (); virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgBranch (void) ; virtual ~ssgBranch (void) ; virtual int getNumKids (void) { return kids.getNumEntities() ; } ssgEntity *getKid ( int n ) { return kids.getEntity ( n ) ; } ssgEntity *getNextKid (void) { return kids.getNextEntity () ; } int searchForKid ( ssgEntity *entity ) { return kids.searchForEntity(entity); } void addKid ( ssgEntity *entity ) ; void removeKid ( int n ) ; void removeKid ( ssgEntity *entity ) ; void removeAllKids (void) ; void replaceKid ( int n, ssgEntity *new_entity ) ; void replaceKid ( ssgEntity *old_entity, ssgEntity *new_entity ) ; void mergeHNodes(); virtual ssgEntity *getByName ( char *match ) ; virtual ssgEntity *getByPath ( char *path ) ; virtual const char *getTypeName(void) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual void recalcBSphere () ; } ; #define SSGTWEEN_STOP_AT_END 0 #define SSGTWEEN_REPEAT 1 class ssgTweenController : public ssgBranch { float curr_bank ; int mode ; /* STOP_AT_END or REPEAT */ protected: virtual void copy_from ( ssgTweenController *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgTweenController (void) ; virtual ~ssgTweenController (void) ; void setMode ( int _mode ) { mode = _mode ; } int getMode () { return mode ; } void selectBank ( float f ) { curr_bank = f ; } float getCurrBank () { return curr_bank ; } virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual const char *getTypeName(void) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; class ssgInvisible : public ssgBranch { protected: virtual void copy_from ( ssgInvisible *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgInvisible (void) ; virtual ~ssgInvisible (void) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; class ssgSelector : public ssgBranch { unsigned char* selection ; protected: int max_kids ; virtual void copy_from ( ssgSelector *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgSelector ( int max_kids = 32 ) ; virtual ~ssgSelector (void) ; void selectStep ( unsigned int s ) { memset ( selection, 0, max_kids ) ; selection [s] = 1 ; } void select ( unsigned int s ) { for ( int i=0; i= 0) ? getKid ( k ) : NULL ; } int getMaxKids (void) const { return max_kids ; } virtual const char *getTypeName(void) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ; } ; class ssgRangeSelector : public ssgSelector { int additive ; float rng_list [ 33 ] ; protected: virtual void copy_from ( ssgRangeSelector *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgRangeSelector (void) ; virtual ~ssgRangeSelector (void) ; void setRanges ( float *ranges, unsigned int nranges ) { for ( unsigned int i = 0 ; i < 33 ; i++ ) if ( i < nranges ) rng_list [ i ] = ranges [ i ] ; else rng_list [ i ] = SG_MAX ; } void setRange ( unsigned int which, float range ) { if ( which < 33 ) rng_list [ which ] = range ; } float *getRanges () { return rng_list ; } float getRange ( unsigned int which ) { return ( which < 33 ) ? rng_list[which] : SG_MAX ; } void setAdditive ( int add ) { additive = add ; } int isAdditive () { return additive ; } virtual const char *getTypeName(void) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ; } ; enum ssgAnimEnum { SSG_ANIM_START, SSG_ANIM_STOP, SSG_ANIM_PAUSE, SSG_ANIM_RESUME } ; enum ssgAnimDirection { SSG_ANIM_SWING, SSG_ANIM_ONESHOT, SSG_ANIM_SHUTTLE } ; enum ssgAnimTimeMode { SSG_ANIM_FRAME, SSG_ANIM_CLOCK }; class ssgTimedSelector : public ssgSelector { _SSG_PUBLIC: ssgAnimEnum running ; ssgAnimDirection mode ; double start_time ; double pause_time ; double loop_time ; float *times ; int curr ; int start ; int end ; protected: ssgAnimTimeMode time_mode ; static ulClock ck ; void compute_loop_time () { loop_time = 0 ; for ( int k = start ; k <= end ; k++ ) loop_time += times [ k ] ; } virtual void copy_from ( ssgTimedSelector *src, int clone_flags ) ; double get_time() const { if (time_mode == SSG_ANIM_FRAME) return (double) ssgGetFrameCounter() ; else return ck.update(), ck.getAbsTime(); } public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgTimedSelector ( int max_kids = 32 ) ; virtual ~ssgTimedSelector (void) ; virtual const char *getTypeName(void) ; int getStep () ; ssgAnimTimeMode getTimeMode() const { return time_mode; } float getDuration ( int i = 0 ) { return times [ i ] ; } void setDuration ( float ti, int i = -1, ssgAnimTimeMode m = SSG_ANIM_FRAME ) { time_mode = m; if ( i >= 0 && i < max_kids ) times [ i ] = ti ; else for ( int j = 0 ; j < max_kids ; j++ ) times [ j ] = ti ; compute_loop_time () ; } void control ( ssgAnimEnum m ) { compute_loop_time () ; if ( m == SSG_ANIM_PAUSE ) { pause_time = get_time() ; curr = getStep () ; } else if ( m == SSG_ANIM_RESUME ) { start_time += get_time () - pause_time ; if ( running != SSG_ANIM_STOP ) m = SSG_ANIM_START ; } else if ( m == SSG_ANIM_START ) { start_time = get_time () ; curr = getStep () ; } running = m ; } ssgAnimEnum getControl () { return running ; } void setMode ( ssgAnimDirection m ) { mode = m ; } ssgAnimDirection getMode () { return mode ; } void setLimits ( int st, int en ) { curr = st ; start = st ; end = en ; compute_loop_time () ; } void getLimits ( int *st, int *en ) { if ( st != NULL ) *st = start ; if ( en != NULL ) *en = end ; } virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ; } ; class ssgBaseTransform : public ssgBranch { protected: sgMat4 transform ; sgMat4 last_transform ; int last_updated ; int first_time ; virtual void copy_from ( ssgBaseTransform *src, int clone_flags ) ; public: ssgBaseTransform (void) ; virtual ~ssgBaseTransform (void) ; void firsttime () { if ( first_time ) { first_time = FALSE ; updateTransform () ; } } void updateTransform () { sgCopyMat4 ( last_transform, transform ) ; last_updated = ssgGetFrameCounter () ; } void getLastTransform ( sgMat4 xform ) { /* If the transform was not updated this - or last frame then we need to equate the two transforms. */ if ( last_updated < ssgGetFrameCounter () - 1 ) updateTransform () ; sgCopyMat4 ( xform, last_transform ) ; } void getTransform ( sgMat4 xform ) { sgCopyMat4 ( xform, transform ) ; } virtual void setTransform ( sgVec3 xyz ) = 0 ; virtual void setTransform ( sgCoord *xform ) = 0 ; virtual void setTransform ( sgCoord *xform, float sx, float sy, float sz )=0; virtual void setTransform ( sgMat4 xform ) = 0 ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual const char *getTypeName(void) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; } ; class ssgTransform : public ssgBaseTransform { protected: virtual void copy_from ( ssgTransform *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgTransform (void) ; ssgTransform ( sgCoord *c ) ; virtual ~ssgTransform (void) ; virtual void setTransform ( sgVec3 xyz ) ; virtual void setTransform ( sgCoord *xform ) ; virtual void setTransform ( sgCoord *xform, float sx, float sy, float sz ) ; virtual void setTransform ( sgMat4 xform ) ; virtual void getNetTransform ( sgMat4 xform ) ; virtual void getLastNetTransform ( sgMat4 xform ) ; virtual const char *getTypeName(void) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void recalcBSphere () ; } ; class ssgAnimTransform : public ssgTransform { float curr_bank ; int mode ; /* SSGTWEEN_STOP_AT_END or SSGTWEEN_REPEAT */ class ssgTransformArray transformations; protected: virtual void copy_from ( ssgAnimTransform *src, int clone_flags ) ; public: void setNum ( unsigned int n ) { transformations.setNum( n ); } void setATransform ( sgMat4 thing, unsigned int n ) { transformations.raw_set ( (char *) thing, n ) ; } ; virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgAnimTransform (void) ; virtual ~ssgAnimTransform (void) ; void setMode ( int _mode ) { mode = _mode ; } int getMode () { return mode ; } void selectBank ( float f ) { curr_bank = f ; } float getCurrBank () { return curr_bank ; } virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual const char *getTypeName(void) ; virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; class ssgAxisTransform : public ssgTransform { sgVec3 rotation_axis ; sgVec3 rotation_center ; float limit_low ; float limit_high ; protected: virtual void copy_from ( ssgAxisTransform *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgAxisTransform (void) ; ssgAxisTransform ( sgVec3 axis, sgVec3 center ) ; virtual ~ssgAxisTransform (void) ; virtual void setAxis ( sgVec3 axis ) ; virtual float *getAxis () ; virtual void setCenter ( sgVec3 center ) ; virtual float *getCenter () ; virtual void setRotation ( float rot ) ; virtual void setRotationLimits ( float low, float high ) ; virtual void setLinearRotation ( float rot ) ; virtual const char *getTypeName(void) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; }; class ssgTexTrans : public ssgBaseTransform { protected: virtual void copy_from ( ssgTexTrans *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgTexTrans (void) ; ssgTexTrans ( sgCoord *c ) ; virtual ~ssgTexTrans (void) ; virtual void setTransform ( sgVec3 xyz ) ; virtual void setTransform ( sgCoord *xform ) ; virtual void setTransform ( sgCoord *xform, float sx, float sy, float sz ) ; virtual void setTransform ( sgMat4 xform ) ; virtual const char *getTypeName(void) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; } ; class ssgCutout : public ssgBranch { int point_rotate ; protected: virtual void copy_from ( ssgCutout *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgCutout (int pntrot=FALSE) ; virtual ~ssgCutout (void) ; int isPointRotate (void) { return point_rotate ; } virtual const char *getTypeName(void) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ; virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ; virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ; } ; class ssgRoot : public ssgBranch { protected: virtual void copy_from ( ssgRoot *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgRoot (void) ; virtual ~ssgRoot (void) ; virtual const char *getTypeName(void) ; virtual int load ( FILE *fd ) ; virtual int save ( FILE *fd ) ; } ; class ssgLight { int id ; int is_headlight ; int is_turned_on ; sgVec4 ambient ; sgVec4 diffuse ; sgVec4 specular ; sgVec4 position ; sgVec3 direction ; float exponent ; float cutoff ; sgVec3 atten ; public: ssgLight () { id = 0 ; is_turned_on = FALSE ; is_headlight = FALSE ; sgSetVec4 ( position, 0.0f, 0.0f, 1.0f, 0.0f ) ; sgSetVec4 ( ambient , 0.2f, 0.2f, 0.2f, 1.0f ) ; sgSetVec4 ( diffuse , 1.0f, 1.0f, 1.0f, 1.0f ) ; sgSetVec4 ( specular, 1.0f, 1.0f, 1.0f, 1.0f ) ; sgSetVec3 ( direction, 0.0f, 0.0f, -1.0f ) ; exponent = 1.0f; cutoff = 90.0f; sgSetVec3 ( atten, 1.0f, 0.0f, 0.0f ) ; } void setID ( int i ) { id = i ; } int isOn () { return is_turned_on ; } void on () { is_turned_on = TRUE ; } void off () { is_turned_on = FALSE ; } void setPosition ( const sgVec3 pos ) { sgCopyVec3 ( position, pos ) ; } void getPosition ( sgVec3 pos ) { sgCopyVec3 ( pos, position ) ; } void setPosition ( float x, float y, float z ) { sgSetVec3 ( position, x, y, z ) ; } void setColour ( GLenum which, const sgVec4 col ) { switch ( which ) { case GL_AMBIENT : sgCopyVec4 ( ambient , col ) ; break ; case GL_DIFFUSE : sgCopyVec4 ( diffuse , col ) ; break ; case GL_SPECULAR : sgCopyVec4 ( specular, col ) ; break ; default : break ; } } void getColour ( GLenum which, sgVec4 col ) { switch ( which ) { case GL_AMBIENT : sgCopyVec4 ( col , ambient ) ; break ; case GL_DIFFUSE : sgCopyVec4 ( col , diffuse ) ; break ; case GL_SPECULAR : sgCopyVec4 ( col, specular ) ; break ; default : break ; } } void setColour ( GLenum which, float r, float g, float b ) { sgVec4 colour = { r, g, b, 1.0f }; setColour(which, colour); } void setHeadlight ( int head ) { is_headlight = head ; } int isHeadlight () { return is_headlight ; } void setSpotlight ( int spot ) { position[3] = ( spot ? 1.0f : 0.0f ) ; } int isSpotlight () { return position[3] != 0.0f; } void setSpotDirection ( const sgVec3 dir ) { sgCopyVec3 ( direction, dir ) ; } void getSpotDirection ( sgVec3 dir ) { sgCopyVec3 ( dir, direction ) ; } void setSpotDirection ( float x, float y, float z ) { sgSetVec3 ( direction, x, y, z ) ; } void setSpotDiffusion ( float exp, float cut = 90.0f ) { exponent = exp; cutoff = cut; } void getSpotDiffusion ( float *exp, float *cut = 0 ) { if (exp != 0) *exp = exponent; if (cut != 0) *cut = cutoff; } void setSpotAttenuation ( float constant, float linear, float quadratic ) { sgSetVec3( atten, constant, linear, quadratic ); } void getSpotAttenuation ( float *constant, float *linear, float *quadratic ) { if (constant != 0) *constant = atten[0]; if (linear != 0) *linear = atten[1]; if (quadratic != 0) *quadratic = atten[2]; } void setup () { if ( is_turned_on ) { glEnable ( (GLenum)(GL_LIGHT0+id) ) ; glLightfv ( (GLenum)(GL_LIGHT0+id), GL_AMBIENT , ambient ) ; glLightfv ( (GLenum)(GL_LIGHT0+id), GL_DIFFUSE , diffuse ) ; glLightfv ( (GLenum)(GL_LIGHT0+id), GL_SPECULAR, specular ) ; glLightfv ( (GLenum)(GL_LIGHT0+id), GL_POSITION, position ) ; if ( isSpotlight() ) { glLightfv ( (GLenum)(GL_LIGHT0+id), GL_SPOT_DIRECTION, direction ) ; glLightf ( (GLenum)(GL_LIGHT0+id), GL_SPOT_EXPONENT, exponent ) ; glLightf ( (GLenum)(GL_LIGHT0+id), GL_SPOT_CUTOFF, cutoff ) ; glLightf ( (GLenum)(GL_LIGHT0+id), GL_CONSTANT_ATTENUATION, atten[0] ); glLightf ( (GLenum)(GL_LIGHT0+id), GL_LINEAR_ATTENUATION, atten[1] ); glLightf ( (GLenum)(GL_LIGHT0+id), GL_QUADRATIC_ATTENUATION, atten[2] ); } } else glDisable ( (GLenum)(GL_LIGHT0+id) ) ; } } ; class ssgHit { _SSG_PUBLIC: int num_entries ; ssgEntity *path [ SSG_MAXPATH ] ; public: ssgLeaf *leaf ; int triangle ; sgVec4 plane ; sgMat4 matrix ; ssgHit () { leaf = NULL ; init () ; } ; void init () { num_entries = 0 ; } void addPath ( ssgEntity *e ) { if ( num_entries < SSG_MAXPATH ) path [ num_entries++ ] = e ; } int getNumPathEntries () { return num_entries ; } ssgEntity *getPathEntry ( int i ) { return ( i >= 0 && i < num_entries ) ? path[i] : (ssgEntity *) NULL ; } } ; class ssgContext { protected: int enabledClipPlanes ; sgVec4 clipPlane [ 6 ] ; ssgSimpleState *currentState ; ssgSimpleState *basicState ; sgFrustum *frustum ; sgMat4 cameraMatrix ; int cullFace ; int ovTexture ; int ovCullface ; ssgState *ovState ; public: ssgContext () ; ~ssgContext () ; void forceBasicState () ; void applyClipPlanes () ; void removeClipPlanes () ; void makeCurrent () ; int isCurrent () ; void clrClipPlane ( int i ) { if ( i >= 0 && i < 6 ) enabledClipPlanes &= ~(1<= 0 && i < 6 ) { sgCopyVec4 ( clipPlane [ i ], plane ) ; enabledClipPlanes |= (1<=6)) ? NULL : clipPlane [i] ; } void overrideState ( ssgState *s ) ; void overrideTexture ( int on_off ) ; void overrideCullface ( int on_off ) ; void setCullface ( int on_off ) { if ( cullFace == on_off || ovCullface ) return ; cullFace = on_off ; if ( cullFace ) glEnable ( GL_CULL_FACE ) ; else glDisable ( GL_CULL_FACE ) ; } ssgState *overriddenState () { return ovState ; } int stateOverridden () { return ovState != NULL ; } int textureOverridden () { return ovTexture ; } int cullfaceOverridden () { return ovCullface ; } int cullfaceIsEnabled () { return cullFace ; } sgFrustum *getFrustum () { return frustum ; } // make a perspective projection void setFrustum ( float l, float r, float b, float t, float n, float f ) ; // make an orthographic projection void setOrtho ( float l, float r, float b, float t, float n, float f ) ; void getNearFar ( float *n, float *f ) ; void getFOV ( float *w, float *h ) ; void getOrtho ( float *w, float *h ) ; void setNearFar ( float n, float f ) ; void setOrtho ( float w, float h ) ; // make orthographic void setFOV ( float w, float h ) ; // make perspective int isOrtho () { return frustum -> isOrtho () ; } // is orthographic ssgSimpleState *getState () { return currentState ; } void cull ( ssgBranch *r ) ; void getCameraPosition ( sgVec3 pos ) ; void setCamera ( sgMat4 mat ) ; void setCamera ( const sgCoord *coord ) ; void setCameraLookAt ( const sgVec3 eye, const sgVec3 center, const sgVec3 up ) ; void setCameraLookAt ( const sgVec3 eye, const sgVec3 center ) ; void loadProjectionMatrix () ; void loadModelviewMatrix () ; void getProjectionMatrix ( sgMat4 dst ) ; void getModelviewMatrix ( sgMat4 dst ) ; void pushProjectionMatrix () ; void pushProjectionMatrix ( sgFrustum *f ) ; void loadModelviewMatrix ( sgMat4 mat ) ; } ; /* Compatibility inlines for pre-ssgContext applications */ extern ssgContext *_ssgCurrentContext ; inline ssgContext *ssgGetCurrentContext () { return _ssgCurrentContext ; } inline void ssgGetCameraPosition ( sgVec3 pos ) { _ssgCurrentContext -> getCameraPosition ( pos ) ; } inline void ssgOverrideState ( ssgState *s ) { _ssgCurrentContext->overrideState ( s ) ; } inline void ssgOverrideTexture ( int on_off ) { _ssgCurrentContext->overrideTexture ( on_off ) ; } inline void ssgOverrideCullface ( int on_off ) { _ssgCurrentContext->overrideCullface ( on_off ) ; } inline void ssgGetNearFar ( float *n, float *f ) { _ssgCurrentContext->getNearFar ( n, f ) ; } inline void ssgGetFOV ( float *w, float *h ) { _ssgCurrentContext->getFOV ( w, h ) ; } inline void ssgGetOrtho ( float *w, float *h ) { _ssgCurrentContext->getOrtho ( w, h ) ; } inline void ssgSetFrustum ( float l, float r, float b, float t, float n, float f ) { _ssgCurrentContext->setFrustum ( l, r, b, t, n, f ) ; } inline void ssgSetOrtho ( float l, float r, float b, float t, float n, float f ) { _ssgCurrentContext->setOrtho ( l, r, b, t, n, f ) ; } inline void ssgSetFOV ( float w, float h ) { _ssgCurrentContext->setFOV ( w, h ) ; } inline void ssgSetOrtho ( float w, float h ) { _ssgCurrentContext->setOrtho ( w, h ) ; } inline void ssgSetNearFar ( float n, float f ) { _ssgCurrentContext->setNearFar ( n, f ) ; } inline void ssgSetCamera ( sgMat4 mat ) { _ssgCurrentContext-> setCamera ( mat ) ; } inline void ssgSetCamera ( sgCoord *coord ) { _ssgCurrentContext-> setCamera ( coord ) ; } inline void ssgSetCameraLookAt ( const sgVec3 eye, const sgVec3 center, const sgVec3 up ) { _ssgCurrentContext-> setCameraLookAt ( eye, center, up ) ; } inline void ssgSetCameraLookAt ( const sgVec3 eye, const sgVec3 center ) { _ssgCurrentContext-> setCameraLookAt ( eye, center ) ; } inline void ssgLoadProjectionMatrix () { _ssgCurrentContext->loadProjectionMatrix () ; } inline void ssgLoadProjectionMatrix ( sgFrustum *f ) { glLoadIdentity () ; _ssgCurrentContext->pushProjectionMatrix ( f ) ; } inline void ssgGetProjectionMatrix ( sgMat4 dst ) { _ssgCurrentContext->getProjectionMatrix ( dst ) ; } inline void ssgGetModelviewMatrix ( sgMat4 dst ) { _ssgCurrentContext->getModelviewMatrix ( dst ) ; } inline void ssgLoadModelviewMatrix () { _ssgCurrentContext->loadModelviewMatrix () ; } inline void ssgLoadModelviewMatrix ( sgMat4 mat ) { _ssgCurrentContext->loadModelviewMatrix ( mat ) ; } inline void ssgForceBasicState () { _ssgCurrentContext -> forceBasicState () ; } inline sgFrustum *ssgGetFrustum () { return _ssgCurrentContext -> getFrustum() ; } void ssgInit () ; void ssgCullAndDraw ( ssgBranch *root ) ; void ssgCullAndPick ( ssgBranch *root, sgVec2 botleft, sgVec2 topright ) ; int ssgIsect ( ssgBranch *root, sgSphere*s,sgMat4 m, ssgHit **results ) ; int ssgHOT ( ssgBranch *root, sgVec3 s, sgMat4 m, ssgHit **results ) ; int ssgLOS ( ssgBranch *root, sgVec3 s, sgMat4 m, ssgHit **results ) ; /* Load/Save functions */ enum { SSG_MD2_STAND, SSG_MD2_RUN, SSG_MD2_ATTACK, SSG_MD2_PAIN_1, SSG_MD2_PAIN_2, SSG_MD2_PAIN_3, SSG_MD2_JUMP, SSG_MD2_FLIPOFF, SSG_MD2_SALUTE, SSG_MD2_TAUNT, SSG_MD2_WAVE, SSG_MD2_POINT, SSG_MD2_CROUCH_STAND, SSG_MD2_CROUCH_WALK, SSG_MD2_CROUCH_PAIN, SSG_MD2_CROUCH_DEATH, SSG_MD2_DEATH_1, SSG_MD2_DEATH_2, SSG_MD2_DEATH_3, SSG_MD2_ALL, SSG_MD2_POSE }; class ssgLoaderOptions { //NOTES: we could add more later //...model scale factor... //...create normals or read them from the file?... //...cutoff angle for smooth shading where there isn`t one in the file format... //...which direction is front-facing in formats that don`t get it right... //...etc... protected: /* for backward compatibility */ ssgState *(*create_state_cb)( char *) ; ssgBranch *(*create_branch_cb)(char *) ; char* model_dir ; char* texture_dir ; char* make_path ( char* path, const char* dir, const char* fname ) const ; public: ssgSimpleStateArray shared_states ; ssgTextureArray shared_textures ; ssgLoaderOptions () { model_dir = 0 ; texture_dir = 0 ; /* for backward compatibility */ create_state_cb = 0 ; create_branch_cb = 0 ; } virtual ~ssgLoaderOptions() { if (model_dir) { delete [] model_dir; model_dir = 0; } if (texture_dir) { delete [] texture_dir; texture_dir = 0; } } const char* getModelDir ( void ) const { return model_dir ; } const char* getTextureDir ( void ) const { return texture_dir ; } void setModelDir ( const char *s ) ; void setTextureDir ( const char *s ) ; // // the idea is that you derive a class from ssgLoaderOptions and // override these methods to customize how the loaders work // virtual void makeModelPath ( char* path, const char *fname ) const ; virtual void makeTexturePath ( char* path, const char *fname ) const ; virtual ssgLeaf* createLeaf ( ssgLeaf* leaf, const char* parent_name ) ; virtual ssgTexture* createTexture ( char* tfname, int wrapu = TRUE, int wrapv = TRUE, int mipmap = TRUE ) ; virtual ssgTransform* createTransform ( ssgTransform* tr, ssgTransformArray* ta ) const ; virtual ssgSelector* createSelector ( ssgSelector* s ) const ; virtual ssgBranch* createBranch ( char* text ) const { if ( create_branch_cb != NULL ) return (*create_branch_cb)(text) ; return NULL ; } virtual ssgState* createState ( char* tfname ) const { if ( create_state_cb != NULL ) return (*create_state_cb)(tfname) ; return NULL ; } virtual ssgSimpleState* createSimpleState ( char* tfname ) const { ssgState *st = createState ( tfname ) ; if ( st != NULL ) { if ( st -> isAKindOf ( ssgTypeSimpleState() ) ) { return (ssgSimpleState*) st ; } else { ulSetError(UL_WARNING, "createState() did not return simple state"); } } return NULL ; } virtual void endLoad () { /* default behavior is to reset sharing after loading a model */ shared_textures.removeAll () ; shared_states.removeAll () ; } // // *** DEPRECATED INTERFACE *** // for backward compatibility // derive and use virtual methods to override // void setCreateBranchCallback ( ssgBranch *(*cb)(char *) ) { create_branch_cb = cb ; } void setCreateStateCallback ( ssgState *(*cb)(char *) ) { create_state_cb = cb ; } } ; int ssgSave ( const char *fname, ssgEntity *ent ) ; int ssgSaveAC ( const char *fname, ssgEntity *ent ) ; int ssgSaveASE ( const char *fname, ssgEntity *ent ) ; int ssgSaveSSG ( const char *fname, ssgEntity *ent ) ; int ssgSaveDXF ( const char *fname, ssgEntity *ent ) ; int ssgSaveTRI ( const char *fname, ssgEntity *ent ) ; int ssgSaveOBJ ( const char *fname, ssgEntity *ent ) ; int ssgSaveX ( const char *fname, ssgEntity *ent ) ; int ssgSaveM ( const char *fname, ssgEntity *ent ) ; int ssgSave3ds ( const char *fname, ssgEntity *ent ) ; int ssgSaveFLT ( const char *fname, ssgEntity *ent ) ; int ssgSaveOFF ( const char *fname, ssgEntity *ent ) ; int ssgSaveQHI ( const char *fname, ssgEntity *ent ) ; int ssgSaveATG ( const char *fname, ssgEntity *ent ) ; int ssgSaveVRML1( const char *fname, ssgEntity *ent ) ; int ssgSaveASC ( const char *fname, ssgEntity *ent ) ; int ssgSaveIV ( const char *fname, ssgEntity *ent ) ; int ssgSavePOV ( const char *fname, ssgEntity *ent ) ; ssgEntity *ssgLoad ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoad3ds ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadAC3D ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadASC ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadSSG ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadASE ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadDOF ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadDXF ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadTRI ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadOBJ ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadMD2 ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadMDL ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadX ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadFLT ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadM ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadStrip( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadOFF ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadATG ( const char *fname, const ssgLoaderOptions *options = NULL ) ; ssgEntity *ssgLoadVRML1( const char *fname, const ssgLoaderOptions* options = NULL ) ; ssgEntity *ssgLoadIV ( const char *fname, const ssgLoaderOptions* options = NULL ) ; ssgEntity *ssgLoadXPlaneOBJ ( const char *fname, const ssgLoaderOptions *options = NULL ) ; typedef ssgEntity *ssgLoadFunc ( const char *, const ssgLoaderOptions * ) ; typedef int ssgSaveFunc ( const char *, ssgEntity * ) ; void ssgAddModelFormat ( const char* extension, ssgLoadFunc *loadfunc , ssgSaveFunc *savefunc ) ; /* current loader options */ extern ssgLoaderOptions* _ssgCurrentOptions ; inline ssgLoaderOptions* ssgGetCurrentOptions () { return _ssgCurrentOptions ; } inline void ssgSetCurrentOptions ( ssgLoaderOptions* options ) { if ( options != NULL ) _ssgCurrentOptions = options ; } /* For backwards compatibility */ inline ssgEntity *ssgLoad ( char *fname, ssgBranch *(*cb)(char *)) { _ssgCurrentOptions -> setCreateBranchCallback ( cb ) ; return ssgLoad ( fname ) ; } inline void ssgSetAppStateCallback ( ssgState *(*cb)(char *) ) { _ssgCurrentOptions -> setCreateStateCallback ( cb ) ; } inline void ssgModelPath ( const char *path ) { _ssgCurrentOptions -> setModelDir ( path ) ; } inline void ssgTexturePath ( const char *path ) { _ssgCurrentOptions -> setTextureDir ( path ) ; } ssgEntity *ssgLoadAC ( const char *fname, const ssgLoaderOptions *options = NULL ) ; void ssgGetValuesFromLastATGFile(double *x, double *y, double *z, double *r); bool ssgConvertTexture( char * fname_output, char * fname_input ) ; class ssgStatistics { int vertex_count ; int leaf_count ; public: void reset () ; void bumpVertexCount ( int i ) { vertex_count += i ; } void bumpLeafCount ( int i ) { leaf_count += i ; } int getVertexCount () { return vertex_count ; } int getLeafCount () { return leaf_count ; } ssgStatistics () { reset () ; } } ; ssgStatistics *ssgGetLatestStatistics () ; /* scene walkers */ void ssgFlatten ( ssgEntity *ent ) ; void ssgStripify ( ssgEntity *ent ) ; void ssgArrayTool ( ssgEntity *ent, float* vtol = 0, bool make_normals = false ) ; void ssgTransTool ( ssgEntity *ent, const sgMat4 trans ) ; ssgLight *ssgGetLight ( int i ) ; char *ssgShowStats () ; void ssgDelete ( ssgBranch *br ) ; const char *ssgGetVersion () ; void ssgSetLoadOFFTranslucent ( int i ); void ssgRegisterType ( int type, ssgBase * ( *create_func ) () ) ; ssgBase *ssgCreateOfType ( int type ) ; #define SSG_BACKFACE_COLLISIONS_SUPPORTED 1 void ssgSetBackFaceCollisions ( bool b ) ; #endif plib-1.8.5/src/ssg/ssgTweenController.cxx0000644000175000001440000000457110765364437015370 00000000000000 /* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgTweenController.cxx 1996 2004-12-29 07:19:40Z sjbaker $ */ #include "ssgLocal.h" const char *ssgTweenController::getTypeName (void) { return "ssgTweenController" ; } void ssgTweenController::copy_from ( ssgTweenController *src, int clone_flags ) { selectBank ( src->getCurrBank () ) ; ssgBranch::copy_from ( src, clone_flags ) ; } ssgBase *ssgTweenController::clone ( int clone_flags ) { ssgTweenController *b = new ssgTweenController ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgTweenController::ssgTweenController (void) { type = ssgTypeTweenController () ; curr_bank = 0.0f ; } ssgTweenController::~ssgTweenController (void) { removeAllKids () ; } void ssgTweenController::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { float old_state = _ssgGetCurrentTweenState () ; int old_mode = _ssgGetCurrentTweenMode () ; _ssgSetCurrentTweenSettings ( curr_bank, mode ) ; ssgBranch::cull ( f, m, test_needed ) ; _ssgSetCurrentTweenSettings ( old_state, old_mode ) ; } int ssgTweenController::load ( FILE *fd ) { _ssgReadFloat ( fd, & curr_bank ) ; return ssgBranch::load ( fd ) ; } int ssgTweenController::save ( FILE *fd ) { _ssgWriteFloat ( fd, curr_bank ) ; return ssgBranch::save ( fd ) ; } void ssgTweenController::print ( FILE *fd, char *indent, int how_much ) { if ( how_much == 0 ) return ; fprintf ( fd, "%sCurrent Bank = %f\n", indent, curr_bank ); ssgBranch::print ( fd, indent, how_much ) ; } plib-1.8.5/src/ssg/ssgLoadMDL.cxx0000644000175000001440000015460510765364437013462 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadMDL.cxx 2012 2005-01-15 20:36:46Z sjbaker $ */ //=========================================================================== // // File: GngMsfsIO.cpp // // Created: Tue Feb 29 22:20:31 2000 // // Author: Thomas Engh Sevaldrud // // Revision: $Id: ssgLoadMDL.cxx 2012 2005-01-15 20:36:46Z sjbaker $ // // Description: // //=========================================================================== // Copyright (c) 2000 Thomas E. Sevaldrud //=========================================================================== #include "ssgLocal.h" // kludge: global int g_noLoDs =1; #ifdef SSG_LOAD_MDL_SUPPORTED #include "ssgLoadMDL.h" #define DEF_SHININESS 50 //#define DEBUG #ifdef DEBUG #include #define DEBUGPRINT(x) std::cerr << x #else #define DEBUGPRINT(x) #endif static ssgLoaderOptions *current_options; // Temporary vertex arrays static ssgVertexArray *curr_vtx_; static ssgNormalArray *curr_norm_; static ssgIndexArray *curr_index_; // Vertex arrays static ssgVertexArray *vertex_array_; static ssgNormalArray *normal_array_; static ssgTexCoordArray *tex_coords_; // Current part (index array) static ssgLeaf *curr_part_; static ssgBranch *model_; // Moving parts static ssgBranch *ailerons_grp_, *elevator_grp_, *rudder_grp_; static ssgBranch *gear_grp_, *spoilers_grp_, *flaps_grp_; static ssgBranch *prop_grp_; static sgMat4 curr_matrix_; static sgVec3 curr_rot_pt_; static sgVec4 curr_col_; static char *curr_tex_name_; static ssgAxisTransform *curr_xfm_; int noGT=0, noLT=0, no0=0; #define EXPERIMENTAL_CULL_FACE_CODE #ifdef EXPERIMENTAL_CULL_FACE_CODE static bool curr_cull_face_; #endif // File Address Stack static const int MAX_STACK_DEPTH = 128; // wk: 32 is too small static long stack_ [MAX_STACK_DEPTH]; // adress part static short lod_ [MAX_STACK_DEPTH]; // lod part of the stack static int stack_depth_; static short noLoDs; static short curr_lod; // static sgMat4 matrix_stack_ [MAX_STACK_DEPTH]; // static char *textures_ [MAX_STACK_DEPTH]; // static ssgBranch *groups_ [MAX_STACK_DEPTH]; static int start_idx_, last_idx_; static int curr_var_; static bool has_normals_, vtx_dirty_, tex_vtx_dirty_; //static bool join_children_, override_normals_; //static char *tex_fmt_; //=========================================================================== /*static void initLoader() { start_idx_ = 0; join_children_ = true; override_normals_ = true; tex_fmt_ = "tif"; stack_depth_ = 0; #ifdef EXPERIMENTAL_CULL_FACE_CODE curr_cull_face_ = false ; #endif }*/ #ifdef DEBUG FILE *wkfp; #define PRINT_STRUCTURE(a, b) fprintf(wkfp, a, b); #define PRINT_STRUCTURE1(a ) fprintf(wkfp, a); #else #define PRINT_STRUCTURE(a, b) #define PRINT_STRUCTURE1(a ) #endif //=========================================================================== static void newPart() { vtx_dirty_ = true; tex_vtx_dirty_ = true; curr_tex_name_ = NULL; sgSetVec4( curr_col_, 1.0f, 1.0f, 1.0f, 1.0f ); delete curr_vtx_; delete curr_norm_; curr_vtx_ = new ssgVertexArray ; curr_norm_ = new ssgNormalArray ; } //=========================================================================== static void push_stack( long entry, short lod ) { assert( stack_depth_ < MAX_STACK_DEPTH - 1 ); lod_ [stack_depth_] = lod; stack_[stack_depth_++] = entry; } static long pop_stack(short &lod) { assert( stack_depth_ > 0 ); lod = lod_[--stack_depth_]; return stack_[stack_depth_]; } //=========================================================================== static void recalcNormals() { DEBUGPRINT( "Calculating normals." << std::endl); sgVec3 n; for (int i = 0; i < curr_index_->getNum() - 2; i++) { unsigned short ix0 = *curr_index_->get(i ); unsigned short ix1 = *curr_index_->get(i + 1); unsigned short ix2 = *curr_index_->get(i + 2); sgMakeNormal( n, vertex_array_->get(ix0), vertex_array_->get(ix1), vertex_array_->get(ix2) ); sgCopyVec3( normal_array_->get(ix0), n ); sgCopyVec3( normal_array_->get(ix1), n ); sgCopyVec3( normal_array_->get(ix2), n ); } } //=========================================================================== static void readPoint(FILE* fp, sgVec3 p) { short x_int, y_int, z_int; y_int = ulEndianReadLittle16(fp); z_int = ulEndianReadLittle16(fp); x_int = ulEndianReadLittle16(fp); // Convert from .MDL units (ca 2mm) to meters p[0] = -x_int/512.0f; p[1] = y_int/512.0f; p[2] = z_int/512.0f; } //=========================================================================== // MtkPoint3D readPoint(FILE* fp) // { // short x_int, y_int, z_int; // fread(&x_int, 2, 1, fp); // fread(&y_int, 2, 1, fp); // fread(&z_int, 2, 1, fp); // // Convert from .MDL units (ca 2mm) to meters // MtkPoint3D p; // p.x() = (double)x_int/512.0; // p.y() = (double)y_int/512.0; // p.z() = (double)z_int/512.0; // /* // for(list::iterator i = matrix_stack_.begin(); // i != matrix_stack_.end(); i++) // { // p = p*(*i); // p += (*i).getCol(3); // } // */ // if(matrix_stack_.size() > 0) // { // MtkTransMatrix3D m = matrix_stack_.front(); // p -= m.getCol(3); // p = p*m; // } // MtkPoint3D r; // r.y() = p.x(); // r.z() = -p.y(); // r.x() = p.z(); // return r; // } //=========================================================================== static void readVector(FILE* fp, sgVec3 v) { short x_int, y_int, z_int; y_int = ulEndianReadLittle16(fp); z_int = ulEndianReadLittle16(fp); x_int = ulEndianReadLittle16(fp); v[0] = -(float)x_int; v[1] = (float)y_int; v[2] = (float)z_int; sgNormaliseVec3( v ); } //=========================================================================== // for new lists, especially vertex list: struct oneVertex { sgVec3 p, n; // point position, normal sgVec2 tc; // texture coords }; struct oneVertex *TheVertexList; // array. Kludge: only one allowed struct oneTexture { char fname[64]; }; struct oneTexture *TheTextureList; // array. Kludge: only one allowed //=========================================================================== static void createTriangIndices(ssgIndexArray *ixarr, int numverts, const sgVec3 s_norm, long dist) { sgVec3 v1, v2, cross; if ( numverts > ixarr->getNum() ) { ulSetError( UL_WARNING, "ssgLoadMDL: Index array with too few entries." ); return; } // triangulate polygons if(numverts == 1) { unsigned short ix0 = *ixarr->get(0); if ( ix0 >= vertex_array_->getNum() ) { ulSetError(UL_WARNING, "ssgLoadMDL: Index out of bounds (%d/%d).", ix0, vertex_array_->getNum() ); return; } curr_index_->add(ix0); curr_index_->add(ix0); curr_index_->add(ix0); } else if(numverts == 2) { unsigned short ix0 = *ixarr->get(0); unsigned short ix1 = *ixarr->get(1); if ( ix0 >= vertex_array_->getNum() || ix1 >= vertex_array_->getNum() ) { ulSetError(UL_WARNING, "ssgLoadMDL: Index out of bounds. (%d,%d / %d", ix0, ix1, vertex_array_->getNum() ); return; } curr_index_->add(ix0); curr_index_->add(ix1); curr_index_->add(ix0); } else if(numverts == 3) { unsigned short ix0 = *ixarr->get(0); unsigned short ix1 = *ixarr->get(1); unsigned short ix2 = *ixarr->get(2); if ( ix0 >= vertex_array_->getNum() || ix1 >= vertex_array_->getNum() || ix2 >= vertex_array_->getNum() ) { ulSetError(UL_WARNING, "ssgLoadMDL: Index out of bounds. " \ "(%d,%d,%d / %d)", ix0, ix1, ix2, vertex_array_->getNum()); return; } sgSubVec3(v1, vertex_array_->get(ix1), vertex_array_->get(ix0)); sgSubVec3(v2, vertex_array_->get(ix2), vertex_array_->get(ix0)); sgVectorProductVec3(cross, v1, v2); if(sgScalarProductVec3(cross, s_norm) >= 0.0f) { curr_index_->add(ix0); curr_index_->add(ix1); curr_index_->add(ix2); } else { curr_index_->add(ix0); curr_index_->add(ix2); curr_index_->add(ix1); } } else { unsigned short ix0 = *ixarr->get(0); unsigned short ix1 = *ixarr->get(1); unsigned short ix2 = *ixarr->get(2); if ( ix0 >= vertex_array_->getNum() || ix1 >= vertex_array_->getNum() || ix2 >= vertex_array_->getNum() ) { ulSetError(UL_WARNING, "ssgLoadMDL: Index out of bounds. " \ "(%d,%d,%d / %d)", ix0, ix1, ix2, vertex_array_->getNum()); return; } // Ensure counter-clockwise ordering sgMakeNormal(cross, vertex_array_->get(ix0), vertex_array_->get(ix1), vertex_array_->get(ix2)); bool flip = (sgScalarProductVec3(cross, s_norm) < 0.0); curr_index_->add(ix0); char tsA[99999]; int bWrong=FALSE; // a lot of debug output follows - sorry! sprintf(tsA, "------- %ld %f\n%f, %f, %f\n", dist, ((float)dist)/(512.0f*32767.0f), s_norm[0], s_norm[1], s_norm[2]); for(int i = 1; i < numverts; i++) { ix1 = *ixarr->get( flip ? numverts-i : i); // SGfloat f = sgScalarProductVec3(s_norm, vertex_array_->get(ix1)); sprintf(tsA, "%s%f, ", tsA, f); f = f - ((float)dist)/(512.0f*32767.0f); if((f<-0.5f) || (f>0.5f)) bWrong = TRUE; // if ( ix1 >= vertex_array_->getNum() ) { ulSetError(UL_WARNING, "ssgLoadMDL: Index out of bounds. (%d/%d)", ix1, vertex_array_->getNum()); continue; } curr_index_->add(ix1); } if (bWrong) printf("%s\n-------\n", tsA); } } //=========================================================================== static bool readTexIndices(FILE *fp, int numverts, const sgVec3 s_norm, bool flip_y, long dist) { ssgIndexArray temp_index_; if(numverts <= 0) return false; if(tex_coords_->getNum() < vertex_array_->getNum()) { sgVec2 dummy_pt; sgSetVec2(dummy_pt, FLT_MAX, FLT_MAX); for(int i = tex_coords_->getNum(); i < vertex_array_->getNum(); i++) tex_coords_->add(dummy_pt); } // Read index values and texture coordinates for(int v = 0; v < numverts; v++) { unsigned short ix; short tx_int, ty_int; ix = ulEndianReadLittle16(fp); tx_int = ulEndianReadLittle16(fp); ty_int = ulEndianReadLittle16(fp); if (flip_y) { ty_int = 255 - ty_int; } int tex_idx = ix - start_idx_ + last_idx_; sgVec2 tc; sgSetVec2(tc, tx_int/255.0f, ty_int/255.0f); sgVec2 curr_tc; if ( tex_idx >= 0 && tex_idx < tex_coords_->getNum() ) { sgCopyVec2(curr_tc, tex_coords_->get(tex_idx)); } else { ulSetError( UL_WARNING, "ssgLoadMDL: Texture coord out of range (%d).", tex_idx ); continue; } double dist = sgDistanceVec2(curr_tc, tc); if((curr_tc[0] >= FLT_MAX - 1 && curr_tc[1] >= FLT_MAX - 1)) { //DEBUGPRINT( "." ); sgCopyVec2(tex_coords_->get(tex_idx), tc); } else if(dist > 0.0001) { // We have a different texture coordinate for an existing vertex, // so we have to copy this vertex and create a new index for it // to get the correct texture mapping. //DEBUGPRINT( "duplicating texture coordinate!\n"); int idx = ix - start_idx_ + last_idx_; tex_idx = vertex_array_->getNum(); ssgVertexArray* vtx_arr = vertex_array_; //curr_vtx_; ssgNormalArray* norm_arr = normal_array_; //curr_norm_; sgVec3 vtx, nrm; sgCopyVec3( vtx, vtx_arr ->get(idx) ); sgCopyVec3( nrm, norm_arr->get(idx) ); vtx_arr ->add(vtx); norm_arr->add(nrm); tex_coords_->add(tc); } temp_index_.add(tex_idx); #ifdef DEBUG int check_index = *temp_index_.get(v); float *check_tc = tex_coords_->get(check_index); DEBUGPRINT( "ix[" << v << "] = " << check_index << " (u=" << check_tc[0] << ", v=" << check_tc[1] << ")" << std::endl); #endif } createTriangIndices(&temp_index_, numverts, s_norm, dist); return true; } //=========================================================================== static bool readIndices(FILE* fp, int numverts, const sgVec3 s_norm, long dist) { ssgIndexArray temp_index_; if(numverts <= 0) return false; // Read index values for(int v = 0; v < numverts; v++) { unsigned short ix; ix = ulEndianReadLittle16(fp); temp_index_.add(ix - start_idx_ + last_idx_); DEBUGPRINT( "ix[" << v << "] = " << *temp_index_.get(v) << std::endl); } createTriangIndices(&temp_index_, numverts, s_norm, dist); return true; } //=========================================================================== static void setColor(int color, int pal_id) { if(pal_id == 0x68) { curr_col_[0] = fsAltPalette[color].r / 255.0f; curr_col_[1] = fsAltPalette[color].g / 255.0f; curr_col_[2] = fsAltPalette[color].b / 255.0f; curr_col_[3] = 0.2f; } else { curr_col_[0] = fsAcPalette[color].r / 255.0f; curr_col_[1] = fsAcPalette[color].g / 255.0f; curr_col_[2] = fsAcPalette[color].b / 255.0f; curr_col_[3] = 1.0f; } } //=========================================================================== static void setColor(int r, int g, int b, int attr) { curr_col_[0] = r / 255.0f; curr_col_[1] = g / 255.0f; curr_col_[2] = b / 255.0f; if(attr < 239) curr_col_[3] = 0.2f; } //=========================================================================== static bool setTexture(char* name) { curr_tex_name_ = name; return true; } //=========================================================================== static ssgSimpleState *createState(bool use_texture) { DEBUGPRINT("new State: col = " << curr_col_[0] << ", " << curr_col_[1] << ", " << curr_col_[2] << ", " << curr_col_[3]); if ( curr_tex_name_ == NULL ) DEBUGPRINT(", tex = " << std::endl); else DEBUGPRINT(", tex = " << curr_tex_name_ << std::endl); ssgSimpleState *state = new ssgSimpleState(); state->setShininess(DEF_SHININESS); state->setShadeModel(GL_SMOOTH); state->enable (GL_LIGHTING); state->enable (GL_CULL_FACE); state->disable (GL_COLOR_MATERIAL); if(curr_col_[3] < 0.99f) { state->setTranslucent(); state->enable(GL_BLEND); state->enable(GL_ALPHA_TEST); } else { state->setOpaque(); state->disable(GL_BLEND); state->disable(GL_ALPHA_TEST); } if(curr_tex_name_ != NULL && use_texture) { state->setMaterial( GL_AMBIENT, 1.0f, 1.0f, 1.0f, curr_col_[3]); state->setMaterial( GL_DIFFUSE, 1.0f, 1.0f, 1.0f, curr_col_[3]); state->enable(GL_TEXTURE_2D); state->setTexture( current_options -> createTexture(curr_tex_name_, FALSE, FALSE) ) ; } else { state->setMaterial( GL_AMBIENT, curr_col_); state->setMaterial( GL_DIFFUSE, curr_col_); state->disable(GL_TEXTURE_2D); } state->setMaterial( GL_SPECULAR, 1.0f, 1.0f, 1.0f, curr_col_[3] ); state->setMaterial( GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f ); return state; } static ssgBranch *getCurrGroup() { //Find the correct parent for the new group if(curr_xfm_) return curr_xfm_; else { return model_; } } //=========================================================================== // wk : It's not completely clear to me whether the following two functions can not be merged; Oh well. // CreateAndAddLeaf1 is called then faces are created and then CreateAndAddLeaf2 is called static void CreateAndAddLeaf1(GLenum ty, ssgTexCoordArray *tex_coords_P, bool use_texture) { curr_index_ = new ssgIndexArray(); curr_part_ = new ssgVtxArray( ty, vertex_array_, normal_array_, tex_coords_P, NULL, curr_index_ ); curr_part_->setState( createState(true) ); char sName[10]; sprintf(sName, "lod %d", (int)curr_lod); curr_part_->setName(sName); } static void CreateAndAddLeaf2() { ssgBranch* grp = getCurrGroup(); ((ssgVtxArray *)curr_part_)->removeUnusedVertices(); grp->addKid( current_options -> createLeaf(curr_part_, NULL) ); } //=========================================================================== static ssgBranch *getMPGroup(int var) { switch(var) { case 0x4c: // Rudder if(!rudder_grp_) { rudder_grp_ = new ssgBranch(); rudder_grp_->setName("rudder"); model_->addKid(rudder_grp_); } return rudder_grp_; break; case 0x4e: // Elevator if(!elevator_grp_) { elevator_grp_ = new ssgBranch(); elevator_grp_->setName("elevator"); model_->addKid(elevator_grp_); } return elevator_grp_; break; case 0x6a: // Ailerons if(!ailerons_grp_) { ailerons_grp_ = new ssgBranch(); ailerons_grp_->setName("ailerons"); model_->addKid(ailerons_grp_); } return ailerons_grp_; break; case 0x6c: // Flaps if(!flaps_grp_) { flaps_grp_ = new ssgBranch(); flaps_grp_->setName("flaps"); model_->addKid(flaps_grp_); } return flaps_grp_; break; case 0x6e: // Gear if(!gear_grp_) { gear_grp_ = new ssgBranch(); gear_grp_->setName("gear"); model_->addKid(gear_grp_); } return gear_grp_; break; case 0x7c: // Spoilers if(!spoilers_grp_) { spoilers_grp_ = new ssgBranch(); spoilers_grp_->setName("spoilers"); model_->addKid(spoilers_grp_); } return spoilers_grp_; break; case 0x58: case 0x7a: // Propeller if(!prop_grp_) { prop_grp_ = new ssgBranch(); prop_grp_->setName("propeller"); model_->addKid(prop_grp_); } return prop_grp_; break; default: return model_; } return NULL; } //=========================================================================== static void getMPLimits(int var, float *min, float *max) { switch(var) { case 0x4c: // Rudder *min = -30.0; *max = 30.0; break; case 0x4e: // Elevator *min = -30.0; *max = 30.0; break; case 0x6a: // Ailerons *min = -30.0; *max = 30.0; break; case 0x6c: // Flaps *min = 0.0; *max = 70.0; break; case 0x6e: // Gear *min = 0.0; *max = -90.0; break; case 0x7c: // Spoilers *min = 0.0; *max = 90.0; break; case 0x58: case 0x7a: // Propeller *min = 0.0; *max = 360.0; break; } } void ParseBGL(FILE *fp) // "traversing" through the file { bool done = false; while(!feof(fp) && !done) { unsigned int skip_offset = 0; PRINT_STRUCTURE( "offset %lx\n", (long)ftell(fp)) unsigned short opcode = ulEndianReadLittle16(fp); DEBUGPRINT( "opcode = " << std::hex << opcode << std::dec << " at address" << ftell(fp)-2 // -2 since opcode has already been read << std::endl ); switch(opcode) { case 0x23: // BGL_CALL { short offset; offset = ulEndianReadLittle16(fp); long addr = ftell(fp); DEBUGPRINT( "BGL_CALL(" << offset << ")\n" ); push_stack(addr, curr_lod); long dst = addr + offset - 4; fseek(fp, dst, SEEK_SET); PRINT_STRUCTURE( "call %lx\n", (long)offset) } break; case 0x8a: // BGL_CALL32 { int offset; offset = ulEndianReadLittle32(fp); long addr = ftell(fp); DEBUGPRINT( "BGL_CALL32(" << offset << ")\n" ); PRINT_STRUCTURE( "call32 %lx\n", (long)offset) push_stack(addr, curr_lod); long dst = addr + offset - 6; fseek(fp, dst, SEEK_SET); } break; case 0x0d: // BGL_JUMP { short offset; offset = ulEndianReadLittle16(fp); PRINT_STRUCTURE( "jump %lx\n", (long)offset) long addr = ftell(fp); long dst = addr + offset - 4; fseek(fp, dst, SEEK_SET); DEBUGPRINT( "BGL_JUMP(" << offset << ")\n" ); } break; case 0x88: // BGL_JUMP32 { int offset; offset = ulEndianReadLittle32(fp); long addr = ftell(fp); DEBUGPRINT( "BGL_JUMP32(" << offset << ")\n" ); PRINT_STRUCTURE( "jump32 %lx\n", (long)offset) long dst = addr + offset - 6; fseek(fp, dst, SEEK_SET); } break; case 0x8e: // BGL_VFILE_MARKER { short offset; offset = ulEndianReadLittle16(fp); DEBUGPRINT( "vars: " << offset << std::endl); break; } case 0x39: // BGL_IFMSK { short offset, var, mask; offset = ulEndianReadLittle16(fp); var = ulEndianReadLittle16(fp); mask = ulEndianReadLittle16(fp); long addr = ftell(fp); long dst = addr + offset - 8; DEBUGPRINT( "BGL_IFMSK(" << offset << ", 0x" << std::hex << var << ", 0x" << mask << std::dec << ")\n" ); // if(var & mask == 0) PRINT_STRUCTURE( "if msk %lx\n", (long)offset) switch(var) { case 0x7e: fseek(fp, dst, SEEK_SET); break; default: break; } } break; case 0x24: // BGL_IFIN1 { short offset, lo, hi; unsigned short var; offset = ulEndianReadLittle16(fp); var = ulEndianReadLittle16(fp); lo = ulEndianReadLittle16(fp); hi = ulEndianReadLittle16(fp); DEBUGPRINT( "BGL_IFIN1(" << offset << ", 0x" << std::hex << var << ", " << std::dec << lo << ", " << hi << ")\n" ); PRINT_STRUCTURE( "ifin1 %lx\n", (long)offset) curr_var_ = var; } break; case 0x46: // BGL_POINT_VICALL { short offset, var_rot_x, var_rot_y, var_rot_z; unsigned short int_rot_x, int_rot_y, int_rot_z; offset = ulEndianReadLittle16(fp); sgVec3 ctr; readPoint(fp, ctr); int_rot_y = ulEndianReadLittle16(fp); var_rot_y = ulEndianReadLittle16(fp); int_rot_x = ulEndianReadLittle16(fp); var_rot_x = ulEndianReadLittle16(fp); int_rot_z = ulEndianReadLittle16(fp); var_rot_z = ulEndianReadLittle16(fp); float rx = 360.0f*(float)int_rot_x/0xffff; float ry = 360.0f*(float)int_rot_y/0xffff; float rz = 360.0f*(float)int_rot_z/0xffff; // We build a rotation matrix by adding all constant // rotations (int_rot_*) to current_matrix_. As soon as we reach // the actual variable rotation, we multiply // the axis of the variable rotation with our current matrix. // This will be the axis of rotation in the original coordinate // system. This can now be inserted into a GngLinearControl // transform. if(var_rot_x > 0 || var_rot_y > 0 || var_rot_z > 0) { ssgAxisTransform* tmp = NULL; if(curr_xfm_) tmp = curr_xfm_; curr_xfm_ = new ssgAxisTransform(); curr_xfm_->setCenter(curr_rot_pt_); int var = 0; if(var_rot_x > 0) var = var_rot_x; else if(var_rot_y > 0) var = var_rot_y; else if(var_rot_z > 0) var = var_rot_z; float min_limit, max_limit; getMPLimits(var, & min_limit, & max_limit); sgVec3 axis = { (float)var_rot_y, (float)var_rot_z, (float)var_rot_x }; sgNormaliseVec3( axis ) ; sgXformVec3( axis, curr_matrix_ ) ; sgNegateVec3(axis); curr_xfm_->setAxis(axis); curr_xfm_->setRotationLimits(min_limit, max_limit); char name[256]; sprintf(name, "ssgAxisRotation(%x)", var); curr_xfm_->setName(name); if(tmp) tmp->addKid(curr_xfm_); else { ssgBranch* grp = getMPGroup(var); grp->addKid(curr_xfm_); } } // Build up the constant rotations sgMat4 rot_mat; sgMakeRotMat4( rot_mat, ry, rz, rx ); sgPostMultMat4( curr_matrix_, rot_mat ); sgAddVec3( curr_rot_pt_, ctr ); long addr = ftell(fp); long dst = addr + offset - 22; fseek(fp, dst, SEEK_SET); push_stack(addr, curr_lod); break; } case 0x5f: // BGL_IFSIZEV { short offset; unsigned short real_size, pixels_ref; offset = ulEndianReadLittle16(fp); real_size = ulEndianReadLittle16(fp); pixels_ref = ulEndianReadLittle16(fp); DEBUGPRINT("BGL_IFSIZEV: jmp = " << offset << ", sz = " << real_size << ", px = " << pixels_ref << std::endl); PRINT_STRUCTURE( "ifsizev!! %lx\n", (long)offset) long addr = ftell(fp); long dst = addr + offset - 8; fseek(fp, dst, SEEK_SET); push_stack(addr, ++noLoDs); break; } case 0x3b: // BGL_VINSTANCE { short offset, var; offset = ulEndianReadLittle16(fp); var = ulEndianReadLittle16(fp); long addr = ftell(fp); long var_abs = addr + var - 6; fseek(fp, var_abs, SEEK_SET); float p = 360.0f * (float)ulEndianReadLittle32(fp) / 0xffffffff; float r = 360.0f * (float)ulEndianReadLittle32(fp) / 0xffffffff; float h = 360.0f * (float)ulEndianReadLittle32(fp) / 0xffffffff; sgMat4 rot_mat; sgMakeRotMat4(rot_mat, h, p, r); sgPostMultMat4(curr_matrix_, rot_mat); DEBUGPRINT( "BGL_VINSTANCE(" << offset << ", h=" << h << ", p=" << p << ", r=" << r << ")\n"); long dst = addr + offset - 6; fseek(fp, dst, SEEK_SET); } break; case 0x0: // EOF case 0x22: // BGL return { curr_xfm_ = NULL; sgMakeIdentMat4( curr_matrix_ ); sgZeroVec3( curr_rot_pt_ ); curr_var_ = 0; DEBUGPRINT( "BGL return\n\n"); PRINT_STRUCTURE1("return\n"); if(stack_depth_ == 0) done = true; else { long addr = pop_stack(curr_lod); fseek(fp, addr, SEEK_SET); } } break; case 0x1a: // RESLIST (point list with no normals) { newPart(); has_normals_ = false; start_idx_ = ulEndianReadLittle16(fp); unsigned short numpoints = ulEndianReadLittle16(fp); DEBUGPRINT( "New group (unlit): start_idx = " << start_idx_ << ", num vertices = " << numpoints << std::endl); sgVec3 null_normal; sgZeroVec3( null_normal ); for(int i = 0; i < numpoints; i++) { sgVec3 p; readPoint(fp, p); curr_vtx_->add(p); curr_norm_->add(null_normal); } } break; case 0x29: // GORAUD RESLIST (point list with normals) { newPart(); has_normals_ = true; start_idx_ = ulEndianReadLittle16(fp); unsigned short numpoints = ulEndianReadLittle16(fp); DEBUGPRINT( "New group (goraud): start_idx = " << start_idx_ << ", num vertices = " << numpoints << std::endl); for(int i = 0; i < numpoints; i++) { sgVec3 p; readPoint(fp, p); sgVec3 v; readVector(fp, v); curr_vtx_->add(p); curr_norm_->add(v); } } break; case 0x0f: // STRRES: Start line definition { unsigned short idx = ulEndianReadLittle16(fp); DEBUGPRINT( "Start line: idx = " << idx << std::endl); if(vtx_dirty_) { last_idx_ = vertex_array_->getNum(); for(int i = 0; i < curr_vtx_->getNum(); i++) { vertex_array_->add(curr_vtx_ ->get(i)); normal_array_->add(curr_norm_->get(i)); } vtx_dirty_ = false; } CreateAndAddLeaf1(GL_LINES, NULL, false); #ifdef EXPERIMENTAL_CULL_FACE_CODE curr_part_->setCullFace ( curr_cull_face_ ) ; #endif curr_index_->add(idx - start_idx_ + last_idx_); ssgBranch *grp = getCurrGroup(); grp->addKid(curr_part_); //assert(curr_part_->getState()->getTexture() == NULL); } break; case 0x10: // CNTRES: Continue line definition { unsigned short idx = ulEndianReadLittle16(fp); DEBUGPRINT( "Cont. line: idx = " << idx << std::endl); curr_index_->add(idx - start_idx_ + last_idx_); } break; case 0x20: case 0x7a: // Goraud shaded Texture-mapped ABCD Facet { if(tex_vtx_dirty_) { last_idx_ = vertex_array_->getNum(); for(int i = 0; i < curr_vtx_->getNum(); i++) { vertex_array_->add(curr_vtx_ ->get(i)); normal_array_->add(curr_norm_->get(i)); } tex_vtx_dirty_ = false; } CreateAndAddLeaf1(GL_TRIANGLE_FAN, tex_coords_, true); //assert(curr_part_->getState()->getTexture() != NULL); unsigned short numverts = ulEndianReadLittle16(fp); DEBUGPRINT( "New part: (goraud/texture), num indices = " << numverts << std::endl); // Normal vector sgVec3 v; readVector(fp, v); // Dot product reference #ifdef EXPERIMENTAL_CULL_FACE_CODE long l = ulEndianReadLittle32(fp) ; if(l>0) noGT++; else if (l<0) noLT++; if((v[0]==0) && (v[1]==0) && (v[2]==0)) no0++; //rr_part_->setCullFace ( curr_cull_face_ ) ; #else ulEndianReadLittle32(fp); #endif // Read vertex indices and texture coordinates bool flip_y = FALSE; if(curr_tex_name_!=NULL) { char *texture_extension = curr_tex_name_ + strlen(curr_tex_name_) - 3; flip_y = ulStrEqual( texture_extension, "BMP" ) != 0 ; } /*old: char *texture_extension = curr_tex_name_ + strlen(curr_tex_name_) - 3; bool flip_y = ulStrEqual( texture_extension, "BMP" ); */ readTexIndices(fp, numverts, v, flip_y, l); // adds stuff to curr_index_ if(!has_normals_) { while (normal_array_->getNum() < vertex_array_->getNum()) normal_array_->add(v); recalcNormals(); } CreateAndAddLeaf2(); } break; case 0x60: // BGL_FACE_TMAP { if(tex_vtx_dirty_) { last_idx_ = vertex_array_->getNum(); for(int i = 0; i < curr_vtx_->getNum(); i++) { vertex_array_->add(curr_vtx_ ->get(i)); normal_array_->add(curr_norm_->get(i)); } tex_vtx_dirty_ = false; } CreateAndAddLeaf1(GL_TRIANGLE_FAN, tex_coords_, true); #ifdef EXPERIMENTAL_CULL_FACE_CODE curr_part_->setCullFace ( curr_cull_face_ ) ; #endif //assert(curr_part_->getState()->getTexture() != NULL); unsigned short numverts = ulEndianReadLittle16(fp); DEBUGPRINT( "New part: (goraud/texture), num indices = " << numverts << std::endl); // Point in polygon sgVec3 p; readPoint(fp, p); // Normal vector sgVec3 v; readVector(fp, v); // Read vertex inidices and texture coordinates bool flip_y = FALSE; if(curr_tex_name_!=NULL) { char *texture_extension = curr_tex_name_ + strlen(curr_tex_name_) - 3; flip_y = ulStrEqual( texture_extension, "BMP" ) != 0 ; } /* char *texture_extension = curr_tex_name_ + strlen(curr_tex_name_) - 3; bool flip_y = ulStrEqual( texture_extension, "BMP" ); */ readTexIndices(fp, numverts, v, flip_y, -11); if(!has_normals_) { while (normal_array_->getNum() < vertex_array_->getNum()) normal_array_->add(v); recalcNormals(); } CreateAndAddLeaf2(); } break; case 0x1d: // BGL_FACE { if(vtx_dirty_) { last_idx_ = vertex_array_->getNum(); for(int i = 0; i < curr_vtx_->getNum(); i++) { vertex_array_->add(curr_vtx_->get(i)); normal_array_->add(curr_norm_->get(i)); } vtx_dirty_ = false; } CreateAndAddLeaf1(GL_TRIANGLE_FAN, NULL, false); #ifdef EXPERIMENTAL_CULL_FACE_CODE curr_part_->setCullFace ( curr_cull_face_ ) ; #endif //assert(curr_part_->getState()->getTexture() == NULL); unsigned short numverts = ulEndianReadLittle16(fp); DEBUGPRINT( "BGL_FACE: num indices = " << numverts << std::endl); sgVec3 p; readPoint(fp, p); // Surface normal sgVec3 v; readVector(fp, v); // Read vertex indices readIndices(fp, numverts, v, -11); if(!has_normals_) { while (normal_array_->getNum() < vertex_array_->getNum()) normal_array_->add(v); recalcNormals(); } CreateAndAddLeaf2(); } break; case 0x3e: // FACETN (no texture) case 0x2a: // Goraud shaded ABCD Facet { if(vtx_dirty_) { last_idx_ = vertex_array_->getNum(); for(int i = 0; i < curr_vtx_->getNum(); i++) { vertex_array_->add(curr_vtx_->get(i)); normal_array_->add(curr_norm_->get(i)); } vtx_dirty_ = false; } CreateAndAddLeaf1(GL_TRIANGLE_FAN, NULL, false); //assert(curr_part_->getState()->getTexture() == NULL); unsigned short numverts = ulEndianReadLittle16(fp); DEBUGPRINT( "BGL_FACETN: num indices = " << numverts << std::endl); // Surface normal sgVec3 v; readVector(fp, v); // dot-ref #ifdef EXPERIMENTAL_CULL_FACE_CODE long l = ulEndianReadLittle32(fp) ; if(l>0) noGT++; else if (l<0) noLT++; if((v[0]==0) && (v[1]==0) && (v[2]==0)) no0++; //rr_part_->setCullFace ( curr_cull_face_ ) ; #else ulEndianReadLittle32(fp); #endif // Read vertex indices readIndices(fp, numverts, v, l); if(!has_normals_) { while (normal_array_->getNum() < vertex_array_->getNum()) normal_array_->add(v); recalcNormals(); } CreateAndAddLeaf2(); } break; case 0x18: // Set texture { unsigned short id, dx, scale, dy; id = ulEndianReadLittle16(fp); dx = ulEndianReadLittle16(fp); scale = ulEndianReadLittle16(fp); dy = ulEndianReadLittle16(fp); char tex_name[14]; fread(tex_name, 1, 14, fp); static char tex_filename[14]; int j = 0; for(int i = 0; i < 14; i++) { if(!isspace(tex_name[i])) tex_filename[j++] = tolower(tex_name[i]); } tex_filename[j] = '\0'; DEBUGPRINT( "Set texture: name = " << tex_filename << ", id = " << id << ", dx = " << dx << ", dy = " << dy << ", scale = " << scale << std::endl); setTexture(tex_filename); } break; case 0x43: // TEXTURE2 { unsigned short length, idx; unsigned char flags, chksum; unsigned int color; static char tex_filename[128]; length = ulEndianReadLittle16(fp); idx = ulEndianReadLittle16(fp); fread(&flags, 1, 1, fp); fread(&chksum, 1, 1, fp); color = ulEndianReadLittle32(fp); if(chksum != 0) { DEBUGPRINT( "warning: TEXTURE2 Checksum != 0\n"); } char c; int i = 0; while((c = getc(fp)) != 0) { if(!isspace(c)) tex_filename[i++] = tolower(c); } tex_filename[i] = '\0'; // Padding byte if((strlen(tex_filename) + 1) % 2) c = getc(fp); DEBUGPRINT( "TEXTURE2: Set texture: name = " << tex_filename << std::endl); setTexture(tex_filename); break; } case 0x50: // GCOLOR (Goraud shaded color) case 0x51: // LCOLOR (Line color) case 0x52: // SCOLOR (Light source shaded surface color) { unsigned char color, param; fread(&color, 1, 1, fp); fread(¶m, 1, 1, fp); DEBUGPRINT( "Set color = " << (int)color << " (" << std::hex << (int)param << std::dec << ")\n"); setColor((int)color, (int)param); } break; case 0x2D: // BGL_SCOLOR24 { unsigned char col[4]; fread(col, 1, 4, fp); DEBUGPRINT( "color = " << (int)col[0] << ", " << (int)col[2] << ", " << (int)col[3] << ", " << (int)col[1] << std::endl); setColor(col[0], col[2], col[3], col[1]); break; } //------------------------------------------- // The next code is either ignored // or for experimental use.. //------------------------------------------- case 0x03: { //DEBUGPRINT( "BGL_CASE\n" ); unsigned short number_cases = ulEndianReadLittle16(fp); skip_offset = 6 + 2 * number_cases; PRINT_STRUCTURE1("case :-( !!\n"); } break; case 0xB0: //BGLOP_CRASH_OCTTREE { /* from scdis code by Takuya Murakami: 2 Jump Offset 2 Crash Type (See CRASH_FLAG_xxx in makemdl.exe) 2 # of nodes 4*3 box x/y/z 4*3 box w/h/d 1*8 ? 1*8*(# of nodes) ? */ ulEndianReadLittle32(fp); // ignore jump offset / crash type int count = ulEndianReadLittle16(fp); //fseek(fp, 4*3+4*3+1*8+1*8*count, SEEK_CUR); fseek(fp, 5*8+8*count, SEEK_CUR); // completely experimental } break; case 0xB2: //light { /*from scdis code by Takuya Murakami: Format: 2 type 4*3 offset (x,y,z, real4) 4 intensity 4 linear attenuation factor (real4) 4 squared attenuation factor (real4) 4 color (BGRA : strange byte order...) 4*3 direction(x,y,z real4) */ fseek(fp, 2+4*10, SEEK_CUR); } break; case 0xB3: //ifinf(1) { // long offset = ulEndianReadLittle32(fp); // unsigned short v = ulEndianReadLittle16(fp); // float low = ulEndianReadLittleFloat(fp); // float high = ulEndianReadLittleFloat(fp); ulEndianReadLittle32(fp); ulEndianReadLittle16(fp); ulEndianReadLittleFloat(fp); ulEndianReadLittleFloat(fp); } break; //------------------------------------------- // The next codes are CFS2 specific //------------------------------------------- case 0xB5: //, VertexList, anaVertexList, 0 ) // VERTEX_LIST_BEGIN { newPart(); int count = ulEndianReadLittle16(fp); ulEndianReadLittle32(fp); // dummy #ifdef UL_WIN32 if(TheVertexList) ::MessageBox(0, "More than one vertexlist", "Warning:", 0); #endif TheVertexList = new oneVertex[count]; // kludge: TheVertexList is unused?? // 4*8 x,y,z,nx,ny,nz,tu,tv (real4) for (int i = 0; i < count; i++) { TheVertexList[i].p[0] = ulEndianReadLittleFloat(fp); // / 1E6; TheVertexList[i].p[1] = ulEndianReadLittleFloat(fp); // / 1E6; TheVertexList[i].p[2] = ulEndianReadLittleFloat(fp); // / 1E6; TheVertexList[i].n[0] = ulEndianReadLittleFloat(fp); TheVertexList[i].n[1] = ulEndianReadLittleFloat(fp); TheVertexList[i].n[2] = ulEndianReadLittleFloat(fp); TheVertexList[i].tc[0]= ulEndianReadLittleFloat(fp); TheVertexList[i].tc[1]= ulEndianReadLittleFloat(fp); curr_vtx_->add(TheVertexList[i].p); curr_norm_->add(TheVertexList[i].n); tex_coords_->add(TheVertexList[i].tc); } } break; case 0xB6: //, MaterialList, anaMaterialList, 0 ) // MATERIAL_LIST_BEGIN { int count = ulEndianReadLittle16(fp); ulEndianReadLittle32(fp); // dummy fseek(fp, count*4*17, SEEK_CUR); } break; case 0xB7: //, TextureList, anaTextureList, 0 ) // TEXTURE_LIST_BEGIN/TEXTURE_DEF/TEXTURE_LIST_END { int count = ulEndianReadLittle16(fp); ulEndianReadLittle32(fp); // dummy #ifdef UL_WIN32 if(TheTextureList) ::MessageBox(0, "More than one texturelist", "Warning:", 0); #endif TheTextureList = new oneTexture[count]; // kludge: TheVertexList is unused?? for(int i=0;igetNum(); for(int i = 0; i < curr_vtx_->getNum(); i++) { vertex_array_->add(curr_vtx_ ->get(i)); normal_array_->add(curr_norm_->get(i)); } tex_vtx_dirty_ = false; } ssgVertexArray *vertex_array_bu = (ssgVertexArray *)vertex_array_->clone(); for(int i=0;igetNum();i++) sgXformPnt3(vertex_array_->get(i), curr_matrix_); CreateAndAddLeaf1(GL_TRIANGLES, tex_coords_, true); //delete vertex_array_; kludge!! vertex_array_ = vertex_array_bu; // to undo the transformation //assert(curr_part_->getState()->getTexture() != NULL); int base = ulEndianReadLittle16(fp); // int vertexcount = ulEndianReadLittle16(fp); ulEndianReadLittle16(fp); int wkcount = ulEndianReadLittle16(fp); wkcount = wkcount / 3; // tri assert(wkcount>0); DEBUGPRINT( "New part: (DrawTriList), num tris = " << wkcount << std::endl); if(tex_coords_->getNum() != vertex_array_->getNum()) { printf("tex_coords_->getNum() = %d, vertex_array_->getNum() = %d\n", tex_coords_->getNum(), vertex_array_->getNum()); assert(FALSE); } assert(tex_coords_->getNum() == normal_array_->getNum()); for(int j=0;j=tex_coords_->getNum()) { printf("i1+base = %d, i1 = %d, base = %d, tex_coords_->getNum() = %d\n", i1+base, i1, base, tex_coords_->getNum()); assert(FALSE); } assert(i2+basegetNum()); assert(i3+basegetNum()); curr_index_->add(i1+base); curr_index_->add(i2+base); curr_index_->add(i3+base); } CreateAndAddLeaf2(); } break; case 0xBA: //, DrawLineList, anaDrawLineList, 0 ) { // int base = ulEndianReadLittle16(fp); // int dummycount = ulEndianReadLittle16(fp); ulEndianReadLittle16(fp); ulEndianReadLittle16(fp); int wkcount = ulEndianReadLittle16(fp); wkcount = wkcount / 2; fseek(fp, 2*2*wkcount, SEEK_CUR); } break; case 0xBB: //, DrawPointList, anaDrawPointList, 0 ) { // int base = ulEndianReadLittle16(fp); // int dummycount = ulEndianReadLittle16(fp); ulEndianReadLittle16(fp); ulEndianReadLittle16(fp); int wkcount = ulEndianReadLittle16(fp); wkcount = wkcount / 1; fseek(fp, 2*1*wkcount, SEEK_CUR); } break; case 0xBC: // BGL_BEGIN / BGLVersion { // long v = ulEndianReadLittle32(fp); ulEndianReadLittle32(fp); PRINT_STRUCTURE("BGLVersion %lx\n", v) } break; case 0xB8: // SetMaterial { ulEndianReadLittle16(fp); // word short TheTextureIndex = ulEndianReadLittle16(fp); // word if (TheTextureIndex != -1) { char *s = TheTextureList[TheTextureIndex].fname; int j = 0; static char tex_filename[64]; for(int i = 0; i < 64; i++) { if(!isspace(s[i])) tex_filename[j++] = tolower(s[i]); } tex_filename[j] = '\0'; //DEBUGPRINT( "Set texture: name = " << tex_filename << std::endl); setTexture(tex_filename); } else curr_tex_name_ = NULL; } break; case 0xB4: // TextureSize ulEndianReadLittle32(fp); // float break; case 0xBD: // BGL_END / EndVersion break; case 0xAE: // BGL_TRANSFORM_END sgMakeIdentMat4( curr_matrix_ ); break; case 0xAF: // BGL_TRANSFORM_MATRIX { sgMat4 this_mat; this_mat[3][0] = ulEndianReadLittleFloat(fp); this_mat[3][1] = ulEndianReadLittleFloat(fp); this_mat[3][2] = ulEndianReadLittleFloat(fp); this_mat[0][0] = ulEndianReadLittleFloat(fp); this_mat[0][1] = ulEndianReadLittleFloat(fp); this_mat[0][2] = ulEndianReadLittleFloat(fp); this_mat[1][0] = ulEndianReadLittleFloat(fp); this_mat[1][1] = ulEndianReadLittleFloat(fp); this_mat[1][2] = ulEndianReadLittleFloat(fp); this_mat[2][0] = ulEndianReadLittleFloat(fp); this_mat[2][1] = ulEndianReadLittleFloat(fp); this_mat[2][2] = ulEndianReadLittleFloat(fp); DEBUGPRINT( "***** Matrix: " << std::endl << "x, y, z = " << this_mat[3][0] << ", " << this_mat[3][1] << ", " << this_mat[3][2] << std::endl << "3 x 3 matrix:" << std::endl << this_mat[0][0] << ", " << this_mat[0][1] << ", " << this_mat[0][2] << std::endl << this_mat[1][0] << ", " << this_mat[1][1] << ", " << this_mat[1][2] << std::endl << this_mat[2][0] << ", " << this_mat[2][1] << ", " << this_mat[2][2] << std::endl); this_mat[0][3] = SG_ZERO ; this_mat[1][3] = SG_ZERO ; this_mat[2][3] = SG_ZERO ; this_mat[3][3] = SG_ONE ; sgPostMultMat4( curr_matrix_, this_mat); } break; default: // Unknown opcode { if (opcode < 256) { if ( opcodes[opcode].size != -1) { DEBUGPRINT( "** " << opcodes[opcode].name << " (size " << opcodes[opcode].size << ")" << std::endl ); skip_offset = opcodes[opcode].size - 2; // opcode already read } else { DEBUGPRINT( "Unhandled opcode " << opcodes[opcode].name << " (" << std::hex << opcode << std::dec << ")" << std::endl ); } } else { DEBUGPRINT( "Op-code out of range: " << std::hex << opcode << std::dec << std::endl ); } } // default break; } // switch if (skip_offset > 0) fseek( fp, skip_offset, SEEK_CUR ); } // while !feof... } //=========================================================================== #define MYMAKEFOURCC(a, b, c, d) \ ((unsigned long)(a) | ((unsigned long)(b) << 8) | \ ((unsigned long)(c) << 16) | ((unsigned long)(d) << 24 )) static unsigned long lRIFF = MYMAKEFOURCC('R', 'I', 'F', 'F'); static unsigned long lMDL8 = MYMAKEFOURCC('M', 'D', 'L', '8'); void FindBGLBeginRIFF(FILE *fp) // place file cursor on the first BGL command. // if none found, places it on the file end // This function is for RIFF format used in MSFS2k2 and 2k4 and CFS2 (and other MS sims?) { unsigned int l; while ((lRIFF != (l = ulEndianReadLittle32(fp))) && (!feof(fp))) ; if (lRIFF != l) // RIFF not found { assert(feof(fp)); return; } ulEndianReadLittle32(fp); // ignore file length l = ulEndianReadLittle32(fp); if (l != MYMAKEFOURCC('M', 'D', 'L', '8')) printf("Warning: Not a 'MDL8' RIFF file\n"); else printf("RIFF file, subtype 'MDL8' recognised\n"); while(!feof(fp)) { char buffer[5]; buffer[4] = 0; fread(buffer, 4, 1, fp); unsigned long offset = ulEndianReadLittle32(fp); if (offset & 1L) offset++; // if offset is odd, add one pad byte printf("RIFF Chunk '%s' found, data length = %ld\n", buffer, offset); if (0==strcmp(buffer, "BGL ")) { // Great!! return; } fseek(fp, offset, SEEK_CUR); } } void FindBGLBeginOldVersion(FILE *fp) // place file cursor on the first BGL command. // if none found, places it on the file end // This function is for old MDL files (for FS98, for example) { unsigned short op1, op2; op1 = ulEndianReadLittle16(fp); while(!feof(fp)) { op2 = ulEndianReadLittle16(fp); if(op1 == 0x76 && op2 == 0x3a) { fseek(fp, -4, SEEK_CUR); break; } op1 = op2; } } ssgEntity *ssgLoadMDL(const char *fname, const ssgLoaderOptions *options) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; ailerons_grp_ = NULL; elevator_grp_ = NULL; rudder_grp_ = NULL; gear_grp_ = NULL; spoilers_grp_ = NULL; flaps_grp_ = NULL; prop_grp_ = NULL; TheVertexList = NULL; TheTextureList = NULL; char filename [ 1024 ] ; current_options -> makeModelPath ( filename, fname ) ; FILE *fp = fopen(filename, "rb"); if(!fp) { ulSetError( UL_WARNING, "ssgLoadMDL: Couldn't open MDL file '%s'!", filename ); return NULL; } // Find beginning of BGL Code segment unsigned long l = ulEndianReadLittle32(fp); fseek(fp, 0, SEEK_SET); if (l == lRIFF) // This is somewhat of a kludge, since ther "RIFF" is mostly at the beginning of the file, but not always. FindBGLBeginRIFF(fp); else { FindBGLBeginOldVersion(fp); if(feof(fp)) { // Ok - so it is not "RIFF" at the beginning of the file and it is not an old file format - // so search for RIFF anywhere // I know of at least one file (the Wellesly V1.4, where the V1.4 is important) // that had two "RIFF"s and ionyl the second one is the one we want. // So we have to search for a place with "RIFF" fseek(fp, 0, SEEK_SET); l = ulEndianReadLittle32(fp); while(!feof(fp)) { unsigned char c = fgetc(fp); l = (l >> 8) | (c << 24); if ( l == lRIFF ) { // check whether it is a red herring... ulEndianReadLittle32(fp); // ignore length unsigned long ll = ulEndianReadLittle32(fp); if (ll == lMDL8) { // found it !! fseek(fp, -12, SEEK_CUR); unsigned long addr = ftell(fp); if(addr&1L) printf("strange... found RIFF, but on an odd adress %lx\n", addr); else printf("found a good RIFF header at address %lx\n", addr); FindBGLBeginRIFF(fp); break; // breaks the while(!feof(fp)) } } } } } if(feof(fp)) { ulSetError( UL_WARNING, "ssgLoadMDL: No BGL Code found in file '%s'!", filename ); fclose(fp); return NULL; } // end find begin // Initialize object graph model_ = new ssgBranch(); char* model_name = new char[128]; char *ptr = (char*)&fname[strlen(fname) - 1]; while(ptr != &fname[0] && *ptr != '/') ptr--; if(*ptr == '/') ptr++; strcpy(model_name, ptr); ptr = &model_name[strlen(model_name)]; while(*ptr != '.' && ptr != &model_name[0]) ptr--; *ptr = '\0'; model_->setName(model_name); // Create group nodes for textured and non-textured objects curr_vtx_ = new ssgVertexArray(); curr_norm_ = new ssgNormalArray(); vertex_array_ = new ssgVertexArray(); normal_array_ = new ssgNormalArray(); tex_coords_ = new ssgTexCoordArray(); start_idx_ = 0; last_idx_ = 0; curr_var_ = 0; stack_depth_ = 0; noLoDs = 1; // if there is no "branch" and no "++noLoDs" is called, we have 1 LoD. // If there is one branch, we have 2, etc. curr_lod = 0; sgMakeIdentMat4(curr_matrix_); // Parse opcodes #ifdef DEBUG #ifdef _MSC_VER wkfp=fopen("c:\\mdl_file_structure.txt", "wt"); #else wkfp=fopen("mdl_file_structure.txt", "wt"); #endif #endif ParseBGL(fp); // "traversing" through the file fclose(fp); #ifdef DEBUG fclose(wkfp); #endif // :-((( delete curr_vtx_; delete curr_norm_; DEBUGPRINT("\n" << vertex_array_->getNum() << " vertices\n"); printf("NoLoDs = %d\n", (int)noLoDs); printf("noGT=%d, noLT=%d, no0=%d\n", noGT, noLT, no0); g_noLoDs = noLoDs; return model_; } #else bool ssgLoadMDLTexture ( const char *fname, ssgTextureInfo* info ) { ulSetError ( UL_WARNING, "ssgLoadTexture: '%s' - MDL support not configured", fname ) ; return false ; } #endif plib-1.8.5/src/ssg/Makefile.in0000644000175000001440000006545010765365024013042 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/ssg DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibssg_a_AR = $(AR) $(ARFLAGS) libplibssg_a_LIBADD = am__libplibssg_a_SOURCES_DIST = ssg.cxx ssgAnimation.cxx ssgBase.cxx \ ssgBaseTransform.cxx ssgBranch.cxx ssgContext.cxx \ ssgCutout.cxx ssgDList.cxx ssgEntity.cxx ssgIsect.cxx \ ssgLeaf.cxx ssgList.cxx ssgLoadDOF.cxx ssgLoadAC.cxx \ ssgLocal.h ssgOptimiser.cxx ssgRoot.cxx ssgSaveAC.cxx \ ssgSelector.cxx ssgSimpleState.cxx ssgState.cxx \ ssgStateTables.cxx ssgStats.cxx ssgTween.cxx \ ssgTweenController.cxx ssgTexTrans.cxx ssgTexture.cxx \ ssgTransform.cxx ssgStateSelector.cxx ssgRangeSelector.cxx \ ssgLoadTexture.cxx ssgLoadBMP.cxx ssgLoadSGI.cxx \ ssgLoadPNG.cxx ssgLoadTGA.cxx ssgLoadPCX.cxx ssgInvisible.cxx \ ssgLoadSSG.cxx ssgVTable.cxx ssgSimpleList.cxx ssgVtxTable.cxx \ ssgIO.cxx ssgLoad3ds.cxx ssgSaveASE.cxx ssgLoadASE.cxx \ ssgParser.cxx ssgParser.h ssgLoadDXF.cxx ssgSaveDXF.cxx \ ssgLoadTRI.cxx ssgSaveTRI.cxx ssgLoadOBJ.cxx ssgSaveOBJ.cxx \ ssgVtxArray.cxx ssgLoadMD2.cxx ssgLoadMDL.cxx ssgLoadX.cxx \ ssgSaveX.cxx ssgLoaderWriterStuff.cxx ssgLoadFLT.cxx \ ssgLoadM.cxx ssgSaveM.cxx ssgLoadStrip.cxx ssgLoadOFF.cxx \ ssgSaveOFF.cxx ssgSaveQHI.cxx ssgLoadVRML1.cxx \ ssgSaveVRML1.cxx ssgLoaderWriterStuff.h ssgMSFSPalette.h \ ssg3ds.h ssgLoadMDL.h ssgSave3ds.cxx ssgAxisTransform.cxx \ ssgLoadATG.cxx ssgSaveFLT.cxx ssgSaveATG.cxx ssgLoadIV.cxx \ ssgLoad.cxx ssgLoadVRML.h ssgLoadMDL_BGLTexture.cxx \ ssgLoadXPlaneObj.cxx ssgLoadASC.cxx ssgSaveASC.cxx \ ssgSaveIV.cxx ssgAnimTransform.cxx ssgVertSplitter.h \ ssgVertSplitter.cxx ssgStatistics.cxx @BUILD_SSG_TRUE@am_libplibssg_a_OBJECTS = ssg.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgAnimation.$(OBJEXT) ssgBase.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgBaseTransform.$(OBJEXT) ssgBranch.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgContext.$(OBJEXT) ssgCutout.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgDList.$(OBJEXT) ssgEntity.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgIsect.$(OBJEXT) ssgLeaf.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgList.$(OBJEXT) ssgLoadDOF.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadAC.$(OBJEXT) ssgOptimiser.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgRoot.$(OBJEXT) ssgSaveAC.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgSelector.$(OBJEXT) ssgSimpleState.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgState.$(OBJEXT) ssgStateTables.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgStats.$(OBJEXT) ssgTween.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgTweenController.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgTexTrans.$(OBJEXT) ssgTexture.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgTransform.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgStateSelector.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgRangeSelector.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadTexture.$(OBJEXT) ssgLoadBMP.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadSGI.$(OBJEXT) ssgLoadPNG.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadTGA.$(OBJEXT) ssgLoadPCX.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgInvisible.$(OBJEXT) ssgLoadSSG.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgVTable.$(OBJEXT) ssgSimpleList.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgVtxTable.$(OBJEXT) ssgIO.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoad3ds.$(OBJEXT) ssgSaveASE.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadASE.$(OBJEXT) ssgParser.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadDXF.$(OBJEXT) ssgSaveDXF.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadTRI.$(OBJEXT) ssgSaveTRI.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadOBJ.$(OBJEXT) ssgSaveOBJ.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgVtxArray.$(OBJEXT) ssgLoadMD2.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadMDL.$(OBJEXT) ssgLoadX.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgSaveX.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoaderWriterStuff.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadFLT.$(OBJEXT) ssgLoadM.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgSaveM.$(OBJEXT) ssgLoadStrip.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadOFF.$(OBJEXT) ssgSaveOFF.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgSaveQHI.$(OBJEXT) ssgLoadVRML1.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgSaveVRML1.$(OBJEXT) ssgSave3ds.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgAxisTransform.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadATG.$(OBJEXT) ssgSaveFLT.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgSaveATG.$(OBJEXT) ssgLoadIV.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoad.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadMDL_BGLTexture.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadXPlaneObj.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgLoadASC.$(OBJEXT) ssgSaveASC.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgSaveIV.$(OBJEXT) ssgAnimTransform.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgVertSplitter.$(OBJEXT) \ @BUILD_SSG_TRUE@ ssgStatistics.$(OBJEXT) libplibssg_a_OBJECTS = $(am_libplibssg_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libplibssg_a_SOURCES) DIST_SOURCES = $(am__libplibssg_a_SOURCES_DIST) am__include_HEADERS_DIST = ssg.h ssgconf.h ssgMSFSPalette.h \ ssgKeyFlier.h pcx.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_SSG_TRUE@lib_LIBRARIES = libplibssg.a @BUILD_SSG_TRUE@include_HEADERS = ssg.h ssgconf.h ssgMSFSPalette.h ssgKeyFlier.h pcx.h @BUILD_SSG_TRUE@libplibssg_a_SOURCES = ssg.cxx ssgAnimation.cxx ssgBase.cxx \ @BUILD_SSG_TRUE@ ssgBaseTransform.cxx ssgBranch.cxx ssgContext.cxx ssgCutout.cxx \ @BUILD_SSG_TRUE@ ssgDList.cxx ssgEntity.cxx ssgIsect.cxx ssgLeaf.cxx ssgList.cxx \ @BUILD_SSG_TRUE@ ssgLoadDOF.cxx ssgLoadAC.cxx \ @BUILD_SSG_TRUE@ ssgLocal.h ssgOptimiser.cxx ssgRoot.cxx ssgSaveAC.cxx \ @BUILD_SSG_TRUE@ ssgSelector.cxx ssgSimpleState.cxx ssgState.cxx ssgStateTables.cxx \ @BUILD_SSG_TRUE@ ssgStats.cxx ssgTween.cxx ssgTweenController.cxx \ @BUILD_SSG_TRUE@ ssgTexTrans.cxx ssgTexture.cxx ssgTransform.cxx \ @BUILD_SSG_TRUE@ ssgStateSelector.cxx ssgRangeSelector.cxx ssgLoadTexture.cxx \ @BUILD_SSG_TRUE@ ssgLoadBMP.cxx ssgLoadSGI.cxx ssgLoadPNG.cxx ssgLoadTGA.cxx \ @BUILD_SSG_TRUE@ ssgLoadPCX.cxx ssgInvisible.cxx ssgLoadSSG.cxx ssgVTable.cxx \ @BUILD_SSG_TRUE@ ssgSimpleList.cxx ssgVtxTable.cxx ssgIO.cxx ssgLoad3ds.cxx \ @BUILD_SSG_TRUE@ ssgSaveASE.cxx ssgLoadASE.cxx ssgParser.cxx ssgParser.h \ @BUILD_SSG_TRUE@ ssgLoadDXF.cxx ssgSaveDXF.cxx ssgLoadTRI.cxx ssgSaveTRI.cxx \ @BUILD_SSG_TRUE@ ssgLoadOBJ.cxx ssgSaveOBJ.cxx ssgVtxArray.cxx ssgLoadMD2.cxx \ @BUILD_SSG_TRUE@ ssgLoadMDL.cxx ssgLoadX.cxx ssgSaveX.cxx ssgLoaderWriterStuff.cxx \ @BUILD_SSG_TRUE@ ssgLoadFLT.cxx ssgLoadM.cxx ssgSaveM.cxx ssgLoadStrip.cxx \ @BUILD_SSG_TRUE@ ssgLoadOFF.cxx ssgSaveOFF.cxx ssgSaveQHI.cxx ssgLoadVRML1.cxx \ @BUILD_SSG_TRUE@ ssgSaveVRML1.cxx ssgLoaderWriterStuff.h ssgMSFSPalette.h ssg3ds.h \ @BUILD_SSG_TRUE@ ssgLoadMDL.h ssgSave3ds.cxx ssgAxisTransform.cxx ssgLoadATG.cxx \ @BUILD_SSG_TRUE@ ssgSaveFLT.cxx ssgSaveATG.cxx ssgLoadIV.cxx ssgLoad.cxx ssgLoadVRML.h \ @BUILD_SSG_TRUE@ ssgLoadMDL_BGLTexture.cxx ssgLoadXPlaneObj.cxx ssgLoadASC.cxx ssgSaveASC.cxx \ @BUILD_SSG_TRUE@ ssgSaveIV.cxx ssgAnimTransform.cxx\ @BUILD_SSG_TRUE@ ssgVertSplitter.h ssgVertSplitter.cxx ssgStatistics.cxx @BUILD_SSG_TRUE@INCLUDES = -I$(top_srcdir)/src/sg -I$(top_srcdir)/src/util EXTRA_DIST = ssg.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/ssg/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/ssg/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibssg.a: $(libplibssg_a_OBJECTS) $(libplibssg_a_DEPENDENCIES) -rm -f libplibssg.a $(libplibssg_a_AR) libplibssg.a $(libplibssg_a_OBJECTS) $(libplibssg_a_LIBADD) $(RANLIB) libplibssg.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgAnimTransform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgAnimation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgAxisTransform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgBase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgBaseTransform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgBranch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgContext.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgCutout.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgDList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgEntity.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgIO.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgInvisible.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgIsect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLeaf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoad.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoad3ds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadAC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadASC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadASE.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadATG.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadBMP.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadDOF.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadDXF.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadFLT.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadIV.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadM.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadMD2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadMDL.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadMDL_BGLTexture.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadOBJ.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadOFF.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadPCX.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadPNG.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadSGI.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadSSG.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadStrip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadTGA.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadTRI.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadTexture.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadVRML1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadX.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoadXPlaneObj.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgLoaderWriterStuff.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgOptimiser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgParser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgRangeSelector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgRoot.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSave3ds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveAC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveASC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveASE.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveATG.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveDXF.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveFLT.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveIV.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveM.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveOBJ.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveOFF.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveQHI.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveTRI.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveVRML1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSaveX.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSelector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSimpleList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgSimpleState.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgState.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgStateSelector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgStateTables.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgStatistics.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgStats.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgTexTrans.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgTexture.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgTransform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgTween.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgTweenController.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgVTable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgVertSplitter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgVtxArray.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgVtxTable.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/ssg/ssgconf.h0000644000175000001440000000376710765364437012622 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgconf.h 1959 2004-09-14 12:19:05Z wolfram_kuss $ */ #ifndef _INCLUDED_SSGCONF_H_ #define _INCLUDED_SSGCONF_H_ /* ssgconf.h - machine configurable file for libssg */ #define _SSG_USE_DLIST 1 /* The following defines give you the ability to remove code from the * library that you will not be using. I wish I could figure out how to * automate this, but I can't do that without making it seriously hard * on the users. So if you are not using an ability, change the #define * to an #undef, and that part of the library will not be compiled. If * your linker can't find a function, you may want to make sure the * ability is defined here. */ /* For optional use of PNG textures, download the glpng library from http://www.wyatt100.freeserve.co.uk/download.htm and change the #undef to a #define in the following line. */ #undef SSG_LOAD_PNG_SUPPORTED #define SSG_LOAD_SGI_SUPPORTED #define SSG_LOAD_TGA_SUPPORTED #define SSG_LOAD_BMP_SUPPORTED #define SSG_LOAD_MDL_SUPPORTED #define SSG_LOAD_MDL_BGL_TEXTURE_SUPPORTED #define SSG_LOAD_XPL_SUPPORTED #define SSG_LOAD_PCX_SUPPORTED #endif plib-1.8.5/src/ssg/ssgSaveDXF.cxx0000644000175000001440000001216010765364437013473 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveDXF.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ // // DXF export for SSG/PLIB // Ported from IVCON by Dave McClurg (dpm@efn.org) in March-2000 // #include "ssgLocal.h" static FILE *fileout ; static void save_vtx_table ( ssgVtxTable *vt ) { GLenum mode = vt -> getPrimitiveType () ; if (( mode == GL_LINES ) || ( mode == GL_LINE_LOOP) || ( mode == GL_LINE_STRIP)) { int num_vert = vt -> getNumVertices () ; num_vert = num_vert - ( num_vert & 1 ) ; //discard odd vertex int local_num_lines = vt -> getNumLines(); for ( int j = 0; j < local_num_lines ; j ++ ) { sgVec3 vert1, vert2; short iv1, iv2; vt -> getLine (j, &iv1, &iv2); sgCopyVec3 ( vert1, vt->getVertex ( iv1 ) ) ; sgCopyVec3 ( vert2, vt->getVertex ( iv2 ) ) ; fprintf ( fileout, "0\n" ); fprintf ( fileout, "LINE\n" ); fprintf ( fileout, "8\n" ); fprintf ( fileout, "0\n" ); fprintf ( fileout, "10\n" ); fprintf ( fileout, "%f\n", vert1[0] ); fprintf ( fileout, "20\n" ); fprintf ( fileout, "%f\n", vert1[1] ); fprintf ( fileout, "30\n" ); fprintf ( fileout, "%f\n", vert1[2] ); fprintf ( fileout, "11\n" ); fprintf ( fileout, "%f\n", vert2[0] ); fprintf ( fileout, "21\n" ); fprintf ( fileout, "%f\n", vert2[1] ); fprintf ( fileout, "31\n" ); fprintf ( fileout, "%f\n", vert2[2] ); } } else if ( mode == GL_TRIANGLES || mode == GL_TRIANGLE_FAN || mode == GL_TRIANGLE_STRIP ) { int num_face = vt -> getNumTriangles () ; for ( int j = 0; j < num_face; j++ ) { short face[3]; vt -> getTriangle ( j, &face[0], &face[1], &face[2] ) ; fprintf ( fileout, "0\n" ); fprintf ( fileout, "3DFACE\n" ); fprintf ( fileout, "8\n" ); fprintf ( fileout, "Cube\n" ); sgVec3 vert; for ( int ivert = 0; ivert < 3; ivert++ ) { sgCopyVec3 ( vert, vt->getVertex ( face[ivert] ) ) ; fprintf ( fileout, "1%d\n", ivert ); fprintf ( fileout, "%f\n", vert[0] ); fprintf ( fileout, "2%d\n", ivert ); fprintf ( fileout, "%f\n", vert[1] ); fprintf ( fileout, "3%d\n", ivert ); fprintf ( fileout, "%f\n", vert[2] ); } fprintf ( fileout, "13\n"); fprintf ( fileout, "%f\n", vert[0] ); fprintf ( fileout, "23\n"); fprintf ( fileout, "%f\n", vert[1] ); fprintf ( fileout, "33\n"); fprintf ( fileout, "%f\n", vert[2] ); } } else ulSetError ( UL_WARNING, "ssgSaveDXF: OpenGL mode %d not implmented yet. Parts or all of the model are ignored!' for writing", (int)mode ) ; } static void save_entities ( ssgEntity *e ) { if ( e -> isAKindOf ( ssgTypeBranch() ) ) { ssgBranch *br = (ssgBranch *) e ; for ( int i = 0 ; i < br -> getNumKids () ; i++ ) save_entities ( br -> getKid ( i ) ) ; } else if ( e -> isAKindOf ( ssgTypeVtxTable() ) ) { ssgVtxTable *vt = (ssgVtxTable *) e ; save_vtx_table ( vt ) ; } } int ssgSaveDXF ( const char *filename, ssgEntity *ent ) { fileout = fopen ( filename, "wa" ) ; if ( fileout == NULL ) { ulSetError ( UL_WARNING, "ssgSaveDXF: Failed to open '%s' for writing", filename ) ; return FALSE ; } /* Initialize. */ fprintf ( fileout, "0\n" ); fprintf ( fileout, "SECTION\n" ); fprintf ( fileout, "2\n" ); fprintf ( fileout, "HEADER\n" ); fprintf ( fileout, "999\n" ); fprintf ( fileout, "%s created by SSG.\n", filename ); fprintf ( fileout, "0\n" ); fprintf ( fileout, "ENDSEC\n" ); fprintf ( fileout, "0\n" ); fprintf ( fileout, "SECTION\n" ); fprintf ( fileout, "2\n" ); fprintf ( fileout, "TABLES\n" ); fprintf ( fileout, "0\n" ); fprintf ( fileout, "ENDSEC\n" ); fprintf ( fileout, "0\n" ); fprintf ( fileout, "SECTION\n" ); fprintf ( fileout, "2\n" ); fprintf ( fileout, "BLOCKS\n" ); fprintf ( fileout, "0\n" ); fprintf ( fileout, "ENDSEC\n" ); fprintf ( fileout, "0\n" ); fprintf ( fileout, "SECTION\n" ); fprintf ( fileout, "2\n" ); fprintf ( fileout, "ENTITIES\n" ); save_entities ( ent ) ; fprintf ( fileout, "0\n" ); fprintf ( fileout, "ENDSEC\n" ); fprintf ( fileout, "0\n" ); fprintf ( fileout, "EOF\n" ); /* Close. */ fclose ( fileout ) ; return TRUE; } plib-1.8.5/src/ssg/ssgTransform.cxx0000644000175000001440000001257010765364437014213 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgTransform.cxx 1992 2004-12-01 08:28:05Z wolfram_kuss $ */ #include "ssgLocal.h" void ssgTransform::copy_from ( ssgTransform *src, int clone_flags ) { ssgBaseTransform::copy_from ( src, clone_flags ) ; } ssgBase *ssgTransform::clone ( int clone_flags ) { ssgTransform *b = new ssgTransform ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgTransform::ssgTransform ( sgCoord *c ) { type = ssgTypeTransform () ; setTransform ( c ) ; } ssgTransform::ssgTransform (void) { type = ssgTypeTransform () ; } ssgTransform::~ssgTransform (void) { } void ssgTransform::recalcBSphere (void) { ssgBranch::recalcBSphere () ; if ( ! bsphere . isEmpty () ) bsphere . orthoXform ( transform ) ; } void ssgTransform::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) ) return ; int cull_result = cull_test ( f, m, test_needed ) ; if ( cull_result == SSG_OUTSIDE ) return ; sgMat4 tmp ; sgCopyMat4 ( tmp, m ) ; sgPreMultMat4 ( tmp, transform ) ; _ssgPushMatrix ( tmp ) ; glPushMatrix () ; glLoadMatrixf ( (float *) tmp ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> cull ( f, tmp, cull_result != SSG_INSIDE ) ; glPopMatrix () ; _ssgPopMatrix () ; postTravTests ( SSGTRAV_CULL ) ; } void ssgTransform::hot ( sgVec3 s, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) ) return ; int hot_result = hot_test ( s, m, test_needed ) ; if ( hot_result == SSG_OUTSIDE ) return ; sgMat4 tmp ; sgCopyMat4 ( tmp, m ) ; sgPreMultMat4 ( tmp, transform ) ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> hot ( s, tmp, hot_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_HOT ) ; } void ssgTransform::los ( sgVec3 s, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) ) return ; int los_result = los_test ( s, m, test_needed ) ; if ( los_result == SSG_OUTSIDE ) return ; sgMat4 tmp ; sgCopyMat4 ( tmp, m ) ; sgPreMultMat4 ( tmp, transform ) ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> los ( s, tmp, los_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_LOS ) ; } void ssgTransform::isect ( sgSphere *s, sgMat4 m, int test_needed ) { if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) ) return ; int isect_result = isect_test ( s, m, test_needed ) ; if ( isect_result == SSG_OUTSIDE ) return ; sgMat4 tmp ; sgCopyMat4 ( tmp, m ) ; sgPreMultMat4 ( tmp, transform ) ; _ssgPushPath ( this ) ; for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid() ) e -> isect ( s, tmp, isect_result != SSG_INSIDE ) ; _ssgPopPath () ; postTravTests ( SSGTRAV_ISECT ) ; } void ssgTransform::setTransform ( sgVec3 xyz ) { sgMat4 tmp_trans; sgMakeTransMat4 ( tmp_trans, xyz ) ; setTransform ( tmp_trans ) ; } void ssgTransform::setTransform ( sgCoord *xform ) { sgMat4 tmp_trans; sgMakeCoordMat4 ( tmp_trans, xform ) ; setTransform ( tmp_trans ) ; } void ssgTransform::setTransform ( sgCoord *xform, float sx, float sy, float sz ) { sgMat4 tmp_trans; sgMakeCoordMat4 ( tmp_trans, xform ) ; sgScaleVec3 ( tmp_trans[0], sx ) ; sgScaleVec3 ( tmp_trans[1], sy ) ; sgScaleVec3 ( tmp_trans[2], sz ) ; setTransform ( tmp_trans ); } void ssgTransform::setTransform ( sgMat4 xform ) { if ( sgEqualVec4( xform[0], transform[0] ) && sgEqualVec4( xform[1], transform[1] ) && sgEqualVec4( xform[2], transform[2] ) && sgEqualVec4( xform[3], transform[3] ) ) return; updateTransform () ; sgCopyMat4 ( transform, xform ) ; firsttime () ; dirtyBSphere () ; } void ssgTransform::getNetTransform ( sgMat4 xform ) { if ( getNumParents () > 0 ) { getParent ( 0 ) -> getNetTransform ( xform ) ; sgPreMultMat4 ( xform, transform ) ; } else sgCopyMat4 ( xform, transform ) ; } void ssgTransform::getLastNetTransform ( sgMat4 xform ) { sgMat4 last_xform ; getLastTransform ( last_xform ) ; if ( getNumParents () > 0 ) { getParent ( 0 ) -> getLastNetTransform ( xform ) ; sgPreMultMat4 ( xform, last_xform ) ; } else sgCopyMat4 ( xform, last_xform ) ; } int ssgTransform::load ( FILE *fd ) { return ssgBaseTransform::load(fd) ; } int ssgTransform::save ( FILE *fd ) { return ssgBaseTransform::save(fd) ; } plib-1.8.5/src/ssg/ssgVtxTable.cxx0000644000175000001440000006025110765364437013770 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgVtxTable.cxx 1992 2004-12-01 08:28:05Z wolfram_kuss $ */ #include "ssgLocal.h" #define HL_DELTA 0.04f int ssgSimpleList::compare(ssgSimpleList *other, int print_result) { int result = TRUE; if (total !=other->total ) { result = FALSE; if(print_result) printf("ERROR: total \n"); } else if(print_result) printf("Ok: total \n"); if (size_of !=other->size_of ) { result = FALSE; if(print_result) printf("ERROR: size_of \n"); } else if(print_result) printf("Ok: size_of \n"); if (memcmp(list, other->list, total*size_of)) { result = FALSE; if(print_result) printf("ERROR: list \n"); } else if(print_result) printf("Ok: list \n"); return result; } int ssgVtxTable::compare(ssgVtxTable *other, int print_result) // returns TRUE, if equal. // prints stuff to stdout. { int result = TRUE; if(print_result) printf("comparing vertices\n"); if(!vertices->compare(other->vertices, print_result)) result=FALSE; if(print_result) printf("comparing normals\n"); if(!normals->compare(other->normals, print_result)) result=FALSE; if(print_result) printf("comparing texcoords\n"); if(!texcoords->compare(other->texcoords, print_result)) result=FALSE; if(print_result) printf("comparing colours \n"); if(!colours ->compare(other->colours, print_result)) result=FALSE; // could be in ssgLeaf: if(getState () == other->getState ()) { if(print_result) printf("Ok: state\n"); } else if(print_result) printf("WARNING: state pointers differ. state contents is not investigated\n"); if (getNumVertices ()!=other->getNumVertices ()) { result = FALSE; if(print_result) printf("ERROR: getNumVertices ()\n"); } else if(print_result) printf("Ok: getNumVertices ()\n"); if (getNumNormals ()!=other->getNumNormals ()) { result = FALSE; if(print_result) printf("ERROR: getNumNormals ()\n"); } else if(print_result) printf("Ok: getNumNormals ()\n"); if (getNumColours ()!=other->getNumColours ()) { result = FALSE; if(print_result) printf("ERROR: getNumColours ()\n"); } else if(print_result) printf("Ok: getNumColours ()\n"); if (getNumTexCoords ()!=other->getNumTexCoords ()) { result = FALSE; if(print_result) printf("ERROR: getNumTexCoords ()\n"); } else if(print_result) printf("Ok: getNumTexCoords ()\n"); // end could be in leaf return result; } void ssgVtxTable::copy_from ( ssgVtxTable *src, int clone_flags ) { ssgLeaf::copy_from ( src, clone_flags ) ; gltype = src -> getPrimitiveType () ; if ( src->vertices != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) vertices = (ssgVertexArray *)( src -> vertices -> clone ( clone_flags )) ; else vertices = src -> vertices ; if ( src->normals != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) normals = (ssgNormalArray *)( src -> normals -> clone ( clone_flags )) ; else normals = src -> normals ; if ( src->texcoords != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) texcoords = (ssgTexCoordArray *)( src -> texcoords -> clone ( clone_flags )) ; else texcoords = src -> texcoords ; if ( src->colours != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) colours = (ssgColourArray *)( src -> colours -> clone ( clone_flags )) ; else colours = src -> colours ; if ( vertices != NULL ) vertices -> ref () ; if ( normals != NULL ) normals -> ref () ; if ( texcoords != NULL ) texcoords -> ref () ; if ( colours != NULL ) colours -> ref () ; recalcBSphere () ; } ssgBase *ssgVtxTable::clone ( int clone_flags ) { ssgVtxTable *b = new ssgVtxTable ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgVtxTable::ssgVtxTable () { type = ssgTypeVtxTable () ; gltype = GL_POINTS ; vertices = NULL ; normals = NULL ; texcoords = NULL ; colours = NULL ; } ssgVtxTable::ssgVtxTable ( GLenum ty, ssgVertexArray *vl, ssgNormalArray *nl, ssgTexCoordArray *tl, ssgColourArray *cl ) { gltype = ty ; type = ssgTypeVtxTable () ; vertices = (vl!=NULL) ? vl : new ssgVertexArray () ; normals = (nl!=NULL) ? nl : new ssgNormalArray () ; texcoords = (tl!=NULL) ? tl : new ssgTexCoordArray () ; colours = (cl!=NULL) ? cl : new ssgColourArray () ; vertices -> ref () ; normals -> ref () ; texcoords -> ref () ; colours -> ref () ; recalcBSphere () ; } void ssgVtxTable::setVertices ( ssgVertexArray *vl ) { ssgDeRefDelete ( vertices ) ; vertices = vl ; if ( vertices != NULL ) vertices -> ref () ; recalcBSphere () ; } void ssgVtxTable::setNormals ( ssgNormalArray *nl ) { ssgDeRefDelete ( normals ) ; normals = nl ; if ( normals != NULL ) normals -> ref () ; } void ssgVtxTable::setTexCoords ( ssgTexCoordArray *tl ) { ssgDeRefDelete ( texcoords ) ; texcoords = tl ; if ( texcoords != NULL ) texcoords -> ref () ; } void ssgVtxTable::setColours ( ssgColourArray *cl ) { ssgDeRefDelete ( colours ) ; colours = cl ; if ( colours != NULL ) colours -> ref () ; } ssgVtxTable::~ssgVtxTable () { ssgDeRefDelete ( vertices ) ; ssgDeRefDelete ( normals ) ; ssgDeRefDelete ( texcoords ) ; ssgDeRefDelete ( colours ) ; } void ssgVtxTable::getTriangle ( int n, short *v1, short *v2, short *v3 ) { switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : *v1 = 0 ; *v2 = n+1 ; *v3 = n+2 ; return ; case GL_TRIANGLES : *v1 = n*3 ; *v2 = n*3+1 ; *v3 = n*3+2 ; return ; case GL_TRIANGLE_STRIP : case GL_QUAD_STRIP : if ( n & 1 ) { *v3 = n ; *v2 = n+1 ; *v1 = n+2 ; } else { *v1 = n ; *v2 = n+1 ; *v3 = n+2 ; } return ; case GL_QUADS : *v1 = n*2 + 0 ; *v2 = n*2 + 1 ; *v3 = n*2 + 2 - (n&1)*4 ; return ; default : return ; } } int ssgVtxTable::getNumTriangles () { switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : return getNumVertices() - 2 ; case GL_TRIANGLES : return getNumVertices() / 3 ; case GL_TRIANGLE_STRIP : return getNumVertices() - 2 ; case GL_QUADS : return ( getNumVertices() / 4 ) * 2 ; case GL_QUAD_STRIP : return ( ( getNumVertices() - 2 ) / 2 ) * 2 ; case GL_POINTS : case GL_LINES : case GL_LINE_LOOP : case GL_LINE_STRIP : return 0; default : break ; } return 0 ; /* Should never get here...but you never know! */ } int ssgVtxTable::getNumLines () { switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : case GL_TRIANGLES : case GL_TRIANGLE_STRIP : case GL_QUADS : case GL_QUAD_STRIP : case GL_POINTS : return 0; case GL_LINES : // wk: FIXME: check the 3 following formulas. I don't have an OpenGL bokk at hand currently :-( return getNumVertices()/2; case GL_LINE_LOOP : return getNumVertices(); case GL_LINE_STRIP : return getNumVertices()-1; default : break ; } assert(false); /* Should never get here */ return 0 ; } void ssgVtxTable::getLine ( int n, short *v1, short *v2 ) { assert( n>=0 ); switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : case GL_TRIANGLES : case GL_TRIANGLE_STRIP : case GL_QUADS : case GL_QUAD_STRIP : case GL_POINTS : assert(false); case GL_LINES : // wk: FIXME: check the 3 following formulas. I don't have an OpenGL bokk at hand currently :-( assert ( 2*n+1 < getNumVertices() ); *v1 = 2*n; *v2 = 2*n+1 ; return ; case GL_LINE_LOOP : assert ( n < getNumVertices() ); *v1 = n; if ( n == getNumVertices()-1 ) *v2 = 0; else *v2 = n+1; return ; case GL_LINE_STRIP : assert ( n < getNumVertices()-1 ); *v1 = n; *v2 = n+1; return; default : break ; } assert(false); /* Should never get here */ return ; } void ssgVtxTable::transform ( const sgMat4 m ) { int i ; int flags = sgClassifyMat4 ( m ) ; if ( flags == 0 ) return ; if ( ( flags & SG_PROJECTION ) ) ulSetError ( UL_WARNING, "ssgVtxTable: Projection matrices currently not supported." ) ; /* note: it is possible to handle projections, but for each normal we would have to know the corresponding vertex coordinates. setting: n[3] = dot(v, n) / v[3] and then transforming with the full 4x4 transposed inverse matrix would do it. see the OpenGL spec. */ int num_vertices = getNumVertices () ; int num_normals = getNumNormals () ; for ( i = 0 ; i < num_vertices ; i++ ) sgXformPnt3 ( vertices->get(i), vertices->get(i), m ) ; if ( ( flags & ( SG_SCALE | SG_MIRROR | SG_NONORTHO ) ) ) { sgMat4 w ; if ( ( flags & SG_NONORTHO ) ) { // use the transposed adjoint matrix (only the upper 3x3 is needed) sgVectorProductVec3 ( w[0], m[1], m[2] ) ; sgVectorProductVec3 ( w[1], m[2], m[0] ) ; sgVectorProductVec3 ( w[2], m[0], m[1] ) ; } else { SGfloat scale = SG_ONE ; if ( ( flags & SG_SCALE ) ) { // prescale matrix to avoid renormalisation scale = scale / sgLengthVec3 ( m[0] ) ; } if ( ( flags & SG_MIRROR ) ) { // negate to keep normals consistent with triangle orientations scale = - scale ; } sgScaleVec3 ( w[0], m[0], scale ) ; sgScaleVec3 ( w[1], m[1], scale ) ; sgScaleVec3 ( w[2], m[2], scale ) ; } for ( i = 0 ; i < num_normals ; i++ ) sgXformVec3 ( normals->get(i), normals->get(i), w ) ; } else for ( i = 0 ; i < num_normals ; i++ ) sgXformVec3 ( normals->get(i), normals->get(i), m ) ; if ( ( flags & SG_NONORTHO ) ) { for ( i = 0 ; i < num_normals ; i++ ) sgNormaliseVec3 ( normals->get(i) ) ; } recalcBSphere () ; } void ssgVtxTable::recalcBSphere () { emptyBSphere () ; bbox . empty () ; int num_vertices = getNumVertices () ; for ( int i = 0 ; i < num_vertices ; i++ ) bbox . extend ( vertices->get(i) ) ; extendBSphere ( & bbox ) ; dirtyBSphere () ; /* Cause parents to redo their bspheres */ bsphere_is_invalid = FALSE ; } void ssgVtxTable::drawHighlight ( sgVec4 colour ) { _ssgForceLineState () ; int i ; int num_vertices = getNumVertices () ; sgVec3 *vx = (sgVec3 *) vertices -> get(0) ; glPushAttrib ( GL_POLYGON_BIT ) ; glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE ) ; glColor4fv ( colour ) ; glBegin ( gltype ) ; for ( i = 0 ; i < num_vertices ; i++ ) glVertex3fv ( vx [ i ] ) ; glEnd () ; glPopAttrib () ; glEnable ( GL_DEPTH_TEST ) ; } void ssgVtxTable::drawHighlight ( sgVec4 colour, int v ) { _ssgForceLineState () ; int num_vertices = getNumVertices () ; if ( v < 0 || v >= num_vertices ) return ; sgVec3 *vx = (sgVec3 *) vertices -> get(v) ; float x = vx[0][0] ; float y = vx[0][1] ; float z = vx[0][2] ; sgVec3 t[6] ; sgSetVec3 ( t[0], x-HL_DELTA,y,z ) ; sgSetVec3 ( t[1], x+HL_DELTA,y,z ) ; sgSetVec3 ( t[2], x,y-HL_DELTA,z ) ; sgSetVec3 ( t[3], x,y+HL_DELTA,z ) ; sgSetVec3 ( t[4], x,y,z-HL_DELTA ) ; sgSetVec3 ( t[5], x,y,z+HL_DELTA ) ; glColor4fv ( colour ) ; glLineWidth ( 4.0f ) ; glBegin ( GL_LINES ) ; glVertex3fv ( t[0] ) ; glVertex3fv ( t[1] ) ; glVertex3fv ( t[2] ) ; glVertex3fv ( t[3] ) ; glVertex3fv ( t[4] ) ; glVertex3fv ( t[5] ) ; glEnd () ; glLineWidth ( 1.0f ) ; glEnable ( GL_DEPTH_TEST ) ; } void ssgVtxTable::draw () { if ( ! preDraw () ) return ; if ( _ssgCurrentContext-> stateOverridden () ) _ssgCurrentContext -> overriddenState () -> apply () ; else if ( hasState () ) getState () -> apply () ; stats_num_leaves++ ; stats_num_vertices += getNumVertices() ; #ifdef _SSG_USE_DLIST if ( dlist ) glCallList ( dlist ) ; else #endif draw_geometry () ; if ( postDrawCB != NULL ) (*postDrawCB)(this) ; } void ssgVtxTable::pick ( int baseName ) { int i ; int num_vertices = getNumVertices () ; sgVec3 *vx = (sgVec3 *) vertices -> get(0) ; /* Test the entire primitive. */ glPushName ( baseName ) ; glBegin ( gltype ) ; for ( i = 0 ; i < num_vertices ; i++ ) glVertex3fv ( vx [ i ] ) ; glEnd () ; /* Then test each vertex in turn */ for ( i = 0 ; i < num_vertices ; i++ ) { glLoadName ( baseName + i + 1 ) ; glBegin ( GL_POINTS ) ; glVertex3fv ( vx [ i ] ) ; glEnd () ; } glPopName () ; } void ssgVtxTable::draw_geometry () { int num_vertices = getNumVertices () ; int num_colours = getNumColours () ; int num_normals = getNumNormals () ; int num_texcoords = getNumTexCoords () ; if ( num_colours == 0 ) glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ; if ( num_colours == 1 ) glColor4fv ( colours -> get(0) ) ; if ( num_normals == 1 ) glNormal3fv ( normals -> get(0) ) ; glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) ; if ( num_colours > 1 ) { glEnableClientState ( GL_COLOR_ARRAY ) ; glColorPointer ( 4, GL_FLOAT, 0, colours->get(0) ) ; } if ( num_normals > 1 ) { glEnableClientState ( GL_NORMAL_ARRAY ) ; glNormalPointer ( GL_FLOAT, 0, normals->get(0) ) ; } if ( num_texcoords > 1 ) { glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ; glTexCoordPointer ( 2, GL_FLOAT, 0, texcoords->get(0) ) ; } glEnableClientState ( GL_VERTEX_ARRAY ) ; glVertexPointer ( 3, GL_FLOAT, 0, vertices->get(0) ) ; _ssgCurrStatistics . bumpVertexCount ( num_vertices ) ; _ssgCurrStatistics . bumpLeafCount ( 1 ) ; glDrawArrays ( gltype, 0, num_vertices ) ; glPopClientAttrib () ; } void ssgVtxTable::hot_triangles ( sgVec3 s, sgMat4 m, int /* test_needed */ ) { int nt = getNumTriangles () ; stats_hot_triangles += nt ; for ( int i = 0 ; i < nt ; i++ ) { short v1, v2, v3 ; sgVec3 vv1, vv2, vv3 ; sgVec4 plane ; if ( _ssgBackFaceCollisions ) getTriangle ( i, &v1, &v3, &v2 ) ; else getTriangle ( i, &v1, &v2, &v3 ) ; sgXformPnt3 ( vv1, getVertex(v1), m ) ; sgXformPnt3 ( vv2, getVertex(v2), m ) ; sgXformPnt3 ( vv3, getVertex(v3), m ) ; /* Does the X/Y coordinate lie outside the triangle's bbox, or does the Z coordinate lie beneath the bbox ? */ if ( ( s[0] < vv1[0] && s[0] < vv2[0] && s[0] < vv3[0] ) || ( s[1] < vv1[1] && s[1] < vv2[1] && s[1] < vv3[1] ) || ( s[0] > vv1[0] && s[0] > vv2[0] && s[0] > vv3[0] ) || ( s[1] > vv1[1] && s[1] > vv2[1] && s[1] > vv3[1] ) || ( s[2] < vv1[2] && s[2] < vv2[2] && s[2] < vv3[2] ) ) continue ; sgMakePlane ( plane, vv1, vv2, vv3 ) ; if ( _ssgIsHotTest ) { /* No HOT from upside-down or vertical triangles */ if ( getCullFace() && plane [ 2 ] <= 0 ) continue ; /* Find the point vertically below the text point as it crosses the plane of the polygon */ float z = sgHeightOfPlaneVec2 ( plane, s ) ; /* No HOT from below the triangle */ if ( z > s[2] ) continue ; /* Outside the vertical extent of the triangle? */ if ( ( z < vv1[2] && z < vv2[2] && z < vv3[2] ) || ( z > vv1[2] && z > vv2[2] && z > vv3[2] ) ) continue ; } /* Now it gets messy - the isect point is inside the bbox of the triangle - but that's not enough. Is it inside the triangle itself? */ float e1 = s [0] * vv1[1] - s [1] * vv1[0] ; float e2 = s [0] * vv2[1] - s [1] * vv2[0] ; float e3 = s [0] * vv3[1] - s [1] * vv3[0] ; float ep1 = vv1[0] * vv2[1] - vv1[1] * vv2[0] ; float ep2 = vv2[0] * vv3[1] - vv2[1] * vv3[0] ; float ep3 = vv3[0] * vv1[1] - vv3[1] * vv1[0] ; float ap = (float) fabs ( ep1 + ep2 + ep3 ) ; float ai = (float) ( fabs ( e1 + ep1 - e2 ) + fabs ( e2 + ep2 - e3 ) + fabs ( e3 + ep3 - e1 ) ) ; if ( ai > ap * 1.01 ) continue ; _ssgAddHit ( this, i, m, plane ) ; } } void ssgVtxTable::los_triangles ( sgVec3 s, sgMat4 m, int /* test_needed */ ) { int nt = getNumTriangles () ; stats_los_triangles += nt ; for ( int i = 0 ; i < nt ; i++ ) { short v1, v2, v3 ; sgVec3 vv1, vv2, vv3 ; sgVec4 plane ; SGfloat edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; SGfloat det,inv_det; SGfloat /*t,*/u,v; if ( _ssgBackFaceCollisions ) getTriangle ( i, &v1, &v3, &v2 ) ; else getTriangle ( i, &v1, &v2, &v3 ) ; sgXformPnt3 ( vv1, getVertex(v1), m ) ; sgXformPnt3 ( vv2, getVertex(v2), m ) ; sgXformPnt3 ( vv3, getVertex(v3), m ) ; sgVec3 cam; cam[0] = m[0][3]; cam[1] = m[1][3]; cam[2] = m[2][3]; //if ( _ssgIsLosTest ) //{ /* find vectors for two edges sharing vert0 */ sgSubVec3(edge1, vv2, vv1); sgSubVec3(edge2, vv3, vv1); /* begin calculating determinant - also used to calculate U parameter */ sgVectorProductVec3(pvec, s, edge2); /* if determinant is near zero, ray lies in plane of triangle */ det = sgScalarProductVec3(edge1, pvec); if (det > -0.0000001 && det < 0.0000001) continue; inv_det = (float)1.0 / det; /* calculate distance from vert0 to ray origin */ sgSubVec3(tvec, cam, vv1); /* calculate U parameter and test bounds */ u = sgScalarProductVec3(tvec, pvec) * inv_det; if (u < 0.0 || u > 1.0) continue; /* prepare to test V parameter */ sgVectorProductVec3(qvec, tvec, edge1); /* calculate V parameter and test bounds */ v = sgScalarProductVec3(s, qvec) * inv_det; if (v < 0.0 || u + v > 1.0) continue; /* calculate t, ray intersects triangle */ //t = sgScalarProductVec3(edge2, qvec) * inv_det; //} sgMakePlane ( plane, vv1, vv2, vv3 ) ; _ssgAddHit ( this, i, m, plane ) ; } } ssgVtxArray *ssgVtxTable::getAs_ssgVtxArray() { ssgIndexArray *indices = new ssgIndexArray (); int i, no = 0; switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : case GL_TRIANGLE_STRIP : no = getNumTriangles() + 2 ; break; case GL_TRIANGLES : no = getNumTriangles() * 3 ; } for(i=0;iadd(i); ssgState * state = getState(); char * name = getName(); ssgVtxArray * s = new ssgVtxArray ( getGLtype(), vertices, normals, texcoords, colours, indices); s->setName(name); s->setState(state); return s; } void ssgVtxTable::isect_triangles ( sgSphere *s, sgMat4 m, int test_needed ) { int nt = getNumTriangles () ; stats_isect_triangles += nt ; for ( int i = 0 ; i < nt ; i++ ) { short v1, v2, v3 ; sgVec3 vv1, vv2, vv3 ; sgVec4 plane ; if ( _ssgBackFaceCollisions ) getTriangle ( i, &v1, &v3, &v2 ) ; else getTriangle ( i, &v1, &v2, &v3 ) ; sgXformPnt3 ( vv1, getVertex(v1), m ) ; sgXformPnt3 ( vv2, getVertex(v2), m ) ; sgXformPnt3 ( vv3, getVertex(v3), m ) ; sgMakePlane ( plane, vv1, vv2, vv3 ) ; if ( ! test_needed ) { _ssgAddHit ( this, i, m, plane ) ; continue ; } float dp = (float) fabs ( sgDistToPlaneVec3 ( plane, s->getCenter() ) ) ; if ( dp > s->getRadius() ) continue ; /* The BSphere touches the plane containing the triangle - but does it actually touch the triangle itself? Let's erect some vertical walls around the triangle. */ /* Construct a 'wall' as a plane through two vertices and a third vertex made by adding the surface normal to the first of those two vertices. */ sgVec3 vvX ; sgVec4 planeX ; sgAddVec3 ( vvX, plane, vv1 ) ; sgMakePlane ( planeX, vv1, vv2, vvX ) ; float dp1 = sgDistToPlaneVec3 ( planeX, s->getCenter() ) ; if ( dp1 > s->getRadius() ) continue ; sgAddVec3 ( vvX, plane, vv2 ) ; sgMakePlane ( planeX, vv2, vv3, vvX ) ; float dp2 = sgDistToPlaneVec3 ( planeX, s->getCenter() ) ; if ( dp2 > s->getRadius() ) continue ; sgAddVec3 ( vvX, plane, vv3 ) ; sgMakePlane ( planeX, vv3, vv1, vvX ) ; float dp3 = sgDistToPlaneVec3 ( planeX, s->getCenter() ) ; if ( dp3 > s->getRadius() ) continue ; /* OK, so we now know that the sphere intersects the plane of the triangle and is not more than one radius outside the walls. However, you can still get close enough to the wall and to the triangle itself and *still* not intersect the triangle itself. However, if the center is inside the triangle then we don't need that costly test. */ if ( dp1 <= 0 && dp2 <= 0 && dp3 <= 0 ) { _ssgAddHit ( this, i, m, plane ) ; continue ; } /* ...now we really need that costly set of tests... If the sphere penetrates the plane of the triangle and the plane of the wall, then we can use pythagoras to determine if the sphere actually intersects that edge between the wall and the triangle. if ( dp_sqd + dp1_sqd > radius_sqd ) ...in! else ...out! */ float r2 = s->getRadius() * s->getRadius() - dp * dp ; if ( dp1 * dp1 <= r2 || dp2 * dp2 <= r2 || dp3 * dp3 <= r2 ) { _ssgAddHit ( this, i, m, plane ) ; continue ; } } } void ssgVtxTable::print ( FILE *fd, char *indent, int how_much ) { char in [ 100 ] ; if ( how_much == 0 ) return ; sprintf ( in, "%s ", indent ); ssgLeaf ::print ( fd, indent, how_much ) ; if ( vertices == NULL ) fprintf ( fd, "%s No Vertices!\n", indent ) ; else vertices -> print ( fd, in, how_much ) ; if ( normals == NULL ) fprintf ( fd, "%s No Normals!\n", indent ) ; else normals -> print ( fd, in, how_much ) ; if ( texcoords == NULL ) fprintf ( fd, "%s No Texcoords!\n", indent ) ; else texcoords -> print ( fd, in, how_much ) ; if ( colours == NULL ) fprintf ( fd, "%s No Colours!\n", indent ) ; else colours -> print ( fd, in, how_much ) ; } int ssgVtxTable::load ( FILE *fd ) { sgVec3 temp; _ssgReadVec3 ( fd, temp ); bbox.setMin( temp ) ; _ssgReadVec3 ( fd, temp ); bbox.setMax( temp ) ; _ssgReadInt ( fd, (int *)(&gltype) ) ; if ( ! ssgLeaf::load(fd) ) return FALSE ; if ( ! _ssgLoadObject ( fd, (ssgBase **)&vertices, ssgTypeVertexArray () ) || ! _ssgLoadObject ( fd, (ssgBase **)&normals, ssgTypeNormalArray () ) || ! _ssgLoadObject ( fd, (ssgBase **)&texcoords, ssgTypeTexCoordArray () ) || ! _ssgLoadObject ( fd, (ssgBase **)&colours, ssgTypeColourArray () ) ) return FALSE ; if ( vertices != NULL ) vertices -> ref () ; if ( normals != NULL ) normals -> ref () ; if ( texcoords != NULL ) texcoords -> ref () ; if ( colours != NULL ) colours -> ref () ; return TRUE ; } int ssgVtxTable::save ( FILE *fd ) { _ssgWriteVec3 ( fd, bbox.getMin() ) ; _ssgWriteVec3 ( fd, bbox.getMax() ) ; _ssgWriteInt ( fd, (int) gltype ) ; if ( ! ssgLeaf::save(fd) ) return FALSE ; if ( ! _ssgSaveObject ( fd, vertices ) || ! _ssgSaveObject ( fd, normals ) || ! _ssgSaveObject ( fd, texcoords ) || ! _ssgSaveObject ( fd, colours ) ) return FALSE ; return TRUE ; } plib-1.8.5/src/ssg/ssgKeyFlier.h0000644000175000001440000002031510765364437013373 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgKeyFlier.h 1924 2004-04-06 13:32:26Z sjbaker $ */ #ifndef _SSG_KEYFLIER_H_ #define _SSG_KEYFLIER_H_ /***********************************************\ * * * SSG_KEYFLIER.H * * * * This file contains inline functions that * * provide an ESIG-like keyboard-driven * * flying carpet flight mode. * * * * Simply declare an instance of this class * * somewhere in your program - and call the * * 'incoming_keystroke' routine every time a * * relevent character is typed - call the * * 'update' function once per frame and the * * 'get_coord' function whenever you need new * * coordinates. Other handy functions are also * * available. * * * * It's handy to use the 'Keyboard' class in * * 'tty_port.h' to provide the incoming keys. * * * \***********************************************/ typedef void (*queryFunc)(float,float,float,float,float,float) ; typedef void (*exitFunc)(int) ; class ssgKeyFlier { protected: float tscale ; float rscale ; sgCoord curr_pos ; sgCoord reset_pos ; sgCoord last_pos ; sgCoord curr_vel ; sgCoord velocity ; queryFunc query_action ; exitFunc exit_action ; public: ssgKeyFlier () { query_action = NULL ; exit_action = NULL ; tscale = 1.0 ; rscale = 1.0 ; sgZeroVec3 ( reset_pos.xyz ) ; sgZeroVec3 ( reset_pos.hpr ) ; sgZeroVec3 ( last_pos.xyz ) ; sgZeroVec3 ( last_pos.hpr ) ; sgZeroVec3 ( velocity.xyz ) ; sgZeroVec3 ( velocity.hpr ) ; update () ; } void set_query_action ( queryFunc f ) { query_action = f ; } void set_exit_action ( exitFunc f ) { exit_action = f ; } void stop_some () { velocity.xyz[0]=velocity.xyz[2]=0.0 ; sgZeroVec3 ( velocity.hpr ) ; update () ; } void stop_all () { sgZeroVec3 ( velocity.xyz ) ; sgZeroVec3 ( velocity.hpr ) ; update () ; } void reset () { stop_all () ; sgCopyVec3 ( last_pos.xyz, reset_pos.xyz ) ; sgCopyVec3 ( last_pos.hpr, reset_pos.hpr ) ; update () ; } void get_scale_factors ( float *translation_scale_factor, float *rotation_scale_factor ) { if ( rotation_scale_factor != NULL ) *rotation_scale_factor = rscale ; if ( translation_scale_factor != NULL ) *translation_scale_factor = tscale ; } /* Scale factors are in meters-per-update and degrees-per-update */ void set_scale_factors ( float translation_scale_factor, float rotation_scale_factor ) { rscale = rotation_scale_factor ; tscale = translation_scale_factor ; } void set_xyz_scale ( float translation_scale_factor ) { tscale = translation_scale_factor ; } void set_hpr_scale ( float rotation_scale_factor ) { rscale = rotation_scale_factor ; } void set_reset ( sgCoord *pos ) { sgCopyCoord ( & reset_pos, pos ) ; } sgCoord *get_velocity () { sgCopyCoord ( & curr_vel, & velocity ) ; return & curr_vel ; } void set_velocity ( sgCoord *vel ) { stop_all () ; sgCopyCoord ( & velocity, vel ) ; update () ; } sgCoord *get_coord () { sgCopyCoord ( & curr_pos, & last_pos ) ; return & curr_pos ; } void set_coord ( sgCoord *pos, int noStop = 0 ) { if ( ! noStop ) stop_all () ; sgCopyCoord ( & last_pos, pos ) ; update () ; } void show_help ( FILE *fd = stderr ) { fprintf ( fd, "ssgKeyFlier HELP.\n" ) ; fprintf ( fd, "=================\n\n" ) ; fprintf ( fd, "f : Faster - Make translational controls more sensitive.\n" ) ; fprintf ( fd, "F : Faster - Make rotational controls more sensitive.\n" ) ; fprintf ( fd, "s : Slower - Make translational controls less sensitive.\n" ) ; fprintf ( fd, "S : Slower - Make rotational controls less sensitive.\n" ) ; fprintf ( fd, "*,/: Same as 'f' and 's'.\n" ) ; fprintf ( fd, "r/R: Reset - Reset eyepoint to pre-defined position.\n" ) ; fprintf ( fd, "h/H: Help - Display this help message.\n" ) ; fprintf ( fd, "^C : - Exit.\n" ) ; fprintf ( fd, "? : - Where am I?\n" ) ; fprintf ( fd, "5 : Stop rotation & slew 0 : Stop all movement.\n"); fprintf ( fd, "2 : Pitch Up 8 : Pitch Down \n"); fprintf ( fd, "4 : Yaw Left 6 : Yaw Right\n"); fprintf ( fd, "7 : Roll Left 9 : Roll Right \n"); fprintf ( fd, "1 : Translate Left. 3 : Translate Right\n"); fprintf ( fd, "+/,: Translate Down - : Translate Up\n"); fprintf ( fd, " . : Translate Backwards ENTER : Translate Forwards\n"); fprintf ( fd, "[Note: Some of these controls may be overridden by the\n"); fprintf ( fd, " application program.].\n"); } void incoming_keystroke ( char k ) { switch ( k ) { case 'h' : case 'H' : show_help () ; break ; case '/' : case 'f' : tscale *= 2.0 ; break ; case 'F' : rscale *= 2.0 ; break ; case '*' : case 's' : tscale /= 2.0 ; break ; case 'S' : rscale /= 2.0 ; break ; case 0x03: if ( exit_action ) exit_action( 0 ) ; exit ( 1 ) ; case '?' : if ( query_action ) query_action ( last_pos.xyz[0], last_pos.xyz[1], last_pos.xyz[2], last_pos.hpr[0], last_pos.hpr[1], last_pos.hpr[2] ) ; else ulSetError ( UL_DEBUG, "ssgKeyFlier: XYZ=(%g,%g,%g), HPR=(%g,%g,%g)", last_pos.xyz[0], last_pos.xyz[1], last_pos.xyz[2], last_pos.hpr[0], last_pos.hpr[1], last_pos.hpr[2] ) ; break ; case 'r' : case 'R' : reset () ; break ; case '5' : stop_some () ; break ; case '0' : stop_all () ; break ; case '1' : velocity.xyz[0] -= tscale ; break ; case '3' : velocity.xyz[0] += tscale ; break ; case '.' : velocity.xyz[1] -= tscale ; break ; case '\n' : case '\r' : velocity.xyz[1] += tscale ; break ; case '+' : velocity.xyz[2] -= tscale ; break ; case '-' : velocity.xyz[2] += tscale ; break ; case '6' : velocity.hpr[0] -= rscale ; break ; case '4' : velocity.hpr[0] += rscale ; break ; /* Kludge to try to prevent *exact* +/-90 degree pitch terms */ case '8' : velocity.hpr[1] -= rscale+0.00001f ; break ; case '2' : velocity.hpr[1] += rscale+0.00001f ; break ; case '7' : velocity.hpr[2] -= rscale ; break ; case '9' : velocity.hpr[2] += rscale ; break ; } } int isStationary () { return ( velocity.hpr[0] == 0.0 && velocity.hpr[1] == 0.0 && velocity.hpr[2] == 0.0 && velocity.xyz[0] == 0.0 && velocity.xyz[1] == 0.0 && velocity.xyz[2] == 0.0 ) ; } virtual void update () { sgMat4 mat ; sgMat4 result ; sgMat4 delta ; /* Form new matrix */ sgMakeCoordMat4 ( delta, & velocity ) ; sgMakeCoordMat4 ( mat , & last_pos ) ; sgMultMat4 ( result, mat, delta ) ; sgSetCoord ( &last_pos, result ) ; } } ; #endif plib-1.8.5/src/ssg/ssgLeaf.cxx0000644000175000001440000001221610765364437013104 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLeaf.cxx 1952 2004-09-13 11:33:58Z wolfram_kuss $ */ #include "ssgLocal.h" //~~ T.G. moved hee from header amd ref counting accounted for void ssgLeaf::setState ( ssgState *st ) { ssgDeRefDelete ( state ) ; state = st ; if ( state != NULL ) state->ref() ; } void ssgLeaf::copy_from ( ssgLeaf *src, int clone_flags ) { ssgEntity::copy_from ( src, clone_flags ) ; cull_face = src -> getCullFace () ; ssgState *s = src -> getState () ; //~~ T.G. Deref ssgDeRefDelete(state); if ( s != NULL && ( clone_flags & SSG_CLONE_STATE ) ) state = (ssgState *)( s -> clone ( clone_flags ) ) ; else state = s ; //~~ T.G. increment ref counter if (state != NULL) state->ref(); setCallback( SSG_CALLBACK_PREDRAW, src->getCallback( SSG_CALLBACK_PREDRAW ) ); setCallback( SSG_CALLBACK_POSTDRAW, src->getCallback( SSG_CALLBACK_POSTDRAW ) ); } ssgLeaf::ssgLeaf (void) { cull_face = TRUE ; state = NULL ; type = ssgTypeLeaf () ; #ifdef _SSG_USE_DLIST dlist = 0 ; #endif preDrawCB = NULL ; postDrawCB = NULL ; } ssgLeaf::~ssgLeaf (void) { //~~ T.G. ssgDeRefDelete checks for null case ssgDeRefDelete ( state ) ; #ifdef _SSG_USE_DLIST deleteDList () ; #endif } #ifdef _SSG_USE_DLIST void ssgLeaf::deleteDList () { if ( dlist != 0 ) glDeleteLists ( dlist, 1 ) ; dlist = 0 ; } void ssgLeaf::makeDList () { deleteDList () ; /* Just to be sure */ dlist = glGenLists ( 1 ) ; glNewList ( dlist, GL_COMPILE ) ; draw_geometry () ; glEndList () ; } #endif // #ifdef _SSG_USE_DLIST void ssgLeaf::cull ( sgFrustum *f, sgMat4 m, int test_needed ) { int cull_result = cull_test ( f, m, test_needed ) ; if ( cull_result == SSG_OUTSIDE ) return ; if ( isTranslucent () ) _ssgDrawLeaf ( this ) ; else draw () ; } void ssgLeaf::hot ( sgVec3 s, sgMat4 m, int test_needed ) { int hot_result = hot_test ( s, m, test_needed ) ; if ( hot_result == SSG_OUTSIDE ) return ; /* Add polygons to hit list! */ hot_triangles ( s, m, hot_result != SSG_INSIDE ) ; } void ssgLeaf::los ( sgVec3 s, sgMat4 m, int test_needed ) { int los_result = los_test ( s, m, test_needed ) ; if ( los_result == SSG_OUTSIDE ) return ; /* Add polygons to hit list! */ los_triangles ( s, m, los_result != SSG_INSIDE ) ; } void ssgLeaf::isect ( sgSphere *s, sgMat4 m, int test_needed ) { int isect_result = isect_test ( s, m, test_needed ) ; if ( isect_result == SSG_OUTSIDE ) return ; /* Add polygons to hit list! */ isect_triangles ( s, m, isect_result != SSG_INSIDE ) ; } void ssgLeaf::getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_verts ) { *num_branches = 0 ; *num_leaves = 1 ; /* this! */ *num_tris = getNumTriangles () ; *num_verts = getNumVertices () ; } void ssgLeaf::print ( FILE *fd, char *indent, int how_much ) { if ( how_much == 0 ) return ; ssgEntity::print ( fd, indent, how_much ) ; if ( getNumParents () != getRef () ) fprintf ( fd, "****** WARNING: Ref count doesn't equal parent count!\n" ) ; if ( state != NULL ) { char in [ 100 ] ; sprintf ( in, "%s ", indent ); if ( how_much == 1 ) fprintf ( fd, "%s %s: %p\n", indent , state->getTypeName(), state) ; else state -> print ( fd, in, how_much ) ; } else fprintf ( fd, "%s No State assigned to this node\n", indent ) ; } int ssgLeaf::preDraw () { if ( preDrawCB != NULL && ! (*preDrawCB)(this) ) return FALSE ; _ssgCurrentContext->setCullface ( getCullFace() ) ; return TRUE ; } int ssgLeaf::load ( FILE *fd ) { _ssgReadInt ( fd, &cull_face ) ; ssgState *st; if ( ! _ssgLoadObject ( fd, (ssgBase **) &st, ssgTypeState () ) ) return FALSE ; if ( st != NULL && st -> isAKindOf ( ssgTypeSimpleState () ) ) { ssgSimpleState *ss = (ssgSimpleState *) st ; char *tfname = ss -> getTextureFilename () ; if ( tfname != NULL ) { ssgState *new_st = ssgGetCurrentOptions () -> createState ( tfname ) ; if ( new_st != NULL ) st = new_st ; } } setState ( st ) ; return ssgEntity::load(fd) ; } int ssgLeaf::save ( FILE *fd ) { _ssgWriteInt ( fd, cull_face ) ; if ( ! _ssgSaveObject ( fd, getState () ) ) return FALSE ; return ssgEntity::save(fd) ; } plib-1.8.5/src/ssg/ssgTexture.cxx0000644000175000001440000001332510765364437013677 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgTexture.cxx 2123 2007-09-15 13:24:45Z fayjf $ */ #include "ssgLocal.h" void ssgTexture::copy_from ( ssgTexture *src, int clone_flags ) { if ( this != src ) { /* Avoid meaningless assignments (OK) and corrupting file name (important) when copying to self */ ssgBase::copy_from ( src, clone_flags ) ; wrapu = src -> wrapu ; wrapv = src -> wrapv ; mipmap = src -> mipmap ; setFilename ( src -> getFilename () ) ; } alloc_handle () ; ssgTextureInfo info ; ssgLoadTexture( filename, &info ) ; has_alpha = (info.alpha != 0) ; setDefaultGlParams(wrapu, wrapv, mipmap); } ssgBase *ssgTexture::clone ( int clone_flags ) { ssgTexture *b = new ssgTexture ; b -> copy_from ( this, clone_flags ) ; return b ; } void ssgTexture::setDefaultGlParams(int wrapu, int wrapv, int mipmap) { glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ; glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) ; glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR ) ; glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapu ? GL_REPEAT : GL_CLAMP ) ; glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapv ? GL_REPEAT : GL_CLAMP ) ; #ifdef GL_VERSION_1_1 glBindTexture ( GL_TEXTURE_2D, 0 ) ; #else glBindTextureEXT ( GL_TEXTURE_2D, 0 ) ; #endif } ssgTexture::ssgTexture () { type = ssgTypeTexture () ; filename = NULL ; own_handle = FALSE ; handle = 0 ; wrapu = TRUE ; wrapv = TRUE ; mipmap = TRUE ; has_alpha = false ; } ssgTexture::ssgTexture ( const char *fname, GLubyte *image, int xsize, int ysize, int zsize, int _wrapu, int _wrapv ) // fname is used when saving the ssgSimpleState to disk. // If there is no associated file, you can use a dummy name. { type = ssgTypeTexture () ; filename = NULL ; own_handle = FALSE ; handle = 0 ; wrapu = _wrapu ; wrapv = _wrapv ; mipmap = TRUE ; setFilename ( fname ) ; alloc_handle () ; #if 0 ssgTextureInfo info ; ssgLoadTexture( filename, &info ) ; has_alpha = (info.alpha != 0) ; #else has_alpha = (zsize == 4) ; ssgMakeMipMaps ( image, xsize, ysize, zsize ); #endif setDefaultGlParams(wrapu, wrapv, TRUE); } ssgTexture::ssgTexture ( const char *fname, int _wrapu, int _wrapv, int _mipmap ) { type = ssgTypeTexture () ; filename = NULL ; own_handle = FALSE ; handle = 0 ; wrapu = _wrapu ; wrapv = _wrapv ; mipmap = _mipmap ; setFilename ( fname ) ; alloc_handle () ; ssgTextureInfo info ; ssgLoadTexture( filename, &info ) ; has_alpha = (info.alpha != 0) ; setDefaultGlParams(wrapu, wrapv, mipmap); } ssgTexture::~ssgTexture (void) { setFilename ( NULL ) ; free_handle () ; } void ssgTexture::alloc_handle () { free_handle () ; own_handle = TRUE ; #ifdef GL_VERSION_1_1 glGenTextures ( 1, & handle ) ; glBindTexture ( GL_TEXTURE_2D, handle ) ; #else /* This is only useful on some ancient SGI hardware */ glGenTexturesEXT ( 1, & handle ) ; glBindTextureEXT ( GL_TEXTURE_2D, handle ) ; #endif } void ssgTexture::free_handle () { if ( handle != 0 ) { if ( own_handle ) { #ifdef GL_VERSION_1_1 glDeleteTextures ( 1, & handle ) ; #else /* This is only useful on some ancient SGI hardware */ glDeleteTexturesEXT ( 1, & handle ) ; #endif } own_handle = FALSE ; handle = 0 ; } } void ssgTexture::setHandle ( GLuint _handle ) { free_handle () ; own_handle = FALSE ; handle = _handle ; } void ssgTexture::print ( FILE *fd, char *ident, int how_much ) { fprintf ( fd, "%s%s: %s\n", ident, getTypeName (), getFilename () ) ; } int ssgTexture::load ( FILE *fd ) { delete [] filename ; _ssgReadString ( fd, & filename ) ; _ssgReadInt ( fd, & wrapu ) ; _ssgReadInt ( fd, & wrapv ) ; _ssgReadInt ( fd, & mipmap ) ; alloc_handle () ; ssgTextureInfo info ; ssgLoadTexture( filename, &info ) ; has_alpha = (info.alpha != 0) ; setDefaultGlParams(wrapu, wrapv, mipmap); return ssgBase::load ( fd ) ; } int ssgTexture::save ( FILE *fd ) { _ssgWriteString ( fd, filename ) ; _ssgWriteInt ( fd, wrapu ) ; _ssgWriteInt ( fd, wrapv ) ; _ssgWriteInt ( fd, mipmap ) ; return ssgBase::save ( fd ) ; } void ssgTextureArray::add ( ssgTexture* tex ) { if ( tex ) { tex -> ref () ; raw_add ( (char *) &tex ) ; } } void ssgTextureArray::removeAll () { for ( int i = 0; i < getNum (); i++ ) ssgDeRefDelete ( get (i) ) ; ssgSimpleList::removeAll () ; } ssgTexture* ssgTextureArray::findByFilename ( const char* fname ) { for ( int i = 0; i < getNum (); i++ ) { ssgTexture *tex = get (i) ; if ( ulStrEqual ( fname, tex->getFilename() ) ) return tex ; } return NULL ; } plib-1.8.5/src/ssg/ssgLoadDXF.cxx0000644000175000001440000006172710765364437013471 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadDXF.cxx 1673 2002-09-15 01:29:12Z ude $ */ // // DXF loader for SSG/PLIB // Ported from IVCON by Dave McClurg (dpm@efn.org) in March-2000 // IVCON::dxf_read() by John Burkardt, 23 May 1999 // Added better support for meshes, August 2001 // Added support for colors, blocks and block references, September 2001 // #include "ssgLocal.h" #define MAX_LINE_LEN 1024 class dxfVert { public: sgVec3 pos ; int color_index ; int isEqual ( class dxfVert * other ); } ; class dxfVertArray : public ssgSimpleList { public: dxfVertArray () : ssgSimpleList ( sizeof(dxfVert), 0, NULL ) {} dxfVert *get ( unsigned int n ) { return (dxfVert *) raw_get ( n ) ; } void add ( const dxfVert* thing ) { raw_add ( (char *) thing ) ; } ; } ; struct dxfMesh { int flags; int size[2]; int vlist[4]; int vnum; } ; enum Entities { ENT_NONE, ENT_LINE, ENT_FACE, ENT_POLYLINE, ENT_VERTEX, ENT_INSERT }; static int ent_type = ENT_NONE ; static const ssgLoaderOptions* current_options = NULL ; static ssgState* current_state = NULL ; static ssgBranch* top_branch = NULL ; static ssgBranch* current_block = NULL ; static ssgBranch* blocks = NULL ; static int num_line; static int num_face; static dxfVertArray tempvert; static dxfVertArray linevert; static dxfVertArray facevert; static dxfVertArray meshvert; static dxfMesh mesh; static int cflags; static sgVec3 cvec; static sgVec3 scale_vec; static float rot_angle; static char* block_name; static int color_index ; static float dxf_colors [256][3] = { { 0.0000f, 0.0000f, 0.0000f }, { 1.0000f, 0.0000f, 0.0000f }, { 1.0000f, 1.0000f, 0.0000f }, { 0.0000f, 1.0000f, 0.0000f }, { 0.0000f, 1.0000f, 1.0000f }, { 0.0000f, 0.0000f, 1.0000f }, { 1.0000f, 0.0000f, 1.0000f }, { 0.0000f, 0.0000f, 0.0000f }, { 0.0000f, 0.0000f, 0.0000f }, { 0.0000f, 0.0000f, 0.0000f }, { 1.0000f, 0.0000f, 0.0000f }, { 1.0000f, 0.5000f, 0.5000f }, { 0.6500f, 0.0000f, 0.0000f }, { 0.6500f, 0.3250f, 0.3250f }, { 0.5000f, 0.0000f, 0.0000f }, { 0.5000f, 0.2500f, 0.2500f }, { 0.3000f, 0.0000f, 0.0000f }, { 0.3000f, 0.1500f, 0.1500f }, { 0.1500f, 0.0000f, 0.0000f }, { 0.1500f, 0.0750f, 0.0750f }, { 1.0000f, 0.2500f, 0.0000f }, { 1.0000f, 0.6250f, 0.5000f }, { 0.6500f, 0.1625f, 0.0000f }, { 0.6500f, 0.4063f, 0.3250f }, { 0.5000f, 0.1250f, 0.0000f }, { 0.5000f, 0.3125f, 0.2500f }, { 0.3000f, 0.0750f, 0.0000f }, { 0.3000f, 0.1875f, 0.1500f }, { 0.1500f, 0.0375f, 0.0000f }, { 0.1500f, 0.0938f, 0.0750f }, { 1.0000f, 0.5000f, 0.0000f }, { 1.0000f, 0.7500f, 0.5000f }, { 0.6500f, 0.3250f, 0.0000f }, { 0.6500f, 0.4875f, 0.3250f }, { 0.5000f, 0.2500f, 0.0000f }, { 0.5000f, 0.3750f, 0.2500f }, { 0.3000f, 0.1500f, 0.0000f }, { 0.3000f, 0.2250f, 0.1500f }, { 0.1500f, 0.0750f, 0.0000f }, { 0.1500f, 0.1125f, 0.0750f }, { 1.0000f, 0.7500f, 0.0000f }, { 1.0000f, 0.8750f, 0.5000f }, { 0.6500f, 0.4875f, 0.0000f }, { 0.6500f, 0.5688f, 0.3250f }, { 0.5000f, 0.3750f, 0.0000f }, { 0.5000f, 0.4375f, 0.2500f }, { 0.3000f, 0.2250f, 0.0000f }, { 0.3000f, 0.2625f, 0.1500f }, { 0.1500f, 0.1125f, 0.0000f }, { 0.1500f, 0.1313f, 0.0750f }, { 1.0000f, 1.0000f, 0.0000f }, { 1.0000f, 1.0000f, 0.5000f }, { 0.6500f, 0.6500f, 0.0000f }, { 0.6500f, 0.6500f, 0.3250f }, { 0.5000f, 0.5000f, 0.0000f }, { 0.5000f, 0.5000f, 0.2500f }, { 0.3000f, 0.3000f, 0.0000f }, { 0.3000f, 0.3000f, 0.1500f }, { 0.1500f, 0.1500f, 0.0000f }, { 0.1500f, 0.1500f, 0.0750f }, { 0.7500f, 1.0000f, 0.0000f }, { 0.8750f, 1.0000f, 0.5000f }, { 0.4875f, 0.6500f, 0.0000f }, { 0.5688f, 0.6500f, 0.3250f }, { 0.3750f, 0.5000f, 0.0000f }, { 0.4375f, 0.5000f, 0.2500f }, { 0.2250f, 0.3000f, 0.0000f }, { 0.2625f, 0.3000f, 0.1500f }, { 0.1125f, 0.1500f, 0.0000f }, { 0.1313f, 0.1500f, 0.0750f }, { 0.5000f, 1.0000f, 0.0000f }, { 0.7500f, 1.0000f, 0.5000f }, { 0.3250f, 0.6500f, 0.0000f }, { 0.4875f, 0.6500f, 0.3250f }, { 0.2500f, 0.5000f, 0.0000f }, { 0.3750f, 0.5000f, 0.2500f }, { 0.1500f, 0.3000f, 0.0000f }, { 0.2250f, 0.3000f, 0.1500f }, { 0.0750f, 0.1500f, 0.0000f }, { 0.1125f, 0.1500f, 0.0750f }, { 0.2500f, 1.0000f, 0.0000f }, { 0.6250f, 1.0000f, 0.5000f }, { 0.1625f, 0.6500f, 0.0000f }, { 0.4063f, 0.6500f, 0.3250f }, { 0.1250f, 0.5000f, 0.0000f }, { 0.3125f, 0.5000f, 0.2500f }, { 0.0750f, 0.3000f, 0.0000f }, { 0.1875f, 0.3000f, 0.1500f }, { 0.0375f, 0.1500f, 0.0000f }, { 0.0938f, 0.1500f, 0.0750f }, { 0.0000f, 1.0000f, 0.0000f }, { 0.5000f, 1.0000f, 0.5000f }, { 0.0000f, 0.6500f, 0.0000f }, { 0.3250f, 0.6500f, 0.3250f }, { 0.0000f, 0.5000f, 0.0000f }, { 0.2500f, 0.5000f, 0.2500f }, { 0.0000f, 0.3000f, 0.0000f }, { 0.1500f, 0.3000f, 0.1500f }, { 0.0000f, 0.1500f, 0.0000f }, { 0.0750f, 0.1500f, 0.0750f }, { 0.0000f, 1.0000f, 0.2500f }, { 0.5000f, 1.0000f, 0.6250f }, { 0.0000f, 0.6500f, 0.1625f }, { 0.3250f, 0.6500f, 0.4063f }, { 0.0000f, 0.5000f, 0.1250f }, { 0.2500f, 0.5000f, 0.3125f }, { 0.0000f, 0.3000f, 0.0750f }, { 0.1500f, 0.3000f, 0.1875f }, { 0.0000f, 0.1500f, 0.0375f }, { 0.0750f, 0.1500f, 0.0938f }, { 0.0000f, 1.0000f, 0.5000f }, { 0.5000f, 1.0000f, 0.7500f }, { 0.0000f, 0.6500f, 0.3250f }, { 0.3250f, 0.6500f, 0.4875f }, { 0.0000f, 0.5000f, 0.2500f }, { 0.2500f, 0.5000f, 0.3750f }, { 0.0000f, 0.3000f, 0.1500f }, { 0.1500f, 0.3000f, 0.2250f }, { 0.0000f, 0.1500f, 0.0750f }, { 0.0750f, 0.1500f, 0.1125f }, { 0.0000f, 1.0000f, 0.7500f }, { 0.5000f, 1.0000f, 0.8750f }, { 0.0000f, 0.6500f, 0.4875f }, { 0.3250f, 0.6500f, 0.5688f }, { 0.0000f, 0.5000f, 0.3750f }, { 0.2500f, 0.5000f, 0.4375f }, { 0.0000f, 0.3000f, 0.2250f }, { 0.1500f, 0.3000f, 0.2625f }, { 0.0000f, 0.1500f, 0.1125f }, { 0.0750f, 0.1500f, 0.1313f }, { 0.0000f, 1.0000f, 1.0000f }, { 0.5000f, 1.0000f, 1.0000f }, { 0.0000f, 0.6500f, 0.6500f }, { 0.3250f, 0.6500f, 0.6500f }, { 0.0000f, 0.5000f, 0.5000f }, { 0.2500f, 0.5000f, 0.5000f }, { 0.0000f, 0.3000f, 0.3000f }, { 0.1500f, 0.3000f, 0.3000f }, { 0.0000f, 0.1500f, 0.1500f }, { 0.0750f, 0.1500f, 0.1500f }, { 0.0000f, 0.7500f, 1.0000f }, { 0.5000f, 0.8750f, 1.0000f }, { 0.0000f, 0.4875f, 0.6500f }, { 0.3250f, 0.5688f, 0.6500f }, { 0.0000f, 0.3750f, 0.5000f }, { 0.2500f, 0.4375f, 0.5000f }, { 0.0000f, 0.2250f, 0.3000f }, { 0.1500f, 0.2625f, 0.3000f }, { 0.0000f, 0.1125f, 0.1500f }, { 0.0750f, 0.1313f, 0.1500f }, { 0.0000f, 0.5000f, 1.0000f }, { 0.5000f, 0.7500f, 1.0000f }, { 0.0000f, 0.3250f, 0.6500f }, { 0.3250f, 0.4875f, 0.6500f }, { 0.0000f, 0.2500f, 0.5000f }, { 0.2500f, 0.3750f, 0.5000f }, { 0.0000f, 0.1500f, 0.3000f }, { 0.1500f, 0.2250f, 0.3000f }, { 0.0000f, 0.0750f, 0.1500f }, { 0.0750f, 0.1125f, 0.1500f }, { 0.0000f, 0.2500f, 1.0000f }, { 0.5000f, 0.6250f, 1.0000f }, { 0.0000f, 0.1625f, 0.6500f }, { 0.3250f, 0.4063f, 0.6500f }, { 0.0000f, 0.1250f, 0.5000f }, { 0.2500f, 0.3125f, 0.5000f }, { 0.0000f, 0.0750f, 0.3000f }, { 0.1500f, 0.1875f, 0.3000f }, { 0.0000f, 0.0375f, 0.1500f }, { 0.0750f, 0.0938f, 0.1500f }, { 0.0000f, 0.0000f, 1.0000f }, { 0.5000f, 0.5000f, 1.0000f }, { 0.0000f, 0.0000f, 0.6500f }, { 0.3250f, 0.3250f, 0.6500f }, { 0.0000f, 0.0000f, 0.5000f }, { 0.2500f, 0.2500f, 0.5000f }, { 0.0000f, 0.0000f, 0.3000f }, { 0.1500f, 0.1500f, 0.3000f }, { 0.0000f, 0.0000f, 0.1500f }, { 0.0750f, 0.0750f, 0.1500f }, { 0.2500f, 0.0000f, 1.0000f }, { 0.6250f, 0.5000f, 1.0000f }, { 0.1625f, 0.0000f, 0.6500f }, { 0.4063f, 0.3250f, 0.6500f }, { 0.1250f, 0.0000f, 0.5000f }, { 0.3125f, 0.2500f, 0.5000f }, { 0.0397f, 0.0000f, 0.3000f }, { 0.1875f, 0.1500f, 0.3000f }, { 0.0375f, 0.0000f, 0.1500f }, { 0.0938f, 0.0750f, 0.1500f }, { 0.5000f, 0.0000f, 1.0000f }, { 0.7500f, 0.5000f, 1.0000f }, { 0.3250f, 0.0000f, 0.6500f }, { 0.4875f, 0.3250f, 0.6500f }, { 0.2500f, 0.0000f, 0.5000f }, { 0.3750f, 0.2500f, 0.5000f }, { 0.1500f, 0.0000f, 0.3000f }, { 0.2250f, 0.1500f, 0.3000f }, { 0.0750f, 0.0000f, 0.1500f }, { 0.1125f, 0.0750f, 0.1500f }, { 0.7500f, 0.0000f, 1.0000f }, { 0.8750f, 0.5000f, 1.0000f }, { 0.4875f, 0.0000f, 0.6500f }, { 0.5688f, 0.3250f, 0.6500f }, { 0.3750f, 0.0000f, 0.5000f }, { 0.4375f, 0.2500f, 0.5000f }, { 0.2250f, 0.0000f, 0.3000f }, { 0.2625f, 0.1500f, 0.3000f }, { 0.1125f, 0.0000f, 0.1500f }, { 0.1313f, 0.0750f, 0.1500f }, { 1.0000f, 0.0000f, 1.0000f }, { 1.0000f, 0.5000f, 1.0000f }, { 0.6500f, 0.0000f, 0.6500f }, { 0.6500f, 0.3250f, 0.6500f }, { 0.5000f, 0.0000f, 0.5000f }, { 0.5000f, 0.2500f, 0.5000f }, { 0.3000f, 0.0000f, 0.3000f }, { 0.3000f, 0.1500f, 0.3000f }, { 0.1500f, 0.0000f, 0.1500f }, { 0.1500f, 0.0750f, 0.1500f }, { 1.0000f, 0.0000f, 0.7500f }, { 1.0000f, 0.5000f, 0.8750f }, { 0.6500f, 0.0000f, 0.4875f }, { 0.6500f, 0.3250f, 0.5688f }, { 0.5000f, 0.0000f, 0.3750f }, { 0.5000f, 0.2500f, 0.4375f }, { 0.3000f, 0.0000f, 0.2250f }, { 0.3000f, 0.1500f, 0.2625f }, { 0.1500f, 0.0000f, 0.1125f }, { 0.1500f, 0.0750f, 0.1313f }, { 1.0000f, 0.0000f, 0.5000f }, { 1.0000f, 0.5000f, 0.7500f }, { 0.6500f, 0.0000f, 0.3250f }, { 0.6500f, 0.3250f, 0.4875f }, { 0.5000f, 0.0000f, 0.2500f }, { 0.5000f, 0.2500f, 0.3750f }, { 0.3000f, 0.0000f, 0.1500f }, { 0.3000f, 0.1500f, 0.2250f }, { 0.1500f, 0.0000f, 0.0750f }, { 0.1500f, 0.0750f, 0.1125f }, { 1.0000f, 0.0000f, 0.2500f }, { 1.0000f, 0.5000f, 0.6250f }, { 0.6500f, 0.0000f, 0.1625f }, { 0.6500f, 0.3250f, 0.4063f }, { 0.5000f, 0.0000f, 0.1250f }, { 0.5000f, 0.2500f, 0.3125f }, { 0.3000f, 0.0000f, 0.0750f }, { 0.3000f, 0.1500f, 0.1875f }, { 0.1500f, 0.0000f, 0.0375f }, { 0.1500f, 0.0750f, 0.0938f }, { 0.3300f, 0.3300f, 0.3300f }, { 0.4640f, 0.4640f, 0.4640f }, { 0.5980f, 0.5980f, 0.5980f }, { 0.7320f, 0.7320f, 0.7320f }, { 0.8660f, 0.8660f, 0.8660f }, { 1.0000f, 1.0000f, 1.0000f }, }; int dxfVert::isEqual ( class dxfVert * other ) // compares strictly (without epsilon) { if ( color_index != other->color_index ) return FALSE; return sgCompareVec3 ( pos, other->pos, 0.0 ); } /*static void copy_vert ( dxfVert& dst, const dxfVert& src ) { dst.color_index = src.color_index ; sgCopyVec3 ( dst.pos, src.pos ) ; }*/ static void add_tri ( const dxfVert* p, const dxfVert* q, const dxfVert* r ) { facevert.add ( p ) ; facevert.add ( q ) ; facevert.add ( r ) ; num_face ++; } static void add_face ( void ) { int num_vert = tempvert.getNum() ; if ( num_vert >= 4 ) //quad? if ( tempvert.get(3)->isEqual ( tempvert.get(2) ) ) // pseudo quad. num_vert=3; if ( num_vert >= 3 ) { if ( num_vert >= 4 ) //quad? { add_tri ( tempvert.get(0), tempvert.get(1), tempvert.get(3) ) ; add_tri ( tempvert.get(3), tempvert.get(1), tempvert.get(2) ) ; } else //triangle { add_tri ( tempvert.get(0), tempvert.get(1), tempvert.get(2) ) ; } } } static void dxf_flush ( void ) { int num_vert = tempvert.getNum() ; if ( ent_type == ENT_LINE ) { if ( num_vert >= 2 ) { linevert.add( tempvert.get(0) ) ; linevert.add( tempvert.get(1) ) ; num_line ++; } } else if ( ent_type == ENT_FACE ) { add_face () ; } else if ( ent_type == ENT_POLYLINE ) { mesh.flags = cflags; meshvert.removeAll(); mesh.size[0] = mesh.vlist[0]; mesh.size[1] = mesh.vlist[1]; } else if ( ent_type == ENT_INSERT ) { if ( block_name != NULL ) { //block_name ssgEntity* found = blocks -> getByName ( block_name ) ; if ( found != NULL ) { //cvec //scale_vec //rot_angle sgMat4 mat, tmp; sgVec3 axis = { 0.0f, 0.0f, 1.0f }; sgMakeRotMat4 ( mat, rot_angle, axis ) ; sgMakeIdentMat4 ( tmp ) ; sgScaleVec4 ( tmp[0], scale_vec[0] ); sgScaleVec4 ( tmp[1], scale_vec[1] ); sgScaleVec4 ( tmp[2], scale_vec[2] ); sgPostMultMat4 ( mat, tmp ) ; sgMakeTransMat4 ( tmp, cvec ) ; sgPostMultMat4 ( mat, tmp ) ; //printf("cvec(%.2f,%.2f,%.2f), scale(%.2f,%.2f,%.2f), rot(%.2f)\n", // cvec[0], cvec[1], cvec[2], cvec[0], cvec[1], cvec[2], rot_angle ) ; //found -> print ( stderr, "", 99 ); ssgTransform* block_tr = new ssgTransform ; block_tr -> setName ( block_name ) ; block_tr -> setTransform ( mat ) ; block_tr -> addKid ( found ) ; top_branch -> addKid ( block_tr ) ; } } } else if ( ent_type == ENT_VERTEX ) { if ( (mesh.flags & 8) != 0 ) { //This is a 3D Polyline if ( (cflags & 32) != 0 ) { //This is a 3D Polyline vertex meshvert.add ( tempvert.get(0) ) ; } } else if ( (mesh.flags & 16) != 0 ) { //This is a 3D polygon MxN mesh. (uniform grid) if ( (cflags & 64) != 0 ) { //This is a 3D polygon mesh vertex meshvert.add ( tempvert.get(0) ) ; } } else if ( (mesh.flags & 64) != 0 ) { //This Polyline is a polyface mesh. if ( (cflags & 128) != 0 ) { if ( (cflags & 64) != 0 ) { //This is a 3D polygon mesh vertex meshvert.add ( tempvert.get(0) ) ; } else if ( mesh.vnum >= 3 ) { //copy each vertex where the first is numbered 1 tempvert.removeAll(); int error = 0; for ( int i=0; i 0 && ival <= meshvert.getNum() ) tempvert.add ( meshvert.get(ival-1) ) ; else error = 1; } if ( error == 0 ) add_face () ; } } } } cflags = 0; cvec[0] = 0.0f; cvec[1] = 0.0f; cvec[2] = 0.0f; scale_vec[0] = 1.0f; scale_vec[1] = 1.0f; scale_vec[2] = 1.0f; rot_angle = 0.0f; color_index = 7 ; tempvert.removeAll(); mesh.vnum = 0 ; mesh.vlist[0] = 0; mesh.vlist[1] = 0; mesh.vlist[2] = 0; mesh.vlist[3] = 0; delete[] block_name; block_name = NULL; } static void dxf_free () { tempvert.removeAll(); linevert.removeAll() ; facevert.removeAll() ; meshvert.removeAll() ; num_line = 0; num_face = 0; ent_type = ENT_NONE; } static sgVec4& get_color ( int ci ) { if ( ci < 0 ) ci = 0 ; else if ( ci > 255 ) ci = 255 ; float* rgb = dxf_colors[ci]; static sgVec4 color ; sgSetVec4 ( color, rgb[0], rgb[1], rgb[2], 1.0f ) ; return color ; } static void dxf_create ( ssgBranch* br ) { dxf_flush () ; //create ssg nodes if ( num_face ) { int num_vert = facevert.getNum () ; ssgVertexArray* vlist = new ssgVertexArray ( num_vert ) ; ssgColourArray* clist = new ssgColourArray ( num_vert ) ; ssgNormalArray* nlist = new ssgNormalArray ( num_vert ) ; sgVec3 normal ; for ( int i=0; i pos, facevert.get(i+1) -> pos, facevert.get(i+2) -> pos ) ; } vlist -> add ( facevert.get(i) -> pos ) ; nlist -> add ( normal ) ; clist -> add ( get_color( facevert.get(i) -> color_index ) ) ; } ssgVtxTable *vtab = new ssgVtxTable ( GL_TRIANGLES, vlist, nlist, 0, clist ); vtab -> setState ( current_state ) ; br -> addKid ( vtab ) ; } if ( num_line ) { int num_vert = linevert.getNum () ; ssgVertexArray* vlist = new ssgVertexArray ( num_vert ) ; ssgColourArray* clist = new ssgColourArray ( num_vert ) ; for ( int i=0; i add ( linevert.get(i) -> pos ) ; clist -> add ( get_color(linevert.get(i) -> color_index) ) ; } ssgVtxTable *vtab = new ssgVtxTable ( GL_LINES, vlist, 0, 0, clist ); vtab -> setState ( current_state ) ; br -> addKid ( vtab ) ; } dxf_free () ; } static int dxf_read ( FILE *filein ) { dxf_free () ; /* Read the next two lines of the file into INPUT1 and INPUT2. */ for ( ;; ) { int count; int code; int width; char input1[MAX_LINE_LEN]; char input2[MAX_LINE_LEN]; /* INPUT1 should contain a single integer, which tells what INPUT2 will contain. */ if ( fgets ( input1, MAX_LINE_LEN, filein ) == NULL ) { break; } count = sscanf ( input1, "%d%n", &code, &width ); if ( count <= 0 ) { break; } /* Read the second line, and interpret it according to the code. */ if ( fgets ( input2, MAX_LINE_LEN, filein ) == NULL ) { break; } if ( code == 0 ) { dxf_flush () ; //set ent_type if ( strncmp( input2, "LINE", 4 ) == 0 ) ent_type = ENT_LINE ; else if ( strncmp( input2, "3DFACE", 6 ) == 0 ) ent_type = ENT_FACE ; else if ( strncmp( input2, "POLYLINE", 8 ) == 0 ) ent_type = ENT_POLYLINE ; else if ( strncmp( input2, "VERTEX", 6 ) == 0 ) ent_type = ENT_VERTEX; else if ( strncmp( input2, "INSERT", 6 ) == 0 ) ent_type = ENT_INSERT; else if ( strncmp( input2, "BLOCK", 5 ) == 0 ) { if ( current_block == NULL ) { current_block = new ssgBranch ; blocks -> addKid ( current_block ) ; } } else if ( strncmp( input2, "ENDBLK", 6 ) == 0 ) { if ( current_block != NULL ) { dxf_create ( current_block ) ; current_block = NULL ; } } else if ( strncmp( input2, "SEQEND", 6 ) == 0 ) { #define PL_CLOSED_IN_M 0x01 #define PL_CURVE_FIT_ADDED 0x02 #define PL_SPLINE_FIT_ADDED 0x04 #define PL_3D_POLYLINE 0x08 #define PL_3D_MESH 0x10 #define PL_CLOSED_IN_N 0x20 #define PL_POLYFACE_MESH 0x40 #define PL_USE_LINETYPE 0x80 int polyline_flags = mesh.flags ; if ( (polyline_flags & PL_3D_POLYLINE) != 0 ) { //This is a 3D Polyline int last = 0; int i = 1; int num_vert = meshvert.getNum () ; if ( (polyline_flags & (PL_CLOSED_IN_M|PL_CLOSED_IN_N)) != 0 ) { //Polyline is closed last = num_vert - 1; i = 0; } for ( ; i= ( mesh.size[0] * mesh.size[1] ) ) { int mesh_m = mesh.size[0]; int mesh_n = mesh.size[1]; dxfVert *buff[2]; buff[0] = meshvert.get(0); buff[1] = meshvert.get(mesh_n); /* create triangles */ int i,j; for (i=1;igetName() == NULL ) { char* name = ulStrDup ( input2 ) ; current_block->setName( name ) ; } } } else if ( ch == '0' || ch == '1' || ch == '2' || ch == '3' ) { float rval; count = sscanf ( input2, "%e%n", &rval, &width ); switch ( input1[cpos] ) { case '1': cvec[0] = rval; break; case '2': cvec[1] = rval; break; case '3': cvec[2] = rval; { dxfVert vert ; vert.color_index = color_index ; sgCopyVec3 ( vert.pos, cvec ) ; tempvert.add ( &vert ) ; } break; } } } else if ( input1[cpos] == '4' ) { float rval; count = sscanf ( input2, "%e%n", &rval, &width ); switch ( input1[cpos+1] ) { case '1': scale_vec[0] = rval; break; case '2': scale_vec[1] = rval; break; case '3': scale_vec[2] = rval; break; } } else if ( input1[cpos] == '5' ) { char ch = input1[cpos+1]; if ( ch == '0' ) { count = sscanf ( input2, "%e%n", &rot_angle, &width ); } } else if ( input1[cpos] == '6' ) { if ( input1[cpos+1] == '2' ) { count = sscanf ( input2, "%d%n", &color_index, &width ); } } else if ( input1[cpos] == '7' ) { int ival ; count = sscanf ( input2, "%d%n", &ival, &width ); switch ( input1[cpos+1] ) { case '0': cflags = ival; break; case '1': mesh.vlist[0] = ival; mesh.vnum = 1; break; case '2': mesh.vlist[1] = ival; mesh.vnum = 2; break; case '3': mesh.vlist[2] = ival; mesh.vnum = 3; break; case '4': mesh.vlist[3] = ival; mesh.vnum = 4; break; } } } } dxf_create ( top_branch ) ; return TRUE; } static ssgState *make_state () { ssgSimpleState *st = new ssgSimpleState () ; sgVec4 spec = { 0.0f, 0.0f, 0.0f, 1.0f }; sgVec4 emis = { 0.0f, 0.0f, 0.0f, 1.0f } ; float shi = { 0.0f } ; st -> setMaterial ( GL_SPECULAR, spec ) ; st -> setMaterial ( GL_EMISSION, emis ) ; st -> setShininess ( shi ) ; st -> enable ( GL_COLOR_MATERIAL ) ; st -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; st -> enable ( GL_LIGHTING ) ; st -> setShadeModel ( GL_SMOOTH ) ; st -> disable ( GL_BLEND ) ; st -> setOpaque () ; st -> disable( GL_TEXTURE_2D ) ; return st ; } ssgEntity *ssgLoadDXF ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; top_branch = NULL ; char filename [ 1024 ] ; current_options -> makeModelPath ( filename, fname ) ; FILE *loader_fd = fopen ( filename, "ra" ) ; if ( loader_fd == NULL ) { ulSetError ( UL_WARNING, "ssgLoadDXF: Failed to open '%s' for reading", filename ) ; return NULL ; } top_branch = new ssgTransform () ; blocks = new ssgBranch ; current_state = make_state () ; blocks -> ref () ; current_state -> ref () ; dxf_read ( loader_fd ) ; fclose ( loader_fd ) ; ssgDeRefDelete ( current_state ) ; ssgDeRefDelete ( blocks ) ; return top_branch ; } plib-1.8.5/src/ssg/ssgSimpleList.cxx0000644000175000001440000001204610765364437014323 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSimpleList.cxx 2057 2005-12-06 14:25:18Z bram $ */ #include "ssgLocal.h" void ssgSimpleList::copy_from ( ssgSimpleList *src, int clone_flags ) { ssgBase::copy_from ( src, clone_flags ) ; if ( own_mem ) delete [] list ; size_of = src -> getSizeOf () ; total = src -> getNum () ; limit = total ; list = new char [ limit * size_of ] ; own_mem = true ; memcpy ( list, src->raw_get ( 0 ), limit * size_of ) ; } ssgBase *ssgSimpleList::clone ( int clone_flags ) { ssgSimpleList *b = new ssgSimpleList () ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgNormalArray::clone ( int clone_flags ) { ssgNormalArray *b = new ssgNormalArray () ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgVertexArray::clone ( int clone_flags ) { ssgVertexArray *b = new ssgVertexArray () ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgTexCoordArray::clone ( int clone_flags ) { ssgTexCoordArray *b = new ssgTexCoordArray () ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgColourArray::clone ( int clone_flags ) { ssgColourArray *b = new ssgColourArray () ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgIndexArray::clone ( int clone_flags ) { ssgIndexArray *b = new ssgIndexArray () ; b -> copy_from ( this, clone_flags ) ; return b ; } void ssgVertexArray::print ( FILE *fd, char *indent, int how_much ) { ssgSimpleList::print ( fd, indent, how_much ) ; if ( how_much < 4 ) return; for ( unsigned int i = 0 ; i < total ; i++ ) fprintf ( fd, "%s V%d) { %f, %f, %f }\n", indent, i, get(i)[0], get(i)[1], get(i)[2] ) ; } void ssgNormalArray::print ( FILE *fd, char *indent, int how_much ) { ssgSimpleList::print ( fd, indent, how_much ) ; if ( how_much < 4 ) return; for ( unsigned int i = 0 ; i < total ; i++ ) fprintf ( fd, "%s N%d) { %f, %f, %f }\n", indent, i, get(i)[0], get(i)[1], get(i)[2] ) ; } void ssgIndexArray::print ( FILE *fd, char *indent, int how_much ) { ssgSimpleList::print ( fd, indent, how_much ) ; if ( how_much < 4 ) return; for ( unsigned int i = 0 ; i < total ; i++ ) fprintf ( fd, "%s I%d) { %d }\n", indent, i, (int) (*get(i)) ) ; } void ssgTexCoordArray::print ( FILE *fd, char *indent, int how_much ) { ssgSimpleList::print ( fd, indent, how_much ) ; if ( how_much < 4 ) return; for ( unsigned int i = 0 ; i < total ; i++ ) fprintf ( fd, "%s T%d) { S=%f, T=%f }\n", indent, i, get(i)[0], get(i)[1] ) ; } void ssgColourArray::print ( FILE *fd, char *indent, int how_much ) { ssgSimpleList::print ( fd, indent, how_much ) ; if ( how_much < 4 ) return; for ( unsigned int i = 0 ; i < total ; i++ ) fprintf ( fd, "%s C%d) { R=%f, G=%f, B=%f, A=%f }\n", indent, i, get(i)[0], get(i)[1], get(i)[2], get(i)[3] ) ; } void ssgSimpleList::print ( FILE *fd, char *indent, int how_much ) { ssgBase::print ( fd, indent, how_much ) ; fprintf ( fd, "%s Total # items = %d\n", indent, total ) ; if ( how_much < 3 ) return; fprintf ( fd, "%s Size of items = %d bytes\n", indent, size_of ) ; } int ssgSimpleList::load ( FILE *fd ) { delete [] list ; _ssgReadUInt ( fd, &size_of ) ; _ssgReadUInt ( fd, &total ) ; limit = total ; list = new char [ limit * size_of ] ; assert(list!=NULL); // wk: The old code: //_ssgReadFloat ( fd, limit * size_of / sizeof(float), (float *)list ) ; // doesn't work since some ssgSimpleLists consist of shorts, so // limit * size_of may not be divisible by sizeof(float). // The new code works, but I am not 100% sure what we want in // the event that there are machines with another sizeof(float). _ssgReadBytes ( fd, limit * size_of , list) ; return ! _ssgReadError () ; } int ssgSimpleList::save ( FILE *fd ) { _ssgWriteUInt ( fd, size_of ) ; _ssgWriteUInt ( fd, total ) ; // see comment in ssgSimpleList::load // _ssgWriteFloat( fd, total * size_of / sizeof(float), (float *)list ) ; _ssgWriteBytes ( fd, total * size_of, list); return ! _ssgWriteError () ; } plib-1.8.5/src/ssg/ssgSaveOFF.cxx0000644000175000001440000000450310765364437013466 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgSaveOFF.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ /* .off writer for SSG/PLIB Warning: There are two formats called OFF, see comment in ssgLoadOFF Written by Wolfram Kuss (Wolfram.Kuss@t-online.de) in February 2001 We only support 2D and 3D data */ #include #include "ssgLocal.h" #include "ssgLoaderWriterStuff.h" int ssgSaveOFF( const char* fname, ssgEntity *ent ) { FILE *fd = fopen ( fname, "w" ) ; int i; if ( fd == NULL ) { ulSetError ( UL_WARNING, "ssgSaveOFF: Failed to open '%s' for writing", fname ); return FALSE ; } ssgVertexArray* vertices = new ssgVertexArray(); ssgIndexArray* indices = new ssgIndexArray (); fprintf(fd, "# Model output by ssgSaveOFF. Original graph structure was:\n"); ent->print(fd, "#", 0); sgMat4 ident; sgMakeIdentMat4( ident ); ssgAccumVerticesAndFaces( ent, ident, vertices, indices, -1 ); fprintf(fd, "nOFF\n3\n"); // 3 dimensions fprintf(fd, "%d %d 0\n", vertices->getNum(), indices->getNum()/3 ); for (i = 0; i < vertices->getNum(); i++) { fprintf(fd, "%f %f %f\n", vertices->get(i)[0], vertices->get(i)[1], vertices->get(i)[2]); } for (i = 0; i < indices->getNum(); i += 3) { fprintf(fd, "3 %d %d %d\n", *indices->get(i ) , *indices->get(i + 1) , *indices->get(i + 2) ); } fclose( fd ) ; delete vertices; delete indices ; return TRUE; } plib-1.8.5/src/ssg/ssgOptimiser.cxx0000644000175000001440000007210310765364437014211 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgOptimiser.cxx 1999 2005-01-09 13:10:08Z bram $ */ #include "ssgLocal.h" #include "ssgVertSplitter.h" static float optimise_vtol [3] = { 0.001f, /* DISTANCE_SLOP = One millimeter */ 0.04f, /* COLOUR_SLOP = Four percent */ 0.004f, /* TEXCOORD_SLOP = One texel on a 256 map */ } ; static float* current_vtol = 0 ; #define DISTANCE_SLOP current_vtol[0] #define COLOUR_SLOP current_vtol[1] #define TEXCOORD_SLOP current_vtol[2] inline float frac ( float x ) { return x - (float) floor(x) ; } struct OptVertex { sgVec3 vertex ; sgVec3 normal ; sgVec2 texcoord ; sgVec4 colour ; int counter ; void print () { ulSetError ( UL_DEBUG, "%d:(%g,%g,%g):(%g,%g):(%g,%g,%g,%g):(%g,%g,%g)", counter, vertex[0],vertex[1],vertex[2], texcoord[0],texcoord[1], colour[0],colour[1],colour[2],colour[3], normal[0],normal[1],normal[2] ) ; } OptVertex ( sgVec3 v, sgVec2 t, sgVec4 c ) { sgCopyVec3 ( vertex , v ) ; sgCopyVec2 ( texcoord, t ) ; sgCopyVec4 ( colour , c ) ; sgSetVec3 ( normal , 0.0f, 0.0f, 0.0f ) ; counter = 1 ; } OptVertex ( OptVertex* cloneFrom ) { sgCopyVec3 ( vertex , cloneFrom -> vertex ) ; sgCopyVec2 ( texcoord, cloneFrom -> texcoord ) ; sgCopyVec4 ( colour , cloneFrom -> colour ) ; sgSetVec3 ( normal , 0.0f, 0.0f, 0.0f ) ; counter = 1 ; } int equal ( sgVec3 v, sgVec2 t, sgVec4 c, int tex_frac ) { if ( ! sgCompareVec3 ( vertex , v, DISTANCE_SLOP ) || ! sgCompareVec4 ( colour , c, COLOUR_SLOP ) ) return FALSE ; if ( ! tex_frac ) return sgCompareVec2 ( texcoord, t, TEXCOORD_SLOP ) ; return ( fabs ( frac ( texcoord[0] ) - frac ( t[0] ) ) <= TEXCOORD_SLOP && fabs ( frac ( texcoord[1] ) - frac ( t[1] ) ) <= TEXCOORD_SLOP ) ; } void bump () { counter++ ; } void dent () { counter-- ; } int getCount () { return counter ; } } ; #define MAX_OPT_VERTEX_LIST 10000 class OptVertexList { public: short vnum, tnum ; OptVertex **vlist ; short *tlist ; ssgState *state ; int cullface ; OptVertexList ( ssgState *s, int cf ) { /* Have to dynamically allocate these to get around Mac's CodeWarrior restriction on 32Kb as max structure size. */ vlist = new OptVertex* [ MAX_OPT_VERTEX_LIST ] ; tlist = new short [ MAX_OPT_VERTEX_LIST * 3 ] ; state = s ; if (state != NULL) state -> ref(); //~T.G. cullface = cf ; vnum = tnum = 0 ; } ~OptVertexList () { for ( int i = 0 ; i < vnum ; i++ ) delete vlist [ i ] ; delete [] vlist ; delete [] tlist ; if (state != NULL) ssgDeRefDelete(state); //~T.G. } short find ( sgVec3 v, sgVec2 t, sgVec4 c, int tex_fraction_only = FALSE ) ; short add ( sgVec3 v1, sgVec2 t1, sgVec4 c1, sgVec3 v2, sgVec2 t2, sgVec4 c2, sgVec3 v3, sgVec2 t3, sgVec4 c3 ) ; short add ( sgVec3 v, sgVec2 t, sgVec4 c ) ; short add ( short v1, short v2, short v3 ) ; void add ( ssgLeaf *l ) ; void makeNormals () ; void print () { ulSetError ( UL_DEBUG, "LIST: %d unique vertices and %d triangles", vnum, tnum ) ; } void follow ( int tri, int v1, int v2, int backwards, int *len, short *list, short *next ) ; int getLeastConnected ( short *t, short *v ) { int least = 32767 ; *v = 0 ; /* Find the least connected vertex that *is* connected */ int i ; for ( i = 0 ; i < vnum ; i++ ) { int c = vlist [ i ] -> getCount () ; if ( c > 0 && c < least ) { least = c ; *v = i ; } } if ( least == 32767 ) /* Didn't find an unused vertex - so punt. */ return FALSE ; least = 32767 ; *t = 32767 ; for ( i = 0 ; i < tnum ; i++ ) if ( tlist[i*3+0] == *v || tlist[i*3+1] == *v || tlist[i*3+2] == *v ) { int c = vlist [ tlist[i*3+0] ] -> getCount () + vlist [ tlist[i*3+1] ] -> getCount () + vlist [ tlist[i*3+2] ] -> getCount () ; if ( c < least ) { least = c ; *t = i ; } } if ( least == 32767 ) /* Didn't find an unused vertex - so punt. */ return FALSE ; return TRUE ; /* Got it! */ } void sub ( short t ) { vlist [ tlist[t*3+0] ] -> dent () ; vlist [ tlist[t*3+1] ] -> dent () ; vlist [ tlist[t*3+2] ] -> dent () ; tlist[t*3+0] = -1 ; tlist[t*3+1] = -1 ; tlist[t*3+2] = -1 ; } } ; short OptVertexList::add ( sgVec3 v1, sgVec2 t1, sgVec4 c1, sgVec3 v2, sgVec2 t2, sgVec4 c2, sgVec3 v3, sgVec2 t3, sgVec4 c3 ) { // If possible, this routine moves the texturecoordinates of // all three vertices of a Tria so that one needs less vertices. // This doesn't affect looks, but enhances the speed a bit. // This is not possible, if warpu or wrapv is FALSE int bWrapsInBothDirections = FALSE; short vi1, vi2, vi3; /* if ( state->isAKindOf( ssgTypeSimpleState() ) ) bWrapsInBothDirections = ( (((ssgSimpleState *)state)->getWrapU()) && (((ssgSimpleState *)state)->getWrapV()) ); */ if (!bWrapsInBothDirections) { /* Find which (if any) of the vertices are a match for one in the list */ vi1 = add ( v1, t1, c1 ) ; vi2 = add ( v2, t2, c2 ) ; vi3 = add ( v3, t3, c3 ) ; } else { /* Sharing vertices is tricky because of texture coordinates that have the same all-important fractional part - but differ in their integer parts. */ sgVec2 adjust ; /* Find which (if any) of the vertices are a match for one in the list */ vi1 = find ( v1, t1, c1, TRUE ) ; vi2 = find ( v2, t2, c2, TRUE ) ; vi3 = find ( v3, t3, c3, TRUE ) ; /* Compute texture offset coordinates (if needed) to make everything match */ if ( vi1 >= 0 ) sgSubVec2 ( adjust, t1, vlist[vi1]->texcoord ) ; else if ( vi2 >= 0 ) sgSubVec2 ( adjust, t2, vlist[vi2]->texcoord ) ; else if ( vi3 >= 0 ) sgSubVec2 ( adjust, t3, vlist[vi3]->texcoord ) ; else { /* OK, there was no match - so just remove any large numbers from the texture coords */ adjust [ 0 ] = (float) floor ( t1[0] ) ; adjust [ 1 ] = (float) floor ( t1[1] ) ; } /* Now adjust the texture coordinates and add them into the list */ sgVec2 tmp ; sgSubVec2 ( tmp, t1, adjust ) ; vi1 = add ( v1, tmp, c1 ) ; sgSubVec2 ( tmp, t2, adjust ) ; vi2 = add ( v2, tmp, c2 ) ; sgSubVec2 ( tmp, t3, adjust ) ; vi3 = add ( v3, tmp, c3 ) ; } return add ( vi1, vi2, vi3 ) ; } short OptVertexList::add ( short v1, short v2, short v3 ) { if ( v1 == v2 || v2 == v3 || v3 == v1 ) /* Toss degenerate triangles */ { vlist [ v1 ] -> dent () ; /* Un-reference their vertices */ vlist [ v2 ] -> dent () ; vlist [ v3 ] -> dent () ; return -1 ; } tlist [ tnum*3+ 0 ] = v1 ; tlist [ tnum*3+ 1 ] = v2 ; tlist [ tnum*3+ 2 ] = v3 ; return tnum++ ; } // // Splits vertices across "sharp" edges to improve the normal // direction. // void OptVertexList::makeNormals () { int i, j ; ssgVertSplitter vs ( vnum, tnum ) ; // Copy in the vertex and triangle data for ( i = 0 ; i < vnum ; i ++ ) sgCopyVec3 ( vs.vert ( i ), vlist[ i ] -> vertex ) ; for ( i = 0 ; i < tnum ; i ++ ) { short* t = tlist + 3 * i ; vs.setTri ( i , t[0], t[1], t[2] ); } // Run the algorithm. Get the "sharp" angle from somewhere // intelligent, instead of hardcoding it. vs.splitAndCalcNormals () ; // Generate the new vertices by cloning their originals int newVerts = vs.newVerts () ; if ( vnum + newVerts > MAX_OPT_VERTEX_LIST ) return; // Oh well. No harm done, at least. for ( i = 0 ; i < newVerts ; i++ ) { OptVertex *ov = vlist[ vs.origVert ( i ) ] ; vlist[ i + vnum ] = new OptVertex ( ov ); } vnum += newVerts; // Copy out the new, optimized normal data for(i=0; inormal, vs.norm(i)); // Zero out the reference counts for the vertices; they will have // changed during the split and will be recalculated below. This // is an ugly hack -- a more elegant solution would be to do the // bump()/dent() calls inside the ssgVertSplitter code as each vertex // is duplicated. for ( i = 0 ; i < vnum ; i++ ) while ( vlist [ i ] -> getCount () ) vlist [ i ] -> dent () ; // Copy out the possibly changed vertices for the triangles for (i = 0 ; i < tnum ; i++ ) { short* oldtri = tlist + 3 * i ; int* newtri = vs.getTri ( i ) ; for ( j = 0 ; j < 3 ; j++ ) { oldtri [ j ] = newtri [ j ] ; vlist[ newtri [ j ] ] -> bump (); } } } short OptVertexList::find ( sgVec3 v, sgVec2 t, sgVec4 c, int tex_frac ) { for ( short i = 0 ; i < vnum ; i++ ) { if ( vlist[i] -> equal ( v, t, c, tex_frac ) ) return i ; } return -1 ; } short OptVertexList::add ( sgVec3 v, sgVec2 t, sgVec4 c ) { short i = find ( v, t, c, FALSE ) ; if ( i >= 0 ) { vlist [ i ] -> bump () ; return i ; } vlist [ vnum ] = new OptVertex ( v, t, c ) ; return vnum++ ; } void OptVertexList::add ( ssgLeaf *l ) { int j ; for ( j = 0 ; j < l -> getNumTriangles () ; j ++ ) { short v1, v2, v3 ; l -> getTriangle ( j, &v1, &v2, &v3 ) ; add ( l->getVertex ( v1 ), l->getTexCoord ( v1 ), l->getColour ( v1 ), l->getVertex ( v2 ), l->getTexCoord ( v2 ), l->getColour ( v2 ), l->getVertex ( v3 ), l->getTexCoord ( v3 ), l->getColour ( v3 ) ) ; } } void OptVertexList::follow ( int tri, int v1, int v2, int backwards, int *len, short *new_vlist, short *new_vc ) { /* WARNING - RECURSIVE !! */ v1 = tlist [ tri*3+ v1 ] ; v2 = tlist [ tri*3+ v2 ] ; /* This triangle's work is done - dump it. */ (*len)++ ; sub ( tri ) ; /* If the exit edge vertices don't *both* have a reference then we are done. */ if ( vlist [ v1 ] -> getCount () <= 0 || vlist [ v2 ] -> getCount () <= 0 ) return ; /* Search for a polygon that shares that edge in the correct direction - and follow it. */ for ( int i = 0 ; i < tnum ; i++ ) { if ( tlist [ i*3+ 0 ] < 0 ) /* Deleted triangle */ continue ; if ( backwards ) { /* If the previous polygon was backwards */ if ( tlist [ i*3+ 0 ] == v1 && tlist [ i*3+ 2 ] == v2 ) { new_vlist [ (*new_vc)++ ] = tlist [ i*3+ 1 ] ; follow ( i, 0, 1, !backwards, len, new_vlist, new_vc ) ; return ; } else if ( tlist [ i*3+ 1 ] == v1 && tlist [ i*3+ 0 ] == v2 ) { new_vlist [ (*new_vc)++ ] = tlist [ i*3+ 2 ] ; follow ( i, 1, 2, !backwards, len, new_vlist, new_vc ) ; return ; } else if ( tlist [ i*3+ 2 ] == v1 && tlist [ i*3+ 1 ] == v2 ) { new_vlist [ (*new_vc)++ ] = tlist [ i*3+ 0 ] ; follow ( i, 2, 0, !backwards, len, new_vlist, new_vc ) ; return ; } } else { /* If the previous polygon was forwards... */ if ( tlist [ i*3+ 0 ] == v1 && tlist [ i*3+ 2 ] == v2 ) { new_vlist [ (*new_vc)++ ] = tlist [ i*3+ 1 ] ; follow ( i, 1, 2, !backwards, len, new_vlist, new_vc ) ; return ; } else if ( tlist [ i*3+ 1 ] == v1 && tlist [ i*3+ 0 ] == v2 ) { new_vlist [ (*new_vc)++ ] = tlist [ i*3+ 2 ] ; follow ( i, 2, 0, !backwards, len, new_vlist, new_vc ) ; return ; } else if ( tlist [ i*3+ 2 ] == v1 && tlist [ i*3+ 1 ] == v2 ) { new_vlist [ (*new_vc)++ ] = tlist [ i*3+ 0 ] ; follow ( i, 0, 1, !backwards, len, new_vlist, new_vc ) ; return ; } } } } static ssgLeaf** build_leaf_list ( ssgEntity *ent, ssgLeaf** leaf_list=0 ) { enum { MAX_LEAF_COUNT = 10000 } ; static int leaf_count ; if ( leaf_list == NULL ) { leaf_list = new ssgLeaf* [ MAX_LEAF_COUNT+1 ] ; leaf_count = 0 ; leaf_list [ leaf_count ] = NULL ; } if ( ent -> isAKindOf ( ssgTypeBranch () ) ) { ssgBranch *b_ent = (ssgBranch *) ent ; for ( ssgEntity *k = b_ent -> getKid ( 0 ) ; k != NULL ; k = b_ent -> getNextKid () ) { build_leaf_list ( k, leaf_list ) ; } } else if ( ent -> isAKindOf ( ssgTypeLeaf () ) ) { ssgLeaf *l = (ssgLeaf *) ent ; bool found = false ; for ( int i = 0 ; leaf_list [ i ] != NULL ; i ++ ) { if ( leaf_list [ i ] == l ) { found = true ; break ; } } if ( !found && leaf_count < MAX_LEAF_COUNT ) { leaf_list [ leaf_count ++ ] = l ; leaf_list [ leaf_count ] = NULL ; } } return leaf_list ; } /* * NAME * ssgArrayTool * * DESCRIPTION * Process the graph and convert all leaf entities into vertex arrays. * * Each vertex is described by a single index (instead of different * indices into the v, vc, vt-arrays). This may introduce new redundant * vertex data into the data set, which may seem silly. However, when * rendering through OpenGL, it is in most cases the optimal solution * to use indexed vertex arrays, which only have ONE index for all * the vertex data. * * INPUTS * * ent - the entity to process * * vtol - an array of 3 floats used to specify tolerances * vtol[0] - tolerance value for vertices * vtol[1] - tolerance for colours * vtol[2] - tolerance for texture coordinates * * make_normals - if true then averaged vertex normals are computed */ void ssgArrayTool ( ssgEntity *ent, float* vtol, bool make_normals ) { current_vtol = vtol? vtol: optimise_vtol ; ssgLeaf** leaf_list = build_leaf_list ( ent ) ; for ( int i = 0 ; leaf_list [ i ] != NULL ; i ++ ) { ssgLeaf *l = leaf_list [ i ] ; ssgState *s = l -> getState() ; int cf = l -> getCullFace() ; OptVertexList list ( s, cf ) ; list . add ( l ) ; if ( list . tnum > 0 ) /* If all the triangles are degenerate maybe */ { ssgIndexArray *new_index = new ssgIndexArray ( list . tnum * 3 ) ; ssgVertexArray *new_coords = new ssgVertexArray ( list . vnum ) ; ssgTexCoordArray *new_texcoords = new ssgTexCoordArray ( list . vnum ) ; ssgColourArray *new_colours = new ssgColourArray ( list . vnum ) ; ssgNormalArray *new_normals = 0 ; if ( make_normals ) { list . makeNormals () ; new_normals = new ssgNormalArray ( list . vnum ) ; } for ( int t = 0 ; t < list . tnum ; t++ ) { new_index -> add ( list . tlist [ t*3+ 0 ] ) ; new_index -> add ( list . tlist [ t*3+ 1 ] ) ; new_index -> add ( list . tlist [ t*3+ 2 ] ) ; } for ( int v = 0 ; v < list . vnum ; v++ ) { new_coords -> add ( list . vlist[ v ]->vertex ) ; new_texcoords-> add ( list . vlist[ v ]->texcoord ) ; new_colours -> add ( list . vlist[ v ]->colour ) ; if ( make_normals ) new_normals -> add ( list . vlist[ v ]->normal ) ; } ssgVtxArray *new_varray = new ssgVtxArray ( GL_TRIANGLES, new_coords, new_normals, new_texcoords, new_colours, new_index ) ; new_varray -> setState ( list.state ) ; new_varray -> setCullFace ( list.cullface ) ; ssgBranch *p ; /* Add the new leaf */ for ( p = l -> getParent ( 0 ) ; p != NULL ; p = l -> getNextParent () ) p -> addKid ( new_varray ) ; /* Remove the old leaf */ for ( p = new_varray -> getParent ( 0 ) ; p != NULL ; p = new_varray -> getNextParent () ) p -> removeKid ( l ) ; } } delete[] leaf_list ; ent -> recalcBSphere () ; } void ssgStripify ( ssgEntity *ent ) { current_vtol = optimise_vtol ; /* Walk down until we find a leaf node, then back up one level, collect all the ssgVtxTables into one big heap and triangulate them. */ if ( ent -> isAKindOf ( ssgTypeLeaf () ) ) return ; ssgBranch *b_ent = (ssgBranch *) ent ; /* Count number of unique materials (and cull-facedness) - make a list of them. Recursively stripify non-leaf nodes. */ int stot = 0 ; ssgState **slist = new ssgState *[ b_ent -> getNumKids () ] ; int *cflist = new int [ b_ent -> getNumKids () ] ; for ( ssgEntity *k = b_ent -> getKid ( 0 ) ; k != NULL ; k = b_ent -> getNextKid () ) { if ( k -> isAKindOf ( ssgTypeVtxTable () ) ) { GLenum thisType = ((ssgVtxTable *)k)->getPrimitiveType (); if ((thisType != GL_POINTS) && (thisType != GL_LINES) && (thisType != GL_LINE_STRIP) && (thisType != GL_LINE_LOOP)) { int i ; ssgState *s = ((ssgLeaf *) k ) -> getState() ; int c = ((ssgLeaf *) k ) -> getCullFace() ; for ( i = 0 ; i < stot ; i++ ) if ( s == slist [ i ] && c == cflist [ i ] ) break ; if ( i >= stot ) { slist [ i ] = s ; cflist [ i ] = c ; stot++ ; } } } else if ( k -> isAKindOf ( ssgTypeBranch () ) ) ssgStripify ( k ) ; } /* Now, for each unique state, grab all the VtxTable leaf nodes and smoosh them into one. */ for ( int i = 0 ; i < stot ; i++ ) { /* Put it into a triangle-oriented structure and then do stripifying and average normal generation. Ick! */ OptVertexList list ( slist [ i ], cflist [ i ] ) ; ssgEntity *k = b_ent -> getKid ( 0 ) ; while ( k != NULL ) { if ( k -> isAKindOf ( ssgTypeVtxTable () ) && ((ssgLeaf *) k ) -> getState() == slist [ i ] && ((ssgLeaf *) k ) -> getCullFace() == cflist [ i ] ) { GLenum thisType = ((ssgVtxTable *)k)->getPrimitiveType (); if ((thisType != GL_POINTS) && (thisType != GL_LINES) && (thisType != GL_LINE_STRIP) && (thisType != GL_LINE_LOOP)) { list . add ( (ssgVtxTable *) k ) ; b_ent -> removeKid ( k ) ; k = b_ent -> getKid ( 0 ) ; } else k = b_ent -> getNextKid () ; } else k = b_ent -> getNextKid () ; } if ( list . tnum == 0 ) /* If all the triangles are degenerate maybe */ continue ; /* So, now we have all the important information sucked out of all those nodes and safely tucked away in the OptVertexList Let's take this opportunity to compute vertex normals. */ list . makeNormals () ; /* Find the least connected triangle. Use it as the starting point. */ short tleast, nleast ; while ( list . getLeastConnected ( & tleast, & nleast ) ) { /* OK, we have our starting point - follow where it leads - but which way to start? We need two vertices with at least two references - and not the least referenced vertex please. */ short *new_vlist = new short [ list.tnum * 3 ] ; short new_vc = 0 ; int striplength = 0 ; if ( nleast == list.tlist[tleast*3+0] ) { new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 0 ] ; new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 1 ] ; new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 2 ] ; list . follow ( tleast, 1, 2, FALSE, &striplength, new_vlist, & new_vc ) ; } else if ( nleast == list.tlist[tleast*3+1] ) { new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 1 ] ; new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 2 ] ; new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 0 ] ; list . follow ( tleast, 2, 0, FALSE, &striplength, new_vlist, & new_vc ) ; } else if ( nleast == list.tlist[tleast*3+2] ) { new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 2 ] ; new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 0 ] ; new_vlist [ new_vc++ ] = list.tlist [ tleast*3+ 1 ] ; list . follow ( tleast, 0, 1, FALSE, &striplength, new_vlist, & new_vc ) ; } else ulSetError ( UL_WARNING, "Tleast doesn't contain nleast!" ) ; ssgVertexArray *new_coords = new ssgVertexArray ( new_vc ) ; ssgNormalArray *new_normals = new ssgNormalArray ( new_vc ) ; ssgTexCoordArray *new_texcoords = new ssgTexCoordArray ( new_vc ) ; ssgColourArray *new_colours = new ssgColourArray ( new_vc ) ; for ( int m = 0 ; m < new_vc ; m++ ) { new_coords -> add ( list.vlist[new_vlist[m]]->vertex ) ; new_normals -> add ( list.vlist[new_vlist[m]]->normal ) ; new_texcoords-> add ( list.vlist[new_vlist[m]]->texcoord ) ; new_colours -> add ( list.vlist[new_vlist[m]]->colour ) ; } delete [] new_vlist ; ssgVtxTable *new_vtable = new ssgVtxTable ( GL_TRIANGLE_STRIP, new_coords, new_normals, new_texcoords, new_colours ) ; new_vtable -> setState ( list.state ) ; new_vtable -> setCullFace ( list.cullface ) ; b_ent -> addKid ( new_vtable ) ; } } delete [] slist ; delete [] cflist ; } /* These routines are essentially non-realtime tree optimisations. */ static void safe_replace_kid ( ssgBranch *parent, ssgEntity *old_kid, ssgEntity *new_kid ) { /* Replace old_kid by new_kid in a "safe" manner. new_kid may be null, in which case old_kid is removed. If parent is null then loop over all parents of old_kid. */ if ( old_kid == new_kid ) return ; if ( parent == NULL ) { int n = old_kid -> getNumParents () ; while ( n-- > 0 ) safe_replace_kid ( old_kid -> getParent ( 0 ), old_kid, new_kid ) ; return ; } // assert ( parent -> searchForKid ( old_kid ) >= 0 ) ; if ( new_kid == NULL ) { if ( parent -> isAKindOf ( ssgTypeSelector () ) ) { /* cannot remove kids from selectors */ parent -> replaceKid ( old_kid, new ssgInvisible ) ; } else { parent -> removeKid ( old_kid ) ; } } else { parent -> replaceKid ( old_kid, new_kid ) ; } } static void strip ( ssgEntity *ent ) { /* Strip off all branches with no kids - and snip out all simple branches with just one kid. A node with user data is always left unchanged. */ if ( ! ent -> isAKindOf ( ssgTypeBranch () ) ) return ; ssgBranch *b_ent = (ssgBranch *) ent ; for ( ssgEntity *k = b_ent -> getKid ( 0 ) ; k != NULL ; k = b_ent -> getNextKid () ) strip ( k ) ; switch ( b_ent -> getNumKids () ) { case 0: if ( b_ent -> getUserData() == NULL && b_ent -> getName () == NULL ) safe_replace_kid ( NULL, b_ent, NULL ) ; break; case 1: if ( b_ent -> isA ( ssgTypeBranch () ) && b_ent -> getUserData () == NULL ) { ssgEntity *k = b_ent -> getKid ( 0 ) ; if ( b_ent -> getName () != NULL && k -> getName () != NULL ) break; if ( b_ent -> getName () != NULL ) k -> setName ( b_ent -> getName () ) ; safe_replace_kid ( NULL, b_ent, k ) ; } else if ( ! b_ent -> isAKindOf ( ssgTypeSelector () ) && b_ent -> getKid ( 0 ) -> isA ( ssgTypeBranch () ) && b_ent -> getKid ( 0 ) -> getUserData () == NULL ) { ssgBranch *b_kid = (ssgBranch *) b_ent -> getKid ( 0 ) ; for ( ssgEntity *k = b_kid -> getKid ( 0 ) ; k != NULL ; k = b_kid -> getNextKid () ) b_ent -> addKid ( k ) ; b_ent -> removeKid ( b_kid ) ; b_ent -> recalcBSphere () ; } break; default: if ( b_ent -> isDirtyBSphere () ) b_ent -> recalcBSphere () ; } } void flatten ( ssgBranch *parent, ssgEntity *ent, sgMat4 mat ) { /* Move all transforms down to the leaf nodes and then multiply them out. You need to strip() the tree after calling this. */ sgMat4 mat2 ; /* The following nodes may (currently) not be flattened: - ssgCutout, - ssgRangeSelector, and - ssgTransform with user data. */ if ( ent -> isAKindOf ( ssgTypeCutout () ) || ent -> isAKindOf ( ssgTypeRangeSelector () ) || ( ent -> isA ( ssgTypeTransform () ) && ent -> getUserData () != NULL ) ) { /* Insert a transform node if needed. */ if ( mat != NULL ) { ssgTransform *tr = new ssgTransform ; tr -> setTransform ( mat ) ; tr -> addKid ( ent ) ; safe_replace_kid ( parent, ent, tr ) ; } /* Traverse as usual. */ if ( ent -> isAKindOf ( ssgTypeBranch () ) ) { ssgBranch *b_ent = (ssgBranch *) ent ; for ( ssgEntity *k = b_ent -> getKid ( 0 ) ; k != NULL ; k = b_ent -> getNextKid () ) flatten ( b_ent, k, NULL ) ; } return ; } /* Clone the node if needed (there is no need to clone it recursively, especially not past unflattable nodes). */ if ( ent -> getRef () > 1 && mat != NULL ) { ssgEntity *clone = (ssgEntity *) ent -> clone ( SSG_CLONE_GEOMETRY | SSG_CLONE_USERDATA ) ; safe_replace_kid ( parent, ent, clone ) ; ent = clone ; } /* Apply the transformation on leaf nodes. */ if ( ent -> isAKindOf ( ssgTypeLeaf () ) ) { if ( mat != NULL ) ((ssgLeaf *) ent) -> transform ( mat ) ; return ; } /* Replace transform nodes with simple branches. */ if ( ent -> isAKindOf ( ssgTypeTransform () ) ) { ssgTransform *t_ent = (ssgTransform *) ent ; t_ent -> getTransform ( mat2 ) ; if ( mat != NULL ) sgPostMultMat4 ( mat2, mat ) ; mat = sgClassifyMat4 ( mat2 ) != 0 ? mat2 : NULL ; ssgBranch *br = new ssgBranch ; /* FIXME! It would have been very neat to do: br -> copy_from ( t_ent, 0 ) ; */ br -> setName ( t_ent -> getName () ) ; for ( ssgEntity *k = t_ent -> getKid ( 0 ) ; k != NULL ; k = t_ent -> getNextKid () ) br -> addKid ( k ) ; t_ent -> removeAllKids () ; safe_replace_kid ( NULL, ent, br ) ; ent = br ; } /* Finally traverse the kids. */ if ( ent -> isAKindOf ( ssgTypeBranch () ) ) { ssgBranch *b_ent = (ssgBranch *) ent ; for ( ssgEntity *k = b_ent -> getKid ( 0 ) ; k != NULL ; k = b_ent -> getNextKid () ) flatten ( b_ent, k, mat ) ; } } void ssgFlatten ( ssgEntity *ent ) { if ( ! ent -> isAKindOf ( ssgTypeBranch () ) ) return ; ssgBranch *b_ent = (ssgBranch *) ent ; sgVec4 *mat = NULL ; sgMat4 xform, ident ; /* If the top level node is a ssgTransform, then do not replace it; instead load an identity transform and multiply out the matrix. */ if ( b_ent -> isA ( ssgTypeTransform () ) && b_ent -> getUserData () == NULL ) { sgMakeIdentMat4 ( ident ) ; ((ssgTransform *) b_ent) -> getTransform ( xform ) ; ((ssgTransform *) b_ent) -> setTransform ( ident ) ; mat = xform ; } /* Since the top level node may not be removed, loop over the kids. Done in two passes because *kid* may be removed. */ ssgEntity *kid; for ( kid = b_ent -> getKid ( 0 ) ; kid != NULL ; kid = b_ent -> getNextKid () ) flatten ( b_ent, kid, mat ) ; for ( kid = b_ent -> getKid ( 0 ) ; kid != NULL ; kid = b_ent -> getNextKid () ) strip ( kid ) ; if ( b_ent -> isDirtyBSphere () ) b_ent -> recalcBSphere () ; } /* * NAME * ssgTransTool * * DESCRIPTION * Apply a transform (translate, rotate, scale) to all verticies of a graph. * * INPUTS * ent -- the entity to process * trans -- transform */ void ssgTransTool ( ssgEntity *ent, const sgMat4 trans ) { if ( ent -> isAKindOf ( ssgTypeLeaf () ) ) { ((ssgLeaf *) ent) -> transform ( trans ) ; return ; } if ( ! ent -> isAKindOf ( ssgTypeBranch () ) ) return ; ssgBranch *b_ent = (ssgBranch *) ent ; sgMat4 mat, ident, xform ; sgCopyMat4 ( mat, trans ) ; if ( b_ent -> isA ( ssgTypeTransform () ) && b_ent -> getUserData () == NULL ) { sgMakeIdentMat4 ( ident ) ; ((ssgTransform *) b_ent) -> getTransform ( xform ) ; ((ssgTransform *) b_ent) -> setTransform ( ident ) ; sgPreMultMat4 ( mat, xform ) ; } else if ( b_ent -> isAKindOf ( ssgTypeTransform () ) || b_ent -> isAKindOf ( ssgTypeCutout () ) || b_ent -> isAKindOf ( ssgTypeRangeSelector () ) ) { ulSetError ( UL_WARNING, "ssgTransTool: Cannot handle this kind of node at top level." ) ; return ; } ssgEntity *kid; for ( kid = b_ent -> getKid ( 0 ) ; kid != NULL ; kid = b_ent -> getNextKid () ) flatten ( b_ent, kid, mat ) ; for ( kid = b_ent -> getKid ( 0 ) ; kid != NULL ; kid = b_ent -> getNextKid () ) strip ( kid ) ; b_ent -> recalcBSphere () ; } plib-1.8.5/src/ssg/ssgVertSplitter.h0000644000175000001440000000405110765364437014327 00000000000000//////////////////////////////////////////////////////////////////////// // // Copyright 2003, Andrew Ross // // Walk through an indexed triangle list, splitting vertices that // share "sharp" edges, and calculate normals for the resulting mesh. // // This code should really live inside the OptVertexList class in // ssgOptimizer.cxx, whose data model is almost 1:1 compatible with // the indexed triangle representation here. It is a separate file // because it comes from separate code that Andy Ross wrote for a // different project, and this was the cleanest way to do the port. // //////////////////////////////////////////////////////////////////////// #ifndef _SSGA_VERTSPLITTER_H #define _SSGA_VERTSPLITTER_H class ssgVertSplitter { public: ssgVertSplitter(int nVerts, int nTris); virtual ~ssgVertSplitter(); void setSharpAngle(float deg); float* vert(int i) { return _verts + 3*i; } float* norm(int i) { return _norms + 3*i; } // Initialize a triangle. The vertex indices might change. void setTri(int tidx, int va, int vb, int vc); // Grab the new/different indices post-split int* getTri(int t); // Number of new vertices (indices start after the original list) int newVerts() { return _nextNewVert; } // Original vertex associated with a given "new" vertex int origVert(int i); void splitAndCalcNormals(); private: struct Tri { int verts[3]; int oVerts[3]; bool degenerate; }; void condenseGeometry(); void expandDuplicates(); int findTriWithVert(int fidx, int vidx, int* tris, int ntris); int nextTri(int fidx, int vidx, int* tris, int ntris); int prevTri(int fidx, int vidx, int* tris, int ntris); static void fixVidx(Tri* t, int oldIdx, int newIdx); float _threshold; int _origVerts; int _vertsAlloced; int _nVerts; float* _verts; float* _norms; int _nTris; Tri* _tris; float* _triNorms; int* _newVertMap; int _nextNewVert; int* _geomVerts; void DUMP(); }; #endif // _SSGA_VERTSPLITTER_H plib-1.8.5/src/ssg/ssgVtxArray.cxx0000644000175000001440000002510710765364437014020 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgVtxArray.cxx 1992 2004-12-01 08:28:05Z wolfram_kuss $ */ #include "ssgLocal.h" #define HL_DELTA 0.04f void ssgVtxArray::copy_from ( ssgVtxArray *src, int clone_flags ) { ssgVtxTable::copy_from ( src, clone_flags ) ; ssgDeRefDelete ( indices ) ; if ( src->indices != NULL && ( clone_flags & SSG_CLONE_GEOMETRY ) ) indices = (ssgIndexArray *)( src -> indices -> clone ( clone_flags )) ; else indices = src -> indices ; if ( indices != NULL ) indices -> ref () ; } ssgBase *ssgVtxArray::clone ( int clone_flags ) { ssgVtxArray *b = new ssgVtxArray ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgVtxArray::ssgVtxArray () : ssgVtxTable() { type = ssgTypeVtxArray () ; indices = NULL ; } ssgVtxArray::ssgVtxArray ( GLenum ty, ssgVertexArray *vl, ssgNormalArray *nl, ssgTexCoordArray *tl, ssgColourArray *cl, ssgIndexArray *il ) : ssgVtxTable( ty, vl, nl, tl, cl ) { type = ssgTypeVtxArray () ; indices = (il!=NULL) ? il : new ssgIndexArray () ; indices -> ref () ; } ssgVtxArray::~ssgVtxArray () { ssgDeRefDelete ( indices ) ; } void ssgVtxArray::setIndices ( ssgIndexArray *il ) { ssgDeRefDelete ( indices ) ; indices = il ; if ( indices != NULL ) indices -> ref () ; } void ssgVtxArray::drawHighlight ( sgVec4 colour ) { _ssgForceLineState () ; glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) ; glDisableClientState ( GL_COLOR_ARRAY ) ; glDisableClientState ( GL_NORMAL_ARRAY ) ; glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ; glEnableClientState ( GL_VERTEX_ARRAY ) ; glVertexPointer ( 3, GL_FLOAT, 0, vertices->get(0) ) ; glPushAttrib ( GL_POLYGON_BIT ) ; glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE ) ; glColor4fv ( colour ) ; int i = getNumIndices (); short *ii = indices->get(0); glDrawElements ( gltype, i, GL_UNSIGNED_SHORT, ii ) ; glPopAttrib () ; glPopClientAttrib () ; glEnable ( GL_DEPTH_TEST ) ; } void ssgVtxArray::drawHighlight ( sgVec4 colour, int i ) { _ssgForceLineState () ; if ( i < 0 || i >= getNumIndices () ) return ; int ii = *( indices->get(i) ); sgVec3 *vx = (sgVec3 *) vertices -> get(ii) ; float x = vx[0][0] ; float y = vx[0][1] ; float z = vx[0][2] ; sgVec3 t[6] ; sgSetVec3 ( t[0], x-HL_DELTA,y,z ) ; sgSetVec3 ( t[1], x+HL_DELTA,y,z ) ; sgSetVec3 ( t[2], x,y-HL_DELTA,z ) ; sgSetVec3 ( t[3], x,y+HL_DELTA,z ) ; sgSetVec3 ( t[4], x,y,z-HL_DELTA ) ; sgSetVec3 ( t[5], x,y,z+HL_DELTA ) ; glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) ; glDisableClientState ( GL_COLOR_ARRAY ) ; glDisableClientState ( GL_NORMAL_ARRAY ) ; glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ; glEnableClientState ( GL_VERTEX_ARRAY ) ; glVertexPointer ( 3, GL_FLOAT, 0, t ) ; glColor4fv ( colour ) ; glLineWidth ( 4.0f ) ; glDrawArrays ( GL_LINES, 0, 6 ) ; glLineWidth ( 1.0f ) ; glPopClientAttrib ( ) ; glEnable ( GL_DEPTH_TEST ) ; } void ssgVtxArray::pick ( int baseName ) { int i ; int num_vertices = getNumIndices () ; glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) ; glEnableClientState ( GL_VERTEX_ARRAY ) ; glVertexPointer ( 3, GL_FLOAT, 0, vertices->get(0) ) ; /* Test the entire primitive. */ glPushName ( baseName ) ; short *ii = indices->get(0); glDrawElements ( gltype, num_vertices, GL_UNSIGNED_SHORT, ii ) ; /* Then test each vertex in turn */ for ( i = 0 ; i < num_vertices ; i++ ) { int ii = *( indices->get(i) ); glLoadName ( baseName + i + 1 ) ; glBegin ( GL_POINTS ) ; glArrayElement ( ii ) ; glEnd () ; } glPopName () ; glPopClientAttrib ( ) ; } void ssgVtxArray::removeUnusedVertices() // this removes any vertices (including normal, TexCoords and colour) // that are not referenced by the index array { bool doNormals = FALSE, doTexCoords = FALSE, doColours = FALSE; assert(vertices); if(!indices) { ulSetError( UL_WARNING, "indices == NULL\n"); return; } if(normals) if(1 < normals->getNum()) doNormals = TRUE; if(texcoords) if(1 < texcoords->getNum()) doTexCoords = TRUE; if(colours) if(1 < colours->getNum()) doColours = TRUE; long * oldIndex2NewIndex = new long[vertices->getNum()]; int i; short oldIndex, newIndex; for(i=0;igetNum();i++) oldIndex2NewIndex[i]=-1; // marker for "not used" ssgVertexArray *newVL= new ssgVertexArray(); ssgNormalArray *newNL = NULL; ssgTexCoordArray *newTL = NULL; ssgColourArray *newCL = NULL; if(doNormals) newNL = new ssgNormalArray(); if (doTexCoords) newTL = new ssgTexCoordArray(); if (doColours) newCL = new ssgColourArray(); for(i=0; igetNum(); i++) { oldIndex = *indices->get(i); if (oldIndex2NewIndex[ oldIndex ] != -1) indices->set(static_cast(oldIndex2NewIndex[ oldIndex ]), i); else { newIndex = newVL->getNum(); indices->set(newIndex , i); oldIndex2NewIndex[ oldIndex ] = newIndex; newVL->add(vertices->get(oldIndex)); if(doNormals) newNL->add(normals->get(oldIndex)); if (doTexCoords) newTL->add(texcoords->get(oldIndex)); if (doColours) newCL->add(colours->get(oldIndex)); } } vertices->deRef(); //ssgDeRefDelete(vertices); vertices = newVL; newVL->ref(); if(doNormals) { normals->deRef(); //ssgDeRefDelete(normals); normals = newNL; newNL->ref(); } if (doTexCoords) { texcoords->deRef(); //ssgDeRefDelete(texcoords); texcoords = newTL; newTL->ref(); } if (doColours) { colours->deRef(); //ssgDeRefDelete(colours); colours = newCL; newCL->ref(); } delete [] oldIndex2NewIndex; } void ssgVtxArray::draw_geometry () { int num_colours = getNumColours () ; int num_normals = getNumNormals () ; int num_texcoords = getNumTexCoords () ; sgVec3 *nm = (sgVec3 *) normals -> get(0) ; sgVec4 *cl = (sgVec4 *) colours -> get(0) ; if ( num_colours == 0 ) glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ; if ( num_colours == 1 ) glColor4fv ( cl [ 0 ] ) ; if ( num_normals == 1 ) glNormal3fv ( nm [ 0 ] ) ; glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) ; if ( num_colours > 1 ) { glEnableClientState ( GL_COLOR_ARRAY ) ; glColorPointer ( 4, GL_FLOAT, 0, colours->get(0) ) ; } if ( num_normals > 1 ) { glEnableClientState ( GL_NORMAL_ARRAY ) ; glNormalPointer ( GL_FLOAT, 0, normals->get(0) ) ; } if ( num_texcoords > 1 ) { glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ; glTexCoordPointer ( 2, GL_FLOAT, 0, texcoords->get(0) ) ; } glEnableClientState ( GL_VERTEX_ARRAY ) ; glVertexPointer ( 3, GL_FLOAT, 0, vertices->get(0) ) ; int i = getNumIndices (); short *ii = indices->get(0); _ssgCurrStatistics . bumpVertexCount ( i ) ; _ssgCurrStatistics . bumpLeafCount ( 1 ) ; glDrawElements ( gltype, i, GL_UNSIGNED_SHORT, ii ) ; glPopClientAttrib ( ) ; } void ssgVtxArray::getTriangle ( int n, short *v1, short *v2, short *v3 ) { short vv1, vv2, vv3 ; ssgVtxTable::getTriangle ( n, &vv1, &vv2, &vv3 ) ; *v1 = *( indices -> get ( vv1 ) ) ; *v2 = *( indices -> get ( vv2 ) ) ; *v3 = *( indices -> get ( vv3 ) ) ; } int ssgVtxArray::getNumTriangles () { switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : return getNumIndices() - 2 ; case GL_TRIANGLES : return getNumIndices() / 3 ; case GL_TRIANGLE_STRIP : return getNumIndices() - 2 ; case GL_QUADS : return ( getNumIndices() / 4 ) * 2 ; case GL_QUAD_STRIP : return ( ( getNumIndices() - 2 ) / 2 ) * 2 ; default : break ; } return 0 ; } int ssgVtxArray::getNumLines () { switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : case GL_TRIANGLES : case GL_TRIANGLE_STRIP : case GL_QUADS : case GL_QUAD_STRIP : case GL_POINTS : return 0 ; case GL_LINES : return getNumIndices () / 2 ; case GL_LINE_LOOP : return getNumIndices () ; case GL_LINE_STRIP : return getNumIndices () - 1 ; default : break ; } assert(false); /* Should never get here */ return 0 ; } void ssgVtxArray::getLine ( int n, short *v1, short *v2 ) { assert( n>=0 ); switch ( getPrimitiveType () ) { case GL_POLYGON : case GL_TRIANGLE_FAN : case GL_TRIANGLES : case GL_TRIANGLE_STRIP : case GL_QUADS : case GL_QUAD_STRIP : case GL_POINTS : assert(false); case GL_LINES : assert ( 2*n+1 < getNumIndices() ); *v1 = *getIndex( 2*n ); *v2 = *getIndex( 2*n+1 ); return ; case GL_LINE_LOOP : assert ( n < getNumIndices() ); *v1 = *getIndex( n ); if ( n == getNumIndices()-1 ) *v2 = *getIndex( 0 ); else *v2 = *getIndex( n+1 ); return ; case GL_LINE_STRIP : assert ( n < getNumIndices()-1 ); *v1 = *getIndex( n ); *v2 = *getIndex( n+1 ); return; default : break ; } assert(false); /* Should never get here */ return ; } void ssgVtxArray::print ( FILE *fd, char *indent, int how_much ) { char in [ 100 ] ; if ( how_much == 0 ) return; // dont print anything sprintf ( in, "%s ", indent ); ssgVtxTable::print ( fd, indent, how_much ) ; indices -> print ( fd, in, how_much ) ; } int ssgVtxArray::load ( FILE *fd ) { if ( ! ssgVtxTable::load(fd) || ! _ssgLoadObject ( fd, (ssgBase **) &indices, ssgTypeIndexArray () ) ) return FALSE ; if ( indices != NULL) indices -> ref () ; return TRUE ; } int ssgVtxArray::save ( FILE *fd ) { if ( ! ssgVtxTable::save(fd) || ! _ssgSaveObject ( fd, indices ) ) return FALSE ; return TRUE ; } plib-1.8.5/src/ssg/ssgIO.cxx0000644000175000001440000001326010765364437012544 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgIO.cxx 1673 2002-09-15 01:29:12Z ude $ */ #include "ssgLocal.h" static int read_error = FALSE ; static int write_error = FALSE ; int _ssgReadError (void) { return read_error ; } int _ssgWriteError (void) { return write_error ; } void _ssgReadFloat ( FILE *fd, float *var ) { if ( fread ( var, sizeof(float), 1, fd ) == 1 ) return ; read_error = TRUE ; } void _ssgWriteFloat ( FILE *fd, const float var ) { if ( fwrite ( & var, sizeof(float), 1, fd ) == 1 ) return ; write_error = TRUE ; } void _ssgReadUInt ( FILE *fd, unsigned int *var ) { if ( fread ( var, sizeof(unsigned int), 1, fd ) == 1 ) return ; read_error = TRUE ; } void _ssgWriteUInt ( FILE *fd, const unsigned int var ) { if ( fwrite ( & var, sizeof(unsigned int), 1, fd ) == 1 ) return ; write_error = TRUE ; } void _ssgReadInt ( FILE *fd, int *var ) { if ( fread ( var, sizeof(int), 1, fd ) == 1 ) return ; read_error = TRUE ; } void _ssgWriteInt ( FILE *fd, const int var ) { if ( fwrite ( & var, sizeof(int), 1, fd ) == 1 ) return ; write_error = TRUE ; } void _ssgReadUShort ( FILE *fd, unsigned short *var ) { if ( fread ( var, sizeof(unsigned short), 1, fd ) == 1 ) return ; read_error = TRUE ; } void _ssgWriteUShort ( FILE *fd, const unsigned short var ) { if ( fwrite ( & var, sizeof(unsigned short), 1, fd ) == 1 ) return ; write_error = TRUE ; } void _ssgReadShort ( FILE *fd, short *var ) { if ( fread ( var, sizeof(short), 1, fd ) == 1 ) return ; read_error = TRUE ; } void _ssgWriteShort ( FILE *fd, const short var ) { if ( fwrite ( & var, sizeof(short), 1, fd ) == 1 ) return ; write_error = TRUE ; } void _ssgReadFloat ( FILE *fd, const unsigned int n, float *var ) { if ( fread ( var, sizeof(float), n, fd ) == n ) return ; read_error = TRUE ; } void _ssgWriteFloat ( FILE *fd, const unsigned int n, const float *var ) { if ( fwrite ( var, sizeof(float), n, fd ) == n ) return ; write_error = TRUE ; } void _ssgReadBytes ( FILE *fd, const unsigned int n, void *var ) { if ( n == 0) return; if ( fread ( var, n, 1, fd ) == 1 ) return ; read_error = TRUE ; } void _ssgWriteBytes ( FILE *fd, const unsigned int n, const void *var ) { if ( n == 0) return; if ( fwrite ( var, n, 1, fd ) == 1 ) return ; write_error = TRUE ; } void _ssgReadUShort ( FILE *fd, const unsigned int n, unsigned short *var ) { if ( fread ( var, sizeof(unsigned short), n, fd ) == n ) return ; read_error = TRUE ; } void _ssgWriteUShort ( FILE *fd, const unsigned int n, const unsigned short *var ) { if ( fwrite ( var, sizeof(unsigned short), n, fd ) == n ) return ; write_error = TRUE ; } void _ssgReadShort ( FILE *fd, const unsigned int n, short *var ) { if ( fread ( var, sizeof(short), n, fd ) == n ) return ; read_error = TRUE ; } void _ssgWriteShort ( FILE *fd, const unsigned int n, const short *var ) { if ( fwrite ( var, sizeof(short), n, fd ) == n ) return ; write_error = TRUE ; } void _ssgReadUInt ( FILE *fd, const unsigned int n, unsigned int *var ) { if ( fread ( var, sizeof(unsigned int), n, fd ) == n ) return ; read_error = TRUE ; } void _ssgWriteUInt ( FILE *fd, const unsigned int n, const unsigned int *var ) { if ( fwrite ( var, sizeof(unsigned int), n, fd ) == n ) return ; write_error = TRUE ; } void _ssgReadInt ( FILE *fd, const unsigned int n, int *var ) { if ( fread ( var, sizeof(int), n, fd ) == n ) return ; read_error = TRUE ; } void _ssgWriteInt ( FILE *fd, const unsigned int n, const int *var ) { if ( fwrite ( var, sizeof(int), n, fd ) == n ) return ; write_error = TRUE ; } #define MAX_ENTITY_NAME_LENGTH 1024 void _ssgReadString ( FILE *fd, char **var ) { int i ; char s [ MAX_ENTITY_NAME_LENGTH ] ; for ( i = 0 ; i < MAX_ENTITY_NAME_LENGTH ; i++ ) { int c = getc ( fd ) ; s [ i ] = c ; if ( c == '\0' ) break ; } if ( i >= MAX_ENTITY_NAME_LENGTH-1 ) s [ MAX_ENTITY_NAME_LENGTH-1 ] = '\0' ; if ( s[0] == '\0' ) *var = NULL ; else *var = ulStrDup ( s ) ; } void _ssgWriteString ( FILE *fd, const char *var ) { if ( var != NULL ) fputs ( var, fd ) ; putc ( '\0', fd ) ; } void _ssgReadVec2 ( FILE *fd, sgVec2 var ) { _ssgReadFloat ( fd, 2, var ) ; } void _ssgWriteVec2 ( FILE *fd, const sgVec2 var ) { _ssgWriteFloat ( fd, 2, var ) ; } void _ssgReadVec3 ( FILE *fd, sgVec3 var ) { _ssgReadFloat ( fd, 3, var ) ; } void _ssgWriteVec3 ( FILE *fd, const sgVec3 var ) { _ssgWriteFloat ( fd, 3, var ) ; } void _ssgReadVec4 ( FILE *fd, sgVec4 var ) { _ssgReadFloat ( fd, 4, var ) ; } void _ssgWriteVec4 ( FILE *fd, const sgVec4 var ) { _ssgWriteFloat ( fd, 4, var ) ; } void _ssgReadMat4 ( FILE *fd, sgMat4 var ) { _ssgReadFloat ( fd, 16, (float *)var ) ; } void _ssgWriteMat4 ( FILE *fd, const sgMat4 var ) { _ssgWriteFloat ( fd, 16, (float *)var ) ; } plib-1.8.5/src/ssg/ssgParser.cxx0000644000175000001440000003274610765364437013503 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgParser.cxx 2117 2007-09-13 23:21:09Z fayjf $ */ // // File parser for SSG/PLIB // Written by Dave McClurg (dpm@efn.org) in Feb-2000 // extended by Wolfram Kuss (w_kuss@rz-online.de) in Nov-2000 // This is mainly an lexical analyzer that extracts tokens from ascii-files // Be sure to read the ssg-documentation, especially the chapter // on loaders/writers #define AM_IN_SSGPARSER_CXX 1 #include "ssgLocal.h" #include "ssgParser.h" static _ssgParserSpec default_spec = { "\r\n\t ", // delim_chars_skipable 0, // delim_chars_non_skipable NULL, // pre_processor 0, // open_brace_chars 0, // close_brace_chars '"', // quote_char 0, // comment_char "//" // comment_string } ; // Output an error void _ssgParser::error( const char *format, ... ) { char msgbuff[ 255 ]; va_list argp; char* msgptr = msgbuff; if (linenum) { msgptr += sprintf ( msgptr,"%s, line %d: ", path, linenum ); } va_start( argp, format ); vsprintf( msgptr, format, argp ); va_end( argp ); ulSetError ( UL_WARNING, "%s", msgbuff ) ; } // Output a message void _ssgParser::message( const char *format, ... ) { char msgbuff[ 255 ]; va_list argp; char* msgptr = msgbuff; if (linenum) { msgptr += sprintf ( msgptr,"%s, line %d: ", path, linenum ); } va_start( argp, format ); vsprintf( msgptr, format, argp ); va_end( argp ); ulSetError ( UL_DEBUG, "%s", msgbuff ) ; } // Opens the file and does a few internal calculations based on the spec. int _ssgParser::openFile( const char* fname, const _ssgParserSpec* _spec ) // returns TRUE on success { if ( !_spec ) _spec = &default_spec ; if ( _spec->comment_string != NULL ) { assert ( _spec->comment_string [0] != 0 ); } memset(this,0,sizeof(_ssgParser)); memcpy( &spec, _spec, sizeof(spec) ); ssgGetCurrentOptions () -> makeModelPath ( path, fname ) ; fileptr = fopen( path, "rb" ); if ( ! fileptr ) { error("cannot open file: %s",path); return FALSE; } eof = FALSE; // Calculate anyDelimiter and return. anyDelimiter[0] = 0; int length = 0; if ( spec.delim_chars_skipable != NULL ) { length +=strlen ( spec.delim_chars_skipable); strcat(anyDelimiter, spec.delim_chars_skipable); } if ( spec.delim_chars_non_skipable != NULL ) { length += strlen ( spec.delim_chars_non_skipable ) ; strcat ( anyDelimiter, spec.delim_chars_non_skipable ) ; } if ( spec.open_brace_chars != NULL ) { length +=strlen ( spec.open_brace_chars ); strcat ( anyDelimiter, spec.open_brace_chars ); } if ( spec.close_brace_chars != NULL ) { length +=strlen ( spec.close_brace_chars ) ; strcat ( anyDelimiter, spec.close_brace_chars ) ; } assert ( length < MAX_DELIMITER_CHARS ); return TRUE; } void _ssgParser::closeFile() { fclose( fileptr ) ; fileptr = 0 ; } static char *EOF_string = "EOF reached"; static char *EOL_string = "EOL reached"; char* _ssgParser::getNextToken( const char* name ) // Fetches next token, even if it has to read over some empty or comment-only lines to get to it. // Never returns NULL. Returns EOF_string on EOF. { while(!( curtok < numtok )) { //int startLevel = level; //ulSetError(UL_DEBUG, "Forcing!"); if(getLine( -999 ) == NULL) // -999 { if ( name ) error("missing %s",name) ; return EOF_string; } assert(curtok==1); curtok=0; // redo the get one token that getLine does } char* token = 0 ; assert ( curtok < numtok ); token = tokptr [ curtok++ ] ; return(token) ; } char *_ssgParser::peekAtNextToken( const char* name ) // Like getNextToken, but doesn't remove the token from the input stream { while(!( curtok < numtok )) { //int startLevel = level; //ulSetError(UL_DEBUG, "Forcing!"); if(getLine( -999 ) == NULL) // -999 { if ( name ) error("missing %s",name) ; return EOF_string; } assert(curtok==1); curtok=0; // redo the get one token that getLine does } char* token = 0 ; assert ( curtok < numtok ); token = tokptr [ curtok ] ; return(token) ; } int _ssgParser::getNextFloat( SGfloat &retVal, const char* name ) // returns TRUE on success { char *endptr, *token = getNextToken(name); retVal = SGfloat(strtod( token, &endptr)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { error("The field %s should contain a floating point number but contains %s",name, token) ; return FALSE; } } int _ssgParser::getNextInt( int & retVal, const char* name ) // returns TRUE on success { char *endptr, *token = getNextToken(name); retVal = int(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } int _ssgParser::getNextString(char *&retVal, const char* name ) // returns TRUE on success // wk: This is only for strings where we know they are inside spec.quote_chars, correct? { char *token = getNextToken( NULL ); if ( spec.quote_char && *token == spec.quote_char ) { //knock off the quotes token++ ; int len = strlen( token ) ; if (len > 0 && token[len-1] == spec.quote_char) token[len-1] = 0; } if( name != NULL && strcmp( token, name ) ) { error("Expected %s but got %s instead", name, token) ; return FALSE; } retVal = token; return TRUE; } int _ssgParser::getNextUInt( unsigned int & retVal, const char* name ) // returns TRUE on success { char *endptr, *token = getNextToken(name); retVal = (unsigned int)(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } void _ssgParser::expectNextToken( const char* name ) // Swallows the next token. If it is not name, then there is an error message { char* token = getNextToken(name); if (strcmp(token,name)) error("missing %s",name) ; } // internal function. A token consisting of a single char has been found. // This is copied to a new buffer, so that I have the space to add the 0. void _ssgParser::addOneCharToken ( char *ptr ) { assert( (long)onechartokenbuf_ptr- (long)onechartokenbuf < 4096 ) ; // Buffer overflow onechartokenbuf_ptr [ 0 ] = *ptr; onechartokenbuf_ptr [ 1 ] = 0; tokptr [ numtok++ ] = onechartokenbuf_ptr; onechartokenbuf_ptr += 2; // prepare for nect onechartoken } static const char *mystrchr( const char *string, int c ) // like strchr, but string may be NULL { if (string == NULL ) return NULL; else return strchr( string, c ); } // gets the next line (no matter where it is), without tokenizing it // useful for parsing text-formatted files which are identified by // comments at the very beginning char* _ssgParser::getRawLine() // return NULL on eof { tokbuf[0]=0; //get the next line with something on it if ( fgets ( linebuf, sizeof(linebuf), fileptr ) == NULL ) { eol = TRUE; eof = TRUE; return(0) ; } memcpy( tokbuf, linebuf, sizeof(linebuf) ) ; return tokbuf; } // wk: This works and is IMHO robust. // However, I feel it could be smaller, more elegant and readable. char* _ssgParser::getLine( int startLevel ) // return NULL on eof or if (level < startLevel) { // throw away old tokens tokbuf [ 0 ] = 0 ; numtok = 0 ; curtok = 0 ; eol = FALSE; onechartokenbuf_ptr = onechartokenbuf ; //get the next line with something on it char* ptr = tokbuf , *tptr; while ( *ptr == 0 ) { linenum++ ; if ( fgets ( linebuf, sizeof(linebuf), fileptr ) == NULL ) { eol = TRUE; eof = TRUE; return(0) ; } if(spec.pre_processor != NULL) spec.pre_processor (linebuf); memcpy( tokbuf, linebuf, sizeof(linebuf) ) ; ptr = tokbuf ; // check for comments tptr=strchr(tokbuf, spec.comment_char); if ( tptr != NULL ) *tptr = 0; if ( spec.comment_string != NULL ) { tptr=strstr(tokbuf, spec.comment_string); if ( tptr != NULL ) *tptr = 0; } //skip delim_chars if ( spec.delim_chars_skipable != NULL ) while ( *ptr && strchr(spec.delim_chars_skipable,*ptr) ) ptr++ ; } //tokenize the line numtok = 0 ; while ( *ptr ) { //skip delim_chars if ( spec.delim_chars_skipable != NULL ) while ( *ptr && strchr(spec.delim_chars_skipable,*ptr) ) ptr++ ; if ( *ptr == 0 ) break; // only skipable stuff left, dont create another token. // now unnessary?: if ( *ptr == spec.comment_char ) { *ptr = 0 ; break; } //count the token tokptr [ numtok++ ] = ptr ; //handle quoted string if ( spec.quote_char && *ptr == spec.quote_char ) { ptr++ ; while ( *ptr && *ptr != spec.quote_char ) ptr++ ; } //adjust level if ( spec.open_brace_chars && *ptr && mystrchr(spec.open_brace_chars,*ptr) ) level++ ; else if ( spec.close_brace_chars && *ptr && mystrchr(spec.close_brace_chars,*ptr) ) level-- ; else //find end of token while ( *ptr && !strchr(anyDelimiter,*ptr) ) ptr++ ; if ( *ptr != 0 ) if ( ptr == tokptr [ numtok-1 ] ) { // we dont want tokens of length zero assert(NULL==mystrchr(spec.delim_chars_skipable,*ptr)); // ptr is non-skipable, return it as token of length one numtok--; // remove zero-length token addOneCharToken ( ptr ) ; // and add new token instead *ptr++ = 0; continue; } //mark end of token if( *ptr && ( mystrchr(spec.delim_chars_non_skipable,*ptr) || mystrchr(spec.open_brace_chars,*ptr) || mystrchr(spec.close_brace_chars,*ptr) ) ) { // ptr is non-skipable, return it as token of length one // additional to the one already in tokptr [ numtok-1 ]. addOneCharToken ( ptr ) ; *ptr++ = 0; } if ( spec.delim_chars_skipable != NULL ) while ( *ptr && strchr(spec.delim_chars_skipable,*ptr) ) *ptr++ = 0 ; } if (level >= startLevel) return parseToken (0) ; return 0 ; } char* _ssgParser::parseToken( const char* name ) // returns the next token from the current line. // Never returns NULL, but may return EOL_string { char* token = EOL_string ; if ( curtok < numtok ) token = tokptr [ curtok++ ] ; else { eol = TRUE; if ( name ) error("missing %s",name) ; } return(token) ; } int _ssgParser::parseString(char *&retVal, const char* name ) // returns TRUE on success // wk: This is only for strings where we know they are inside spec.quote_chars, correct? { char* token = EOL_string ; retVal = EOL_string ; if ( curtok >= numtok ) { eol = TRUE; if ( name ) error("missing %s",name) ; return FALSE; } if ( numtok > 0 && spec.quote_char && *tokptr [ curtok ] == spec.quote_char ) { token = tokptr [ curtok++ ] ; //knock off the quotes token++ ; int len = strlen (token) ; if (len > 0 && token[len-1] == spec.quote_char) token[len-1] = 0 ; } else { if ( name ) error("missing %s",name) ; return FALSE; } retVal = token; return TRUE; } int _ssgParser::parseDouble( double &retVal, const char* name ) // returns TRUE on success { char *endptr, *token = parseToken(name); retVal = strtod( token, &endptr); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { error("The field %s should contain a floating point number but contains %s",name, token) ; return FALSE; } } int _ssgParser::parseFloat( SGfloat &retVal, const char* name ) // returns TRUE on success { char *endptr, *token = parseToken(name); retVal = SGfloat(strtod( token, &endptr)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { error("The field %s should contain a floating point number but contains %s",name, token) ; return FALSE; } } int _ssgParser::parseInt(int &retVal, const char* name ) // returns TRUE on success { char *endptr, *token = parseToken(name); retVal = int(strtol( token, &endptr, 10)); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } int _ssgParser::parseUInt(unsigned int &retVal, const char* name ) // returns TRUE on success { char *endptr, *token = parseToken(name); long l = strtol( token, &endptr, 10); if (l<0) message("The field %s should contain an UNSIGNED integer number but contains %s",name, token) ; retVal = (unsigned int)(l); if ( (endptr == NULL) || (*endptr == 0)) return TRUE; else { error("The field %s should contain an integer number but contains %s",name, token) ; return FALSE; } } void _ssgParser::expect( const char* name ) // Swallows the next token. If it is not name, then there is an error message { char* token = parseToken(name); if (strcmp(token,name)) error("missing %s",name) ; } plib-1.8.5/src/ssg/ssgLoad.cxx0000644000175000001440000001413710765364437013120 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoad.cxx 1848 2004-01-24 18:25:45Z wolfram_kuss $ */ #include "ssgLocal.h" static ssgLoaderOptions default_options ; ssgLoaderOptions *_ssgCurrentOptions = &default_options ; char* ssgLoaderOptions::make_path ( char* path, const char* dir, const char* fname ) const { if ( fname != NULL && fname [ 0 ] != '\0' ) { if ( ! ulIsAbsolutePathName ( fname ) && dir != NULL && dir[0] != '\0' ) { strcpy ( path, dir ) ; strcat ( path, "/" ) ; strcat ( path, fname ) ; } else strcpy ( path, fname ) ; //convert backward slashes to forward slashes for ( char* ptr = path ; *ptr ; ptr ++ ) { if ( *ptr == '\\' ) *ptr = '/' ; } } else path [0] = 0 ; return( path ); } void ssgLoaderOptions::makeModelPath ( char *path, const char *fname ) const { make_path ( path, model_dir, fname ) ; } void ssgLoaderOptions::makeTexturePath ( char *path, const char *fname ) const { /* Remove all leading path information. */ const char* seps = "\\/" ; const char* fn = & fname [ strlen ( fname ) - 1 ] ; for ( ; fn != fname && strchr(seps,*fn) == NULL ; fn-- ) /* Search back for a seperator */ ; if ( strchr(seps,*fn) != NULL ) fn++ ; fname = fn ; make_path ( path, texture_dir, fname ) ; } ssgLeaf* ssgLoaderOptions::createLeaf ( ssgLeaf* leaf, const char* parent_name ) { if ( leaf != NULL ) { /* try to do some state sharing */ ssgState* st = leaf -> getState () ; if ( st != NULL && st -> isA ( ssgTypeSimpleState () ) ) { ssgSimpleState *ss = (ssgSimpleState*) st ; ssgSimpleState *match = shared_states.findMatch ( ss ) ; if ( match != NULL ) leaf -> setState ( match ) ; else shared_states.add ( ss ) ; } } return leaf ; } ssgTexture* ssgLoaderOptions::createTexture ( char* tfname, int wrapu, int wrapv, int mipmap ) { char filename [ 1024 ] ; makeTexturePath ( filename, tfname ) ; ssgTexture *tex = shared_textures.findByFilename ( filename ) ; if ( tex ) return tex ; tex = new ssgTexture ( filename, wrapu, wrapv, mipmap ) ; if ( tex ) shared_textures.add ( tex ) ; return tex ; } ssgTransform* ssgLoaderOptions::createTransform ( ssgTransform* tr, ssgTransformArray* ta ) const { if ( ta != NULL ) tr -> setUserData ( ta ) ; return tr ; } ssgSelector* ssgLoaderOptions::createSelector ( ssgSelector* s ) const { return s ; } void ssgLoaderOptions::setModelDir ( const char *s ) { delete [] model_dir ; model_dir = ulStrDup ( s ) ; } void ssgLoaderOptions::setTextureDir ( const char *s ) { delete [] texture_dir ; texture_dir = ulStrDup ( s ) ; } static const char *file_extension ( const char *fname ) { const char *p = & ( fname [ strlen(fname) ] ) ; while ( p != fname && *p != '/' && *p != '.' ) p-- ; return p ; } struct _ssgModelFormat { const char *extension ; ssgLoadFunc *loadfunc ; ssgSaveFunc *savefunc ; } ; enum { MAX_FORMATS = 100 } ; static _ssgModelFormat formats [ MAX_FORMATS ] ; static int num_formats = 0 ; void ssgAddModelFormat ( const char* extension, ssgLoadFunc *loadfunc , ssgSaveFunc *savefunc ) { for ( int i = 0 ; i < num_formats ; i++ ) { if ( ulStrEqual ( formats [ i ] . extension, extension ) ) { formats [ i ] . extension = extension ; formats [ i ] . loadfunc = loadfunc ; formats [ i ] . savefunc = savefunc ; return ; } } if ( num_formats < MAX_FORMATS ) { formats [ num_formats ] . extension = extension ; formats [ num_formats ] . loadfunc = loadfunc ; formats [ num_formats ] . savefunc = savefunc ; num_formats ++ ; } else { ulSetError ( UL_WARNING, "ssgAddModelFormat: too many formats" ); } } ssgEntity *ssgLoad ( const char *fname, const ssgLoaderOptions* options ) { if ( fname == NULL || *fname == '\0' ) return NULL ; // find appropiate loader and call its loadfunc const char *extn = file_extension ( fname ) ; if ( *extn != '.' ) { ulSetError ( UL_WARNING, "ssgLoad: Cannot determine file type for '%s'", fname ); return NULL ; } extern int g_noLoDs; g_noLoDs = 1; _ssgModelFormat *f = formats ; for ( int i=0; iloadfunc != NULL && ulStrEqual ( extn, f->extension ) ) { ssgEntity* entity = f -> loadfunc( fname, options ) ; ssgGetCurrentOptions () -> endLoad () ; return entity ; } } ulSetError ( UL_WARNING, "ssgLoad: Unrecognised file type '%s'", extn ) ; return NULL ; } int ssgSave ( const char *fname, ssgEntity *ent ) { if ( fname == NULL || ent == NULL || *fname == '\0' ) return FALSE ; const char *extn = file_extension ( fname ) ; if ( *extn != '.' ) { ulSetError ( UL_WARNING, "ssgSave: Cannot determine file type for '%s'", fname ); return FALSE ; } _ssgModelFormat *f = formats ; for ( int i=0; isavefunc != NULL && ulStrEqual ( extn, f->extension ) ) return f->savefunc( fname, ent ) ; } ulSetError ( UL_WARNING, "ssgSave: Unrecognised file type '%s'", extn ) ; return FALSE ; } plib-1.8.5/src/ssg/ssgLoadASE.cxx0000644000175000001440000012506210765364437013451 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgLoadASE.cxx 1988 2004-10-29 22:41:37Z wolfram_kuss $ */ /**** * NAME * ssgLoadASE -- ASE model loader * * DESCRIPTION * ssgLoadASE will load an ASE model exported from 3dsmax using * the standard ascii export v2.00 plugin. * * The material list and geometry objects are parsed and converted * into an SSG scene graph. shape, light, camera, and helper * nodes are ignored. * * If the geometry has vertex colours (pre-lit) then lighting is * disabled for that leaf. * * mesh animation creates ssgSelector entities. transform * animation creates ssgTransform entities with ssgTransformArray * user_data. see the viewer example for details on controlling * animation. * * NOTE: be sure you _reset the transform_ of the top-level object * in 3dsmax before exporting transform animation. * * Please report any bugs to the author. Complete information about * the ASE format can be found in the 3dsmax SDK source code. * * AUTHOR * Dave McClurg * * CREATION DATE * Feb-2000 * * MODIFICATION HISTORY * November 2000 - v1.1, Dave McClurg * o support for transform animation samples ****/ #include "ssgLocal.h" #include "ssgParser.h" #define u32 unsigned int #define f32 float #define cchar const char static ssgLoaderOptions* current_options = NULL ; struct aseVertexBuffer { bool use_flag ; int index ; sgVec3 v ; sgVec2 tv ; sgVec3 cv ; } ; struct aseFace { u32 v[3]; u32 tv[3]; u32 cv[3]; u32 sub_index; // SAC: Additional vals to track normals for each face vertex. // Since each vertex can supposedly have various normals if shared by two // non-smoothed faces, we track them per face. I haven't checked this as // good as I should have with smoothed & unsmoothed shapes :) bool has_vertex_normals; sgVec3 vn [3]; }; struct aseTransform { sgVec3 pos ; sgVec3 axis ; // axis of rotation (unit vector) f32 angle ; // angle of rotation in radians (always >0) sgVec3 scale ; } ; struct aseMesh { u32 num_faces ; u32 num_verts ; u32 num_tverts ; u32 num_cverts ; aseFace* faces ; sgVec3* verts ; sgVec2* tverts ; sgVec3* cverts ; aseMesh(); ~aseMesh(); }; struct aseObject { enum Type { GEOM, HELPER, CAMERA } ; int type ; char* name ; char* parent ; bool inherit_pos [3] ; sgVec3 pos ; sgVec3 target ; u32 mat_index ; u32 num_tkeys ; aseTransform* tkeys ; enum { MAX_FRAMES = 256 }; aseMesh* mesh_list[ MAX_FRAMES ]; int mesh_count ; aseObject( Type type ); ~aseObject(); }; struct aseMaterial { char* name ; u32 mat_index ; u32 sub_index ; bool sub_flag ; sgVec4 amb ; sgVec4 diff ; sgVec4 spec ; f32 shine ; f32 transparency ; char* tfname ; sgVec2 texrep ; sgVec2 texoff ; }; #define MAX_MATERIALS 1000 static aseMaterial** materials ; static u32 num_materials ; static u32 first_frame ; static u32 last_frame ; static u32 frame_speed ; static u32 ticks_per_frame ; static u32 num_frames=0 ; static _ssgParserSpec parser_spec = { "\r\n\t ", // delim_chars_skipable 0, // delim_chars_non_skipable NULL, // pre_processor "{", // open_brace_chars "}", // close_brace_chars '"', // quote_char 0, // comment_char 0 // comment_string } ; static _ssgParser parser; static ssgBranch* top_branch; aseMesh::aseMesh() { memset(this,0,sizeof(aseMesh)); } aseMesh::~aseMesh() { delete[] faces; delete[] verts; delete[] tverts; delete[] cverts; } aseObject::aseObject( aseObject::Type _type ) { memset(this,0,sizeof(aseObject)); type = _type ; } aseObject::~aseObject() { delete[] name; delete[] parent; delete[] tkeys; for ( int i=0; imat_index == mat_index && mat->sub_flag ) count ++; } return count ; } static aseMaterial* find_material( u32 mat_index, u32 sub_index ) { u32 i; //find sub-material for ( i=0; imat_index == mat_index && mat->sub_index == sub_index ) return(mat); } //just match material # for ( i=0; imat_index == mat_index ) return(mat); } parser.error("unknown material #%d",mat_index); return(0); } static ssgSimpleState* make_state( aseMaterial* mat, bool prelit ) { if ( mat -> tfname != NULL) { ssgSimpleState *st = current_options -> createSimpleState ( mat -> tfname ) ; if ( st != NULL ) return st ; } ssgSimpleState *st = new ssgSimpleState () ; bool has_alpha = false ; if (mat -> tfname != NULL) { ssgTexture* tex = current_options -> createTexture ( mat->tfname ) ; has_alpha = tex -> hasAlpha () ; st -> setTexture ( tex ) ; st -> enable ( GL_TEXTURE_2D ) ; } else { st -> disable( GL_TEXTURE_2D ) ; } st -> disable ( GL_ALPHA_TEST ) ; if ( sgCompareFloat ( mat -> transparency, 0.0f, 0.01f ) > 0 || has_alpha ) { st -> enable ( GL_BLEND ) ; st -> setTranslucent () ; } else { st -> disable ( GL_BLEND ) ; st -> setOpaque () ; } if ( prelit ) { st -> disable ( GL_LIGHTING ) ; } else { st -> setMaterial ( GL_AMBIENT, mat -> amb ) ; st -> setMaterial ( GL_DIFFUSE, mat -> diff ) ; st -> setMaterial ( GL_SPECULAR, mat -> spec ) ; st -> setShininess ( mat -> shine ) ; st -> disable ( GL_COLOR_MATERIAL ) ; st -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ; st -> enable ( GL_LIGHTING ) ; } st -> setShadeModel ( GL_SMOOTH ) ; return st ; } static ssgSimpleState* get_state( aseMaterial* mat, bool prelit ) { // is material an ifl (image file list) #ifdef UL_WIN32 if ( strnicmp ( "ifl_", mat -> name, 4 ) == 0 ) #else if ( strncasecmp ( "ifl_", mat -> name, 4 ) == 0 ) #endif { u32 num_subs = count_sub_materials ( mat -> mat_index ); if ( num_subs < 2 ) parser.error("ifl material only has <2 frames: %s",mat -> name); ssgStateSelector* selector = new ssgStateSelector ( num_subs ) ; for ( u32 i=0; i mat_index, i ) ; assert ( mat2 != NULL ) ; ssgSimpleState* st = make_state ( mat2, prelit ) ; selector -> setStep ( i, st ) ; } selector -> selectStep ( 0 ) ; return selector ; } return make_state ( mat, prelit ) ; } static int parse_map( aseMaterial* mat ) // return TRUE on success { char* token; int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (!strcmp(token,"*BITMAP")) { if ( mat->tfname != NULL ) parser.error("multiple textures for material: %s",mat->name); else { char* fname; if (! parser.parseString(fname, "bitmap filename") ) return FALSE; //strip existing directory from fname char* slash = strrchr ( fname, '/' ) ; if ( !slash ) slash = strrchr ( fname, '\\' ) ; //for dos if ( slash ) fname = slash + 1 ; mat->tfname = ulStrDup ( fname ) ; } } else if (!strcmp(token,"*UVW_U_TILING")) { if (! parser.parseFloat(mat->texrep[0], "tiling.u")) return FALSE; } else if (!strcmp(token,"*UVW_V_TILING")) { if (! parser.parseFloat(mat->texrep[1], "tiling.v")) return FALSE; } else if (!strcmp(token,"*UVW_U_OFFSET")) { if (! parser.parseFloat(mat->texoff[0] , "offset.u")) return FALSE; } else if (!strcmp(token,"*UVW_V_OFFSET")) { if (! parser.parseFloat(mat->texoff[1] , "offset.v")) return FALSE; } } return TRUE; } static int parse_material( u32 mat_index, u32 sub_index, cchar* mat_name ) // return TRUE on success { if ( num_materials >= MAX_MATERIALS ) { parser.error( "too many materials" ); // skip material definition int startLevel = parser.level; while (parser.getLine( startLevel ) != NULL) ; return TRUE; // go on parsing } aseMaterial* mat = new aseMaterial; materials [ num_materials++ ] = mat ; memset ( mat, 0, sizeof(aseMaterial) ) ; mat->mat_index = mat_index ; mat->sub_index = sub_index ; mat->sub_flag = ( mat_name != 0 ) ; mat->texrep[0] = 1.0f ; mat->texrep[1] = 1.0f ; mat->texoff[0] = 0.0f ; mat->texoff[1] = 0.0f ; char* token; int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (!strcmp(token,"*MATERIAL_NAME")) { char* name; if (! parser.parseString(name, "mat name") ) return FALSE; if ( mat->sub_flag ) { char buff [ 256 ] ; sprintf( buff, "%s, sub#%d", mat_name, sub_index ); mat->name = ulStrDup ( buff ) ; } else mat->name = ulStrDup ( name ) ; } else if (!strcmp(token,"*MATERIAL_AMBIENT")) { if (! parser.parseFloat(mat->amb[ 0 ], "amb.r")) return FALSE; if (! parser.parseFloat(mat->amb[ 1 ], "amb.g")) return FALSE; if (! parser.parseFloat(mat->amb[ 2 ], "amb.b")) return FALSE; mat->amb[ 3 ] = 1.0f; } else if (!strcmp(token,"*MATERIAL_DIFFUSE")) { if (! parser.parseFloat(mat->diff[ 0 ], "diff.r")) return FALSE; if (! parser.parseFloat(mat->diff[ 1 ], "diff.g")) return FALSE; if (! parser.parseFloat(mat->diff[ 2 ], "diff.b")) return FALSE; mat->diff[ 3 ] = 1.0f; } else if (!strcmp(token,"*MATERIAL_SPECULAR")) { if (! parser.parseFloat(mat->spec[ 0 ], "spec.r")) return FALSE; if (! parser.parseFloat(mat->spec[ 1 ], "spec.g")) return FALSE; if (! parser.parseFloat(mat->spec[ 2 ], "spec.b")) return FALSE; mat->spec[ 3 ] = 1.0f; } else if (!strcmp(token,"*MATERIAL_SHINE")) { if (! parser.parseFloat(mat->shine, "shine")) return FALSE; // SAC: Shine seems off. If I load a 3ds of the same shape // the shine is 256x as much and works better, so I'll tweak // the val here :) I couldn't clarify the range used by // MAX SDK anywhere in the docs (though this assumes 0 - 0.5). // OpenGL is 0-128. mat->shine = mat->shine * 256.0f; if ( mat->shine > 128 ) mat->shine = 128; } else if (!strcmp(token,"*MATERIAL_TRANSPARENCY")) { if (! parser.parseFloat(mat->transparency, "transparency")) return FALSE; } else if (!strcmp(token,"*MAP_DIFFUSE")) { //Need: what about MAP_GENERIC, MAP_AMBIENT, etc?? if (! parse_map( mat )) return FALSE; } else if (!strcmp(token,"*SUBMATERIAL")) { u32 sub_index; if (! parser.parseUInt(sub_index, "sub mat #")) return FALSE; if (! parse_material( mat_index, sub_index, mat->name )) return FALSE; } } //parser.message("material: %s (%s)",mat->name,mat->tfname); return TRUE; } static int parse_material_list() // return TRUE on success { if ( num_materials ) parser.error("multiple material lists"); char* token; int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (!strcmp(token,"*MATERIAL")) { u32 mat_index; if (! parser.parseUInt(mat_index, "mat #")) return FALSE; if (! parse_material( mat_index, 9999, NULL )) return FALSE; } } return TRUE; } static int parse_mesh( aseObject* obj ) { aseMesh* mesh = NULL ; u32 mesh_face_normal_index = 0x7fffffff; u32 mesh_face_normal_count = 0; char* token; int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if ( mesh == NULL ) { u32 frame = aseObject::MAX_FRAMES ; if (!strcmp(token,"*TIMEVALUE")) { u32 time; if (! parser.parseUInt(time, "time")) return FALSE; frame = (time + (ticks_per_frame-1)) / ticks_per_frame - first_frame; } else { parser.error("missing *TIMEVALUE"); frame = aseObject::MAX_FRAMES ; } if ( frame >= aseObject::MAX_FRAMES || obj->mesh_list [ frame ] != NULL ) { //ignore this mesh while (parser.getLine( startLevel )) ; return TRUE; // go on parsing } mesh = new aseMesh ; obj->mesh_list [ frame ] = mesh ; obj->mesh_count ++ ; } else if (!strcmp(token,"*MESH_NUMFACES")) { if (mesh -> faces) parser.error("%s already seen",token); else { if (! parser.parseUInt(mesh -> num_faces, "num_faces")) return FALSE; mesh -> faces = new aseFace[ mesh -> num_faces ]; // SAC: Help clear all the has_vertex_normals flags memset ( mesh -> faces, 0, mesh -> num_faces * sizeof (aseFace) ); } } else if (!strcmp(token,"*MESH_NUMTVFACES")) { u32 ntfaces; if (! parser.parseUInt(ntfaces, "ntfaces")) return FALSE; if (ntfaces != mesh -> num_faces) parser.error("NUMTFACES(%d) != NUMFACES(%d)",ntfaces,mesh -> num_faces); } else if (!strcmp(token,"*MESH_NUMCVFACES")) { u32 ncfaces; if (! parser.parseUInt(ncfaces, "ncfaces")) return FALSE; if (ncfaces != mesh -> num_faces) parser.error("NUMCFACES(%d) != NUMFACES(%d)",ncfaces,mesh -> num_faces); } else if (!strcmp(token,"*MESH_NUMVERTEX")) { if (mesh -> verts) parser.error("%s already seen",token); else { if (! parser.parseUInt(mesh -> num_verts, "num_verts")) return FALSE; mesh -> verts = new sgVec3[ mesh -> num_verts ]; } } else if (!strcmp(token,"*MESH_NUMTVERTEX")) { if (mesh -> tverts) parser.error("%s already seen",token); else { if (! parser.parseUInt(mesh -> num_tverts, "num_tverts")) return FALSE; if (mesh -> num_tverts) mesh -> tverts = new sgVec2[ mesh -> num_tverts ]; } } else if (!strcmp(token,"*MESH_NUMCVERTEX")) { if (mesh -> cverts) parser.error("%s already seen",token); else { if (! parser.parseUInt(mesh -> num_cverts, "num_cverts")) return FALSE; if (mesh -> num_cverts) mesh -> cverts = new sgVec3[ mesh -> num_cverts ]; } } else if (!strcmp(token,"*MESH_FACE")) { u32 index; // wk: The old parseInt converted a "3:" into 3, // the new would give an error. Therefore I had to change this code: char *my_endptr, *my_token = parser.parseToken("face #"); if (my_token[strlen(my_token)-1]==':') my_token[strlen(my_token)-1]=0; index = (unsigned int)(strtol( my_token, &my_endptr, 10)); if ( (my_endptr != NULL) && (*my_endptr != 0)) { parser.error("The field face # should contain an integer number but contains %s", my_token) ; return FALSE; } if (index >= mesh -> num_faces) parser.error("bad face #"); else { aseFace& face = mesh -> faces[ index ]; parser.expect("A:"); if (! parser.parseUInt(face.v[0], "face.v[0]")) return FALSE; parser.expect("B:"); if (! parser.parseUInt(face.v[1], "face.v[1]")) return FALSE; parser.expect("C:"); if (! parser.parseUInt(face.v[2], "face.v[2]")) return FALSE; //search for other flags token = parser.parseToken(0); while ( ! parser.eol ) { if ( strcmp(token,"*MESH_MTLID") == 0 ) { if (! parser.parseUInt(face.sub_index, "mat #")) return FALSE; } token = parser.parseToken(0); } } } else if (!strcmp(token,"*MESH_TFACE")) { u32 index; if (! parser.parseUInt(index, "tface #")) return FALSE; if (index >= mesh -> num_faces) parser.error("bad tface #"); else { aseFace& face = mesh -> faces[ index ]; if (! parser.parseUInt(face.tv[0], "tface.tv[0]")) return FALSE; if (! parser.parseUInt(face.tv[1], "tface.tv[1]")) return FALSE; if (! parser.parseUInt(face.tv[2], "tface.tv[2]")) return FALSE; } } else if (!strcmp(token,"*MESH_CFACE")) { u32 index; if (! parser.parseUInt(index, "cface #")) return FALSE; if (index >= mesh -> num_faces) parser.error("bad cface #"); else { aseFace& face = mesh -> faces[ index ]; if (! parser.parseUInt(face.cv[0], "tface.cv[0]")) return FALSE; if (! parser.parseUInt(face.cv[1], "tface.cv[1]")) return FALSE; if (! parser.parseUInt(face.cv[2], "tface.cv[2]")) return FALSE; } } // SAC: START OF VERTEX NORMAL PARSING SECTION // NOTE: Assumes that three correctly-ordered *MESH_VERTEXNORMAL lines // come after each *MESH_FACENORMAL line. Which seems to be the case // in current exporter else if (!strcmp(token,"*MESH_FACENORMAL")) { if (! parser.parseUInt(mesh_face_normal_index, "face normal #")) return FALSE; mesh_face_normal_count = 0; } else if (!strcmp(token,"*MESH_VERTEXNORMAL")) { //int nverts = mesh -> num_verts; if ( mesh_face_normal_index >= mesh -> num_faces ) parser.error("bad mesh_face_normal_index #"); if ( mesh_face_normal_count >= 3 ) parser.error("bad mesh_face_normal_count"); aseFace& face = mesh -> faces[ mesh_face_normal_index ]; sgVec3& vn = face . vn [ mesh_face_normal_count ]; face.has_vertex_normals = true; u32 vertex_index; if (! parser.parseUInt(vertex_index, "vertex normal #")) return FALSE; if ( face.v [mesh_face_normal_count] != vertex_index ) parser.error("bad MESH_VERTEXNORMAL entries out of order!"); if (! parser.parseFloat(vn[0], "vertexNormal.x")) return FALSE; if (! parser.parseFloat(vn[1], "vertexNormal.y")) return FALSE; if (! parser.parseFloat(vn[2], "vertexNormal.z")) return FALSE; // sgNormaliseVec3 ( vn ) ; mesh_face_normal_count++; } // SAC: END OF VERTEX NORMAL PARSING SECTION else if (!strcmp(token,"*MESH_VERTEX")) { u32 index; if (! parser.parseUInt(index, "vertex #")) return FALSE; if (index >= mesh -> num_verts) parser.error("bad vertex #"); else { sgVec3& vert = mesh -> verts[ index ]; if (! parser.parseFloat(vert[0], "vert.x")) return FALSE; if (! parser.parseFloat(vert[1], "vert.y")) return FALSE; if (! parser.parseFloat(vert[2], "vert.z")) return FALSE; } } else if (!strcmp(token,"*MESH_TVERT")) { u32 index; if (! parser.parseUInt(index, "tvertex #")) return FALSE; if (index >= mesh -> num_tverts) parser.error("bad tvertex #"); else { sgVec2& tvert = mesh -> tverts[ index ]; if (! parser.parseFloat(tvert[0], "tvert.x")) return FALSE; if (! parser.parseFloat(tvert[1], "tvert.y")) return FALSE; } } else if (!strcmp(token,"*MESH_VERTCOL")) { u32 index; if (! parser.parseUInt(index, "cvertex #")) return FALSE; if (index >= mesh -> num_cverts) parser.error("bad cvertex #"); else { sgVec3& cvert = mesh -> cverts[ index ]; if (! parser.parseFloat(cvert[0], "cvert.x")) return FALSE; if (! parser.parseFloat(cvert[1], "cvert.y")) return FALSE; if (! parser.parseFloat(cvert[2], "cvert.z")) return FALSE; } } } return TRUE; } static void get_texcoord ( aseMaterial* mat, sgVec2 tv ) { //invert Y coordinate tv[1] = 1.0f - tv[1] ; tv[0] *= mat->texrep[0] ; tv[1] *= mat->texrep[1] ; tv[0] += mat->texoff[0] ; tv[1] += mat->texoff[1] ; } static ssgLeaf* add_points( aseObject* obj, aseMesh* mesh ) { ssgVertexArray* vl = NULL ; if ( obj->type == aseObject::CAMERA ) { /* compute a normalized target vector */ sgVec3 target ; sgCopyVec3 ( target, obj->target ) ; sgSubVec3 ( target, obj->pos ) ; SGfloat len = sgLengthVec3 ( target ) ; if ( len == SG_ZERO ) { vl = new ssgVertexArray ( 1 ) ; vl -> add ( obj->pos ) ; } else { vl = new ssgVertexArray ( 2 ) ; sgNormaliseVec3 ( target ) ; sgAddVec3 ( target, obj->pos ) ; vl -> add ( obj->pos ) ; vl -> add ( target ) ; } } else if ( mesh != NULL ) { u32 num_verts = mesh -> num_verts ; if ( num_verts == 0 ) return NULL; vl = new ssgVertexArray ( num_verts ) ; //pass the data to ssg sgVec3* vert = mesh -> verts ; for ( u32 i=0; i < num_verts; i++, vert++ ) vl -> add ( *vert ) ; } else { return NULL ; } ssgVtxTable* leaf = new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, NULL ) ; if ( leaf != NULL ) { // leaves with no faces are used for game logic // and should not be culled and rendered leaf -> clrTraversalMaskBits ( SSGTRAV_CULL ) ; } return ssgGetCurrentOptions () -> createLeaf ( leaf, obj -> name ) ; } static ssgLeaf* add_mesh( aseObject* obj, aseMesh* mesh, u32 sub_index ) { u32 i ; aseMaterial* mat = find_material ( obj->mat_index, sub_index ) ; if ( mat == NULL ) return NULL ; //compute number of faces for this sub-material u32 num_faces = mesh -> num_faces ; if ( mat->sub_flag ) { num_faces = 0 ; aseFace* face = mesh -> faces ; for ( i=0; i num_faces; i++, face++ ) { if ( face->sub_index == mat->sub_index ) num_faces ++ ; } } if ( num_faces == 0 ) return NULL ; if ( mesh -> cverts == NULL ) { u32 num_verts = num_faces * 3 ; //pass the data to ssg ssgSimpleState* st = get_state ( mat, false ) ; ssgColourArray* cl = new ssgColourArray ( 1 ) ; ssgVertexArray* vl = new ssgVertexArray ( num_verts ) ; ssgNormalArray* nl = new ssgNormalArray ( num_verts ) ; ssgTexCoordArray* tl = 0 ; if ( mesh -> tverts ) tl = new ssgTexCoordArray ( num_verts ) ; //set the material colour sgVec4 c ; sgCopyVec3 ( c, mat -> diff ) ; c[3] = 1.0f - mat -> transparency ; cl -> add ( c ) ; aseFace* face = mesh -> faces ; for ( i=0; i num_faces; i++, face++ ) { if ( mat->sub_flag && face->sub_index != mat->sub_index ) continue ; sgVec3 n ; sgMakeNormal ( n, mesh -> verts[ face->v[0] ] , mesh -> verts[ face->v[1] ] , mesh -> verts[ face->v[2] ] ) ; for ( u32 j=0; j<3; j++ ) { vl -> add ( mesh -> verts[ face->v[j] ] ) ; // SAC: If per-vertex normals were found, use 'em. // Else use the face normal computed above if ( face -> has_vertex_normals ) nl -> add ( face->vn [j] ) ; else nl -> add ( n ) ; if ( mesh -> tverts ) { sgVec2 tv ; sgCopyVec2 ( tv, mesh -> tverts[ face->tv[j] ] ) ; get_texcoord ( mat, tv ) ; tl -> add ( tv ) ; } } } ssgVtxTable* leaf = new ssgVtxTable ( GL_TRIANGLES, vl, nl, tl, cl ) ; leaf -> setCullFace ( TRUE ) ; leaf -> setState ( st ) ; return current_options -> createLeaf ( leaf, obj->name ) ; } //allocate map_index array int* map_index = new int [ mesh -> num_faces * 3 ] ; //allocate the vertex list u32 max_verts = mesh -> num_verts + mesh -> num_faces * 3 ; aseVertexBuffer* vert_list = new aseVertexBuffer [ max_verts ] ; //mark each vertex as *not* used aseVertexBuffer* vert = vert_list ; for ( i=0; i < max_verts; i++, vert++ ) { vert -> use_flag = false ; } u32 extra_verts = 0 ; //build the vertex list aseFace* face = mesh -> faces ; for ( i=0; i num_faces; i++, face++ ) { if ( mat->sub_flag && face->sub_index != mat->sub_index ) continue ; for ( u32 j=0; j<3; j++ ) { int k = i*3+j; map_index [k] = face->v[j] ; vert = vert_list + map_index[k]; if ( vert -> use_flag ) { //check for match bool match = true ; if ( mesh -> tverts && sgCompareVec2 ( vert -> tv, mesh -> tverts[ face->tv[j] ], 0.0f ) != 0 ) match = false ; else if ( mesh -> cverts && sgCompareVec3 ( vert -> cv, mesh -> cverts[ face->cv[j] ], 0.0f ) != 0 ) match = false ; if ( match ) continue ; //texcoord and color matches other vertex extra_verts ++ ; map_index [k] = mesh -> num_verts + k ; vert = vert_list + map_index[k]; } //add the vertex vert -> use_flag = true; sgCopyVec3 ( vert -> v, mesh -> verts[ face->v[j] ] ) ; if ( mesh -> tverts ) sgCopyVec2 ( vert -> tv, mesh -> tverts[ face->tv[j] ] ) ; if ( mesh -> cverts ) sgCopyVec3 ( vert -> cv, mesh -> cverts[ face->cv[j] ] ) ; } } //assign a unique index to each vertex int num_verts = 0 ; vert = vert_list; for ( i=0; i < max_verts; i++, vert++ ) { if ( vert -> use_flag ) vert -> index = num_verts ++; } //if ( extra_verts > 0 ) // ulSetError( UL_DEBUG, "%d verts; %d added", num_verts-extra_verts, extra_verts ); //else // ulSetError( UL_DEBUG, "%d verts", num_verts ); //pass the data to ssg ssgSimpleState* st = get_state ( mat, ( mesh -> cverts != NULL ) ) ; ssgIndexArray* il = new ssgIndexArray ( num_faces * 3 ) ; ssgVertexArray* vl = new ssgVertexArray ( num_verts ) ; ssgTexCoordArray* tl = 0 ; ssgColourArray* cl = 0 ; if ( mesh -> tverts ) tl = new ssgTexCoordArray ( num_verts ) ; if ( mesh -> cverts ) cl = new ssgColourArray ( num_verts ) ; //build the index list face = mesh -> faces ; for ( i=0; i num_faces; i++, face++ ) { if ( mat->sub_flag && face->sub_index != mat->sub_index ) continue ; for ( u32 j=0; j<3; j++ ) { int k = i*3+j; vert = vert_list + map_index[k]; if ( ! vert -> use_flag ) ulSetError ( UL_FATAL, "internal error" ) ; il -> add ( vert -> index ) ; } } //copy the vertex lists vert = vert_list; for ( i=0; i < max_verts; i++, vert++ ) { if ( vert -> use_flag ) { vl -> add ( vert -> v ) ; if ( mesh -> tverts ) { sgVec2 tv ; sgCopyVec2 ( tv, vert -> tv ) ; get_texcoord ( mat, tv ) ; tl -> add ( tv ) ; } if ( mesh -> cverts ) { sgVec4 c ; sgCopyVec3 ( c, vert -> cv ) ; c[3] = 1.0f - mat -> transparency ; cl -> add ( c ) ; } } } delete[] vert_list ; delete[] map_index ; ssgVtxArray* leaf = new ssgVtxArray ( GL_TRIANGLES, vl, NULL, tl, cl, il ) ; leaf -> setCullFace ( TRUE ) ; leaf -> setState ( st ) ; return current_options -> createLeaf ( leaf, obj -> name ) ; } static aseTransform* get_tkey( aseObject* obj, u32 time ) { if ( obj->tkeys == NULL ) { obj->num_tkeys = 0; obj->tkeys = new aseTransform [ num_frames ] ; //initialize aseTransform* tkey = obj->tkeys ; for ( u32 i=0; ipos, 0, 0, 0 ) ; sgSetVec3 ( tkey->axis, 0, 0, 1 ) ; tkey->angle = 0.0f ; sgSetVec3 ( tkey->scale, 1, 1, 1 ) ; } } //compute frame number u32 frame = time / ticks_per_frame - first_frame; if ((time % ticks_per_frame) != 0 || frame >= num_frames) parser.error("bad time"); if ( frame+1 > obj->num_tkeys ) obj->num_tkeys = frame+1; return( &obj->tkeys[ frame ] ); } #define MAX_TKEY_PER_MESH 256 static int parse_tkeys( aseObject* obj ) { bool match = false ; void *tkeys[MAX_TKEY_PER_MESH]; int num_tkeys=0; char* token; int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (!strcmp(token,"*NODE_NAME")) { char* name; if (! parser.parseString(name, "obj name")) return FALSE; if ( obj->name && !strcmp(name,obj->name) ) match = true ; } else if (match) { if (!strcmp(token,"*CONTROL_POS_SAMPLE")) { u32 time; if (! parser.parseUInt(time, "time")) return FALSE; aseTransform* tkey = get_tkey( obj, time ); if (! parser.parseFloat(tkey->pos[0], "pos.x")) return FALSE; if (! parser.parseFloat(tkey->pos[1], "pos.y")) return FALSE; if (! parser.parseFloat(tkey->pos[2], "pos.z")) return FALSE; if ( obj->parent == NULL ) { sgSubVec3 ( tkey->pos, obj->pos ) ; } else { for ( int i=0; i<3; i++ ) { if ( obj->inherit_pos[i] ) tkey->pos[i] -= obj->pos[i] ; } } //copy the position forward for ( u32 i=obj->num_tkeys; itkeys[ i ].pos, tkey->pos ) ; } else if (!strcmp(token,"*CONTROL_ROT_SAMPLE")) { u32 time; if (!parser.parseUInt(time, "time")) return FALSE; aseTransform* tkey = get_tkey( obj, time ); if (! parser.parseFloat(tkey->axis[0], "axis.x")) return FALSE; if (! parser.parseFloat(tkey->axis[1], "axis.y")) return FALSE; if (! parser.parseFloat(tkey->axis[2], "axis.z")) return FALSE; if (! parser.parseFloat(tkey->angle, "angle")) return FALSE; } else if (!strcmp(token,"*CONTROL_TCB_ROT_KEY")) { u32 time; if (!parser.parseUInt(time, "time")) return FALSE; aseTransform* tkey = new aseTransform; tkeys[num_tkeys++] = tkey; assert(num_tkeys < MAX_TKEY_PER_MESH); sgSetVec3 ( tkey->pos, 0, 0, 0 ) ; // "TCB": only rotation allowed :-/ sgSetVec3 ( tkey->axis, 0, 0, 1 ) ; tkey->angle = 0.0f ; sgSetVec3 ( tkey->scale, 1, 1, 1 ) ; // *CONTROL_TCB_ROT_KEY 160 -0.9949 -0.0914 0.0434 3.1336 0.0000 0.0000 0.0000 0.0000 0.0000 if (! parser.parseFloat(tkey->axis[0], "axis.x")) return FALSE; if (! parser.parseFloat(tkey->axis[1], "axis.y")) return FALSE; if (! parser.parseFloat(tkey->axis[2], "axis.z")) return FALSE; if (! parser.parseFloat(tkey->angle, "angle")) return FALSE; float dummy; if (! parser.parseFloat(dummy, "tens")) return FALSE; if (! parser.parseFloat(dummy, "cont")) return FALSE; if (! parser.parseFloat(dummy, "bias")) return FALSE; if (! parser.parseFloat(dummy, "easeIn")) return FALSE; if (! parser.parseFloat(dummy, "easeOut")) return FALSE; } else if (!strcmp(token,"*CONTROL_SCALE_SAMPLE")) { u32 time; if (! parser.parseUInt(time, "time")) return FALSE; aseTransform* tkey = get_tkey( obj, time ); if (! parser.parseFloat(tkey->scale[0], "scale.x")) return FALSE; if (! parser.parseFloat(tkey->scale[1], "scale.y")) return FALSE; if (! parser.parseFloat(tkey->scale[2], "scale.z")) return FALSE; } } } if(num_tkeys) { obj->num_tkeys = num_tkeys; obj->tkeys = new aseTransform [ num_tkeys ] ; for(int i=0; itkeys[i] = *((aseTransform *)tkeys[i]); } return TRUE; } static int parse_object( aseObject::Type type ) { aseObject* obj = new aseObject ( type ) ; char* token; int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (!strcmp(token,"*NODE_NAME")) { if ( !obj->name ) { char* name; if (! parser.parseString(name, "obj name")) return FALSE; obj->name = ulStrDup ( name ) ; } } else if (!strcmp(token,"*NODE_PARENT")) { if ( !obj->parent ) { char* name; if (! parser.parseString(name, "parent name")) return FALSE; obj->parent = ulStrDup ( name ) ; } } else if (!strcmp(token,"*NODE_TM")) { bool target = false ; bool match = false ; int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (!strcmp(token,"*NODE_NAME")) { char* name; if (! parser.parseString(name, "obj name")) return FALSE; if ( obj->name && !strcmp(name,obj->name) ) match = true ; if ( strstr(name,".Target") != NULL ) target = true ; } else if (match) { if (!strcmp(token,"*TM_POS")) { if (! parser.parseFloat(obj->pos[0], "pos.x")) return FALSE; if (! parser.parseFloat(obj->pos[1], "pos.y")) return FALSE; if (! parser.parseFloat(obj->pos[2], "pos.z")) return FALSE; sgCopyVec3 ( obj->target, obj->pos ) ; } else if (!strcmp(token,"*INHERIT_POS")) { int temp ; if (! parser.parseInt(temp, "inherit_pos.x")) return FALSE; obj->inherit_pos[0] = ( temp != 0 ) ; if (! parser.parseInt(temp, "inherit_pos.y")) return FALSE; obj->inherit_pos[1] = ( temp != 0 ) ; if (! parser.parseInt(temp, "inherit_pos.z")) return FALSE; obj->inherit_pos[2] = ( temp != 0 ) ; } } else if (target) { if (!strcmp(token,"*TM_POS")) { if (! parser.parseFloat(obj->target[0], "pos.x")) return FALSE; if (! parser.parseFloat(obj->target[1], "pos.y")) return FALSE; if (! parser.parseFloat(obj->target[2], "pos.z")) return FALSE; } } } } else if (!strcmp(token,"*MESH")) { if (! parse_mesh( obj )) return FALSE; } else if (!strcmp(token,"*MESH_ANIMATION")) { int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (!strcmp(token,"*MESH")) { if (! parse_mesh( obj )) return FALSE; } } } else if (!strcmp(token,"*TM_ANIMATION")) { if (! parse_tkeys( obj )) return FALSE; } else if (!strcmp(token,"*MATERIAL_REF")) { if (! parser.parseUInt(obj->mat_index, "mat #")) return FALSE; } } //if ( obj->parent != NULL ) // ulSetError( UL_DEBUG, "add_mesh: %s, parent=%s", obj->name, obj->parent ) ; //else // ulSetError( UL_DEBUG, "add_mesh: %s", obj->name ) ; ssgEntity* mesh_entity = NULL ; if ( obj->mesh_count > 1 ) { //how many frames? int num_frames = 0 ; int i ; for ( i=0; imesh_list [ i ] ; if ( mesh != NULL ) num_frames ++ ; } //allocate selector ssgSelector* selector = new ssgSelector ( num_frames ) ; //init for ( i=0; imesh_list [ i ] ; if ( mesh == NULL ) continue ; u32 num_subs = count_sub_materials ( obj->mat_index ); if ( num_subs > 1 ) { //break apart the mesh for each sub material ssgBranch* branch = new ssgBranch ; for ( u32 sub_index=0; sub_index addKid ( leaf ) ; } selector -> addKid ( branch ) ; } else { ssgLeaf* leaf = add_mesh ( obj, mesh, 0 ) ; if ( leaf ) selector -> addKid ( leaf ) ; } } selector -> selectStep ( 0 ) ; mesh_entity = current_options -> createSelector ( selector ) ; } else if ( obj->mesh_list [ 0 ] != NULL ) { aseMesh* mesh = obj->mesh_list [ 0 ] ; ssgBranch* branch = new ssgBranch ; u32 num_faces = mesh -> num_faces ; if ( num_faces == 0 ) { ssgLeaf* leaf = add_points( obj, mesh ) ; if ( leaf ) branch -> addKid ( leaf ) ; } else { u32 num_subs = count_sub_materials ( obj->mat_index ); if ( num_subs > 1 ) { //break apart the mesh for each sub material for ( u32 sub_index=0; sub_index addKid ( leaf ) ; } } else { ssgLeaf* leaf = add_mesh ( obj, mesh, 0 ); if ( leaf ) branch -> addKid ( leaf ) ; } } mesh_entity = branch ; } else { ssgBranch* branch = new ssgBranch ; ssgLeaf* leaf = add_points( obj, NULL ) ; if ( leaf ) branch -> addKid ( leaf ) ; mesh_entity = branch ; } if ( mesh_entity != NULL ) { //add to graph -- find parent branch ssgBranch* parent_branch ; if ( obj->parent ) { ssgEntity* found = top_branch -> getByName ( obj->parent ) ; if ( found != NULL ) { assert ( found -> isAKindOf ( ssgTypeBranch() ) ) ; parent_branch = (ssgBranch *) found ; } else { //parser.error("object %s: parent %s not seen",obj->name,obj->parent); parent_branch = top_branch ; } } else { parent_branch = top_branch ; } if ( obj->num_tkeys > 0 ) { ssgAnimTransform * at = new ssgAnimTransform; at->setNum( obj->num_tkeys ); /* Build the transforms */ sgMat4 rmat; sgMakeIdentMat4 ( rmat ) ; at->setATransform ( rmat, 0); for ( u32 i = 1 ; i < obj->num_tkeys ; i++ ) { aseTransform* tkey = obj->tkeys + i ; sgVec3 pos ; sgMat4 tmp ; sgMat4 mat ; /* * compute rmat * the key rotation is additive to the last rotation */ sgMakeRotMat4 ( tmp, -tkey->angle * SG_RADIANS_TO_DEGREES, tkey->axis ) ; sgPostMultMat4 ( rmat, tmp ) ; /* * rotation is around the mesh pivot point (obj->pos) * translate -obj->pos */ sgCopyVec3 ( pos, obj->pos ) ; sgNegateVec3 ( pos ) ; sgMakeTransMat4 ( mat, pos ) ; /* * perform the rotation */ sgPostMultMat4 ( mat, rmat ) ; /* * translate obj->pos + tkey->pos */ sgCopyVec3 ( pos, obj->pos ) ; sgAddVec3 ( pos, tkey->pos ) ; sgMakeTransMat4 ( tmp, pos ) ; sgPostMultMat4 ( mat, tmp ) ; at->setATransform ( mat, i); } // insert the ssgAnimTransform into the scene graph: at-> addKid ( mesh_entity ) ; mesh_entity = at; } parent_branch -> addKid ( mesh_entity ) ; mesh_entity -> setName ( obj->name ) ; } delete obj ; return TRUE; } static bool parse() { materials = new aseMaterial* [ MAX_MATERIALS ]; if ( !materials ) { parser.error("not enough memory"); return false ; } num_materials = 0 ; first_frame = 0 ; last_frame = 0 ; frame_speed = 0 ; ticks_per_frame = 0 ; num_frames = 0 ; bool firsttime = true; char* token; int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (firsttime) { if (strcmp(token,"*3DSMAX_ASCIIEXPORT")) { parser.error("not ASE format"); return false ; } u32 version_number; if (! parser.parseUInt(version_number, "version number") ) return false ; if ( version_number != 200) { parser.error("invalid %s version",token); return false ; } firsttime = false; } else if (!strcmp(token,"*SCENE")) { int startLevel = parser.level; while ((token = parser.getLine( startLevel )) != NULL) { if (!strcmp(token,"*SCENE_FIRSTFRAME")) { if (! parser.parseUInt(first_frame, "FIRSTFRAME #")) return FALSE; } else if (!strcmp(token,"*SCENE_LASTFRAME")) { if (! parser.parseUInt(last_frame, "LASTFRAME #")) return FALSE; num_frames = last_frame - first_frame + 1; } else if (!strcmp(token,"*SCENE_FRAMESPEED")) { if (! parser.parseUInt(frame_speed, "FRAMESPEED #")) return FALSE; } else if (!strcmp(token,"*SCENE_TICKSPERFRAME")) { if (! parser.parseUInt(ticks_per_frame, "TICKSPERFRAME #")) return FALSE; } } } else if (!strcmp(token,"*MATERIAL_LIST")) { if (! parse_material_list()) return FALSE; } else if (!strcmp(token,"*GEOMOBJECT")) { if (! parse_object( aseObject::GEOM )) return FALSE; } else if (!strcmp(token,"*HELPEROBJECT")) { if (! parse_object( aseObject::HELPER )) return FALSE; } else if (!strcmp(token,"*CAMERAOBJECT")) { if (! parse_object( aseObject::CAMERA )) return FALSE; } } return true ; } static void parse_free() { u32 i ; for ( i = 0 ; i < num_materials ; i++ ) { delete [] materials[ i ] -> name ; delete [] materials[ i ] -> tfname ; delete materials[ i ] ; } delete[] materials ; materials = 0 ; } ssgEntity *ssgLoadASE ( const char *fname, const ssgLoaderOptions* options ) { ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ; current_options = ssgGetCurrentOptions () ; top_branch = new ssgBranch ; if ( !parser.openFile( fname, &parser_spec ) ) { delete top_branch ; return 0; } if ( !parse() ) { delete top_branch ; top_branch = 0 ; } parse_free(); parser.closeFile(); return top_branch ; } plib-1.8.5/src/pw/0000777000175000001440000000000010765365521010703 500000000000000plib-1.8.5/src/pw/pw.h0000644000175000001440000000736610765364434011434 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pw.h 1928 2004-04-06 23:45:19Z sjbaker $ */ #ifndef _PW_H_ #define _PW_H_ 1 #include #define PW_IS_PRESENT 1 typedef void pwResizeCB ( int w, int h ) ; typedef void pwExitCB () ; typedef void pwKeybdFunc ( int key, int updown, int x, int y ) ; typedef void pwMouseFunc ( int key, int updown, int x, int y ) ; typedef void pwMousePosFunc ( int x, int y ) ; void pwInit ( int multisample, int num_samples ) ; void pwInit ( int x, int y, int w, int h, int multisample, char *title, int border, int num_samples ) ; void pwSetCallbacks ( pwKeybdFunc *kb = NULL, pwMouseFunc *ms = NULL, pwMousePosFunc *mp = NULL, pwResizeCB *rcb = NULL, pwExitCB *ecb = NULL ) ; int pwGetModifiers () ; void pwSwapBuffers () ; void pwGetSize ( int *w, int *h ) ; void pwSetSizeOrigin ( int x, int y, int w, int h ) ; void pwSetSize ( int x, int y ) ; void pwSetOrigin ( int w, int h ) ; void pwSetCursor ( int c ) ; void pwCleanup () ; void pwSetAutoRepeatKey ( bool enable ) ; #define PW_CURSOR_NONE 0 #define PW_CURSOR_RIGHT 1 #define PW_CURSOR_LEFT 2 #define PW_CURSOR_QUERY 3 #define PW_CURSOR_AIM 4 #define PW_CURSOR_CIRCLE 5 #define PW_CURSOR_WAIT 6 #define PW_CURSOR_CROSS 7 #define PW_CURSOR_CUSTOM 8 /* WARNING: These have to be the same as PU_KEY_whatever. */ #define PW_KEY_SPECIAL_OFFSET 256 #define PW_KEY_F1 (1 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F2 (2 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F3 (3 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F4 (4 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F5 (5 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F6 (6 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F7 (7 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F8 (8 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F9 (9 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F10 (10 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F11 (11 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_F12 (12 + PW_KEY_SPECIAL_OFFSET) #define PW_KEY_LEFT (100+ PW_KEY_SPECIAL_OFFSET) #define PW_KEY_UP (101+ PW_KEY_SPECIAL_OFFSET) #define PW_KEY_RIGHT (102+ PW_KEY_SPECIAL_OFFSET) #define PW_KEY_DOWN (103+ PW_KEY_SPECIAL_OFFSET) #define PW_KEY_PAGE_UP (104+ PW_KEY_SPECIAL_OFFSET) #define PW_KEY_PAGE_DOWN (105+ PW_KEY_SPECIAL_OFFSET) #define PW_KEY_HOME (106+ PW_KEY_SPECIAL_OFFSET) #define PW_KEY_END (107+ PW_KEY_SPECIAL_OFFSET) #define PW_KEY_INSERT (108+ PW_KEY_SPECIAL_OFFSET) /* The three standard keyboard modifiers */ #define PW_SHIFT 1 #define PW_CTRL 2 #define PW_ALT 4 /* Whether a button has been pressed (DOWN) or released (UP) */ #define PW_DOWN 0 #define PW_UP 1 /* Mouse Buttons */ #define PW_LEFT_BUTTON 0 #define PW_MIDDLE_BUTTON 1 #define PW_RIGHT_BUTTON 2 #endif plib-1.8.5/src/pw/pw.cxx0000644000175000001440000000011510765364434011770 00000000000000 #include "ul.h" #include "pw.h" /* This space intentionally left blank */ plib-1.8.5/src/pw/Makefile.am0000644000175000001440000000030610765364434012654 00000000000000if BUILD_PW lib_LIBRARIES = libplibpw.a include_HEADERS = pw.h libplibpw_a_SOURCES = pw.cxx pwX11.cxx pwWindows.cxx pwMacOSX.cxx INCLUDES = -I$(top_srcdir)/src/util endif EXTRA_DIST = pw.dsp plib-1.8.5/src/pw/Makefile.in0000644000175000001440000003634310765365023012672 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/pw DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibpw_a_AR = $(AR) $(ARFLAGS) libplibpw_a_LIBADD = am__libplibpw_a_SOURCES_DIST = pw.cxx pwX11.cxx pwWindows.cxx \ pwMacOSX.cxx @BUILD_PW_TRUE@am_libplibpw_a_OBJECTS = pw.$(OBJEXT) pwX11.$(OBJEXT) \ @BUILD_PW_TRUE@ pwWindows.$(OBJEXT) pwMacOSX.$(OBJEXT) libplibpw_a_OBJECTS = $(am_libplibpw_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libplibpw_a_SOURCES) DIST_SOURCES = $(am__libplibpw_a_SOURCES_DIST) am__include_HEADERS_DIST = pw.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_PW_TRUE@lib_LIBRARIES = libplibpw.a @BUILD_PW_TRUE@include_HEADERS = pw.h @BUILD_PW_TRUE@libplibpw_a_SOURCES = pw.cxx pwX11.cxx pwWindows.cxx pwMacOSX.cxx @BUILD_PW_TRUE@INCLUDES = -I$(top_srcdir)/src/util EXTRA_DIST = pw.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/pw/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/pw/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibpw.a: $(libplibpw_a_OBJECTS) $(libplibpw_a_DEPENDENCIES) -rm -f libplibpw.a $(libplibpw_a_AR) libplibpw.a $(libplibpw_a_OBJECTS) $(libplibpw_a_LIBADD) $(RANLIB) libplibpw.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwMacOSX.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwWindows.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwX11.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/pw/pwMacOSX.cxx0000644000175000001440000006404710765364434013021 00000000000000 /* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pwMacOSX.cxx 2095 2006-10-29 07:42:41Z bram $ */ #include "ul.h" /* ONLY COMPILE THIS FILE FOR MACINTOSH OR MACOSX SYSTEMS */ /* PLEASE DON'T REMOVE THIS LINE AGAIN!!! */ #if defined(UL_MACINTOSH) || defined(UL_MAC_OSX) /* YES - THAT MEANS YOU! */ /* * * - the fullscreen mode is indeed a "game mode"; * - the fullscreen mode does not change the resolution of the screen: * it uses the resolution (width, height and depth) in use before entering pw; * - it is possible to toggle between modes by calling pwCleanup() * and calling again pwInit; * - the "border" parameter in pwInit is not used; * - the "about" menu shows a standard alert box with the current version of plib * and with the url to the plib official site. * *----------------------------------------- * * - with Mac OS 8.6 to 9.2: * - must be linked with the following libraries: * InterfaceLib, accessors.o, AppearanceLib, DrawSprocketLib * and OpenGL (agl is in OpenGL) * * - ACTIVE_SLEEPTIME must be defined to 0 for the fastest execution; * but it will not let other app to get events. * * - with Mac OS X: must be linked with the following frameworks: * Carbon, AGL * * * - if not using Xcode, the following compiler falgs should be set to avoid errors or warnings * CPPFLAGS = -fpascal-strings -funsigned-char */ /* version of 2004-04-03 * - changes from previous version: * - fullscreen also implemented with mac OS 8.6 and 9; * - key up events are now reported in mac OS 8.6 to 9.2 * (these events are disabled by default...) * - multisample added for mac OS X; * - no auto-key repeat event by default (can be set by pwSetAutoRepeatKey(bool on_off) ); * - better error handling and use of ulSetError; */ #if defined (UL_MAC_OSX) # define TARGET_API_MAC_CARBON 1 # include # include #elif defined (UL_MACINTOSH) //# define TARGET_API_MAC_CARBON 0 # undef ACCESSOR_CALLS_ARE_FUNCTIONS // already defined by ul.h !!! # define ACCESSOR_CALLS_ARE_FUNCTIONS 1 # include # include # include # include # include # include # include # include # include # include # include # include //#else //# error only for Mac OS (8.6 to OS X) operating system! #endif #include #include #include "pw.h" /* Apple menu: */ #define mApple 128 #define iAbout 1 /* File menu: */ #ifdef UL_MAC_OSX # define ACTIVE_SLEEPTIME 0 # define INACTIVE_SLEEPTIME 10 # define mFile 129 # define iQuit 1 #else // UL_MACINTOSH # define ACTIVE_SLEEPTIME 1 // 0 is fastest, but does not let other app to catch events. // set to 0 if you want your app only to have CPU time # define INACTIVE_SLEEPTIME 10 # define mFile 129 # define iQuit 1 #endif static bool pwInitialized = false ; static int origin [2] = { 0, 0 } ; static int size [2] = { 640, 480 } ; static SInt16 horScrSze, verScrSze; // screen dimensions static bool full_screen; static bool auto_repeat_key = false ; #if TARGET_API_MAC_CARBON static bool pwQuitFlag ; #endif static int modifiers ; static int click_modifiers ; static SInt32 sleepTime = ACTIVE_SLEEPTIME; static pwResizeCB *resizeCB = NULL ; static pwExitCB *exitCB = NULL ; static pwKeybdFunc *kbCB = NULL ; static pwMouseFunc *msCB = NULL ; static pwMousePosFunc *mpCB = NULL ; #if TARGET_API_MAC_CARBON static WindowPtr pwWindow = NULL ; # define SETPORT(w) SetPortWindowPort(w) # define GRAFPTR #else static CWindowPtr pwWindow = NULL ; # define SETPORT(w) SetPort((GrafPtr)w) # define GRAFPTR (GrafPtr) #endif #ifdef UL_MACINTOSH // DrawSprocket stuff: static DSpContextReference dspContext; #endif // generic OpenGL stuff static AGLContext currContext = NULL ; static void HandleEvents(void); static void Initialize(void); static bool MakeWindow(int x, int y, int w, int h, char* title); static void CreateContext(int multisample, int num_samples, bool fullscreen); static void MakeMenu(void); static void handleMenuEvent(long menuResult); static void handleKeyEvent(EventRecord* eventPtr, int updown); static void handleMouseMoveEvt(EventRecord* eventPtr); #if TARGET_API_MAC_CARBON static pascal OSErr QuitAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, long refcon); #endif static void pwAboutBox(void); static void defaultExitFunc (); #ifdef UL_MACINTOSH static bool InitDSP(); #endif static void CtoPcpy( Str255 pstr, char *cstr ); #if TARGET_API_MAC_CARBON static pascal OSErr QuitAppleEventHandler( const AppleEvent*, AppleEvent*, long ) { pwQuitFlag = true; return(noErr); } #endif static void Initialize() { OSErr err = noErr; BitMap scrBits; #if !TARGET_API_MAC_CARBON InitGraf(&qd.thePort); InitFonts(); FlushEvents(everyEvent, 0); InitWindows(); InitMenus(); InitDialogs(nil); sleepTime = ACTIVE_SLEEPTIME; SetEventMask(everyEvent); // to enable key up events !!! #else pwQuitFlag = false; err = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false ); // this funtion is to handle the "cmd+Q" event. This key event is not send as a keyDown event with carbon! if (err != noErr) { ulSetError(UL_FATAL, "Error in initialization of the system." ); } #endif InitCursor(); exitCB = defaultExitFunc; // get screen size: GetQDGlobalsScreenBits(&scrBits); horScrSze = scrBits.bounds.right - scrBits.bounds.left; verScrSze = scrBits.bounds.bottom - scrBits.bounds.top; } // Copy a C string into a Pascal string static void CtoPcpy( Str255 pstr, char* cstr ) { int i = 1; while( (*cstr) && (i < 255) ) pstr[i++] = *cstr++; pstr[0] = i - 1; } static bool MakeWindow(int x, int y, int w, int h, char* title) { Rect wRect; Str255 pTitle; CtoPcpy( pTitle, title ); SetRect(&wRect, x, y, w+x, h+y); #if TARGET_API_MAC_CARBON pwWindow = NewCWindow(nil, &wRect, pTitle, true, zoomNoGrow, (WindowPtr) -1, true, 0); #else if (full_screen) // use DrawSprocket pwWindow = (CWindowPtr) NewCWindow (nil, &wRect, pTitle, true, plainDBox, (WindowPtr)-1, 0, 0); else pwWindow = (CWindowPtr) NewCWindow(nil, &wRect, pTitle, true, zoomNoGrow, (WindowPtr) -1, true, 0); #endif if (pwWindow == NULL) { ulSetError(UL_WARNING, "pw: can not open a window; will exit"); return false; } SETPORT(pwWindow); return true; } static void CreateContext(int multisample, int num_samples, bool fullscreen) { AGLPixelFormat aglPixFmt; // Choose pixel format: GLint attrib[10]; GLint i = 0; attrib[i++] = AGL_RGBA; attrib[i++] = AGL_DOUBLEBUFFER; #ifdef UL_MAC_OSX if (fullscreen) attrib[i++] = AGL_FULLSCREEN; #endif attrib[i++] = AGL_DEPTH_SIZE; attrib[i++] = 32; //attrib[i++] = AGL_ALL_RENDERERS; attrib[i++] = AGL_NONE; if (multisample) { #ifdef UL_MAC_OSX i--; attrib[i++] = AGL_SAMPLE_BUFFERS_ARB ; attrib[i++] = 1 ; attrib[i++] = AGL_SAMPLES_ARB ; attrib[i++] = num_samples; attrib[i++] = AGL_NONE; aglPixFmt = aglChoosePixelFormat(NULL, 0, attrib); if (aglPixFmt == NULL) { multisample = 0; // retry without ulSetError(UL_WARNING, "pw: multisample pixel format not found"); i -= 5; attrib[i++] = AGL_NONE; } #else multisample = 0; // retry without ulSetError(UL_WARNING, "pw: multisample not implemented with MacOS 8 & 9"); #endif } if (!multisample) { aglPixFmt = aglChoosePixelFormat(NULL, 0, attrib); } if (aglPixFmt == NULL) { ulSetError(UL_FATAL, "pw: can not find a pixel format"); } // Create an AGL context currContext = aglCreateContext(aglPixFmt, NULL); aglDestroyPixelFormat ( aglPixFmt ); if (currContext == NULL) { ulSetError(UL_FATAL, "pw: can not create an OpenGL context\n"); } // swap buffers only every k vertical retrace: //long k = 100; //aglSetInteger(currContext, AGL_SWAP_INTERVAL, &k); } void MakeMenu() { SInt32 response; MenuRef menu; CreateNewMenu(mApple, 0, &menu); SetMenuTitleWithCFString( menu, CFSTR("Plib") ); InsertMenu(menu, 0); InsertMenuItemTextWithCFString(menu, CFSTR("About Plib..."), 0, 0, iAbout); #if !TARGET_API_MAC_CARBON AppendResMenu(menu, 'DRVR'); #endif // If we not running on OS X then we need to add a File:Quit command: Gestalt( gestaltMenuMgrAttr, &response ); if ( ( response & gestaltMenuMgrAquaLayoutMask ) == 0 ) { menu = NewMenu (mFile, (ConstStr255Param) "File"); // new menu InsertMenu (menu, 0); // add menu to end AppendMenu (menu, (ConstStr255Param) "Quit"); // add items } DrawMenuBar(); } static void defaultExitFunc () { pwCleanup () ; exit(0); } void pwSetCallbacks( pwKeybdFunc *kb, pwMouseFunc *ms, pwMousePosFunc *mp, pwResizeCB *rcb, pwExitCB *ecb ) { resizeCB = rcb; exitCB = (ecb == NULL) ? defaultExitFunc : ecb ; kbCB = kb ; msCB = ms ; mpCB = mp ; } int pwGetModifiers() { return modifiers; } void pwSetAutoRepeatKey( bool on_off ) { auto_repeat_key = on_off; } static void pwAboutBox() { // show a dialog box with info on plib: SInt16 outItemHit; char version[32]; Str255 Pversion; char* about = "for more info see "; Str255 Pabout; sprintf(version, "PLIB v %i.%i.%i", PLIB_MAJOR_VERSION, PLIB_MINOR_VERSION, PLIB_TINY_VERSION ); CtoPcpy( Pversion, version ); CtoPcpy( Pabout, about ); StandardAlert ( kAlertPlainAlert, Pversion, Pabout, NULL, &outItemHit ); } static void handleMenuEvent(long menuCmd) { #if !TARGET_API_MAC_CARBON Str255 DAName; #endif int menuNum = HiWord(menuCmd); int itemNum = LoWord(menuCmd); switch (menuNum) { case mApple: // apple menu: { switch (itemNum) { case iAbout: pwAboutBox(); break; default: #if !TARGET_API_MAC_CARBON GetMenuItemText(GetMenuHandle(mApple), itemNum, DAName); OpenDeskAcc(DAName); #endif break; } break; } case mFile: // File menu: { switch (itemNum) { case iQuit: (*exitCB)(); break; default: ; } } } HiliteMenu(0); // remove. the highlight on the selected menu. } static int translateKey(int ch, int key) { /* if ( modifiers & PW_ALT ) { UInt32 state = 0; long keyResult = KeyTranslate ( (void *) GetScriptManagerVariable (smKCHRCache), (UInt16) key, &state ); ch = 0xFF & keyResult; } */ // special characters: switch (ch) { case kLeftArrowCharCode: ch = PW_KEY_LEFT; break; case kUpArrowCharCode: ch = PW_KEY_UP; break; case kRightArrowCharCode: ch = PW_KEY_RIGHT; break; case kDownArrowCharCode: ch = PW_KEY_DOWN; break; case kPageUpCharCode: ch = PW_KEY_PAGE_UP; break; case kPageDownCharCode: ch = PW_KEY_PAGE_DOWN; break; case kHomeCharCode: ch = PW_KEY_HOME; break; case kEndCharCode: ch = PW_KEY_END; break; case kHelpCharCode: ch = PW_KEY_INSERT; break; case kFunctionKeyCharCode: // fonction keys: switch(key) { case 0x7A: ch = PW_KEY_F1; break; case 0x78: ch = PW_KEY_F2; break; case 0x63: ch = PW_KEY_F3; break; case 0x76: ch = PW_KEY_F4; break; case 0x60: ch = PW_KEY_F5; break; case 0x61: ch = PW_KEY_F6; break; case 0x62: ch = PW_KEY_F7; break; case 0x64: ch = PW_KEY_F8; break; case 0x65: ch = PW_KEY_F9; break; case 0x6D: ch = PW_KEY_F10; break; case 0x67: ch = PW_KEY_F11; break; case 0x6F: ch = PW_KEY_F12; break; default: break; } break; default: ; } return ch; } static void handleKeyEvent(EventRecord* eventPtr, int updown) { GrafPtr origPort; if ( ! kbCB ) return; // handle key_events: int ch = eventPtr->message & charCodeMask ; // character pressed int key = (eventPtr->message & keyCodeMask) >> 8 ; // key pressed ch = translateKey(ch, key); GetPort(&origPort); SETPORT(pwWindow); GlobalToLocal(&eventPtr->where); (*kbCB) ( ch, updown, eventPtr->where.h, eventPtr->where.v ) ; SetPort(origPort); return; } static void handleDrag(WindowPtr window, Point mouseloc) { Point loc; GrafPtr origPort; Rect dragBounds, windowBounds; GetRegionBounds(GetGrayRgn(), &dragBounds); DragWindow(window, mouseloc, &dragBounds); GetPort (&origPort); // save Port SETPORT(pwWindow); GetWindowPortBounds(window, &windowBounds); loc.h = windowBounds.left; loc.v = windowBounds.top; LocalToGlobal (&loc); origin[0] = loc.h; // save new origin origin[1] = loc.v; MoveWindow(GRAFPTR pwWindow, loc.h, loc.v, false); // update OpenGL Context: aglUpdateContext(currContext); //SETPORT(pwWindow); SetPort (origPort); // restore Port } static void handleGoAwayBox(WindowPtr window, Point mouseloc) { GrafPtr origPort; GetPort(&origPort); SETPORT(window); if( TrackGoAway(window, mouseloc) ) { (*exitCB)(); // quit... } SetPort(origPort); } static int last_m_h = 0; static int last_m_v = 0; static void handleMouseMoveEvt(EventRecord* eventPtr) { GrafPtr origPort; if ( ! mpCB ) return; int m_h = eventPtr->where.h; int m_v = eventPtr->where.v; if ( (m_v != last_m_v) || (m_h != last_m_h) ) { last_m_v = m_v ; last_m_h = m_h ; // screen coord. GetPort(&origPort); SETPORT(pwWindow); GlobalToLocal(&eventPtr->where); (*mpCB) ( eventPtr->where.h, eventPtr->where.v ) ; SetPort(origPort); } return; } static void HandleEvents() { EventRecord event; GrafPtr origPort; // bool testNextEvent = true; #if TARGET_API_MAC_CARBON if (pwQuitFlag) (*exitCB)(); // quit! #endif // while ( testNextEvent ) // { WaitNextEvent(everyEvent, &event, sleepTime, nil) ; #ifdef UL_MACINTOSH if (full_screen) { Boolean dspEventProcessed; DSpProcessEvent(&event, &dspEventProcessed); if (dspEventProcessed) return; } #endif int updown = PW_UP ; modifiers = 0; if ( event.modifiers & (shiftKey | rightShiftKey) ) modifiers |= PW_SHIFT ; if ( event.modifiers & (optionKey | rightOptionKey) ) modifiers |= PW_ALT ; if ( event.modifiers & (controlKey | rightControlKey) ) modifiers |= PW_CTRL ; switch ( event.what ) { case keyDown: // test for a 'command' + key (menu): if(event.modifiers & cmdKey) { char achar = (char) (event.message & charCodeMask); handleMenuEvent( MenuKey(achar) ) ; return; } // FALLTHROUGH (not a command) handleKeyEvent(&event, PW_DOWN); return; case autoKey: if ( ! auto_repeat_key ) { // report a mouse move event, if any: handleMouseMoveEvt(&event); return; } // else report a key down event: updown = PW_DOWN ; case keyUp: handleKeyEvent(&event, updown); return; case mouseDown: { short part; WindowPtr window; part = FindWindow(event.where, &window); switch(part) { case inMenuBar: handleMenuEvent( MenuSelect(event.where) ); return; #if !TARGET_API_MAC_CARBON case inSysWindow: SystemClick(&event, window); break; #endif case inDrag: handleDrag(window, event.where); return; case inGoAway: handleGoAwayBox(window, event.where); return; case inContent: if(!window) return; if ( GRAFPTR pwWindow != FrontWindow() ) { SelectWindow (GRAFPTR pwWindow); return; } } // FALLTHROUGH (not a system click) updown = PW_DOWN ; click_modifiers = modifiers; } case mouseUp: int button; switch( click_modifiers ) { case PW_ALT : button = PW_RIGHT_BUTTON ; break ; case PW_CTRL : button = PW_MIDDLE_BUTTON ; break ; default : button = PW_LEFT_BUTTON ; break ; } GetPort(&origPort); SETPORT(pwWindow); GlobalToLocal(&event.where); modifiers = 0; // reset modifiers with mouse events if (msCB) (*msCB)( button, updown, event.where.h, event.where.v ); SetPort(origPort); return; case osEvt: { unsigned char subcode = event.message >> 24; if (subcode == suspendResumeMessage) // Suspend/resume event if (resumeFlag & event.message) // Resume { #ifdef UL_MACINTOSH if (full_screen) sleepTime = 0; else #endif sleepTime = ACTIVE_SLEEPTIME; return; } else // suspend sleepTime = INACTIVE_SLEEPTIME; break; } case activateEvt: if (event.modifiers & activeFlag) { #ifdef UL_MACINTOSH if (full_screen) sleepTime = 0; else #endif sleepTime = ACTIVE_SLEEPTIME; return; } else sleepTime = INACTIVE_SLEEPTIME; break; case updateEvt: case nullEvent: // likely an idle event (i.e. no events) // report mouse location, only if mouse has moved: // (there is no mouse move events on Mac!) handleMouseMoveEvt(&event); return; default : /* printf ("event: %i \n", event.what); */ break; } // switch(event.what) // } // while ( testNextEvent ) } #ifdef UL_MACINTOSH bool InitDSP() { DSpContextAttributes dspAttributes; DisplayIDType displayID; if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpStartup) { ulSetError(UL_WARNING, "DrawSprocket extension not found"); return false; } // start DrawSprocket: if (noErr != DSpStartup ()) { ulSetError(UL_WARNING, "Unable to start DrawSprocket"); return false; } // initialise to zero all fields of DSpContextAttributes: BlockZero( &dspAttributes, sizeof (DSpContextAttributes) ); dspAttributes.displayWidth = horScrSze; dspAttributes.displayHeight = verScrSze; dspAttributes.colorNeeds = kDSpColorNeeds_Require; dspAttributes.displayDepthMask = kDSpDepthMask_16; dspAttributes.displayBestDepth = 16; dspAttributes.backBufferDepthMask = kDSpDepthMask_All; // must be specified even if only fornt buffer is needed dspAttributes.backBufferBestDepth = 16; dspAttributes.pageCount = 1; //dspAttributes.contextOptions = 0 | kDSpContextOption_DontSyncVBL; // no page flipping and no VBL sync needed // look for a DSp context: dspContext = NULL; OSStatus err = DSpFindBestContext(&dspAttributes, &dspContext); ulSetError(UL_DEBUG, " display width = %li, height = %li, depth = %li, mask = %lX ", dspAttributes.displayWidth, dspAttributes.displayHeight, dspAttributes.displayBestDepth, dspAttributes.displayDepthMask ); if (err != noErr) { if (err == kDSpContextNotFoundErr) ulSetError(UL_WARNING, "Unable to find a DrawSprocket context"); else ulSetError(UL_WARNING, "DSpFindBestContext error"); return false; } err = DSpContext_Reserve ( dspContext, &dspAttributes ); if (noErr != err) { ulSetError(UL_WARNING, "Unable to set the display!"); return false; } // activate DSp context: //DSpContext_FadeGammaOut (NULL, NULL); // remove for debug DSpContext_SetState (dspContext, kDSpContextState_Active); if ( !MakeWindow( 0, 0, horScrSze, verScrSze, "" ) ) return false; //DSpContext_FadeGammaIn (NULL, NULL); return true; } #endif void pwInit ( int multisample, int num_samples ) { pwInit ( 0,0,-1,-1, multisample, "", 0, num_samples ) ; } void pwInit ( int x, int y, int w, int h, int multisample, char *title, int border, int num_samples ) { if (pwInitialized) { ulSetError(UL_WARNING, "pwInit already called"); return; } full_screen = ( (w<0) || (h<0) ) ? true : false ; Initialize(); pwInitialized = true; pwWindow = NULL; // Initialize OpenGL stuff (format, context, ...): CreateContext(multisample, num_samples, full_screen); if (full_screen) { sleepTime = 0; #ifdef UL_MACINTOSH // initialisation of fullscreen mode with DrawSprocket dspContext = NULL; if ( ! InitDSP() ) { pwCleanup(); // releases GL contexts, windows, ... exit(4); } // attach OpenGl to the screen: aglSetDrawable(currContext, GetWindowPort (GRAFPTR pwWindow)); /* ulSetError(UL_DEBUG, "aglSetDrawable error: %s", (const char*) aglErrorString(aglGetError()) ); */ // activate our GL context aglSetCurrentContext(currContext); #else aglSetCurrentContext(currContext); aglSetFullScreen (currContext, 0, 0, 0, 0); #endif // initialise origin and size of the window (for pwGetSize) origin[0] = 0; origin[1] = 0; size[0] = horScrSze; size[1] = verScrSze; } else // full_screen { if ( ! MakeWindow(x,y,w,h, title) ) { pwCleanup(); // releases GL contexts, windows, ... exit(4); } // Attach the context to the window aglSetDrawable(currContext, GetWindowPort (GRAFPTR pwWindow)); #ifdef UL_MACINTOSH { // because aglSetDrawable is slow... (not needed with OSX) EventRecord event; WaitNextEvent (everyEvent, &event, 2, NULL); } #endif aglSetCurrentContext(currContext); // create a default menu bar (with the "quit" command): MakeMenu(); // initialise origin and size of the window (for pwGetSize) origin[0] = x; origin[1] = y; size[0] = w; size[1] = h; } } void pwGetSize ( int *w, int *h ) { *w = size[0]; *h = size[1]; } //special cursors: static Cursor q_curs = // question mark cursor { {0x0380, 0x07c0, 0x0c60, 0x1830, 0x1830, 0x0030, 0x0060, 0x00c0, 0x0180, 0x0180, 0x0180, 0, 0, 0x0180, 0x0180, 0}, // data {0x0380, 0x07e0, 0x0ff0, 0x1e38, 0x1c38, 0x1c38, 0x0078, 0x00f0, 0x01e0, 0x01c0, 0x01c0, 0x01c0, 0, 0x01c0, 0x01c0, 0x01c0}, // mask { 14, 7 } // hotspot }; static Cursor c_curs = // circle cursor { {0, 0x03e0, 0x0c18, 0x1004, 0x2002, 0x2002, 0x4001, 0x4001, 0x4001, 0x4001, 0x4001, 0x2002, 0x2002, 0x1004, 0x0c18, 0x03e0}, // data {0, 0x03e0, 0x0ff8, 0x1c1c, 0x3006, 0x3006, 0x6003, 0x6003, 0x6003, 0x6003, 0x6003, 0x3006, 0x3006, 0x1c1c, 0x0ff8, 0x03e0}, // mask { 8, 8 } // hotspot }; static Cursor r_curs = // right arrow cursor { {0, 0x0008, 0x0018, 0x0038, 0x0078, 0x00f8, 0x01f8, 0x03f8, 0x07f8, 0x00f8, 0x00d8, 0x0188, 0x0180, 0x0300, 0x0300, 0}, // data {0x000c, 0x001c, 0x003c, 0x007c, 0x00fc, 0x01fc, 0x03fc, 0x07fc, 0x0ffc, 0x0ffc, 0x01fc, 0x03dc, 0x03cc, 0x0780, 0x0780, 0x0700}, // mask { 1, 12 } // hotspot }; static Cursor x_curs = // circle + cross cursor { {0, 0x03e0, 0x0c98, 0x1084, 0x2082, 0x2082, 0x4081, 0x4081, 0x7fff, 0x4081, 0x4081, 0x2082, 0x2082, 0x1084, 0x0c98, 0x03e0}, // data {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // mask { 8, 8 } // hotspot }; void pwSetCursor ( int c ) { UInt32 csr = 0xFFFF; Cursor * csrPtr; switch (c) { case PW_CURSOR_NONE : HideCursor(); return; case PW_CURSOR_LEFT : csr = kThemeArrowCursor; break; case PW_CURSOR_RIGHT : csrPtr = &r_curs; break; case PW_CURSOR_AIM : csrPtr = &x_curs; break; //case PW_CURSOR_CARET : csr = kThemeIBeamCursor; break; // ??? case PW_CURSOR_WAIT : csr = kThemeWatchCursor; break; case PW_CURSOR_CROSS : csr = kThemeCrossCursor; break; case PW_CURSOR_QUERY : csrPtr = &q_curs; break; case PW_CURSOR_CIRCLE : csrPtr = &c_curs; break; case PW_CURSOR_CUSTOM : default : csr = kThemeArrowCursor; ulSetError(UL_WARNING, "Unknown or unavailable cursor type\n"); } if (csr==0xFFFF) SetCursor(csrPtr); else SetThemeCursor(csr); ShowCursor(); } void pwSetSize ( int w, int h ) { if (!pwInitialized) { ulSetError(UL_WARNING, "call to pwSetSize without call to pwInit"); return; } if ( full_screen ) { ulSetError(UL_WARNING, "call to pwSetSize in full screen mode"); return; } if ( ( w == size[0] ) && ( h == size[1] ) ) return; GrafPtr origPort; if (w<50) w = 50; if (w>horScrSze) w = horScrSze; if (h<50) h = 50; if (h>verScrSze) h = verScrSze; GetPort(&origPort); size[0] = w; // save size size[1] = h; SizeWindow(GRAFPTR pwWindow, w, h, false); // update OpenGL Context: aglUpdateContext(currContext); if ( resizeCB != NULL ) (*resizeCB) ( w, h ) ; SetPort(origPort); } void pwSetOrigin ( int x, int y ) { if (!pwInitialized) { ulSetError(UL_WARNING, "call to pwSetOrigin without call to pwInit"); return; } if ( full_screen ) { ulSetError(UL_WARNING, "call to pwSetOrigin in full screen mode"); return; } if ( ( x == origin[0] ) && ( y == origin[1] ) ) return; if ( (x + size[0]) < 10) x = 10 - size[0]; if ( x > (horScrSze-10) ) x = horScrSze-10; if ( (y + size[1]) < 60) y = 60 - size[1]; if ( y > (verScrSze-10) ) y = verScrSze-10; MoveWindow(GRAFPTR pwWindow, x, y, false); // update OpenGL Context: aglUpdateContext(currContext); origin[0] = x; // save new origin origin[1] = y; } void pwSetSizeOrigin ( int x, int y, int w, int h ) { if (!pwInitialized) { ulSetError(UL_WARNING, "call to pwSetSizeOrigin without call to pwInit"); return; } if ( full_screen ) { ulSetError(UL_WARNING, "call to pwSetSizeOrigin in full screen mode"); return; } pwSetOrigin( x, y ); pwSetSize( w, h ); } void pwSwapBuffers () { if (!pwInitialized) { ulSetError(UL_WARNING, "call to pwSwapBuffers without call to pwInit"); return; } // glFlush () ; aglSwapBuffers ( currContext ) ; HandleEvents () ; } void pwCleanup () { if (!pwInitialized) { ulSetError(UL_WARNING, "call to pwCleanup without call to pwInit"); return; } if (currContext != NULL) { aglSetDrawable (currContext, NULL); aglSetCurrentContext (NULL); aglDestroyContext ( currContext ); } if (pwWindow != NULL) DisposeWindow(GRAFPTR pwWindow); #ifdef UL_MACINTOSH if (full_screen) { if (dspContext != NULL) { //DSpContext_FadeGammaOut (NULL, NULL); // remove for debug DSpContext_SetState (dspContext, kDSpContextState_Inactive); //DSpContext_FadeGammaIn (NULL, NULL); DSpContext_Release (dspContext); } DSpShutdown (); } #endif pwInitialized = false; } #endif plib-1.8.5/src/pw/pw.dsp0000644000175000001440000000610210765364434011756 00000000000000# Microsoft Developer Studio Project File - Name="pw" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=pw - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "pw.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "pw.mak" CFG="pw - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "pw - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "pw - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "pw - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\util" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD BASE RSC /l 0xc09 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Cmds=copy release\*.lib ..\..\*.* copy pw.h ..\..\pw.h # End Special Build Tool !ELSEIF "$(CFG)" == "pw - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\util" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD BASE RSC /l 0xc09 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\pw_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy pw.h ..\..\pw.h # End Special Build Tool !ENDIF # Begin Target # Name "pw - Win32 Release" # Name "pw - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\pwWindows.cxx # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\pw.h # End Source File # End Group # End Target # End Project plib-1.8.5/src/pw/pwWindows.cxx0000644000175000001440000003365710765364434013364 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pwWindows.cxx 2046 2005-09-02 21:03:43Z bram $ */ #include "ul.h" /* ONLY COMPILE THIS FILE FOR MS-WINDOWS SYSTEMS */ #ifdef UL_WIN32 #define WIN32_LEAN_AND_MEAN #include #include #include "pw.h" static int initialised = 0 ; static int modifiers = 0 ; static int origin [2] = { 0, 0 } ; static int size [2] = { 640, 480 } ; static bool autoRepeat = false ; static DWORD style = 0 ; static pwResizeCB *resizeCB = NULL ; static pwExitCB *exitCB = NULL ; static pwKeybdFunc *kbCB = NULL ; static pwMouseFunc *msCB = NULL ; static pwMousePosFunc *mpCB = NULL ; static HINSTANCE currInstance = NULL ; static HWND currWnd = NULL ; static HDC currDC = NULL ; static HGLRC currGLRC = NULL ; void defaultExitFunc () { pwCleanup () ; exit ( 0 ) ; } static void refreshModifiers () { modifiers = 0 ; if( ( GetKeyState ( VK_SHIFT ) & 0x8000 ) != 0 ) modifiers |= PW_SHIFT ; if( ( GetKeyState ( VK_CONTROL ) & 0x8000 ) != 0 ) modifiers |= PW_CTRL ; if( ( GetKeyState ( VK_MENU ) & 0x8000 ) != 0 ) modifiers |= PW_ALT ; } inline void clientSizeToWindowSize ( int& w, int& h, DWORD dwStyle ) { RECT rect; rect.left = 0 ; rect.right = w ; rect.top = 0 ; rect.bottom = h ; AdjustWindowRect( &rect, dwStyle, false ) ; w = rect.right - rect.left ; h = rect.bottom - rect.top ; } LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static int key = -1 ; static int updown = PW_UP ; static int old_key = -1 ; // We need this because "key" changes case int button = -1 ; static int mb = 0 ; static int lastx = 0 ; static int lasty = 0 ; refreshModifiers () ; switch (uMsg) { case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: updown = PW_DOWN ; if ( uMsg == WM_LBUTTONDOWN ) { button = PW_LEFT_BUTTON ; mb |= 1 ; } else if ( uMsg == WM_MBUTTONDOWN ) { button = PW_MIDDLE_BUTTON ; mb |= 2 ; } else { button = PW_RIGHT_BUTTON ; mb |= 4 ; } SetCapture ( hWnd ) ; lastx = SHORT ( LOWORD ( lParam ) ) ; lasty = SHORT ( HIWORD ( lParam ) ) ; if ( button != -1 && msCB ) (*msCB) ( button, updown, lastx, lasty ) ; break; case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: updown = PW_UP ; if ( uMsg == WM_LBUTTONUP ) { button = PW_LEFT_BUTTON ; mb &= ~1 ; } else if ( uMsg == WM_MBUTTONUP ) { button = PW_MIDDLE_BUTTON ; mb &= ~2 ; } else { button = PW_RIGHT_BUTTON ; mb &= ~4 ; } if ( mb == 0 ) ReleaseCapture () ; lastx = SHORT ( LOWORD ( lParam ) ) ; lasty = SHORT ( HIWORD ( lParam ) ) ; if ( button != -1 && msCB ) (*msCB) ( button, updown, lastx, lasty ) ; break; case WM_MOUSEMOVE: lastx = SHORT ( LOWORD ( lParam ) ) ; lasty = SHORT ( HIWORD ( lParam ) ) ; if ( mpCB ) (*mpCB) ( lastx, lasty ) ; break; case WM_KEYDOWN: /* If the key is already down, we are on auto-repeat. Break if the autorepeat is disabled. */ if ( ( updown == PW_DOWN ) && ( int(wParam) == old_key ) ) { if ( autoRepeat ) { /* Disable CTRL, SHIFT, CapsLock keys from making a callback */ if ( ( key == VK_CONTROL ) || ( key == VK_SHIFT ) || ( key == VK_CAPITAL ) ) break ; if ( key != -1 && kbCB ) // Autorepeat enabled, call the callback with an "up" setting (*kbCB) ( key, PW_UP, lastx, lasty ) ; } else break ; // Autorepeat not enabled, just break } updown = PW_DOWN ; old_key = wParam ; /* FALLTHROUGH */ case WM_KEYUP: if ( uMsg == WM_KEYUP ) updown = PW_UP ; key = wParam ; /* Disable CTRL, SHIFT, CapsLock keys from making a callback */ if ( ( key == VK_CONTROL ) || ( key == VK_SHIFT ) || ( key == VK_CAPITAL ) ) break ; switch ( key ) { case VK_F1: key = PW_KEY_F1; break; case VK_F2: key = PW_KEY_F2; break; case VK_F3: key = PW_KEY_F3; break; case VK_F4: key = PW_KEY_F4; break; case VK_F5: key = PW_KEY_F5; break; case VK_F6: key = PW_KEY_F6; break; case VK_F7: key = PW_KEY_F7; break; case VK_F8: key = PW_KEY_F8; break; case VK_F9: key = PW_KEY_F9; break; case VK_F10: key = PW_KEY_F10; break; case VK_F11: key = PW_KEY_F11; break; case VK_F12: key = PW_KEY_F12; break; case VK_LEFT: key = PW_KEY_LEFT; break; case VK_RIGHT: key = PW_KEY_RIGHT; break; case VK_UP: key = PW_KEY_UP; break; case VK_DOWN: key = PW_KEY_DOWN; break; case VK_PRIOR: key = PW_KEY_PAGE_UP; break; case VK_NEXT: key = PW_KEY_PAGE_DOWN; break; case VK_HOME: key = PW_KEY_HOME; break; case VK_END: key = PW_KEY_END; break; case VK_INSERT: key = PW_KEY_INSERT; break; default: // don't do this for WinCE BYTE state[ 256 ]; WORD code[ 2 ]; BOOL b = GetKeyboardState( state ); assert(b); code [ 0 ] = 0; // WK: I need to do this, or on my Win2k box, the upper bits remain unchanged. if( ToAscii( key, 0, state, code, 0 ) == 1 ) if((0xFF00 & code[0]) == 0) // setting a high bit in key causes crashes later on (out of range array access) key=code[ 0 ]; } if ( key != -1 && kbCB ) (*kbCB) ( key, updown, lastx, lasty ) ; break; case WM_SIZE: size[0] = LOWORD ( lParam ) ; size[1] = HIWORD ( lParam ) ; if ( resizeCB ) (*resizeCB) ( size[0], size[1] ) ; break; case WM_CLOSE: (*exitCB)(); break; default: return ( DefWindowProc ( hWnd, uMsg, wParam, lParam ) ) ; } return 0; } void pwSetAutoRepeatKey ( bool enable ) { autoRepeat = enable ; } void pwSetCallbacks ( pwKeybdFunc *kb, pwMouseFunc *ms, pwMousePosFunc *mp, pwResizeCB *rcb, pwExitCB *ecb ) { if ( ! initialised ) { fprintf ( stderr, "PW: You must not call pwSetCallbacks before pwInit.\n"); exit ( 1 ) ; } kbCB = kb ; msCB = ms ; mpCB = mp ; resizeCB = rcb ; exitCB = ecb ? ecb : defaultExitFunc ; } void pwInit ( int multisample, int num_samples ) { pwInit ( 0, 0, -1, -1, multisample, "NoName", FALSE, num_samples ) ; } //typedef const char * wglGetExtensionsStringARBtype ( HDC hdc ) ; void pwInit ( int x, int y, int w, int h, int multisample, char *title, int border, int num_samples ) { currInstance = GetModuleHandleA( NULL ) ; /* Register the window class */ WNDCLASS wc; wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW ; wc.lpfnWndProc = WndProc ; wc.cbClsExtra = 0 ; wc.cbWndExtra = 0 ; wc.hInstance = currInstance ; wc.hIcon = LoadIcon ( NULL, IDI_APPLICATION ) ; wc.hCursor = LoadCursor ( NULL, IDC_ARROW ) ; wc.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 ) ; wc.lpszMenuName = NULL ; wc.lpszClassName = "PlibAppClass" ; if ( !RegisterClass( &wc ) ) { fprintf ( stderr, "PW: Can't register window class" ) ; exit ( 1 ) ; } /* Setup window style */ bool fullscn = (w == -1 && h == -1 ) ? true : false ; if ( w == -1 ) w = GetSystemMetrics( SM_CXSCREEN ) ; if ( h == -1 ) h = GetSystemMetrics( SM_CYSCREEN ) ; origin [ 0 ] = x ; origin [ 1 ] = y ; size [ 0 ] = w ; size [ 1 ] = h ; RECT rect ; rect.left = x ; rect.top = y ; rect.right = rect.left + w ; rect.bottom = rect.top + h ; if ( !fullscn ) style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ; else style = WS_POPUP ; AdjustWindowRect( &rect, style, false ) ; // The origin is really where the upper left of the window should be. // rect is the setting for the window if the origin is for the client area. // Adjust the window rect so that it will be located at the origin (x,y). int deltaX = x - rect.left ; int deltaY = y - rect.top ; rect.left += deltaX ; rect.right += deltaX ; rect.top += deltaY ; rect.bottom += deltaY ; /* Create the window */ currWnd = CreateWindow( "PlibAppClass", title, style, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, currInstance, NULL ) ; if ( !currWnd ) { fprintf ( stderr, "PW: Can't create window" ) ; exit ( 1 ) ; } /* Get DC for this window */ currDC = GetDC ( currWnd ) ; if ( !currDC ) { fprintf ( stderr, "PW: Can't get window DC" ) ; exit ( 1 ) ; } // wglGetExtensionsStringARBtype *wglGetExtensionsStringARB = (wglGetExtensionsStringARBtype *)wglGetProcAddress ( "wglGetExtensionsStringARB" ) ; // const char *extensionsString = wglGetExtensionsStringARB ( currDC ) ; // printf ( "%s %x %s\n", glGetString ( GL_EXTENSIONS ), wglGetExtensionsStringARB, extensionsString ) ; // if (!GLExtensionExists("WGL_ARB_multisample ")) // return suggestedFormat; /* Set pixel format for DC */ 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 */ 32, /* 32-bit z-buffer */ 0, /* no stencil buffer */ 0, /* no auxiliary buffer */ PFD_MAIN_PLANE, /* main layer */ 0, /* reserved */ 0, 0, 0 /* layer masks ignored */ }; /* Get best available match of pixel format for DC */ int iPixelFormat = ChoosePixelFormat ( currDC, &pfd ) ; if ( iPixelFormat == 0 ) { fprintf ( stderr, "PW: Can't get OpenGL pixel format" ) ; exit ( 1 ) ; } /* Set the pixel format of the DC */ if ( !SetPixelFormat( currDC, iPixelFormat, &pfd ) ) { fprintf ( stderr, "PW: Can't set OpenGL pixel format" ) ; exit ( 1 ) ; } /* Show the window and paint its contents */ ShowWindow ( currWnd, SW_SHOW ) ; UpdateWindow ( currWnd ) ; /* Create openGL context and make it current */ currGLRC = wglCreateContext ( currDC ) ; if ( !currGLRC ) { fprintf ( stderr, "PW: Can't create OpenGL context" ) ; exit ( 1 ) ; } if ( !wglMakeCurrent ( currDC, currGLRC ) ) { fprintf ( stderr, "PW: Can't make OpenGL context current" ) ; exit ( 1 ) ; } kbCB = NULL ; msCB = NULL ; mpCB = NULL ; resizeCB = NULL ; exitCB = defaultExitFunc ; initialised = 1 ; glClear ( GL_COLOR_BUFFER_BIT ) ; pwSwapBuffers () ; glClear ( GL_COLOR_BUFFER_BIT ) ; pwSwapBuffers () ; } void pwGetSize ( int *w, int *h ) { if ( w ) *w = size[0] ; if ( h ) *h = size[1] ; } void pwSetCursor ( int c ) { LPCSTR cursor; switch ( c ) { case PW_CURSOR_RIGHT : cursor = IDC_ARROW ; break ; case PW_CURSOR_LEFT : cursor = IDC_ARROW ; break ; case PW_CURSOR_QUERY : cursor = IDC_HELP ; break ; /*case PW_CURSOR_AIM : cursor = ??? ; break ;*/ case PW_CURSOR_CIRCLE : cursor = IDC_NO ; break ; case PW_CURSOR_WAIT : cursor = IDC_WAIT ; break ; case PW_CURSOR_CROSS : cursor = IDC_CROSS ; break ; case PW_CURSOR_NONE : cursor = 0 ; break ; default: cursor = IDC_ARROW; } SetCursor( LoadCursor ( NULL, cursor ) ) ; } void pwSetSize ( int w, int h ) { clientSizeToWindowSize ( w, h, style ) ; SetWindowPos ( currWnd, HWND_TOP, 0, 0, w, h, SWP_NOMOVE ) ; } void pwSetOrigin ( int x, int y ) { SetWindowPos ( currWnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE ) ; } void pwSetSizeOrigin ( int x, int y, int w, int h ) { clientSizeToWindowSize ( w, h, style ) ; SetWindowPos ( currWnd, HWND_TOP, x, y, w, h, 0 ) ; } int pwGetModifiers () { return modifiers ; } static void getEvents () { MSG msg; while ( PeekMessage( &msg, currWnd, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ) ; DispatchMessage ( &msg ) ; } } void pwSwapBuffers () { glFlush () ; SwapBuffers ( currDC ) ; getEvents () ; } void pwCleanup () { wglMakeCurrent ( NULL, NULL ) ; wglDeleteContext ( currGLRC ) ; DestroyWindow ( currWnd ) ; } #endif plib-1.8.5/src/pw/pwX11.cxx0000644000175000001440000004100310765364434012263 00000000000000#include "ul.h" /* ONLY COMPILE THIS FILE FOR GLX/X11 EQUIPPED SYSTEMS */ #ifdef UL_GLX #include "pw.h" #include #include #include #include #include extern "C" { #include #include #include #include #include #include } #include #include /* These are supposed to be defined in /usr/include/GL/glxext.h But at time of writing, they were missing. The OpenGL ARB people have been informed by email. */ #ifndef GLX_SAMPLE_BUFFERS_ARB #define GLX_SAMPLE_BUFFERS_ARB 100000 #define GLX_SAMPLES_ARB 100001 #endif #ifdef HAVE_MOTIF extern "C" { #include } #else /* bit definitions for MwmHints.flags */ #define MWM_HINTS_FUNCTIONS (1L << 0) #define MWM_HINTS_DECORATIONS (1L << 1) #define MWM_HINTS_INPUT_MODE (1L << 2) #define MWM_HINTS_STATUS (1L << 3) /* bit definitions for MwmHints.decorations */ #define MWM_DECOR_ALL (1L << 0) #define MWM_DECOR_BORDER (1L << 1) #define MWM_DECOR_RESIZEH (1L << 2) #define MWM_DECOR_TITLE (1L << 3) #define MWM_DECOR_MENU (1L << 4) #define MWM_DECOR_MINIMIZE (1L << 5) #define MWM_DECOR_MAXIMIZE (1L << 6) typedef struct { unsigned long flags ; unsigned long functions ; unsigned long decorations ; long inputMode ; unsigned long status ; } PropMotifWmHints ; #define PROP_MOTIF_WM_HINTS_ELEMENTS 5 #endif static bool initialised = false ; static bool insideCallback = false ; static int modifiers = 0 ; static int origin [2] = { 0, 0 } ; static int size [2] = { 640, 480 } ; static int currScreen = 0 ; static int currConnect = 0 ; static int currCursor = PW_CURSOR_LEFT ; static pwResizeCB *resizeCB = NULL ; static pwExitCB *exitCB = NULL ; static pwKeybdFunc *kbCB = NULL ; static pwMouseFunc *msCB = NULL ; static pwMousePosFunc *mpCB = NULL ; static Display *currDisplay = NULL ; static XVisualInfo *visualInfo = NULL ; static Window currHandle ; static GLXContext currContext ; static Window rootWindow ; static Atom delWinAtom ; static bool autoRepeat = false ; void pwSetAutoRepeatKey ( bool enable ) { autoRepeat = enable ; } struct PixelFormat { int num_samples ; int bits_per_pixel ; ; int z_bits ; } ; static PixelFormat preferred_pixel_formats [] = { /* NumSamples, RGB_bits, Z_bits */ { 0, 24, 24 }, /* Progressively nastier image formats */ { 0, 16, 24 }, { 0, 16, 16 }, { 0, 3, 16 }, { 0, 3, 1 }, { -1, -1, -1 } /* Magic end marker */ } ; void defaultExitFunc () { pwCleanup () ; exit ( 0 ) ; } static void chooseVisual ( PixelFormat *pf ) { int attribs [ 100 ] ; int n = 0 ; attribs [n++] = GLX_RGBA ; switch ( pf->bits_per_pixel ) { case 3 : attribs [n++] = GLX_RED_SIZE ; attribs [n++] = 1 ; attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 1 ; attribs [n++] = GLX_BLUE_SIZE ; attribs [n++] = 1 ; break ; case 16 : attribs [n++] = GLX_RED_SIZE ; attribs [n++] = 5 ; attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 6 ; attribs [n++] = GLX_BLUE_SIZE ; attribs [n++] = 5 ; break ; case 24 : attribs [n++] = GLX_RED_SIZE ; attribs [n++] = 8 ; attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 8 ; attribs [n++] = GLX_BLUE_SIZE ; attribs [n++] = 8 ; break ; } switch ( pf->z_bits ) { case 1 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 1 ; break ; case 16 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 16 ; break ; case 24 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 24 ; break ; case 32 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 32 ; break ; } if ( pf->num_samples > 0 ) { attribs [n++] = GLX_SAMPLE_BUFFERS_ARB ; attribs [n++] = 1 ; attribs [n++] = GLX_SAMPLES_ARB ; attribs [n++] = pf->num_samples ; } attribs [n++] = GLX_DOUBLEBUFFER ; attribs [n++] = None ; visualInfo = glXChooseVisual ( currDisplay, currScreen, attribs ) ; } void pwInit ( int multisample, int num_samples ) { pwInit ( 0, 0, -1, -1, multisample, "NoName", FALSE, num_samples ) ; } void pwSetCallbacks ( pwKeybdFunc *kb, pwMouseFunc *ms, pwMousePosFunc *mp, pwResizeCB *rcb, pwExitCB *ecb ) { if ( ! initialised ) { fprintf ( stderr, "PW: You must not call pwSetCallbacks before pwInit.\n"); exit ( 1 ) ; } kbCB = kb ; msCB = ms ; mpCB = mp ; resizeCB = rcb ; exitCB = ecb ? ecb : defaultExitFunc ; } void pwInit ( int x, int y, int w, int h, int multisample, char *title, int border, int num_samples ) { char *displayName = getenv ( "DISPLAY" ) ; if ( displayName == NULL ) displayName = ":0.0" ; currDisplay = XOpenDisplay ( displayName ) ; if ( currDisplay == NULL ) { fprintf ( stderr, "PW: Can't open display '%s'", XDisplayName ( displayName ) ) ; exit ( 1 ) ; } /* OpenGL GLX extension availability? */ if ( ! glXQueryExtension ( currDisplay, NULL, NULL ) ) { fprintf ( stderr, "PW: GLX extension not available on display '%s'?!?", XDisplayName ( displayName ) ) ; exit ( 1 ) ; } currScreen = DefaultScreen ( currDisplay ) ; rootWindow = RootWindow ( currDisplay, currScreen ) ; currConnect = ConnectionNumber ( currDisplay ) ; delWinAtom = XInternAtom ( currDisplay, "WM_DELETE_WINDOW", 0 ) ; if ( w == -1 ) w = DisplayWidth ( currDisplay, currScreen ) ; if ( h == -1 ) h = DisplayHeight ( currDisplay, currScreen ) ; origin [ 0 ] = x ; origin [ 1 ] = y ; size [ 0 ] = w ; size [ 1 ] = h ; XSetWindowAttributes attribs ; XTextProperty textProperty ; XSizeHints sizeHints ; XWMHints wmHints ; unsigned int mask ; PixelFormat pf ; for ( int i = 0 ; preferred_pixel_formats [ i ] . num_samples >= 0 ; i++ ) { pf = preferred_pixel_formats [ i ] ; pf . num_samples = num_samples ; chooseVisual ( &pf ) ; if ( visualInfo != NULL ) break ; } if ( visualInfo == NULL ) { num_samples = 0 ; for ( int i = 0 ; preferred_pixel_formats [ i ] . num_samples >= 0 ; i++ ) { pf = preferred_pixel_formats [ i ] ; pf . num_samples = num_samples ; chooseVisual ( &pf ) ; if ( visualInfo != NULL ) break ; } if ( visualInfo == NULL ) { fprintf ( stderr, "PW: Unable to open a suitable graphics window,\n" ) ; exit ( 1 ) ; } } attribs.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | VisibilityChangeMask ; attribs.background_pixmap = None ; attribs.background_pixel = 0 ; attribs.border_pixel = 0 ; attribs.colormap = XCreateColormap ( currDisplay, rootWindow, visualInfo->visual, AllocNone ) ; mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; currHandle = XCreateWindow ( currDisplay, rootWindow, x, y, w, h, 0, visualInfo->depth, InputOutput, visualInfo->visual, mask, &attribs ) ; currContext = glXCreateContext ( currDisplay, visualInfo, NULL, 1 ) ; glXMakeCurrent ( currDisplay, currHandle, currContext ) ; if ( ! glXIsDirect ( currDisplay, glXGetCurrentContext() ) ) { fprintf ( stderr,"PW: This is an *INDIRECT* rendering context.") ; fprintf ( stderr,"PW: That may be bad for performance." ) ; } sizeHints.flags = 0 ; if ( x >= 0 && y >= 0 ) sizeHints.flags |= USPosition ; sizeHints.flags |= USSize ; sizeHints.x = x ; sizeHints.y = y ; sizeHints.width = w ; sizeHints.height = h ; wmHints.flags = StateHint; wmHints.initial_state = NormalState ; PropMotifWmHints hints ; Atom prop_t ; Atom prop ; hints . flags = MWM_HINTS_DECORATIONS ; hints . decorations = border ? MWM_DECOR_ALL : 0 ; prop_t = prop = XInternAtom ( currDisplay, "_MOTIF_WM_HINTS", True ) ; if ( prop != 0 ) XChangeProperty ( currDisplay, currHandle, prop, prop_t, 32, PropModeReplace, (unsigned char *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS) ; XStringListToTextProperty ( (char **) &title, 1, &textProperty ) ; XSetWMProperties ( currDisplay, currHandle, &textProperty, &textProperty, 0, 0, &sizeHints, &wmHints, NULL ) ; XSetWMProtocols ( currDisplay, currHandle, &delWinAtom , 1 ); XMapWindow ( currDisplay, currHandle ) ; glXMakeCurrent ( currDisplay, currHandle, currContext ) ; pwSetCursor ( PW_CURSOR_LEFT ) ; #ifdef GL_MULTISAMPLE_FILTER_HINT_NV glHint ( GL_MULTISAMPLE_FILTER_HINT_NV, multisample ) ; #endif kbCB = NULL ; msCB = NULL ; mpCB = NULL ; resizeCB = NULL ; exitCB = defaultExitFunc ; initialised = true ; insideCallback = false ; glClear ( GL_COLOR_BUFFER_BIT ) ; pwSwapBuffers () ; glClear ( GL_COLOR_BUFFER_BIT ) ; pwSwapBuffers () ; } void pwGetSize ( int *w, int *h ) { if ( w ) *w = size[0] ; if ( h ) *h = size[1] ; } void pwSetCursor ( int c ) { switch ( c ) { case PW_CURSOR_RIGHT : currCursor = XC_right_ptr ; break ; case PW_CURSOR_LEFT : currCursor = XC_left_ptr ; break ; case PW_CURSOR_QUERY : currCursor = XC_question_arrow ; break ; case PW_CURSOR_AIM : currCursor = XC_target ; break ; case PW_CURSOR_CIRCLE : currCursor = XC_circle ; break ; case PW_CURSOR_WAIT : currCursor = XC_watch ; break ; case PW_CURSOR_CROSS : currCursor = XC_crosshair ; break ; case PW_CURSOR_NONE : default: { Pixmap pix ; char blank_cursor [ 16*16 ] = { 0 } ; XColor bcol = { 0 } ; pix = XCreateBitmapFromData ( currDisplay, rootWindow, blank_cursor, 16, 16 ) ; XDefineCursor ( currDisplay, currHandle, XCreatePixmapCursor ( currDisplay, pix, pix, &bcol, &bcol, 0, 0 ) ) ; XFreePixmap ( currDisplay, pix ) ; currCursor = 0 ; } return ; } XDefineCursor( currDisplay, currHandle, XCreateFontCursor ( currDisplay, currCursor ) ) ; } void pwSetSize ( int w, int h ) { XResizeWindow ( currDisplay, currHandle, w, h ) ; XFlush ( currDisplay ) ; } void pwSetOrigin ( int x, int y ) { XMoveWindow ( currDisplay, currHandle, x, y ) ; XFlush ( currDisplay ) ; } void pwSetSizeOrigin ( int x, int y, int w, int h ) { XMoveWindow ( currDisplay, currHandle, x, y ) ; XResizeWindow ( currDisplay, currHandle, w, h ) ; XFlush ( currDisplay ) ; } static void refreshModifiers( XEvent *event ) { modifiers = 0 ; if( event->xkey.state & ( ShiftMask | LockMask ) ) modifiers |= PW_SHIFT ; if( event->xkey.state & ControlMask ) modifiers |= PW_CTRL ; if( event->xkey.state & Mod1Mask ) modifiers |= PW_ALT ; } int pwGetModifiers () { return modifiers ; } static void getEvents () { bool repeating = false ; char keyflags [ 32 ] ; XEvent event ; insideCallback = true ; while ( XPending ( currDisplay ) ) { int updown = PW_DOWN ; XNextEvent ( currDisplay, &event ) ; refreshModifiers ( &event ) ; switch ( event.type ) { case ClientMessage : (*exitCB)() ; break ; case DestroyNotify : (*exitCB)() ; break ; case ConfigureNotify : if ( currHandle == event.xconfigure.window && ( size[0] != event.xconfigure.width || size[1] != event.xconfigure.height ) ) { size[0] = event.xconfigure.width ; size[1] = event.xconfigure.height ; glXMakeCurrent ( currDisplay, currHandle, currContext ) ; glXWaitX () ; if ( resizeCB != NULL ) (*resizeCB) ( size[0], size[1] ) ; } break; case MappingNotify: XRefreshKeyboardMapping ( (XMappingEvent *) &event ) ; break; case EnterNotify : case LeaveNotify : case VisibilityNotify: case Expose : break ; case MotionNotify : if ( mpCB ) (*mpCB) ( event.xmotion.x, event.xmotion.y ) ; break ; case ButtonRelease : updown = PW_UP ; /* FALLTHROUGH */ case ButtonPress : { int button = -1 ; switch ( event.xbutton.button ) { case 1 : button = PW_LEFT_BUTTON ; break ; case 2 : button = PW_MIDDLE_BUTTON ; break ; case 3 : button = PW_RIGHT_BUTTON ; break ; } if ( button != -1 && msCB ) (*msCB) ( button, updown, event.xbutton.x, event.xbutton.y ) ; } break ; case KeyRelease : updown = PW_UP ; XQueryKeymap ( currDisplay, keyflags ) ; repeating = ( ( keyflags [ event.xkey.keycode >> 3 ] & ( 1 << ( event.xkey.keycode & 7 ) ) ) != 0 ) ; /* FALLTHROUGH */ case KeyPress : /* Only generate a key up callback if the key is actually up and not repeating. */ if ( ! autoRepeat && repeating ) break ; XComposeStatus composeStatus ; char asciiCode [ 32 ] ; KeySym keySym ; int len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode), &keySym, &composeStatus ) ; int result = -1 ; if( len > 0 ) result = asciiCode[ 0 ] ; else { switch( keySym ) { case XK_F1: result = PW_KEY_F1; break; case XK_F2: result = PW_KEY_F2; break; case XK_F3: result = PW_KEY_F3; break; case XK_F4: result = PW_KEY_F4; break; case XK_F5: result = PW_KEY_F5; break; case XK_F6: result = PW_KEY_F6; break; case XK_F7: result = PW_KEY_F7; break; case XK_F8: result = PW_KEY_F8; break; case XK_F9: result = PW_KEY_F9; break; case XK_F10: result = PW_KEY_F10; break; case XK_F11: result = PW_KEY_F11; break; case XK_F12: result = PW_KEY_F12; break; case XK_Left: result = PW_KEY_LEFT; break; case XK_Right: result = PW_KEY_RIGHT; break; case XK_Up: result = PW_KEY_UP; break; case XK_Down: result = PW_KEY_DOWN; break; case XK_KP_Prior: case XK_Prior: result = PW_KEY_PAGE_UP; break; case XK_KP_Next: case XK_Next: result = PW_KEY_PAGE_DOWN; break; case XK_KP_Home: case XK_Home: result = PW_KEY_HOME; break; case XK_KP_End: case XK_End: result = PW_KEY_END; break; case XK_KP_Insert: case XK_Insert: result = PW_KEY_INSERT; break; } } if ( result != -1 && kbCB != NULL ) (*kbCB) ( result, updown, event.xkey.x, event.xkey.y ) ; break ; } } insideCallback = false ; glXMakeCurrent ( currDisplay, currHandle, currContext ) ; } void pwSwapBuffers () { if ( ! initialised ) { fprintf ( stderr, "PLIB/PW: FATAL - Application called pwSwapBuffers" " before pwInit.\n" ) ; exit ( 1 ) ; } if ( insideCallback ) { fprintf ( stderr, "PLIB/PW: FATAL - Application called pwSwapBuffers" " from inside a callback function.\n" ) ; exit ( 1 ) ; } glFlush () ; glXSwapBuffers ( currDisplay, currHandle ) ; getEvents () ; } #ifdef NEED_GAMMA void pwSetGamma ( float g ) { XF86VidModeGamma gamma ; gamma.red = gamma.green = gamma.blue = g ; XF86VidModeSetGamma ( currDisplay, currScreen, & gamma ) ; } #endif void pwCleanup () { if ( ! initialised ) fprintf ( stderr, "PLIB/PW: WARNING - Application called pwCleanup" " before pwInit.\n" ) ; glXDestroyContext ( currDisplay, currContext ) ; XDestroyWindow ( currDisplay, currHandle ) ; XFlush ( currDisplay ) ; } #endif plib-1.8.5/src/sg/0000777000175000001440000000000010765365520010665 500000000000000plib-1.8.5/src/sg/sg.cxx0000644000175000001440000015416610765364434011756 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: sg.cxx 1944 2004-08-05 01:07:09Z puggles $ */ #include "sg.h" sgVec3 _sgGravity = { 0.0f, 0.0f, -9.8f } ; void sgVectorProductVec3 ( sgVec3 dst, const sgVec3 a, const sgVec3 b ) { dst[0] = a[1] * b[2] - a[2] * b[1] ; dst[1] = a[2] * b[0] - a[0] * b[2] ; dst[2] = a[0] * b[1] - a[1] * b[0] ; } inline SGfloat _sgClampToUnity ( const SGfloat x ) { if ( x > SG_ONE ) return SG_ONE ; if ( x < -SG_ONE ) return -SG_ONE ; return x ; } int sgCompare3DSqdDist( const sgVec3 v1, const sgVec3 v2, const SGfloat sqd_dist ) { sgVec3 tmp ; sgSubVec3 ( tmp, v2, v1 ) ; SGfloat sqdist = tmp[0] * tmp[0] + tmp[1] * tmp[1] + tmp[2] * tmp[2] ; if ( sqdist > sqd_dist ) return 1 ; if ( sqdist < sqd_dist ) return -1 ; return 0 ; } void sgMakeRotMat4( sgMat4 mat, const SGfloat angle, const sgVec3 axis ) { sgVec3 ax ; sgNormalizeVec3 ( ax, axis ) ; SGfloat temp_angle = angle * SG_DEGREES_TO_RADIANS ; SGfloat s = (SGfloat) sin ( temp_angle ) ; SGfloat c = (SGfloat) cos ( temp_angle ) ; SGfloat t = SG_ONE - c ; mat[0][0] = t * ax[0] * ax[0] + c ; mat[0][1] = t * ax[0] * ax[1] + s * ax[2] ; mat[0][2] = t * ax[0] * ax[2] - s * ax[1] ; mat[0][3] = SG_ZERO ; mat[1][0] = t * ax[1] * ax[0] - s * ax[2] ; mat[1][1] = t * ax[1] * ax[1] + c ; mat[1][2] = t * ax[1] * ax[2] + s * ax[0] ; mat[1][3] = SG_ZERO ; mat[2][0] = t * ax[2] * ax[0] + s * ax[1] ; mat[2][1] = t * ax[2] * ax[1] - s * ax[0] ; mat[2][2] = t * ax[2] * ax[2] + c ; mat[2][3] = SG_ZERO ; mat[3][0] = SG_ZERO ; mat[3][1] = SG_ZERO ; mat[3][2] = SG_ZERO ; mat[3][3] = SG_ONE ; } void sgMakePickMatrix( sgMat4 mat, sgFloat x, sgFloat y, sgFloat width, sgFloat height, sgVec4 viewport ) { sgFloat sx = viewport[2] / width ; sgFloat sy = viewport[3] / height ; sgFloat tx = ( viewport[2] + SG_TWO * (viewport[0] - x) ) / width ; sgFloat ty = ( viewport[3] + SG_TWO * (viewport[1] - y) ) / height ; mat[0][0] = sx ; mat[0][1] = SG_ZERO ; mat[0][2] = SG_ZERO ; mat[0][3] = SG_ZERO ; mat[1][0] = SG_ZERO ; mat[1][1] = sy ; mat[1][2] = SG_ZERO ; mat[1][3] = SG_ZERO ; mat[2][0] = SG_ZERO ; mat[2][1] = SG_ZERO ; mat[2][2] = SG_ONE ; mat[2][3] = SG_ZERO ; mat[3][0] = tx ; mat[3][1] = ty ; mat[3][2] = SG_ZERO ; mat[3][3] = SG_ONE ; } void sgMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center, const sgVec3 up ) { // Caveats: // 1) In order to compute the line of sight, the eye point must not be equal // to the center point. // 2) The up vector must not be parallel to the line of sight from the eye // to the center point. /* Compute the direction vectors */ sgVec3 x,y,z; /* Y vector = center - eye */ sgSubVec3 ( y, center, eye ) ; /* Z vector = up */ sgCopyVec3 ( z, up ) ; /* X vector = Y cross Z */ sgVectorProductVec3 ( x, y, z ) ; /* Recompute Z = X cross Y */ sgVectorProductVec3 ( z, x, y ) ; /* Normalize everything */ sgNormaliseVec3 ( x ) ; sgNormaliseVec3 ( y ) ; sgNormaliseVec3 ( z ) ; /* Build the matrix */ sgSetVec4 ( dst[0], x[0], x[1], x[2], SG_ZERO ) ; sgSetVec4 ( dst[1], y[0], y[1], y[2], SG_ZERO ) ; sgSetVec4 ( dst[2], z[0], z[1], z[2], SG_ZERO ) ; sgSetVec4 ( dst[3], eye[0], eye[1], eye[2], SG_ONE ) ; } // -dw- inconsistent linkage! float sgTriArea( sgVec3 p0, sgVec3 p1, sgVec3 p2 ) { /* From comp.graph.algorithms FAQ 2A(P) = abs(N.(sum_{i=0}^{n-1}(v_i x v_{i+1}))) This is an optimized version for a triangle but easily extended for planar polygon's with more sides by passing in the number of sides and the vv array sgTriArea( int nsides, float **vv ) and changing the normal calculation and the for loop appropriately sgMakeNormal( norm, vv[0], vv[1], vv[2] ) for( int i=0; i 0.99999 ) deltaAngle = SG_PI*0.5; else deltaAngle = (SGfloat)asin((double)myNorm); // deltaAngle is in the range -SG_PI*0.5 to +SG_PI*0.5 here // However, the correct result could also be // deltaAngleS := pi - deltaAngle // Please note that: // cos(deltaAngleS)=cos(pi-deltaAngle)=-cos(deltaAngle) // So, the question is whether + or - cos(deltaAngle) // is sgScalarProductVec3(first, second) if ( deltaAngle < 0 ) deltaAngle = deltaAngle + 2*SG_PI; // unnessecary? SProduct = sgScalarProductVec3(first, second); myCos = (SGfloat) cos(deltaAngle); abs1 = SProduct - myCos; abs2 = SProduct + myCos; if ( abs1 < 0 ) abs1 = -abs1 ; if ( abs2 < 0 ) abs2 = -abs2 ; assert( (abs1 < 0.1) || (abs2 < 0.1) ) ; if ( abs2 < abs1 ) { // deltaAngleS is the correct result if ( deltaAngle <= SG_PI ) deltaAngle = SG_PI - deltaAngle ; else deltaAngle = 3*SG_PI - deltaAngle ; } assert ( deltaAngle >= 0.0 ) ; assert ( deltaAngle <= 2.0*SG_PI ) ; return deltaAngle * SG_RADIANS_TO_DEGREES ; } SGfloat sgAngleBetweenVec3 ( sgVec3 v1, sgVec3 v2, sgVec3 normal ) { // nornmal has to be normalized. sgVec3 nv1, nv2 ; sgNormalizeVec3 ( nv1, v1 ) ; sgNormalizeVec3 ( nv2, v2 ) ; return sgAngleBetweenNormalizedVec3 ( nv1, nv2, normal ) ; } /*********************\ * sgBox routines * \*********************/ void sgBox::extend ( const sgVec3 v ) { if ( isEmpty () ) { sgCopyVec3 ( min, v ) ; sgCopyVec3 ( max, v ) ; } else { if ( v[0] < min[0] ) min[0] = v[0] ; if ( v[1] < min[1] ) min[1] = v[1] ; if ( v[2] < min[2] ) min[2] = v[2] ; if ( v[0] > max[0] ) max[0] = v[0] ; if ( v[1] > max[1] ) max[1] = v[1] ; if ( v[2] > max[2] ) max[2] = v[2] ; } } void sgBox::extend ( const sgBox *b ) { if ( b -> isEmpty () ) return ; if ( isEmpty () ) { sgCopyVec3 ( min, b->getMin() ) ; sgCopyVec3 ( max, b->getMax() ) ; } else { extend ( b->getMin() ) ; extend ( b->getMax() ) ; } } void sgBox::extend ( const sgSphere *s ) { if ( s -> isEmpty () ) return ; /* In essence, this extends around a box around the sphere - which is still a perfect solution because both boxes are axially aligned. */ sgVec3 x ; sgSetVec3 ( x, s->getCenter()[0]+s->getRadius(), s->getCenter()[1]+s->getRadius(), s->getCenter()[2]+s->getRadius() ) ; extend ( x ) ; sgSetVec3 ( x, s->getCenter()[0]-s->getRadius(), s->getCenter()[1]-s->getRadius(), s->getCenter()[2]-s->getRadius() ) ; extend ( x ) ; } int sgBox::intersects ( const sgVec4 plane ) const { /* Save multiplies by not redoing Ax+By+Cz+D for each point. */ SGfloat Ax_min = plane[0] * min[0] ; SGfloat By_min = plane[1] * min[1] ; SGfloat Cz_min_plus_D = plane[2] * min[2] + plane[3] ; SGfloat Ax_max = plane[0] * max[0] ; SGfloat By_max = plane[1] * max[1] ; SGfloat Cz_max_plus_D = plane[2] * max[2] + plane[3] ; /* Count the number of vertices on the positive side of the plane. */ int count = ( Ax_min + By_min + Cz_min_plus_D > SG_ZERO ) + ( Ax_min + By_min + Cz_max_plus_D > SG_ZERO ) + ( Ax_min + By_max + Cz_min_plus_D > SG_ZERO ) + ( Ax_min + By_max + Cz_max_plus_D > SG_ZERO ) + ( Ax_max + By_min + Cz_min_plus_D > SG_ZERO ) + ( Ax_max + By_min + Cz_max_plus_D > SG_ZERO ) + ( Ax_max + By_max + Cz_min_plus_D > SG_ZERO ) + ( Ax_max + By_max + Cz_max_plus_D > SG_ZERO ) ; /* The plane intersects the box unless all 8 are positive or none of them are positive. */ return count != 0 && count != 8 ; } /**********************\ * sgSphere routines * \**********************/ void sgSphere::extend ( const sgVec3 v ) { if ( isEmpty () ) { sgCopyVec3 ( center, v ) ; radius = SG_ZERO ; return ; } SGfloat d = sgDistanceVec3 ( center, v ) ; if ( d <= radius ) /* Point is already inside sphere */ return ; SGfloat new_radius = (radius + d) / SG_TWO ; /* Grow radius */ SGfloat ratio = (new_radius - radius) / d ; center[0] += (v[0]-center[0]) * ratio ; /* Move center */ center[1] += (v[1]-center[1]) * ratio ; center[2] += (v[2]-center[2]) * ratio ; radius = new_radius ; } void sgSphere::extend ( const sgBox *b ) { if ( b -> isEmpty () ) return ; if ( isEmpty() ) { sgAddVec3 ( center, b->getMin(), b->getMax() ) ; sgScaleVec3 ( center, SG_HALF ) ; radius = sgDistanceVec3 ( center, b->getMax() ) ; return ; } /* I can't think of a faster way to get an utterly minimal sphere. The tighter algorithm:- enclose each of eight vertices of the box in turn - it looks like being pretty costly. [8 sqrt()'s] The looser algorithm:- enclose the box with an empty sphere and then do a sphere-extend-sphere. This algorithm does well for close-to-cube boxes, but makes very poor spheres for long, thin boxes. [2 sqrt()'s] */ #ifdef DONT_REALLY_NEED_A_TIGHT_SPHERE_EXTEND_BOX /* LOOSER/FASTER sphere-around-sphere-around-box */ sgSphere s ; s.empty () ; s.enclose ( b ) ; /* Fast because s is empty */ enclose ( s ) ; #else /* TIGHTER/EXPENSIVE sphere-around-eight-points */ sgVec3 x ; extend ( b->getMin() ) ; sgSetVec3 ( x, b->getMin()[0],b->getMin()[1],b->getMax()[2] ) ; extend ( x ) ; sgSetVec3 ( x, b->getMin()[0],b->getMax()[1],b->getMin()[2] ) ; extend ( x ) ; sgSetVec3 ( x, b->getMin()[0],b->getMax()[1],b->getMax()[2] ) ; extend ( x ) ; sgSetVec3 ( x, b->getMax()[0],b->getMin()[1],b->getMin()[2] ) ; extend ( x ) ; sgSetVec3 ( x, b->getMax()[0],b->getMin()[1],b->getMax()[2] ) ; extend ( x ) ; sgSetVec3 ( x, b->getMax()[0],b->getMax()[1],b->getMin()[2] ) ; extend ( x ) ; extend ( b->getMax() ) ; #endif } void sgSphere::extend ( const sgSphere *s ) { if ( s->isEmpty () ) return ; if ( isEmpty () ) { sgCopyVec3 ( center, s->getCenter() ) ; radius = s->getRadius() ; return ; } /* d == The distance between the sphere centers */ SGfloat d = sgDistanceVec3 ( center, s->getCenter() ) ; if ( d + s->getRadius() <= radius ) /* New sphere is already inside this one */ return ; if ( d + radius <= s->getRadius() ) /* New sphere completely contains this one */ { sgCopyVec3 ( center, s->getCenter() ) ; radius = s->getRadius() ; return ; } /* Build a new sphere that completely contains the other two: The center point lies halfway along the line between the furthest points on the edges of the two spheres. Computing those two points is ugly - so we'll use similar triangles */ SGfloat new_radius = (radius + d + s->getRadius() ) / SG_TWO ; SGfloat ratio = ( new_radius - radius ) / d ; center[0] += ( s->getCenter()[0] - center[0] ) * ratio ; center[1] += ( s->getCenter()[1] - center[1] ) * ratio ; center[2] += ( s->getCenter()[2] - center[2] ) * ratio ; radius = new_radius ; } int sgSphere::intersects ( const sgBox *b ) const { sgVec3 closest ; if ( b->getMin()[0] > center[0] ) closest[0] = b->getMin()[0] ; else if ( b->getMax()[0] < center[0] ) closest[0] = b->getMax()[0] ; else closest[0] = center[0] ; if ( b->getMin()[1] > center[1] ) closest[1] = b->getMin()[1] ; else if ( b->getMax()[1] < center[1] ) closest[1] = b->getMax()[1] ; else closest[1] = center[1] ; if ( b->getMin()[2] > center[2] ) closest[2] = b->getMin()[2] ; else if ( b->getMax()[2] < center[2] ) closest[2] = b->getMax()[2] ; else closest[2] = center[2] ; return sgCompare3DSqdDist ( closest, center, sgSquare ( radius ) ) <= 0 ; } /************************\ * sgFrustum routines * \************************/ void sgFrustum::update () { if ( fabs ( ffar - nnear ) < 0.1 ) { ulSetError ( UL_WARNING, "sgFrustum: Can't support depth of view <0.1 units."); return ; } if ( hfov != SG_ZERO && vfov != SG_ZERO ) { if ( fabs ( hfov ) < 0.1 || fabs ( vfov ) < 0.1 ) { ulSetError ( UL_WARNING, ortho ? "sgFrustum: Can't support width or height <0.1 units." : "sgFrustum: Can't support fields of view narrower than 0.1 degrees." ) ; return ; } if ( ortho ) { right = SG_HALF * hfov ; top = SG_HALF * vfov ; } else { right = nnear * (SGfloat) tan ( hfov * SG_DEGREES_TO_RADIANS / SG_TWO ) ; top = nnear * (SGfloat) tan ( vfov * SG_DEGREES_TO_RADIANS / SG_TWO ) ; } left = -right ; bot = -top ; } /* Compute the projection matrix */ SGfloat width = right - left ; SGfloat height = top - bot ; SGfloat depth = ffar - nnear ; if ( ortho ) { /* orthographic */ mat[0][0] = SG_TWO / width ; mat[0][1] = SG_ZERO ; mat[0][2] = SG_ZERO ; mat[0][3] = SG_ZERO ; mat[1][0] = SG_ZERO ; mat[1][1] = SG_TWO / height ; mat[1][2] = SG_ZERO ; mat[1][3] = SG_ZERO ; mat[2][0] = SG_ZERO ; mat[2][1] = SG_ZERO ; mat[2][2] = -SG_TWO / depth ; mat[2][3] = SG_ZERO ; mat[3][0] = -( left + right ) / width ; mat[3][1] = -( bot + top ) / height ; mat[3][2] = -( nnear + ffar ) / depth ; mat[3][3] = SG_ONE ; } else { /* perspective */ mat[0][0] = SG_TWO * nnear / width ; mat[0][1] = SG_ZERO ; mat[0][2] = SG_ZERO ; mat[0][3] = SG_ZERO ; mat[1][0] = SG_ZERO ; mat[1][1] = SG_TWO * nnear / height ; mat[1][2] = SG_ZERO ; mat[1][3] = SG_ZERO ; mat[2][0] = ( right + left ) / width ; mat[2][1] = ( top + bot ) / height ; mat[2][2] = -( ffar + nnear ) / depth ; mat[2][3] = -SG_ONE ; mat[3][0] = SG_ZERO ; mat[3][1] = SG_ZERO ; mat[3][2] = -SG_TWO * nnear * ffar / depth ; mat[3][3] = SG_ZERO ; } /* * The clip planes are derived from the projection matrix. * * After projection (in clip coordinates), the clip planes are simply: * * left: ( 1, 0, 0, 1 ) * right: ( -1, 0, 0, 1 ) * bottom: ( 0, 1, 0, 1 ) * top: ( 0, -1, 0, 1 ) * near: ( 0, 0, 1, 1 ) * far: ( 0, 0, -1, 1 ) * * These can easily be transformed *backwards* by * multiplying by the transposed projection matrix, i.e: * * ( A ) ( A') * ( B ) = mat^T ( B') * ( C ) ( C') * ( D ) ( D') * * where (A',B',C',D') represents a plane in clip coordinates, * and (A,B,C,D) is the same plane expressed in eye coordinates. */ sgSetVec4( plane[ SG_LEFT_PLANE ], SG_ONE, SG_ZERO, SG_ZERO, SG_ONE ); sgSetVec4( plane[ SG_RIGHT_PLANE ], -SG_ONE, SG_ZERO, SG_ZERO, SG_ONE ); sgSetVec4( plane[ SG_BOT_PLANE ], SG_ZERO, SG_ONE, SG_ZERO, SG_ONE ); sgSetVec4( plane[ SG_TOP_PLANE ], SG_ZERO, -SG_ONE, SG_ZERO, SG_ONE ); sgSetVec4( plane[ SG_NEAR_PLANE ], SG_ZERO, SG_ZERO, SG_ONE, SG_ONE ); sgSetVec4( plane[ SG_FAR_PLANE ], SG_ZERO, SG_ZERO, -SG_ONE, SG_ONE ); for ( int i = 0 ; i < 6 ; i++ ) { sgVec4 tmp ; for ( int j = 0 ; j < 4 ; j++ ) tmp[j] = sgScalarProductVec4 ( plane[i], mat[j] ) ; sgScaleVec4 ( plane[i], tmp, SG_ONE / sgLengthVec3 ( tmp ) ) ; } } #define OC_LEFT_SHIFT 0 #define OC_RIGHT_SHIFT 1 #define OC_TOP_SHIFT 2 #define OC_BOT_SHIFT 3 #define OC_NEAR_SHIFT 4 #define OC_FAR_SHIFT 5 #define OC_ALL_ON_SCREEN 0x3F #define OC_OFF_TRF ((1<= -tmp[3] ) << OC_LEFT_SHIFT ) | (( tmp[1] <= tmp[3] ) << OC_TOP_SHIFT ) | (( tmp[1] >= -tmp[3] ) << OC_BOT_SHIFT ) | (( tmp[2] <= tmp[3] ) << OC_FAR_SHIFT ) | (( tmp[2] >= -tmp[3] ) << OC_NEAR_SHIFT ) ; } int sgFrustum::contains ( const sgVec3 pt ) const { return getOutcode ( pt ) == OC_ALL_ON_SCREEN ; } int sgFrustum::contains ( const sgSphere *s ) const { const SGfloat *center = s->getCenter() ; const SGfloat radius = s->getRadius() ; /* Lop off half the database (roughly) with a quick near-plane test - and lop off a lot more with a quick far-plane test */ if ( -center[2] + radius < nnear || -center[2] - radius > ffar ) return SG_OUTSIDE ; /* OK, so the sphere lies between near and far. Measure the distance of the center point from the four sides of the frustum, if it's outside by more than the radius then it's history. It's tempting to do a quick test to see if the center point is onscreen using sgFrustumContainsPt - but that takes a matrix transform which is 16 multiplies and 12 adds - versus this test which does the whole task using only 12 multiplies and 8 adds. */ /* A few operations are saved by observing that certain values in the plane equations are zero or one. These are specific to orthographic and perspective projections respectively. */ SGfloat sp1, sp2, sp3, sp4 ; if ( ortho ) { /* left: ( 1, 0, 0, x ) right: ( -1, 0, 0, x ) bottom: ( 0, 1, 0, x ) top: ( 0, -1, 0, x ) */ sp1 = plane[ SG_LEFT_PLANE ][3] + center[0] ; sp2 = plane[ SG_RIGHT_PLANE ][3] - center[0] ; sp3 = plane[ SG_BOT_PLANE ][3] + center[1] ; sp4 = plane[ SG_TOP_PLANE ][3] - center[1] ; } else { /* left: ( x, 0, x, 0 ) right: ( x, 0, x, 0 ) bottom: ( 0, x, x, 0 ) top: ( 0, x, x, 0 ) */ sp1 = plane[ SG_LEFT_PLANE ][0] * center[0] + plane[ SG_LEFT_PLANE ][2] * center[2] ; sp2 = plane[ SG_RIGHT_PLANE ][0] * center[0] + plane[ SG_RIGHT_PLANE ][2] * center[2] ; sp3 = plane[ SG_BOT_PLANE ][1] * center[1] + plane[ SG_BOT_PLANE ][2] * center[2] ; sp4 = plane[ SG_TOP_PLANE ][1] * center[1] + plane[ SG_TOP_PLANE ][2] * center[2] ; } /* Note: in the general case, we would have to do: sp1 = sgScalarProductVec3 ( left_plane, center ) + left_plane[3] ; sp2 = sgScalarProductVec3 ( right_plane, center ) + right_plane[3] ; ... sp6 = sgScalarProductVec3 ( far_plane, center ) + far_plane[3] ; */ if ( -sp1 > radius || -sp2 > radius || -sp3 > radius || -sp4 > radius ) return SG_OUTSIDE ; /* If it's inside by more than the radius then it's *completely* inside and we can save time elsewhere if we know that for sure. */ if ( sp1 >= radius && sp2 >= radius && sp3 >= radius && sp4 >= radius && -center[2] - radius >= nnear && -center[2] + radius <= ffar ) return SG_INSIDE ; return SG_STRADDLE ; } int sgFrustum::contains ( const sgBox *b ) const { sgVec3 p[8] = { { b->getMin()[0], b->getMin()[1], b->getMin()[2] }, { b->getMax()[0], b->getMin()[1], b->getMin()[2] }, { b->getMin()[0], b->getMax()[1], b->getMin()[2] }, { b->getMax()[0], b->getMax()[1], b->getMin()[2] }, { b->getMin()[0], b->getMin()[1], b->getMax()[2] }, { b->getMax()[0], b->getMin()[1], b->getMax()[2] }, { b->getMin()[0], b->getMax()[1], b->getMax()[2] }, { b->getMax()[0], b->getMax()[1], b->getMax()[2] }, } ; int all = -1 ; int one = 0 ; for (int i = 0 ; i < 8 ; i++ ) { int tmp = ~ getOutcode ( p[i] ) ; all &= tmp ; one |= tmp ; } return ( all ? SG_OUTSIDE : one ? SG_STRADDLE : SG_INSIDE ) ; } SGfloat sgDistSquaredToLineVec3 ( const sgLine3 line, const sgVec3 pnt ) { sgVec3 r ; sgSubVec3 ( r, pnt, line.point_on_line ) ; float projectedDistance = sgScalarProductVec3(r,line.direction_vector); return sgScalarProductVec3 ( r, r ) - projectedDistance * projectedDistance; } SGfloat sgDistSquaredToLineSegmentVec3 ( const sgLineSegment3 line, const sgVec3 pnt ) { sgVec3 v ; sgSubVec3 ( v, line.b, line.a ) ; sgVec3 r1 ; sgSubVec3 ( r1, pnt, line.a ) ; SGfloat r1_dot_v = sgScalarProductVec3 ( r1, v ) ; if ( r1_dot_v <= 0 ) /* Off the "A" end */ return sgScalarProductVec3 ( r1, r1 ) ; sgVec3 r2 ; sgSubVec3 ( r2, pnt, line.b ) ; SGfloat r2_dot_v = sgScalarProductVec3 ( r2, v ) ; if ( r2_dot_v >= 0 ) /* Off the "B" end */ return sgScalarProductVec3 ( r2, r2 ) ; /* Closest point on line is on the line segment */ return sgScalarProductVec3 ( r1, r1 ) - r1_dot_v * r1_dot_v / sgScalarProductVec3 ( v, v ) ; } void sgMakeCoordMat4 ( sgMat4 m, const SGfloat x, const SGfloat y, const SGfloat z, const SGfloat h, const SGfloat p, const SGfloat r ) { SGfloat ch, sh, cp, sp, cr, sr, srsp, crsp, srcp ; if ( h == SG_ZERO ) { ch = SGD_ONE ; sh = SGD_ZERO ; } else { sh = sgSin ( h ) ; ch = sgCos ( h ) ; } if ( p == SG_ZERO ) { cp = SGD_ONE ; sp = SGD_ZERO ; } else { sp = sgSin ( p ) ; cp = sgCos ( p ) ; } if ( r == SG_ZERO ) { cr = SGD_ONE ; sr = SGD_ZERO ; srsp = SGD_ZERO ; srcp = SGD_ZERO ; crsp = sp ; } else { sr = sgSin ( r ) ; cr = sgCos ( r ) ; srsp = sr * sp ; crsp = cr * sp ; srcp = sr * cp ; } m[0][0] = (SGfloat)( ch * cr - sh * srsp ) ; m[1][0] = (SGfloat)( -sh * cp ) ; m[2][0] = (SGfloat)( sr * ch + sh * crsp ) ; m[3][0] = x ; m[0][1] = (SGfloat)( cr * sh + srsp * ch ) ; m[1][1] = (SGfloat)( ch * cp ) ; m[2][1] = (SGfloat)( sr * sh - crsp * ch ) ; m[3][1] = y ; m[0][2] = (SGfloat)( -srcp ) ; m[1][2] = (SGfloat)( sp ) ; m[2][2] = (SGfloat)( cr * cp ) ; m[3][2] = z ; m[0][3] = SG_ZERO ; m[1][3] = SG_ZERO ; m[2][3] = SG_ZERO ; m[3][3] = SG_ONE ; } void sgMakeTransMat4 ( sgMat4 m, const sgVec3 xyz ) { m[0][1] = m[0][2] = m[0][3] = m[1][0] = m[1][2] = m[1][3] = m[2][0] = m[2][1] = m[2][3] = SG_ZERO ; m[0][0] = m[1][1] = m[2][2] = m[3][3] = SG_ONE ; sgCopyVec3 ( m[3], xyz ) ; } void sgMakeTransMat4 ( sgMat4 m, const SGfloat x, const SGfloat y, const SGfloat z ) { m[0][1] = m[0][2] = m[0][3] = m[1][0] = m[1][2] = m[1][3] = m[2][0] = m[2][1] = m[2][3] = SG_ZERO ; m[0][0] = m[1][1] = m[2][2] = m[3][3] = SG_ONE ; sgSetVec3 ( m[3], x, y, z ) ; } void sgSetCoord ( sgCoord *dst, const sgMat4 src ) { sgCopyVec3 ( dst->xyz, src[3] ) ; sgMat4 mat ; SGfloat s = sgLengthVec3 ( src[0] ) ; if ( s <= 0.00001 ) { ulSetError ( UL_WARNING, "sgMat4ToCoord: ERROR - Bad Matrix." ) ; sgSetVec3 ( dst -> hpr, SG_ZERO, SG_ZERO, SG_ZERO ) ; return ; } sgScaleMat4 ( mat, src, SG_ONE / s ) ; dst->hpr[1] = sgASin ( _sgClampToUnity ( mat[1][2] ) ) ; SGfloat cp = sgCos ( dst->hpr[1] ) ; /* If pointing nearly vertically up - then heading is ill-defined */ if ( cp > -0.00001 && cp < 0.00001 ) { SGfloat cr = _sgClampToUnity ( mat[0][1] ) ; SGfloat sr = _sgClampToUnity (-mat[2][1] ) ; dst->hpr[0] = SG_ZERO ; dst->hpr[2] = sgATan2 ( sr, cr ) ; } else { cp = SG_ONE / cp ; SGfloat sr = _sgClampToUnity ( -mat[0][2] * cp ) ; SGfloat cr = _sgClampToUnity ( mat[2][2] * cp ) ; SGfloat sh = _sgClampToUnity ( -mat[1][0] * cp ) ; SGfloat ch = _sgClampToUnity ( mat[1][1] * cp ) ; if ( (sh == SG_ZERO && ch == SG_ZERO) || (sr == SG_ZERO && cr == SG_ZERO) ) { cr = _sgClampToUnity ( mat[0][1] ) ; sr = _sgClampToUnity (-mat[2][1] ) ; dst->hpr[0] = SG_ZERO ; } else dst->hpr[0] = sgATan2 ( sh, ch ) ; dst->hpr[2] = sgATan2 ( sr, cr ) ; } } void sgMakeNormal(sgVec2 dst, const sgVec2 a, const sgVec2 b ) { sgSubVec2 ( dst, b, a ) ; float tmp = dst [ 0 ] ; dst [ 0 ] = -dst [ 1 ] ; dst [ 1 ] = tmp ; sgNormaliseVec2 ( dst ) ; } void sgMakeNormal(sgVec3 dst, const sgVec3 a, const sgVec3 b, const sgVec3 c ) { sgVec3 ab ; sgSubVec3 ( ab, b, a ) ; sgVec3 ac ; sgSubVec3 ( ac, c, a ) ; sgVectorProductVec3 ( dst, ab,ac ) ; sgNormaliseVec3 ( dst ) ; } void sgPreMultMat4( sgMat4 dst, const sgMat4 src ) { sgMat4 mat ; sgMultMat4 ( mat, dst, src ) ; sgCopyMat4 ( dst, mat ) ; } void sgPostMultMat4( sgMat4 dst, const sgMat4 src ) { sgMat4 mat ; sgMultMat4 ( mat, src, dst ) ; sgCopyMat4 ( dst, mat ) ; } void sgMultMat4( sgMat4 dst, const sgMat4 m1, const sgMat4 m2 ) { for ( int j = 0 ; j < 4 ; j++ ) { dst[0][j] = m2[0][0] * m1[0][j] + m2[0][1] * m1[1][j] + m2[0][2] * m1[2][j] + m2[0][3] * m1[3][j] ; dst[1][j] = m2[1][0] * m1[0][j] + m2[1][1] * m1[1][j] + m2[1][2] * m1[2][j] + m2[1][3] * m1[3][j] ; dst[2][j] = m2[2][0] * m1[0][j] + m2[2][1] * m1[1][j] + m2[2][2] * m1[2][j] + m2[2][3] * m1[3][j] ; dst[3][j] = m2[3][0] * m1[0][j] + m2[3][1] * m1[1][j] + m2[3][2] * m1[2][j] + m2[3][3] * m1[3][j] ; } } void sgTransposeNegateMat4 ( sgMat4 dst, const sgMat4 src ) { /* Poor man's invert - can be used when matrix is a simple rotate-translate */ dst[0][0] = src[0][0] ; dst[1][0] = src[0][1] ; dst[2][0] = src[0][2] ; dst[3][0] = - sgScalarProductVec3 ( src[3], src[0] ) ; dst[0][1] = src[1][0] ; dst[1][1] = src[1][1] ; dst[2][1] = src[1][2] ; dst[3][1] = - sgScalarProductVec3 ( src[3], src[1] ) ; dst[0][2] = src[2][0] ; dst[1][2] = src[2][1] ; dst[2][2] = src[2][2] ; dst[3][2] = - sgScalarProductVec3 ( src[3], src[2] ) ; dst[0][3] = SG_ZERO ; dst[1][3] = SG_ZERO ; dst[2][3] = SG_ZERO ; dst[3][3] = SG_ONE ; } void sgTransposeNegateMat4 ( sgMat4 dst ) { sgMat4 src ; sgCopyMat4 ( src, dst ) ; sgTransposeNegateMat4 ( dst, src ) ; } void sgInvertMat4 ( sgMat4 dst, const sgMat4 src ) { sgMat4 tmp ; sgCopyMat4 ( tmp, src ) ; sgMakeIdentMat4 ( dst ) ; for ( int i = 0 ; i != 4 ; i++ ) { SGfloat val = tmp[i][i] ; int ind = i ; int j ; for ( j = i + 1 ; j != 4 ; j++ ) { if ( fabs ( tmp[i][j] ) > fabs(val) ) { ind = j; val = tmp[i][j] ; } } if ( ind != i ) { /* swap columns */ for ( j = 0 ; j != 4 ; j++ ) { SGfloat t ; t = dst[j][i]; dst[j][i] = dst[j][ind]; dst[j][ind] = t ; t = tmp[j][i]; tmp[j][i] = tmp[j][ind]; tmp[j][ind] = t ; } } // if ( val == SG_ZERO) if ( fabs(val) <= FLT_EPSILON ) { ulSetError ( UL_WARNING, "sg: ERROR - Singular matrix, no inverse!" ) ; sgMakeIdentMat4 ( dst ) ; /* Do *something* */ return; } SGfloat ival = SG_ONE / val ; for ( j = 0 ; j != 4 ; j++ ) { tmp[j][i] *= ival ; dst[j][i] *= ival ; } for (j = 0; j != 4; j++) { if ( j == i ) continue ; val = tmp[i][j] ; for ( int k = 0 ; k != 4 ; k++ ) { tmp[k][j] -= tmp[k][i] * val ; dst[k][j] -= dst[k][i] * val ; } } } } void sgXformVec3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) { SGfloat t0 = src[ 0 ] ; SGfloat t1 = src[ 1 ] ; SGfloat t2 = src[ 2 ] ; dst[0] = t0 * mat[ 0 ][ 0 ] + t1 * mat[ 1 ][ 0 ] + t2 * mat[ 2 ][ 0 ] ; dst[1] = t0 * mat[ 0 ][ 1 ] + t1 * mat[ 1 ][ 1 ] + t2 * mat[ 2 ][ 1 ] ; dst[2] = t0 * mat[ 0 ][ 2 ] + t1 * mat[ 1 ][ 2 ] + t2 * mat[ 2 ][ 2 ] ; } void sgXformPnt3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) { SGfloat t0 = src[ 0 ] ; SGfloat t1 = src[ 1 ] ; SGfloat t2 = src[ 2 ] ; dst[0] = t0 * mat[ 0 ][ 0 ] + t1 * mat[ 1 ][ 0 ] + t2 * mat[ 2 ][ 0 ] + mat[ 3 ][ 0 ] ; dst[1] = t0 * mat[ 0 ][ 1 ] + t1 * mat[ 1 ][ 1 ] + t2 * mat[ 2 ][ 1 ] + mat[ 3 ][ 1 ] ; dst[2] = t0 * mat[ 0 ][ 2 ] + t1 * mat[ 1 ][ 2 ] + t2 * mat[ 2 ][ 2 ] + mat[ 3 ][ 2 ] ; } void sgXformPnt4 ( sgVec4 dst, const sgVec4 src, const sgMat4 mat ) { SGfloat t0 = src[ 0 ] ; SGfloat t1 = src[ 1 ] ; SGfloat t2 = src[ 2 ] ; SGfloat t3 = src[ 3 ] ; dst[0] = t0 * mat[ 0 ][ 0 ] + t1 * mat[ 1 ][ 0 ] + t2 * mat[ 2 ][ 0 ] + t3 * mat[ 3 ][ 0 ] ; dst[1] = t0 * mat[ 0 ][ 1 ] + t1 * mat[ 1 ][ 1 ] + t2 * mat[ 2 ][ 1 ] + t3 * mat[ 3 ][ 1 ] ; dst[2] = t0 * mat[ 0 ][ 2 ] + t1 * mat[ 1 ][ 2 ] + t2 * mat[ 2 ][ 2 ] + t3 * mat[ 3 ][ 2 ] ; dst[3] = t0 * mat[ 0 ][ 3 ] + t1 * mat[ 1 ][ 3 ] + t2 * mat[ 2 ][ 3 ] + t3 * mat[ 3 ][ 3 ] ; } void sgFullXformPnt3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) { sgVec4 tmp ; tmp [ 0 ] = src [ 0 ] ; tmp [ 1 ] = src [ 1 ] ; tmp [ 2 ] = src [ 2 ] ; tmp [ 3 ] = SG_ONE ; sgXformPnt4 ( tmp, tmp, mat ) ; sgScaleVec3 ( dst, tmp, SG_ONE / tmp [ 3 ] ) ; } void sgHPRfromVec3 ( sgVec3 hpr, const sgVec3 src ) { sgVec3 tmp ; sgCopyVec3 ( tmp, src ) ; sgNormaliseVec3 ( tmp ) ; hpr[0] = - sgATan2 ( tmp [ 0 ], tmp [ 1 ] ) ; hpr[1] = - sgATan2 ( tmp [ 2 ], sgSqrt ( sgSquare ( tmp [ 0 ] ) + sgSquare ( tmp [ 1 ] ) ) ) ; hpr[2] = SG_ZERO ; } /* Quaternion routines are Copyright (C) 1999 Kevin B. Thompson Modified by Sylvan W. Clebsch Largely rewritten by "Negative0" More added by John Fay. */ void sgQuatToAngleAxis ( SGfloat *angle, SGfloat *x, SGfloat *y, SGfloat *z, const sgQuat src ) { sgVec3 axis ; sgQuatToAngleAxis ( angle, axis, src ) ; *x = axis [ 0 ] ; *y = axis [ 1 ] ; *z = axis [ 2 ] ; } void sgQuatToAngleAxis ( SGfloat *angle, sgVec3 axis, const sgQuat src ) { SGfloat a = (SGfloat) acos ( src[SG_W] ) ; SGfloat s = (SGfloat) sin ( a ) ; *angle = a * SG_RADIANS_TO_DEGREES * SG_TWO ; if ( s == SG_ZERO ) sgSetVec3 ( axis, SG_ZERO, SG_ZERO, SG_ONE ); else { sgSetVec3 ( axis, src[SG_X], src[SG_Y], src[SG_Z] ) ; sgScaleVec3 ( axis, SG_ONE / s ) ; } } void sgAngleAxisToQuat ( sgQuat dst, const SGfloat angle, const SGfloat x, const SGfloat y, const SGfloat z ) { sgVec3 axis ; sgSetVec3 ( axis, x, y, z ) ; sgAngleAxisToQuat ( dst, angle, axis ) ; } void sgAngleAxisToQuat ( sgQuat dst, const SGfloat angle, const sgVec3 axis ) { SGfloat temp_angle = angle * SG_DEGREES_TO_RADIANS / SG_TWO ; sgVec3 ax ; sgNormaliseVec3 ( ax, axis ) ; SGfloat s = - (SGfloat) sin ( temp_angle ) ; dst[SG_W] = (SGfloat) cos ( temp_angle ) ; sgScaleVec3 ( dst, ax, s ) ; } //from gamasutra.com //by nb void sgMatrixToQuat( sgQuat quat, const sgMat4 m ) { SGfloat tr, s, q[4] ; int i, j, k ; int nxt[3] = {1, 2, 0}; tr = m[0][0] + m[1][1] + m[2][2]; // check the diagonal if (tr > SG_ZERO ) { s = (SGfloat) sgSqrt (tr + SG_ONE); quat[SG_W] = s / SG_TWO; s = SG_HALF / s; quat[SG_X] = (m[1][2] - m[2][1]) * s; quat[SG_Y] = (m[2][0] - m[0][2]) * s; quat[SG_Z] = (m[0][1] - m[1][0]) * s; } else { // diagonal is negative i = 0; if (m[1][1] > m[0][0]) i = 1; if (m[2][2] > m[i][i]) i = 2; j = nxt[i]; k = nxt[j]; s = (SGfloat) sgSqrt ((m[i][i] - (m[j][j] + m[k][k])) + SG_ONE); q[i] = s * SG_HALF; if (s != SG_ZERO) s = SG_HALF / s; q[3] = (m[j][k] - m[k][j]) * s; q[j] = (m[i][j] + m[j][i]) * s; q[k] = (m[i][k] + m[k][i]) * s; quat[SG_X] = q[0]; quat[SG_Y] = q[1]; quat[SG_Z] = q[2]; quat[SG_W] = q[3]; } // seems to yield the inverse rotation, so: quat[SG_W] = - quat[SG_W]; } void sgMultQuat ( sgQuat dst, const sgQuat a, const sgQuat b ) { /* [ ww' - v.v', vxv' + wv' + v'w ] */ SGfloat t[8]; t[0] = (a[SG_W] + a[SG_X]) * (b[SG_W] + b[SG_X]); t[1] = (a[SG_Z] - a[SG_Y]) * (b[SG_Y] - b[SG_Z]); t[2] = (a[SG_X] - a[SG_W]) * (b[SG_Y] + b[SG_Z]); t[3] = (a[SG_Y] + a[SG_Z]) * (b[SG_X] - b[SG_W]); t[4] = (a[SG_X] + a[SG_Z]) * (b[SG_X] + b[SG_Y]); t[5] = (a[SG_X] - a[SG_Z]) * (b[SG_X] - b[SG_Y]); t[6] = (a[SG_W] + a[SG_Y]) * (b[SG_W] - b[SG_Z]); t[7] = (a[SG_W] - a[SG_Y]) * (b[SG_W] + b[SG_Z]); dst[SG_W] = t[1] + ((-t[4] - t[5] + t[6] + t[7]) * SG_HALF); dst[SG_X] = t[0] - (( t[4] + t[5] + t[6] + t[7]) * SG_HALF); dst[SG_Y] = -t[2] + (( t[4] - t[5] + t[6] - t[7]) * SG_HALF); dst[SG_Z] = -t[3] + (( t[4] - t[5] - t[6] + t[7]) * SG_HALF); } //from gamasutra.com //by nb@netcom.ca void sgMultQuat2 ( sgQuat dst, const sgQuat a, const sgQuat b ) { SGfloat A, B, C, D, E, F, G, H; A = (a[SG_W] + a[SG_X]) * (b[SG_W] + b[SG_X]) ; B = (a[SG_Z] - a[SG_Y]) * (b[SG_Y] - b[SG_Z]) ; C = (a[SG_X] - a[SG_W]) * (b[SG_Y] + b[SG_Z]) ; D = (a[SG_Y] + a[SG_Z]) * (b[SG_X] - b[SG_W]) ; E = (a[SG_X] + a[SG_Z]) * (b[SG_X] + b[SG_Y]) ; F = (a[SG_X] - a[SG_Z]) * (b[SG_X] - b[SG_Y]) ; G = (a[SG_W] + a[SG_Y]) * (b[SG_W] - b[SG_Z]) ; H = (a[SG_W] - a[SG_Y]) * (b[SG_W] + b[SG_Z]) ; dst[SG_W] = B + (-E - F + G + H) / SG_TWO ; dst[SG_X] = A - ( E + F + G + H) / SG_TWO ; dst[SG_Y] = -C + ( E - F + G - H) / SG_TWO ; dst[SG_Z] = -D + ( E - F - G + H) / SG_TWO ; } //from gamasutra.com //by nb@netcom.ca void sgEulerToQuat(sgQuat quat, const sgVec3 hpr ) { SGfloat cr, cp, cy, sr, sp, sy, cpcy, spsy; // calculate trig identities cr = (SGfloat) cos(hpr[2]*SG_DEGREES_TO_RADIANS/SG_TWO); cp = (SGfloat) cos(hpr[1]*SG_DEGREES_TO_RADIANS/SG_TWO); cy = (SGfloat) cos(hpr[0]*SG_DEGREES_TO_RADIANS/SG_TWO); sr = (SGfloat) sin(hpr[2]*SG_DEGREES_TO_RADIANS/SG_TWO); sp = (SGfloat) sin(hpr[1]*SG_DEGREES_TO_RADIANS/SG_TWO); sy = (SGfloat) sin(hpr[0]*SG_DEGREES_TO_RADIANS/SG_TWO); cpcy = cp * cy; spsy = sp * sy; quat[SG_W] = cr * cpcy + sr * spsy; quat[SG_X] = sr * cpcy - cr * spsy; quat[SG_Y] = cr * sp * cy + sr * cp * sy; quat[SG_Z] = cr * cp * sy - sr * sp * cy; } //from darwin3d.com // jeffl@darwin3d.com void sgQuatToEuler( sgVec3 hpr, const sgQuat quat ) { SGfloat matrix[3][3]; SGfloat cx,sx; SGfloat cy,sy; SGfloat cz,sz; // CONVERT QUATERNION TO MATRIX - I DON'T REALLY NEED ALL OF IT matrix[0][0] = SG_ONE - (SG_TWO * quat[SG_Y] * quat[SG_Y]) - (SG_TWO * quat[SG_Z] * quat[SG_Z]); //matrix[0][1] = (SG_TWO * quat->x * quat->y) - (SG_TWO * quat->w * quat->z); //matrix[0][2] = (SG_TWO * quat->x * quat->z) + (SG_TWO * quat->w * quat->y); matrix[1][0] = (SG_TWO * quat[SG_X] * quat[SG_Y]) + (SG_TWO * quat[SG_W] * quat[SG_Z]); //matrix[1][1] = SG_ONE - (SG_TWO * quat->x * quat->x) // - (SG_TWO * quat->z * quat->z); //matrix[1][2] = (SG_TWO * quat->y * quat->z) - (SG_TWO * quat->w * quat->x); matrix[2][0] = (SG_TWO * quat[SG_X] * quat[SG_Z]) - (SG_TWO * quat[SG_W] * quat[SG_Y]); matrix[2][1] = (SG_TWO * quat[SG_Y] * quat[SG_Z]) + (SG_TWO * quat[SG_W] * quat[SG_X]); matrix[2][2] = SG_ONE - (SG_TWO * quat[SG_X] * quat[SG_X]) - (SG_TWO * quat[SG_Y] * quat[SG_Y]); sy = -matrix[2][0]; cy = (SGfloat)sgSqrt(SG_ONE - (sy * sy)); hpr[1] = sgATan2 ( sy, cy ) ; // AVOID DIVIDE BY ZERO ERROR ONLY WHERE Y= +-90 or +-270 // NOT CHECKING cy BECAUSE OF PRECISION ERRORS if (sy != SG_ONE && sy != -SG_ONE) { cx = matrix[2][2] / cy; sx = matrix[2][1] / cy; hpr[0] = sgATan2 ( sx, cx ) ; cz = matrix[0][0] / cy; sz = matrix[1][0] / cy; hpr[2] = sgATan2 ( sz, cz ) ; } else { // SINCE Cos(Y) IS 0, I AM SCREWED. ADOPT THE STANDARD Z = 0 // I THINK THERE IS A WAY TO FIX THIS BUT I AM NOT SURE. EULERS SUCK // NEED SOME MORE OF THE MATRIX TERMS NOW matrix[1][1] = SG_ONE - (SG_TWO * quat[SG_X] * quat[SG_X]) - (SG_TWO * quat[SG_Z] * quat[SG_Z]); matrix[1][2] = (SG_TWO * quat[SG_Y] * quat[SG_Z]) - (SG_TWO * quat[SG_W] * quat[SG_X]); cx = matrix[1][1]; sx = -matrix[1][2]; hpr[0] = sgATan2 ( sx, cx ) ; cz = SG_ONE ; sz = SG_ZERO ; hpr[2] = sgATan2 ( sz, cz ) ; } } void sgQuatToMatrix ( sgMat4 dst, const sgQuat q ) { SGfloat two_xx = q[SG_X] * (q[SG_X] + q[SG_X]) ; SGfloat two_xy = q[SG_X] * (q[SG_Y] + q[SG_Y]) ; SGfloat two_xz = q[SG_X] * (q[SG_Z] + q[SG_Z]) ; SGfloat two_wx = q[SG_W] * (q[SG_X] + q[SG_X]) ; SGfloat two_wy = q[SG_W] * (q[SG_Y] + q[SG_Y]) ; SGfloat two_wz = q[SG_W] * (q[SG_Z] + q[SG_Z]) ; SGfloat two_yy = q[SG_Y] * (q[SG_Y] + q[SG_Y]) ; SGfloat two_yz = q[SG_Y] * (q[SG_Z] + q[SG_Z]) ; SGfloat two_zz = q[SG_Z] * (q[SG_Z] + q[SG_Z]) ; sgSetVec4 ( dst[0], SG_ONE-(two_yy+two_zz), two_xy-two_wz, two_xz+two_wy, SG_ZERO ) ; sgSetVec4 ( dst[1], two_xy+two_wz, SG_ONE-(two_xx+two_zz), two_yz-two_wx, SG_ZERO ) ; sgSetVec4 ( dst[2], two_xz-two_wy, two_yz+two_wx, SG_ONE-(two_xx+two_yy), SG_ZERO ) ; sgSetVec4 ( dst[3], SG_ZERO, SG_ZERO, SG_ZERO, SG_ONE ) ; } //from gamasutra.com //by nb@netcom.ca /***************************** DEPRECATED...use sgQuatToMatrix instead. *****************************/ void sgMakeRotMat42( sgMat4 m, sgQuat quat ){ SGfloat wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; // calculate coefficients x2 = quat[SG_X] + quat[SG_X]; y2 = quat[SG_Y] + quat[SG_Y]; z2 = quat[SG_Z] + quat[SG_Z]; xx = quat[SG_X] * x2; xy = quat[SG_X] * y2; xz = quat[SG_X] * z2; yy = quat[SG_Y] * y2; yz = quat[SG_Y] * z2; zz = quat[SG_Z] * z2; wx = quat[SG_W] * x2; wy = quat[SG_W] * y2; wz = quat[SG_W] * z2; m[0][0] = SG_ONE- (yy + zz); m[0][1] = xy - wz; m[0][2] = xz + wy; m[0][3] = SG_ZERO ; m[1][0] = xy + wz; m[1][1] = SG_ONE- (xx + zz); m[1][2] = yz - wx; m[1][3] = SG_ZERO ; m[2][0] = xz - wy; m[2][1] = yz + wx; m[2][2] = SG_ONE- (xx + yy); m[2][3] = SG_ZERO ; m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; } //from gamasutra.com //by nb@netcom.ca void sgSlerpQuat2( sgQuat dst, const sgQuat from, const sgQuat to, const SGfloat t ) { SGfloat to1[4]; SGfloat omega, cosom, sinom, scale0, scale1; // calc cosine cosom = from[SG_X] * to[SG_X] + from[SG_Y] * to[SG_Y] + from[SG_Z] * to[SG_Z] + from[SG_W] * to[SG_W]; // adjust signs (if necessary) if ( cosom < SG_ZERO ) { cosom = -cosom; to1[0] = - to[SG_X]; to1[1] = - to[SG_Y]; to1[2] = - to[SG_Z]; to1[3] = - to[SG_W]; } else { to1[0] = to[SG_X]; to1[1] = to[SG_Y]; to1[2] = to[SG_Z]; to1[3] = to[SG_W]; } // calculate coefficients #define DELTA SG_ZERO if ( (SG_ONE- cosom) > DELTA ) { // standard case (slerp) omega = (SGfloat) acos(cosom); sinom = (SGfloat) sin(omega); scale0 = (SGfloat) sin((SG_ONE- t) * omega) / sinom; scale1 = (SGfloat) sin(t * omega) / sinom; } else { // "from" and "to" quaternions are very close // ... so we can do a linear interpolation scale0 = SG_ONE- t; scale1 = t; } // calculate final values dst[SG_X] = scale0 * from[SG_X] + scale1 * to1[0]; dst[SG_Y] = scale0 * from[SG_Y] + scale1 * to1[1]; dst[SG_Z] = scale0 * from[SG_Z] + scale1 * to1[2]; dst[SG_W] = scale0 * from[SG_W] + scale1 * to1[3]; } void sgSlerpQuat( sgQuat dst, const sgQuat from, const sgQuat to, const SGfloat t ) { SGfloat co, scale0, scale1; bool flip = false ; /* SWC - Interpolate between to quaternions */ co = sgScalarProductVec4 ( from, to ) ; if ( co < SG_ZERO ) { co = -co; flip = true ; } if ( co < SG_ONE - (SGfloat) 1e-6 ) { SGfloat o = (SGfloat) acos ( co ); SGfloat so = SG_ONE / (SGfloat) sin ( o ); scale0 = (SGfloat) sin ( (SG_ONE - t) * o ) * so; scale1 = (SGfloat) sin ( t * o ) * so; } else { scale0 = SG_ONE - t; scale1 = t; } if ( flip ) { scale1 = -scale1 ; } dst[SG_X] = scale0 * from[SG_X] + scale1 * to[SG_X] ; dst[SG_Y] = scale0 * from[SG_Y] + scale1 * to[SG_Y] ; dst[SG_Z] = scale0 * from[SG_Z] + scale1 * to[SG_Z] ; dst[SG_W] = scale0 * from[SG_W] + scale1 * to[SG_W] ; } /* Function to rotate a vector through a given quaternion using the formula * R = Q r Q-1 -- this gives the components of a ROTATED vector in a STATIONARY * coordinate system. We assume that Q is a unit quaternion. */ void sgRotateVecQuat ( sgVec3 vec, sgQuat q ) { sgVec3 rot ; sgFloat qwqw = q[SG_W] * q[SG_W] ; sgFloat qwqx = q[SG_W] * q[SG_X] ; sgFloat qwqy = q[SG_W] * q[SG_Y] ; sgFloat qwqz = q[SG_W] * q[SG_Z] ; sgFloat qxqx = q[SG_X] * q[SG_X] ; sgFloat qxqy = q[SG_X] * q[SG_Y] ; sgFloat qxqz = q[SG_X] * q[SG_Z] ; sgFloat qyqy = q[SG_Y] * q[SG_Y] ; sgFloat qyqz = q[SG_Y] * q[SG_Z] ; sgFloat qzqz = q[SG_Z] * q[SG_Z] ; rot[SG_X] = ( qwqw + qxqx - qyqy - qzqz ) * vec[SG_X] + 2.0f * ( qxqy - qwqz ) * vec[SG_Y] + 2.0f * ( qxqz + qwqy ) * vec[SG_Z] ; rot[SG_Y] = ( qwqw - qxqx + qyqy - qzqz ) * vec[SG_Y] + 2.0f * ( qyqz - qwqx ) * vec[SG_Z] + 2.0f * ( qxqy + qwqz ) * vec[SG_X] ; rot[SG_Z] = ( qwqw - qxqx - qyqy + qzqz ) * vec[SG_Z] + 2.0f * ( qxqz - qwqy ) * vec[SG_X] + 2.0f * ( qyqz + qwqx ) * vec[SG_Y] ; sgCopyVec3 ( vec, rot ) ; } /* Function to rotate a vector through a given quaternion using the formula * R = Q-1 r Q -- this gives the components of a STATIONARY vector in a ROTATED * coordinate system. We assume that Q is a unit quaternion. */ void sgRotateCoordQuat ( sgVec3 vec, sgQuat q ) { sgVec3 rot ; sgFloat qwqw = q[SG_W] * q[SG_W] ; sgFloat qwqx = q[SG_W] * q[SG_X] ; sgFloat qwqy = q[SG_W] * q[SG_Y] ; sgFloat qwqz = q[SG_W] * q[SG_Z] ; sgFloat qxqx = q[SG_X] * q[SG_X] ; sgFloat qxqy = q[SG_X] * q[SG_Y] ; sgFloat qxqz = q[SG_X] * q[SG_Z] ; sgFloat qyqy = q[SG_Y] * q[SG_Y] ; sgFloat qyqz = q[SG_Y] * q[SG_Z] ; sgFloat qzqz = q[SG_Z] * q[SG_Z] ; rot[SG_X] = ( qwqw + qxqx - qyqy - qzqz ) * vec[SG_X] + 2.0f * ( qxqy + qwqz ) * vec[SG_Y] + 2.0f * ( qxqz - qwqy ) * vec[SG_Z] ; rot[SG_Y] = ( qwqw - qxqx + qyqy - qzqz ) * vec[SG_Y] + 2.0f * ( qyqz + qwqx ) * vec[SG_Z] + 2.0f * ( qxqy - qwqz ) * vec[SG_X] ; rot[SG_Z] = ( qwqw - qxqx - qyqy + qzqz ) * vec[SG_Z] + 2.0f * ( qxqz + qwqy ) * vec[SG_X] + 2.0f * ( qyqz - qwqx ) * vec[SG_Y] ; sgCopyVec3 ( vec, rot ) ; } sgFloat sgDistSquaredToLineLineSegment ( const sgLineSegment3 seg, const sgLine3 line ) { /* Convert the line segment to a line. We will deal with the segment limits later. */ sgLine3 line2 ; sgLineSegment3ToLine3 ( &line2, seg ) ; /* Get the dot product of the two direction vectors */ sgFloat t1_dot_t2 = sgScalarProductVec3 ( line.direction_vector, line2.direction_vector ) ; /* If the lines are parallel, distance is just the distance from a point to the other line */ if ( fabs ( t1_dot_t2 ) >= 1.0 ) return sgDistSquaredToLineVec3 ( line, seg.a ) ; /* Get the parametric coordinates of the closest points on the two lines. The first line * is parameterized by r = r1 + t1 u while the second is parameterized by r = r2 + t2 v. * The square of the distance between them is [ ( r1 + t1 u ) - ( r2 + t2 v ) ] dot * [ ( r1 + t1 u ) - ( r2 + t2 v ) ]. Differentiating this dot product with respect to * u and v and setting the derivatives to zero gives a matrix equation: * [ 1 -(t1 dot t2) ] [ u ] = [ ( r1 - r2 ) dot t1 ] * [ -(t1 dot t2) 1 ] [ v ] [ -( r1 - r2 ) dot t2 ] * We invert the matrix to get the equations below. */ sgVec3 r1_minus_r2 ; sgSubVec3 ( r1_minus_r2, line.point_on_line, line2.point_on_line ) ; /* t1_t2_t2_minus_t1 = ( t1 dot t2 ) t2 - t1 * t2_minus_t1_t2_t1 = t2 - ( t1 dot t2 ) t1 */ sgVec3 t1_t2_t2_minus_t1, t2_minus_t1_t2_t1 ; sgAddScaledVec3 ( t1_t2_t2_minus_t1, line.direction_vector, line2.direction_vector, -t1_dot_t2 ) ; sgNegateVec3 ( t1_t2_t2_minus_t1 ) ; sgAddScaledVec3 ( t2_minus_t1_t2_t1, line2.direction_vector, line.direction_vector, -t1_dot_t2 ) ; sgFloat u = sgScalarProductVec3 ( r1_minus_r2, t1_t2_t2_minus_t1 ) / ( 1.0f - t1_dot_t2 * t1_dot_t2 ) ; sgFloat v = sgScalarProductVec3 ( r1_minus_r2, t2_minus_t1_t2_t1 ) / ( 1.0f - t1_dot_t2 * t1_dot_t2 ) ; /* Since line 2 is a line segment, we limit "v" to between 0 and the distance between the points. */ sgFloat length = sgDistanceVec3 ( seg.a, seg.b ) ; if ( v < 0.0 ) v = 0.0 ; if ( v > length ) v = length ; sgVec3 point1, point2 ; sgAddScaledVec3 ( point1, line.point_on_line, line.direction_vector, u ) ; sgAddScaledVec3 ( point2, line2.point_on_line, line2.direction_vector, v ) ; return sgDistanceSquaredVec3 ( point1, point2 ) ; } void sgReflectInPlaneVec3 ( sgVec3 dst, const sgVec3 src, const sgVec4 plane ) { SGfloat src_dot_norm = sgScalarProductVec3 ( src, plane ) ; sgVec3 tmp ; sgScaleVec3 ( tmp, plane, SG_TWO * src_dot_norm ) ; sgSubVec3 ( dst, src, tmp ) ; } int sgClassifyMat4 ( const sgMat4 m ) { const SGfloat epsilon = 1e-6f ; int flags = 0 ; SGfloat sx, sy, sz ; if ( m[0][1] == SG_ZERO && m[0][2] == SG_ZERO && m[1][0] == SG_ZERO && m[1][2] == SG_ZERO && m[2][0] == SG_ZERO && m[2][1] == SG_ZERO ) { int n = ( m[0][0] < 0 ) + ( m[1][1] < 0 ) + ( m[2][2] < 0 ) ; if ( n > 1 ) flags |= SG_ROTATION ; if ( n % 2 != 0 ) flags |= SG_MIRROR ; sx = m[0][0] * m[0][0] ; sy = m[1][1] * m[1][1] ; sz = m[2][2] * m[2][2] ; } else { flags |= SG_ROTATION ; if ( sgAbs ( sgScalarProductVec3 ( m[1], m[2] ) ) > epsilon || sgAbs ( sgScalarProductVec3 ( m[2], m[0] ) ) > epsilon || sgAbs ( sgScalarProductVec3 ( m[0], m[1] ) ) > epsilon ) { flags |= SG_NONORTHO ; } sgVec3 temp ; sgVectorProductVec3 ( temp, m[0], m[1] ) ; SGfloat det = sgScalarProductVec3 ( temp, m[2] ) ; if ( det < 0 ) flags |= SG_MIRROR ; sx = sgScalarProductVec3 ( m[0], m[0] ) ; sy = sgScalarProductVec3 ( m[1], m[1] ) ; sz = sgScalarProductVec3 ( m[2], m[2] ) ; } if ( sgAbs ( sx - sy ) > epsilon || sgAbs ( sx - sz ) > epsilon ) { flags |= SG_NONORTHO ; flags |= SG_GENERAL_SCALE ; // also set general scale bit, though it may be deleted in the future } else { if ( sgAbs ( sx - SG_ONE ) > epsilon ) flags |= SG_SCALE ; } if ( m[3][0] != SG_ZERO || m[3][1] != SG_ZERO || m[3][2] != SG_ZERO ) { flags |= SG_TRANSLATION ; } if ( m[0][3] != SG_ZERO || m[1][3] != SG_ZERO || m[2][3] != SG_ZERO || m[3][3] != SG_ONE ) { flags |= SG_PROJECTION ; } return flags ; } SGfloat sgTriangleSolver_ASAtoArea ( SGfloat angA, SGfloat lenB, SGfloat angC ) { /* Get the third angle */ SGfloat angB = SG_180 - (angA + angC) ; /* Use Sine Rule to get length of a second side - then use SAStoArea. */ SGfloat sinB = sgSin ( angB ) ; if ( sinB == SG_ZERO ) return SG_ZERO ; SGfloat lenA = lenB * sgSin(angA) / sinB ; return sgTriangleSolver_SAStoArea ( lenA, angC, lenB ) ; } SGfloat sgTriangleSolver_SAStoArea ( SGfloat lenA, SGfloat angB, SGfloat lenC ) { return SG_HALF * lenC * lenA * sgSin ( angB ) ; } SGfloat sgTriangleSolver_SSStoArea ( SGfloat lenA, SGfloat lenB, SGfloat lenC ) { /* Heron's formula */ SGfloat s = ( lenA + lenB + lenC ) / SG_TWO ; SGfloat q = s * (s-lenA) * (s-lenB) * (s-lenC) ; /* Ikky illegal triangles generate zero areas. */ return ( q <= SG_ZERO ) ? SG_ZERO : sgSqrt ( q ) ; } SGfloat sgTriangleSolver_ASStoArea ( SGfloat angB, SGfloat lenA, SGfloat lenB, int angA_is_obtuse ) { SGfloat lenC ; sgTriangleSolver_ASStoSAA ( angB, lenA, lenB, angA_is_obtuse, &lenC, NULL, NULL ) ; return sgTriangleSolver_SAStoArea ( lenA, angB, lenC ) ; } SGfloat sgTriangleSolver_SAAtoArea ( SGfloat lenA, SGfloat angB, SGfloat angA ) { SGfloat lenC ; sgTriangleSolver_SAAtoASS ( lenA, angB, angA, NULL, NULL, &lenC ) ; return sgTriangleSolver_SAStoArea ( lenA, angB, lenC ) ; } void sgTriangleSolver_SSStoAAA ( SGfloat lenA, SGfloat lenB, SGfloat lenC, SGfloat *angA, SGfloat *angB, SGfloat *angC ) { SGfloat aa, bb, cc ; int flag = ( lenA == SG_ZERO ) | (( lenB == SG_ZERO )<<1) | (( lenC == SG_ZERO )<<2) ; /* Ikky zero-sized triangles generate zero/90 angles appropriately. */ /* Ikky triangles with all lengths zero generate 60 degree angles. */ /* Ikky impossible triangles generate all zero angles. */ switch ( flag ) { case 0 : /* no zero-lengthed sides */ /* Cosine law */ aa = sgACos (( lenB*lenB + lenC*lenC - lenA*lenA )/(SG_TWO*lenB*lenC)) ; bb = sgACos (( lenA*lenA + lenC*lenC - lenB*lenB )/(SG_TWO*lenA*lenC)) ; cc = sgACos (( lenA*lenA + lenB*lenB - lenC*lenC )/(SG_TWO*lenA*lenB)) ; break ; case 1 : /* lenA is zero */ aa = SG_ZERO ; bb = cc = SG_90 ; break ; case 2 : /* lenB is zero */ bb = SG_ZERO ; aa = cc = SG_90 ; break ; case 4 : /* lenC is zero */ cc = SG_ZERO ; aa = bb = SG_90 ; break ; case 3 : /* Two lengths are zero and the third isn't?!? */ case 5 : case 6 : aa = bb = cc = SG_ZERO ; break ; default : /* All three sides are zero length */ aa = bb = cc = SG_60 ; break ; } if ( angA ) *angA = aa ; if ( angB ) *angB = bb ; if ( angC ) *angC = cc ; } void sgTriangleSolver_SAStoASA ( SGfloat lenA, SGfloat angB, SGfloat lenC, SGfloat *angA, SGfloat *lenB, SGfloat *angC ) { /* Get third side using Cosine Rule */ SGfloat s = lenC * lenC + lenA * lenA - SG_TWO * lenC * lenA * sgCos( angB ) ; SGfloat lb = ( s <= SG_ZERO ) ? SG_ZERO : (SGfloat) sqrt ( s ) ; if ( lenB ) *lenB = lb ; sgTriangleSolver_SSStoAAA ( lenA, lb, lenC, angA, NULL, angC ) ; } void sgTriangleSolver_ASAtoSAS ( SGfloat angA, SGfloat lenB, SGfloat angC, SGfloat *lenA, SGfloat *angB, SGfloat *lenC ) { /* Find the missing angle */ SGfloat bb = SG_180 - (angA + angC) ; if ( angB ) *angB = bb ; /* Use Sine Rule */ SGfloat sinB = sgSin ( bb ) ; if ( sinB == SG_ZERO ) { if ( lenA ) *lenA = lenB / SG_TWO ; /* One valid interpretation */ if ( lenC ) *lenC = lenB / SG_TWO ; } else { if ( lenA ) *lenA = lenB * sgSin(angA) / sinB ; if ( lenC ) *lenC = lenB * sgSin(angC) / sinB ; } } void sgTriangleSolver_ASStoSAA ( SGfloat angB, SGfloat lenA, SGfloat lenB, int angA_is_obtuse, SGfloat *lenC, SGfloat *angA, SGfloat *angC ) { /* Sine law */ SGfloat aa = (lenB == SG_ZERO ) ? SG_ZERO : sgASin (lenA * sgSin(angB)/lenB) ; if ( angA_is_obtuse ) aa = SG_180 - aa ; if ( angA ) *angA = aa ; /* Find the missing angle */ SGfloat cc = SG_180 - (aa + angB) ; if ( angC ) *angC = cc ; /* Use SAStoASA to get the last length */ sgTriangleSolver_SAStoASA ( lenA, cc, lenB, NULL, lenC, NULL ) ; } void sgTriangleSolver_SAAtoASS ( SGfloat lenA, SGfloat angB, SGfloat angA, SGfloat *angC, SGfloat *lenB, SGfloat *lenC ) { /* Find the missing angle */ SGfloat cc = SG_180 - (angB + angA) ; if ( angC ) *angC = cc ; sgTriangleSolver_ASAtoSAS ( cc, lenA, angB, lenC, NULL, lenB ) ; } plib-1.8.5/src/sg/sg.h0000644000175000001440000024361610765364434011402 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: sg.h 2121 2007-09-15 03:36:21Z fayjf $ */ #ifndef SG_H #define SG_H 1 #include #include "ul.h" #define sgFloat float #define SGfloat float #define SG_ZERO 0.0f #define SG_HALF 0.5f #define SG_ONE 1.0f #define SG_TWO 2.0f #define SG_THREE 3.0f #define SG_FOUR 4.0f #define SG_45 45.0f #define SG_60 60.0f #define SG_90 90.0f #define SG_180 180.0f #define SG_MAX FLT_MAX #define SG_X 0 #define SG_Y 1 #define SG_Z 2 #define SG_W 3 #ifndef M_PI #define SG_PI 3.1415926535f #else #define SG_PI ((SGfloat) M_PI) #endif #define SG_DEGREES_TO_RADIANS (SG_PI/SG_180) #define SG_RADIANS_TO_DEGREES (SG_180/SG_PI) /* These are just convenient redefinitions of standard math library functions to stop float/double warnings. */ inline SGfloat sgSqrt ( const SGfloat x ) { return (SGfloat) sqrt ( x ) ; } inline SGfloat sgSquare ( const SGfloat x ) { return x * x ; } inline SGfloat sgAbs ( const SGfloat a ) { return (axyz, src->hpr ) ; } extern void sgMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center, const sgVec3 up ) ; extern void sgMakeRotMat4 ( sgMat4 dst, const SGfloat angle, const sgVec3 axis ) ; inline void sgMakeRotMat4 ( sgMat4 dst, const sgVec3 hpr ) { sgMakeCoordMat4 ( dst, SG_ZERO, SG_ZERO, SG_ZERO, hpr[0], hpr[1], hpr[2] ) ; } inline void sgMakeRotMat4 ( sgMat4 dst,const SGfloat h, const SGfloat p, const SGfloat r ) { sgMakeCoordMat4 ( dst, SG_ZERO, SG_ZERO, SG_ZERO, h, p, r ) ; } extern void sgMakeTransMat4 ( sgMat4 dst, const sgVec3 xyz ) ; extern void sgMakeTransMat4 ( sgMat4 dst, const SGfloat x, const SGfloat y, const SGfloat z ) ; extern void sgSetCoord ( sgCoord *coord, const sgMat4 src ) ; extern void sgMultMat4 ( sgMat4 dst, const sgMat4 a, const sgMat4 b ) ; extern void sgPostMultMat4 ( sgMat4 dst, const sgMat4 a ) ; extern void sgPreMultMat4 ( sgMat4 dst, const sgMat4 a ) ; extern void sgTransposeNegateMat4 ( sgMat4 dst ) ; extern void sgTransposeNegateMat4 ( sgMat4 dst, const sgMat4 src ) ; extern void sgInvertMat4 ( sgMat4 dst, const sgMat4 src ) ; inline void sgInvertMat4 ( sgMat4 dst ) { sgInvertMat4 ( dst, dst ) ; } extern void sgXformVec3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) ; extern void sgXformPnt3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) ; extern void sgXformVec4 ( sgVec4 dst, const sgVec4 src, const sgMat4 mat ) ; extern void sgXformPnt4 ( sgVec4 dst, const sgVec4 src, const sgMat4 mat ) ; extern void sgFullXformPnt3 ( sgVec3 dst, const sgVec3 src, const sgMat4 mat ) ; extern void sgFullXformPnt4 ( sgVec4 dst, const sgVec4 src, const sgMat4 mat ) ; inline void sgXformVec3 ( sgVec3 dst, const sgMat4 mat ) { sgXformVec3 ( dst, dst, mat ) ; } inline void sgXformPnt3 ( sgVec3 dst, const sgMat4 mat ) { sgXformPnt3 ( dst, dst, mat ) ; } inline void sgXformVec4 ( sgVec4 dst, const sgMat4 mat ) { sgXformVec4 ( dst, dst, mat ) ; } inline void sgXformPnt4 ( sgVec4 dst, const sgMat4 mat ) { sgXformPnt4 ( dst, dst, mat ) ; } inline void sgFullXformPnt3 ( sgVec3 dst, const sgMat4 mat ) { sgFullXformPnt3 ( dst, dst, mat ) ; } inline void sgFullXformPnt4 ( sgVec4 dst, const sgMat4 mat ) { sgFullXformPnt4 ( dst, dst, mat ) ; } /* Bits returned by sgClassifyMat4 */ #define SG_IDENTITY 0x00 // for clarity #define SG_ROTATION 0x01 // includes a rotational component #define SG_MIRROR 0x02 // changes handedness (det < 0) #define SG_SCALE 0x04 // uniform scaling #define SG_NONORTHO 0x10 // 3x3 not orthogonal #define SG_TRANSLATION 0x20 // translates #define SG_PROJECTION 0x40 // forth column not 0,0,0,1 /* Are these needed? sgClassifyMat4() does set the general scale bit for some matrices, * but it is not easily defined. Use SG_NONORTHO instead (which is also set). */ #define SG_UNIFORM_SCALE SG_SCALE #define SG_GENERAL_SCALE 0x08 // x, y and z scaled differently extern int sgClassifyMat4 ( const sgMat4 mat ) ; /* Basic low-level vector functions. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For each of Vec2, Vec3 and Vec4, we provide inlines for Zero - set all elements to zero. Set - set each element individually. Add - add vectors element by element. Sub - subtract vectors element by element. Scale - multiply each element of a vector by a variable. AddScaled - multiply second vector by a constant and add the result to the first vector. Negate - negate each element of a vector. Compare - compare vectors element by element with optional tolerance. (return TRUE if vectors are equal - within tolerances) Equal - return TRUE if vectors are exactly equal. Length - compute length of a vector. Distance - compute distance between two points. ScalarProduct - scalar (dot) product. VectorProduct - vector (cross) product (3-element vectors ONLY!). Normalise/Normalize - make vector be one unit long. */ inline void sgZeroVec2 ( sgVec2 dst ) { dst[0]=dst[1]=SG_ZERO ; } inline void sgZeroVec3 ( sgVec3 dst ) { dst[0]=dst[1]=dst[2]=SG_ZERO ; } inline void sgZeroVec4 ( sgVec4 dst ) { dst[0]=dst[1]=dst[2]=dst[3]=SG_ZERO ; } inline void sgSetVec2 ( sgVec2 dst, const SGfloat x, const SGfloat y ) { dst [ 0 ] = x ; dst [ 1 ] = y ; } inline void sgSetVec3 ( sgVec3 dst, const SGfloat x, const SGfloat y, const SGfloat z ) { dst [ 0 ] = x ; dst [ 1 ] = y ; dst [ 2 ] = z ; } inline void sgSetVec4 ( sgVec4 dst, const SGfloat x, const SGfloat y, const SGfloat z, const SGfloat w ) { dst [ 0 ] = x ; dst [ 1 ] = y ; dst [ 2 ] = z ; dst [ 3 ] = w ; } inline void sgCopyVec2 ( sgVec2 dst, const sgVec2 src ) { dst [ 0 ] = src [ 0 ] ; dst [ 1 ] = src [ 1 ] ; } inline void sgCopyVec3 ( sgVec3 dst, const sgVec3 src ) { dst [ 0 ] = src [ 0 ] ; dst [ 1 ] = src [ 1 ] ; dst [ 2 ] = src [ 2 ] ; } inline void sgCopyVec4 ( sgVec4 dst, const sgVec4 src ) { dst [ 0 ] = src [ 0 ] ; dst [ 1 ] = src [ 1 ] ; dst [ 2 ] = src [ 2 ] ; dst [ 3 ] = src [ 3 ] ; } inline void sgAddVec2 ( sgVec2 dst, const sgVec2 src ) { dst [ 0 ] += src [ 0 ] ; dst [ 1 ] += src [ 1 ] ; } inline void sgAddVec3 ( sgVec3 dst, const sgVec3 src ) { dst [ 0 ] += src [ 0 ] ; dst [ 1 ] += src [ 1 ] ; dst [ 2 ] += src [ 2 ] ; } inline void sgAddVec4 ( sgVec4 dst, const sgVec4 src ) { dst [ 0 ] += src [ 0 ] ; dst [ 1 ] += src [ 1 ] ; dst [ 2 ] += src [ 2 ] ; dst [ 3 ] += src [ 3 ] ; } inline void sgAddVec2 ( sgVec2 dst, const sgVec2 src1, const sgVec2 src2 ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; } inline void sgAddVec3 ( sgVec3 dst, const sgVec3 src1, const sgVec3 src2 ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] ; } inline void sgAddVec4 ( sgVec4 dst, const sgVec4 src1, const sgVec4 src2 ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] ; dst [ 3 ] = src1 [ 3 ] + src2 [ 3 ] ; } inline void sgSubVec2 ( sgVec2 dst, const sgVec2 src ) { dst [ 0 ] -= src [ 0 ] ; dst [ 1 ] -= src [ 1 ] ; } inline void sgSubVec3 ( sgVec3 dst, const sgVec3 src ) { dst [ 0 ] -= src [ 0 ] ; dst [ 1 ] -= src [ 1 ] ; dst [ 2 ] -= src [ 2 ] ; } inline void sgSubVec4 ( sgVec4 dst, const sgVec4 src ) { dst [ 0 ] -= src [ 0 ] ; dst [ 1 ] -= src [ 1 ] ; dst [ 2 ] -= src [ 2 ] ; dst [ 3 ] -= src [ 3 ] ; } inline void sgSubVec2 ( sgVec2 dst, const sgVec2 src1, const sgVec2 src2 ) { dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; } inline void sgSubVec3 ( sgVec3 dst, const sgVec3 src1, const sgVec3 src2 ) { dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; dst [ 2 ] = src1 [ 2 ] - src2 [ 2 ] ; } inline void sgSubVec4 ( sgVec4 dst, const sgVec4 src1, const sgVec4 src2 ) { dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; dst [ 2 ] = src1 [ 2 ] - src2 [ 2 ] ; dst [ 3 ] = src1 [ 3 ] - src2 [ 3 ] ; } inline void sgNegateVec2 ( sgVec2 dst ) { dst [ 0 ] = -dst [ 0 ] ; dst [ 1 ] = -dst [ 1 ] ; } inline void sgNegateVec3 ( sgVec3 dst ) { dst [ 0 ] = -dst [ 0 ] ; dst [ 1 ] = -dst [ 1 ] ; dst [ 2 ] = -dst [ 2 ] ; } inline void sgNegateVec4 ( sgVec4 dst ) { dst [ 0 ] = -dst [ 0 ] ; dst [ 1 ] = -dst [ 1 ] ; dst [ 2 ] = -dst [ 2 ] ; dst [ 3 ] = -dst [ 3 ] ; } inline void sgNegateVec2 ( sgVec2 dst, const sgVec2 src ) { dst [ 0 ] = -src [ 0 ] ; dst [ 1 ] = -src [ 1 ] ; } inline void sgNegateVec3 ( sgVec3 dst, const sgVec3 src ) { dst [ 0 ] = -src [ 0 ] ; dst [ 1 ] = -src [ 1 ] ; dst [ 2 ] = -src [ 2 ] ; } inline void sgNegateVec4 ( sgVec4 dst, const sgVec4 src ) { dst [ 0 ] = -src [ 0 ] ; dst [ 1 ] = -src [ 1 ] ; dst [ 2 ] = -src [ 2 ] ; dst [ 3 ] = -src [ 3 ] ; } inline void sgScaleVec2 ( sgVec2 dst, const SGfloat s ) { dst [ 0 ] *= s ; dst [ 1 ] *= s ; } inline void sgScaleVec3 ( sgVec3 dst, const SGfloat s ) { dst [ 0 ] *= s ; dst [ 1 ] *= s ; dst [ 2 ] *= s ; } inline void sgScaleVec4 ( sgVec4 dst, const SGfloat s ) { dst [ 0 ] *= s ; dst [ 1 ] *= s ; dst [ 2 ] *= s ; dst [ 3 ] *= s ; } inline void sgScaleVec2 ( sgVec2 dst, const sgVec2 src, const SGfloat s ) { dst [ 0 ] = src [ 0 ] * s ; dst [ 1 ] = src [ 1 ] * s ; } inline void sgScaleVec3 ( sgVec3 dst, const sgVec3 src, const SGfloat s ) { dst [ 0 ] = src [ 0 ] * s ; dst [ 1 ] = src [ 1 ] * s ; dst [ 2 ] = src [ 2 ] * s ; } inline void sgScaleVec4 ( sgVec4 dst, const sgVec4 src, const SGfloat s ) { dst [ 0 ] = src [ 0 ] * s ; dst [ 1 ] = src [ 1 ] * s ; dst [ 2 ] = src [ 2 ] * s ; dst [ 3 ] = src [ 3 ] * s ; } inline void sgAddScaledVec2 ( sgVec2 dst, const sgVec2 src, const SGfloat s ) { dst [ 0 ] += src [ 0 ] * s ; dst [ 1 ] += src [ 1 ] * s ; } inline void sgAddScaledVec3 ( sgVec3 dst, const sgVec3 src, const SGfloat s ) { dst [ 0 ] += src [ 0 ] * s ; dst [ 1 ] += src [ 1 ] * s ; dst [ 2 ] += src [ 2 ] * s ; } inline void sgAddScaledVec4 ( sgVec4 dst, const sgVec4 src, const SGfloat s ) { dst [ 0 ] += src [ 0 ] * s ; dst [ 1 ] += src [ 1 ] * s ; dst [ 2 ] += src [ 2 ] * s ; dst [ 3 ] += src [ 3 ] * s ; } inline void sgAddScaledVec2 ( sgVec2 dst, const sgVec2 src1, const sgVec2 src2, const SGfloat s ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; } inline void sgAddScaledVec3 ( sgVec3 dst, const sgVec3 src1, const sgVec3 src2, const SGfloat s ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] * s ; } inline void sgAddScaledVec4 ( sgVec4 dst, const sgVec4 src1, const sgVec4 src2, const SGfloat s ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] * s ; dst [ 3 ] = src1 [ 3 ] + src2 [ 3 ] * s ; } inline int sgCompareVec2 ( const sgVec2 a, const sgVec2 b, const SGfloat tol ) { if ( sgCompareFloat( a[0], b[0], tol ) != 0 ) return FALSE ; if ( sgCompareFloat( a[1], b[1], tol ) != 0 ) return FALSE ; return TRUE ; } inline int sgCompareVec3 ( const sgVec3 a, const sgVec3 b, const SGfloat tol ) { if ( sgCompareFloat( a[0], b[0], tol ) != 0 ) return FALSE ; if ( sgCompareFloat( a[1], b[1], tol ) != 0 ) return FALSE ; if ( sgCompareFloat( a[2], b[2], tol ) != 0 ) return FALSE ; return TRUE ; } inline int sgCompareVec4 ( const sgVec4 a, const sgVec4 b, const SGfloat tol ) { if ( sgCompareFloat( a[0], b[0], tol ) != 0 ) return FALSE ; if ( sgCompareFloat( a[1], b[1], tol ) != 0 ) return FALSE ; if ( sgCompareFloat( a[2], b[2], tol ) != 0 ) return FALSE ; if ( sgCompareFloat( a[3], b[3], tol ) != 0 ) return FALSE ; return TRUE ; } inline int sgEqualVec2 ( const sgVec2 a, const sgVec2 b ) { return a[0] == b[0] && a[1] == b[1] ; } inline int sgEqualVec3 ( const sgVec3 a, const sgVec3 b ) { return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] ; } inline int sgEqualVec4 ( const sgVec4 a, const sgVec4 b ) { return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3] ; } inline SGfloat sgScalarProductVec2 ( const sgVec2 a, const sgVec2 b ) { return a[0]*b[0] + a[1]*b[1] ; } inline SGfloat sgScalarProductVec3 ( const sgVec3 a, const sgVec3 b ) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] ; } inline SGfloat sgScalarProductVec4 ( const sgVec4 a, const sgVec4 b ) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3] ; } extern void sgVectorProductVec3 ( sgVec3 dst, const sgVec3 a, const sgVec3 b ) ; inline SGfloat sgLerp ( const SGfloat a, const SGfloat b, const SGfloat f ) { return a + f * ( b - a ) ; } inline void sgLerpVec4 ( sgVec4 dst, const sgVec4 a, const sgVec4 b, const SGfloat f ) { dst[0] = a[0] + f * ( b[0] - a[0] ) ; dst[1] = a[1] + f * ( b[1] - a[1] ) ; dst[2] = a[2] + f * ( b[2] - a[2] ) ; dst[3] = a[3] + f * ( b[3] - a[3] ) ; } inline void sgLerpVec3 ( sgVec3 dst, const sgVec3 a, const sgVec3 b, const SGfloat f ) { dst[0] = a[0] + f * ( b[0] - a[0] ) ; dst[1] = a[1] + f * ( b[1] - a[1] ) ; dst[2] = a[2] + f * ( b[2] - a[2] ) ; } inline void sgLerpVec2 ( sgVec2 dst, const sgVec2 a, const sgVec2 b, const SGfloat f ) { dst[0] = a[0] + f * ( b[0] - a[0] ) ; dst[1] = a[1] + f * ( b[1] - a[1] ) ; } inline void sgLerpAnglesVec3 ( sgVec3 dst, const sgVec3 a, const sgVec3 b, const SGfloat f ) { sgVec3 tmp ; if ( b[0] - a[0] > 180.0f ) tmp[0] = a[0] + 360.0f ; else if ( b[0] - a[0] < -180.0f ) tmp[0] = a[0] - 360.0f ; else tmp[0] = a[0] ; if ( b[1] - a[1] > 180.0f ) tmp[1] = a[1] + 360.0f ; else if ( b[1] - a[1] < -180.0f ) tmp[1] = a[1] - 360.0f ; else tmp[1] = a[1] ; if ( b[2] - a[2] > 180.0f ) tmp[2] = a[2] + 360.0f ; else if ( b[2] - a[2] < -180.0f ) tmp[2] = a[2] - 360.0f ; else tmp[2] = a[2] ; dst[0] = tmp[0] + f * ( b[0] - tmp[0] ) ; dst[1] = tmp[1] + f * ( b[1] - tmp[1] ) ; dst[2] = tmp[2] + f * ( b[2] - tmp[2] ) ; } inline SGfloat sgDistanceSquaredVec2 ( const sgVec2 a, const sgVec2 b ) { return sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) ; } inline SGfloat sgDistanceSquaredVec3 ( const sgVec3 a, const sgVec3 b ) { return sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) + sgSquare ( a[2]-b[2] ) ; } inline SGfloat sgDistanceSquaredVec4 ( const sgVec4 a, const sgVec4 b ) { return sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) + sgSquare ( a[2]-b[2] ) + sgSquare ( a[3]-b[3] ) ; } inline SGfloat sgDistanceVec2 ( const sgVec2 a, const sgVec2 b ) { return sgSqrt ( sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) ) ; } inline SGfloat sgDistanceVec3 ( const sgVec3 a, const sgVec3 b ) { return sgSqrt ( sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) + sgSquare ( a[2]-b[2] ) ) ; } inline SGfloat sgDistanceVec4 ( const sgVec4 a, const sgVec4 b ) { return sgSqrt ( sgSquare ( a[0]-b[0] ) + sgSquare ( a[1]-b[1] ) + sgSquare ( a[2]-b[2] ) + sgSquare ( a[3]-b[3] ) ) ; } inline SGfloat sgLengthVec2 ( const sgVec2 src ) { return sgSqrt ( sgScalarProductVec2 ( src, src ) ) ; } inline SGfloat sgLengthVec3 ( const sgVec3 src ) { return sgSqrt ( sgScalarProductVec3 ( src, src ) ) ; } inline SGfloat sgLengthVec4 ( const sgVec4 src ) { return sgSqrt ( sgScalarProductVec4 ( src, src ) ) ; } inline SGfloat sgLengthSquaredVec2 ( sgVec2 const src ) { return sgScalarProductVec2 ( src, src ) ; } inline SGfloat sgLengthSquaredVec3 ( sgVec3 const src ) { return sgScalarProductVec3 ( src, src ) ; } inline SGfloat sgLengthSquaredVec4 ( sgVec4 const src ) { return sgScalarProductVec4 ( src, src ) ; } /* Anglo-US spelling issues. */ #define sgNormalizeVec2 sgNormaliseVec2 #define sgNormalizeVec3 sgNormaliseVec3 #define sgNormalizeVec4 sgNormaliseVec4 #define sgNormalizeQuat sgNormaliseQuat inline void sgNormaliseVec2 ( sgVec2 dst ) { sgScaleVec2 ( dst, SG_ONE / sgLengthVec2 ( dst ) ) ; } inline void sgNormaliseVec3 ( sgVec3 dst ) { sgScaleVec3 ( dst, SG_ONE / sgLengthVec3 ( dst ) ) ; } inline void sgNormaliseVec4 ( sgVec4 dst ) { sgScaleVec4 ( dst, SG_ONE / sgLengthVec4 ( dst ) ) ; } inline void sgNormaliseVec2 ( sgVec2 dst, const sgVec2 src ) { sgScaleVec2 ( dst, src, SG_ONE / sgLengthVec2 ( src ) ) ; } inline void sgNormaliseVec3 ( sgVec3 dst, const sgVec3 src ) { sgScaleVec3 ( dst, src, SG_ONE / sgLengthVec3 ( src ) ) ; } inline void sgNormaliseVec4 ( sgVec4 dst, const sgVec4 src ) { sgScaleVec4 ( dst, src, SG_ONE / sgLengthVec4 ( src ) ) ; } inline void sgZeroCoord ( sgCoord *dst ) { sgSetVec3 ( dst->xyz, SG_ZERO, SG_ZERO, SG_ZERO ) ; sgSetVec3 ( dst->hpr, SG_ZERO, SG_ZERO, SG_ZERO ) ; } inline void sgSetCoord ( sgCoord *dst, const SGfloat x, const SGfloat y, const SGfloat z, const SGfloat h, const SGfloat p, const SGfloat r ) { sgSetVec3 ( dst->xyz, x, y, z ) ; sgSetVec3 ( dst->hpr, h, p, r ) ; } inline void sgSetCoord ( sgCoord *dst, const sgVec3 xyz, const sgVec3 hpr ) { sgCopyVec3 ( dst->xyz, xyz ) ; sgCopyVec3 ( dst->hpr, hpr ) ; } inline void sgCopyCoord ( sgCoord *dst, const sgCoord *src ) { sgCopyVec3 ( dst->xyz, src->xyz ) ; sgCopyVec3 ( dst->hpr, src->hpr ) ; } inline void sgCopyMat4 ( sgMat4 dst, const sgMat4 src ) { sgCopyVec4 ( dst[ 0 ], src[ 0 ] ) ; sgCopyVec4 ( dst[ 1 ], src[ 1 ] ) ; sgCopyVec4 ( dst[ 2 ], src[ 2 ] ) ; sgCopyVec4 ( dst[ 3 ], src[ 3 ] ) ; } inline void sgScaleMat4 ( sgMat4 dst, const sgMat4 src, const SGfloat scale ) { sgScaleVec4 ( dst[0], src[0], scale ) ; sgScaleVec4 ( dst[1], src[1], scale ) ; sgScaleVec4 ( dst[2], src[2], scale ) ; sgScaleVec4 ( dst[3], src[3], scale ) ; } inline void sgMakeIdentMat4 ( sgMat4 dst ) { sgSetVec4 ( dst[0], SG_ONE , SG_ZERO, SG_ZERO, SG_ZERO ) ; sgSetVec4 ( dst[1], SG_ZERO, SG_ONE , SG_ZERO, SG_ZERO ) ; sgSetVec4 ( dst[2], SG_ZERO, SG_ZERO, SG_ONE , SG_ZERO ) ; sgSetVec4 ( dst[3], SG_ZERO, SG_ZERO, SG_ZERO, SG_ONE ) ; } extern void sgMakePickMatrix( sgMat4 mat, sgFloat x, sgFloat y, sgFloat width, sgFloat height, sgVec4 viewport ) ; extern int sgCompare3DSqdDist ( const sgVec3 a, const sgVec3 b, const SGfloat sqd_dist ) ; inline SGfloat sgDistToLineVec2 ( const sgVec3 line, const sgVec2 pnt ) { return sgScalarProductVec2 ( line, pnt ) + line[2] ; } struct sgLineSegment3 /* Bounded line segment */ { sgVec3 a ; sgVec3 b ; } ; struct sgLine3 /* Infinite line */ { sgVec3 point_on_line ; sgVec3 direction_vector ; /* Should be a unit vector */ } ; inline void sgLineSegment3ToLine3 ( sgLine3 *line, const sgLineSegment3 lineseg ) { sgCopyVec3 ( line->point_on_line , lineseg.a ) ; sgSubVec3 ( line->direction_vector, lineseg.b, lineseg.a ) ; sgNormaliseVec3 ( line->direction_vector ) ; } SGfloat sgDistSquaredToLineVec3 ( const sgLine3 line, const sgVec3 pnt ) ; SGfloat sgDistSquaredToLineSegmentVec3 ( const sgLineSegment3 line, const sgVec3 pnt ) ; inline SGfloat sgDistToLineVec3 ( const sgLine3 line, const sgVec3 pnt ) { return sgSqrt ( sgDistSquaredToLineVec3 ( line, pnt ) ); } inline SGfloat sgDistToLineSegmentVec3 ( const sgLineSegment3 line, const sgVec3 pnt ) { return sgSqrt ( sgDistSquaredToLineSegmentVec3(line,pnt) ) ; } inline SGfloat sgDistToPlaneVec3 ( const sgVec4 plane, const sgVec3 pnt ) { return sgScalarProductVec3 ( plane, pnt ) + plane[3] ; } inline SGfloat sgHeightAbovePlaneVec3 ( const sgVec4 plane, const sgVec3 pnt ) { return pnt[2] - sgHeightOfPlaneVec2 ( plane, pnt ) ; } extern void sgReflectInPlaneVec3 ( sgVec3 dst, const sgVec3 src, const sgVec4 plane ) ; inline void sgReflectInPlaneVec3 ( sgVec3 dst, const sgVec4 plane ) { sgReflectInPlaneVec3 ( dst, dst, plane ) ; } extern void sgMakeNormal ( sgVec2 dst, const sgVec3 a, const sgVec3 b ) ; extern void sgMakeNormal ( sgVec3 dst, const sgVec3 a, const sgVec3 b, const sgVec3 c ) ; inline void sgMake2DLine ( sgVec3 dst, const sgVec2 a, const sgVec2 b ) { dst[0] = b[1]-a[1] ; dst[1] = -(b[0]-a[0]) ; sgNormalizeVec2 ( dst ) ; dst[2] = - ( dst[0]*a[0] + dst[1]*a[1] ) ; } inline void sgMakePlane ( sgVec4 dst, const sgVec3 normal, const sgVec3 pnt ) { sgCopyVec3 ( dst, normal ) ; dst [ 3 ] = - sgScalarProductVec3 ( normal, pnt ) ; } inline void sgMakePlane ( sgVec4 dst, const sgVec3 a, const sgVec3 b, const sgVec3 c ) { /* Ax + By + Cz + D == 0 ; D = - ( Ax + By + Cz ) = - ( A*a[0] + B*a[1] + C*a[2] ) = - sgScalarProductVec3 ( normal, a ) ; */ sgMakeNormal ( dst, a, b, c ) ; dst [ 3 ] = - sgScalarProductVec3 ( dst, a ) ; } float sgTriArea( sgVec3 p0, sgVec3 p1, sgVec3 p2 ); // Fast code. Result is in the range 0..180: inline SGfloat sgAngleBetweenNormalizedVec3 ( sgVec3 v1, sgVec3 v2 ) { float f = sgScalarProductVec3 ( v1, v2 ) ; return (float) acos ( ( f >= 1.0f ) ? 1.0f : ( f <= -1.0f ) ? -1.0f : f ) * SG_RADIANS_TO_DEGREES ; } // Fast code. Result is in the range 0..180: SGfloat sgAngleBetweenVec3 ( sgVec3 v1, sgVec3 v2 ); // All three have to be normalized. Slow code. Result is in the range 0..360: SGfloat sgAngleBetweenNormalizedVec3 (sgVec3 first, sgVec3 second, sgVec3 normal); // Normal has to be normalized. Slow code. Result is in the range 0..360: SGfloat sgAngleBetweenVec3 ( sgVec3 v1, sgVec3 v2, sgVec3 normal ); class sgSphere { public: sgVec3 center ; SGfloat radius ; sgSphere () { empty () ; } const SGfloat *getCenter (void) const { return center ; } void setCenter ( const sgVec3 c ) { sgCopyVec3 ( center, c ) ; } void setCenter ( const SGfloat x, const SGfloat y, const SGfloat z ) { sgSetVec3 ( center, x, y, z ) ; } SGfloat getRadius (void) const { return radius ; } void setRadius ( const SGfloat r ) { radius = r ; } int isEmpty (void) const { return radius < SG_ZERO ; } void empty (void) { radius = - SG_ONE ; } void orthoXform ( const sgMat4 m ) { sgXformPnt3 ( center, center, m ) ; // radius *= sgLengthVec3 ( m[0] ) ; -- degrades performance for non-scaled matrices ... } void extend ( const sgSphere *s ) ; void extend ( const sgBox *b ) ; void extend ( const sgVec3 v ) ; int intersects ( const sgSphere *s ) const { return sgCompare3DSqdDist ( center, s->getCenter(), sgSquare ( radius + s->getRadius() ) ) <= 0 ; } int intersects ( const sgVec4 plane ) const { return sgAbs ( sgDistToPlaneVec3 ( plane, center ) ) <= radius ; } int intersects ( const sgBox *b ) const ; } ; class sgBox { public: sgVec3 min ; sgVec3 max ; sgBox () { empty () ; } const SGfloat *getMin (void) const { return min ; } const SGfloat *getMax (void) const { return max ; } void setMin ( const SGfloat x, const SGfloat y, const SGfloat z ) { sgSetVec3 ( min, x, y, z ) ; } void setMin ( const sgVec3 src ) { sgCopyVec3 ( min, src ) ; } void setMax ( const SGfloat x, const SGfloat y, const SGfloat z ) { sgSetVec3 ( max, x, y, z ) ; } void setMax ( const sgVec3 src ) { sgCopyVec3 ( max, src ) ; } int isEmpty(void) const { return ( min[0] > max[0] || min[1] > max[1] || min[2] > max[2] ) ; } void empty (void) { sgSetVec3 ( min, SG_MAX, SG_MAX, SG_MAX ) ; sgSetVec3 ( max, -SG_MAX, -SG_MAX, -SG_MAX ) ; } void extend ( const sgSphere *s ) ; void extend ( const sgBox *b ) ; void extend ( const sgVec3 v ) ; int intersects ( const sgSphere *s ) const { return s -> intersects ( this ) ; } int intersects ( const sgBox *b ) const { return min[0] <= b->getMax()[0] && max[0] >= b->getMin()[0] && min[1] <= b->getMax()[1] && max[1] >= b->getMin()[1] && min[2] <= b->getMax()[2] && max[2] >= b->getMin()[2] ; } int intersects ( const sgVec4 plane ) const ; } ; #define SG_LEFT_PLANE 0 #define SG_RIGHT_PLANE 1 #define SG_BOT_PLANE 2 #define SG_TOP_PLANE 3 #define SG_NEAR_PLANE 4 #define SG_FAR_PLANE 5 class sgFrustum { /* Is the projection orthographic (or perspective)? */ int ortho ; /* The parameters for glFrustum/glOrtho */ SGfloat left, right, bot, top, nnear, ffar ; /* The computed projection matrix for this frustum */ sgMat4 mat ; /* The A,B,C,D terms of the plane equations of the clip planes */ /* A point (x,y,z) is inside the frustum iff Ax + By + Cz + D >= 0 for all planes */ sgVec4 plane [ 6 ] ; /* These two are only valid for simple frusta */ /* Note that to convert to parameters for gluPerspective you do the following: * "fovy" is "vfov" * "aspect" is the ratio "hfov" / "vfov" * Note also that the "hfov" and "vfov" variables are NOT automatically set. */ SGfloat hfov ; /* Horizontal Field of View -or- Orthographic Width */ SGfloat vfov ; /* Vertical Field of View -or- Orthographic Height */ void update (void) ; int getOutcode ( const sgVec4 src ) const ; public: sgFrustum (void) { ortho = FALSE ; nnear = SG_ONE ; ffar = 1000000.0f ; hfov = SG_45 ; vfov = SG_45 ; update () ; } void setFrustum ( const SGfloat l, const SGfloat r, const SGfloat b, const SGfloat t, const SGfloat n, const SGfloat f ) { ortho = FALSE ; left = l ; right = r ; bot = b ; top = t ; nnear = n ; ffar = f ; hfov = vfov = SG_ZERO ; update () ; } void setOrtho ( const SGfloat l, const SGfloat r, const SGfloat b, const SGfloat t, const SGfloat n, const SGfloat f ) { ortho = TRUE ; left = l ; right = r ; bot = b ; top = t ; nnear = n ; ffar = f ; hfov = vfov = SG_ZERO ; update () ; } void getMat4 ( sgMat4 dst ) { sgCopyMat4 ( dst, mat ) ; } SGfloat getLeft (void) const { return left ; } SGfloat getRight(void) const { return right ; } SGfloat getBot (void) const { return bot ; } SGfloat getTop (void) const { return top ; } SGfloat getNear (void) const { return nnear ; } SGfloat getFar (void) const { return ffar ; } const SGfloat *getPlane ( int i ) const { return plane [ i ] ; } SGfloat getHFOV (void) const { return hfov ; } SGfloat getVFOV (void) const { return vfov ; } void getFOV ( SGfloat *h, SGfloat *v ) const { if ( h != (SGfloat *) 0 ) *h = hfov ; if ( v != (SGfloat *) 0 ) *v = vfov ; } void setFOV ( const SGfloat h, const SGfloat v ) { ortho = FALSE ; hfov = ( h <= 0 ) ? ( v * SG_FOUR / SG_THREE ) : h ; vfov = ( v <= 0 ) ? ( h * SG_THREE / SG_FOUR ) : v ; update () ; } void getOrtho ( SGfloat *w, SGfloat *h ) const { if ( w != (SGfloat *) 0 ) *w = right - left ; if ( h != (SGfloat *) 0 ) *h = top - bot ; } void setOrtho ( const SGfloat w, const SGfloat h ) { ortho = TRUE ; hfov = ( w <= 0 ) ? ( h * SG_FOUR / SG_THREE ) : w ; vfov = ( h <= 0 ) ? ( w * SG_FOUR / SG_THREE ) : h ; update () ; } void getNearFar ( SGfloat *n, SGfloat *f ) const { if ( n != (SGfloat *) 0 ) *n = nnear ; if ( f != (SGfloat *) 0 ) *f = ffar ; } void setNearFar ( const SGfloat n, const SGfloat f ) { nnear = n ; ffar = f ; update () ; } int isOrtho (void) const { return ortho ; } int contains ( const sgVec3 p ) const ; int contains ( const sgSphere *s ) const ; int contains ( const sgBox *b ) const ; } ; /* Quaternion routines are Copyright (C) 1999 Kevin B. Thompson Modified by Sylvan W. Clebsch Largely rewritten by "Negative0" Added to by John Fay */ /* Quaternion structure w = real, (x, y, z) = vector CHANGED sqQuat to float array so that syntax matches vector and matrix routines */ inline void sgMakeIdentQuat ( sgQuat dst ) { sgSetVec4 ( dst, SG_ZERO, SG_ZERO, SG_ZERO, SG_ONE ) ; } inline void sgSetQuat ( sgQuat dst, const SGfloat w, const SGfloat x, const SGfloat y, const SGfloat z ) { sgSetVec4 ( dst, x, y, z, w ) ; } inline void sgCopyQuat ( sgQuat dst, const sgQuat src ) { sgCopyVec4 ( dst, src ) ; } /* Construct a unit quaternion (length==1) */ inline void sgNormaliseQuat ( sgQuat dst, const sgQuat src ) { SGfloat d = sgScalarProductVec4 ( src, src ) ; d = (d > SG_ZERO) ? (SG_ONE / sgSqrt ( d )) : SG_ONE ; sgScaleVec4 ( dst, src, d ) ; } inline void sgNormaliseQuat ( sgQuat dst ) { sgNormaliseQuat ( dst, dst ) ; } inline void sgInvertQuat ( sgQuat dst, const sgQuat src ) { SGfloat d = sgScalarProductVec4 ( src, src ) ; d = ( d == SG_ZERO ) ? SG_ONE : ( SG_ONE / d ) ; dst[SG_W] = src[SG_W] * d ; dst[SG_X] = -src[SG_X] * d ; dst[SG_Y] = -src[SG_Y] * d ; dst[SG_Z] = -src[SG_Z] * d ; } inline void sgInvertQuat ( sgQuat dst ) { sgInvertQuat ( dst, dst ) ; } /* Make an angle and axis of rotation from a Quaternion. */ void sgQuatToAngleAxis ( SGfloat *angle, sgVec3 axis, const sgQuat src ) ; void sgQuatToAngleAxis ( SGfloat *angle, SGfloat *x, SGfloat *y, SGfloat *z, const sgQuat src ) ; /* Make a quaternion from a given angle and axis of rotation */ void sgAngleAxisToQuat ( sgQuat dst, const SGfloat angle, const sgVec3 axis ) ; void sgAngleAxisToQuat ( sgQuat dst, const SGfloat angle, const SGfloat x, const SGfloat y, const SGfloat z ) ; /* Convert a matrix to/from a quat */ void sgMatrixToQuat ( sgQuat quat, const sgMat4 m ) ; void sgQuatToMatrix ( sgMat4 m, const sgQuat quat ) ; /* Convert a set of eulers to/from a quat */ void sgQuatToEuler( sgVec3 hpr, const sgQuat quat ) ; void sgEulerToQuat( sgQuat quat, const sgVec3 hpr ) ; inline void sgEulerToQuat( sgQuat dst, SGfloat h, SGfloat p, SGfloat r ) { sgVec3 hpr ; sgSetVec3 ( hpr, h, p, r ) ; sgEulerToQuat( dst, hpr ) ; } inline void sgHPRToQuat ( sgQuat dst, SGfloat h, SGfloat p, SGfloat r ) { sgVec3 hpr; hpr[0] = h * SG_DEGREES_TO_RADIANS ; hpr[1] = p * SG_DEGREES_TO_RADIANS ; hpr[2] = r * SG_DEGREES_TO_RADIANS ; sgEulerToQuat( dst, hpr ) ; } inline void sgHPRToQuat ( sgQuat dst, const sgVec3 hpr ) { sgVec3 tmp ; sgScaleVec3 ( tmp, hpr, SG_DEGREES_TO_RADIANS ) ; sgEulerToQuat ( dst, tmp ) ; } /* Multiply quaternions together (concatenate rotations) */ void sgMultQuat ( sgQuat dst, const sgQuat a, const sgQuat b ) ; inline void sgPostMultQuat ( sgQuat dst, const sgQuat q ) { sgQuat r ; sgCopyQuat ( r, dst ) ; sgMultQuat ( dst, r, q ) ; } inline void sgPreMultQuat ( sgQuat dst, const sgQuat q ) { sgQuat r ; sgCopyQuat ( r, dst ) ; sgMultQuat ( dst, q, r ) ; } /* Rotate a quaternion by a given angle and axis (convenience function) */ inline void sgPreRotQuat ( sgQuat dst, const SGfloat angle, const sgVec3 axis ) { sgQuat q ; sgAngleAxisToQuat ( q, angle, axis ) ; sgPreMultQuat ( dst, q ) ; sgNormaliseQuat ( dst ) ; } inline void sgPostRotQuat ( sgQuat dst, const SGfloat angle, const sgVec3 axis ) { sgQuat q ; sgAngleAxisToQuat ( q, angle, axis ) ; sgPostMultQuat ( dst, q ) ; sgNormaliseQuat ( dst ) ; } inline void sgPreRotQuat ( sgQuat dst, const SGfloat angle, const SGfloat x, const SGfloat y, const SGfloat z ) { sgVec3 axis ; sgSetVec3 ( axis, x, y, z ) ; sgPreRotQuat ( dst, angle, axis ) ; } inline void sgPostRotQuat ( sgQuat dst, const SGfloat angle, const SGfloat x, const SGfloat y, const SGfloat z ) { sgVec3 axis ; sgSetVec3 ( axis, x, y, z ) ; sgPostRotQuat ( dst, angle, axis ) ; } /* more meaningful names */ #define sgWorldRotQuat sgPostRotQuat #define sgLocalRotQuat sgPreRotQuat /* for backwards compatibility */ #define sgRotQuat sgPostRotQuat /* SWC - Interpolate between to quaternions */ extern void sgSlerpQuat ( sgQuat dst, const sgQuat from, const sgQuat to, const SGfloat t ) ; /* Intersection testing. */ int sgIsectPlanePlane ( sgVec3 point, sgVec3 dir, sgVec4 plane1, sgVec4 plane2 ) ; int sgIsectInfLinePlane ( sgVec3 dst, sgVec3 l_org, sgVec3 l_vec, sgVec4 plane ) ; int sgIsectInfLineInfLine ( sgVec3 dst, sgVec3 l1_org, sgVec3 l1_vec, sgVec3 l2_org, sgVec3 l2_vec ) ; SGfloat sgIsectLinesegPlane ( sgVec3 dst, sgVec3 v1, sgVec3 v2, sgVec4 plane ) ; bool sgPointInTriangle3 ( sgVec3 point, sgVec3 tri[3] ) ; bool sgPointInTriangle2 ( sgVec2 point, sgVec2 tri[3] ) ; inline bool sgPointInTriangle ( sgVec3 point, sgVec3 tri[3] ) { return sgPointInTriangle3 ( point, tri ) ; } /**********************************************************************/ #define sgdFloat double #define SGDfloat double #define SGD_ZERO 0.0 #define SGD_HALF 0.5 #define SGD_ONE 1.0 #define SGD_TWO 2.0 #define SGD_THREE 3.0 #define SGD_FOUR 4.0 #define SGD_45 45.0 #define SGD_60 60.0 #define SGD_90 90.0 #define SGD_180 180.0 #define SGD_MAX DBL_MAX #define SGD_X 0 #define SGD_Y 1 #define SGD_Z 2 #define SGD_W 3 #ifndef M_PI #define SGD_PI 3.14159265358979323846 /* From M_PI under Linux/X86 */ #else #define SGD_PI M_PI #endif #define SGD_DEGREES_TO_RADIANS (SGD_PI/SGD_180) #define SGD_RADIANS_TO_DEGREES (SGD_180/SGD_PI) /* These are just convenient redefinitions of standard math library functions to stop float/double warnings. */ inline SGDfloat sgdSqrt ( const SGDfloat x ) { return sqrt ( x ) ; } inline SGDfloat sgdSquare ( const SGDfloat x ) { return x * x ; } inline SGDfloat sgdAbs ( const SGDfloat a ) { return ( a < SGD_ZERO ) ? -a : a ; } inline SGDfloat sgdASin ( SGDfloat s ) { return (SGDfloat) asin ( s ) * SGD_RADIANS_TO_DEGREES ; } inline SGDfloat sgdACos ( SGDfloat s ) { return (SGDfloat) acos ( s ) * SGD_RADIANS_TO_DEGREES ; } inline SGDfloat sgdATan ( SGDfloat s ) { return (SGDfloat) atan ( s ) * SGD_RADIANS_TO_DEGREES ; } inline SGDfloat sgdATan2 ( SGDfloat y, SGDfloat x ) { return (SGDfloat) atan2 ( y,x ) * SGD_RADIANS_TO_DEGREES ; } inline SGDfloat sgdSin ( SGDfloat s ) { return (SGDfloat) sin ( s * SGD_DEGREES_TO_RADIANS ) ; } inline SGDfloat sgdCos ( SGDfloat s ) { return (SGDfloat) cos ( s * SGD_DEGREES_TO_RADIANS ) ; } inline SGDfloat sgdTan ( SGDfloat s ) { return (SGDfloat) tan ( s * SGD_DEGREES_TO_RADIANS ) ; } inline int sgdCompareFloat ( const SGDfloat a, const SGDfloat b, const SGDfloat tol ) { if ( ( a + tol ) < b ) return -1 ; if ( ( b + tol ) < a ) return 1 ; return 0 ; } /* Types used in SGD. */ typedef SGDfloat sgdVec2 [ 2 ] ; typedef SGDfloat sgdVec3 [ 3 ] ; typedef SGDfloat sgdVec4 [ 4 ] ; typedef sgdVec4 sgdQuat ; typedef SGDfloat sgdMat3 [3][3] ; typedef SGDfloat sgdMat4 [4][4] ; struct sgdCoord { sgdVec3 xyz ; sgdVec3 hpr ; } ; class sgdSphere ; class sgdBox ; class sgdFrustum ; /* Some handy constants */ #define SGD_OUTSIDE FALSE #define SGD_INSIDE TRUE #define SGD_STRADDLE 2 inline SGDfloat sgdHeightOfPlaneVec2 ( const sgdVec4 plane, const sgdVec2 pnt ) { if ( plane[2] == SGD_ZERO ) return SGD_ZERO ; else return -( plane[0] * pnt[0] + plane[1] * pnt[1] + plane[3] ) / plane[2] ; } /* Convert a direction vector into a set of euler angles, (with zero roll) */ extern void sgdHPRfromVec3 ( sgdVec3 hpr, const sgdVec3 src ) ; extern void sgdMakeCoordMat4 ( sgdMat4 dst, const SGDfloat x, const SGDfloat y, const SGDfloat z, const SGDfloat h, const SGDfloat p, const SGDfloat r ) ; inline void sgdMakeCoordMat4( sgdMat4 dst, const sgdVec3 xyz, const sgdVec3 hpr ) { sgdMakeCoordMat4 ( dst, xyz[0], xyz[1], xyz[2], hpr[0], hpr[1], hpr[2] ) ; } inline void sgdMakeCoordMat4( sgdMat4 dst, const sgdCoord *src ) { sgdMakeCoordMat4 ( dst, src->xyz, src->hpr ) ; } extern void sgdMakeRotMat4 ( sgdMat4 dst, const SGDfloat angle, const sgdVec3 axis ) ; inline void sgdMakeRotMat4 ( sgdMat4 dst, const sgdVec3 hpr ) { sgdMakeCoordMat4 ( dst, SGD_ZERO, SGD_ZERO, SGD_ZERO, hpr[0], hpr[1], hpr[2] ) ; } inline void sgdMakeRotMat4 ( sgdMat4 dst, const SGDfloat h, const SGDfloat p, const SGDfloat r ) { sgdMakeCoordMat4 ( dst, SGD_ZERO, SGD_ZERO, SGD_ZERO, h, p, r ) ; } extern void sgdMakeTransMat4 ( sgdMat4 dst, const sgdVec3 xyz ) ; extern void sgdMakeTransMat4 ( sgdMat4 dst, const SGDfloat x, const SGDfloat y, const SGDfloat z ) ; extern void sgdSetCoord ( sgdCoord *coord, const sgdMat4 src ) ; extern void sgdMultMat4 ( sgdMat4 dst, const sgdMat4 a, const sgdMat4 b ) ; extern void sgdPostMultMat4 ( sgdMat4 dst, const sgdMat4 a ) ; extern void sgdPreMultMat4 ( sgdMat4 dst, const sgdMat4 a ) ; extern void sgdTransposeNegateMat4 ( sgdMat4 dst ) ; extern void sgdTransposeNegateMat4 ( sgdMat4 dst, const sgdMat4 src ) ; extern void sgdInvertMat4 ( sgdMat4 dst, const sgdMat4 src ) ; inline void sgdInvertMat4 ( sgdMat4 dst ) { sgdInvertMat4 ( dst, dst ) ; } extern void sgdXformVec3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) ; extern void sgdXformPnt3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) ; extern void sgdXformVec4 ( sgdVec4 dst, const sgdVec4 src, const sgdMat4 mat ) ; extern void sgdXformPnt4 ( sgdVec4 dst, const sgdVec4 src, const sgdMat4 mat ) ; extern void sgdFullXformPnt3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) ; extern void sgdFullXformPnt4 ( sgdVec4 dst, const sgdVec4 src, const sgdMat4 mat ) ; inline void sgdXformVec3 ( sgdVec3 dst, const sgdMat4 mat ) { sgdXformVec3 ( dst, dst, mat ) ; } inline void sgdXformPnt3 ( sgdVec3 dst, const sgdMat4 mat ) { sgdXformPnt3 ( dst, dst, mat ) ; } inline void sgdXformVec4 ( sgdVec4 dst, const sgdMat4 mat ) { sgdXformVec4 ( dst, dst, mat ) ; } inline void sgdXformPnt4 ( sgdVec4 dst, const sgdMat4 mat ) { sgdXformPnt4 ( dst, dst, mat ) ; } inline void sgdFullXformPnt3 ( sgdVec3 dst, const sgdMat4 mat ) { sgdFullXformPnt3 ( dst, dst, mat ) ; } inline void sgdFullXformPnt4 ( sgdVec4 dst, const sgdMat4 mat ) { sgdFullXformPnt4 ( dst, dst, mat ) ; } /* Basic low-level vector functions. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For each of Vec2, Vec3 and Vec4, we provide inlines for Zero - set all elements to zero. Set - set each element individually. Add - add vectors element by element. Sub - subtract vectors element by element. Scale - multiply each element of a vector by a variable. Negate - negate each element of a vector. Compare - compare vectors element by element with optional tolerance. (return TRUE if vectors are equal - within tolerances) Equal - return TRUE if vectors are exactly equal. Length - compute length of a vector. Distance - compute distance between two points. LengthSquared - compute the square of the length of a vector. DistanceSquared - compute the square of the distance between two points. ScalarProduct - scalar (dot) product. VectorProduct - vector (cross) product (3-element vectors ONLY!). Normalise/Normalize - make vector be one unit long. Lerp - linear interpolation by a fraction 'f'. */ inline void sgdZeroVec2 ( sgdVec2 dst ) { dst[0]=dst[1]=SGD_ZERO ; } inline void sgdZeroVec3 ( sgdVec3 dst ) { dst[0]=dst[1]=dst[2]=SGD_ZERO ; } inline void sgdZeroVec4 ( sgdVec4 dst ) { dst[0]=dst[1]=dst[2]=dst[3]=SGD_ZERO ; } inline void sgdSetVec2 ( sgdVec2 dst, const SGDfloat x, const SGDfloat y ) { dst [ 0 ] = x ; dst [ 1 ] = y ; } inline void sgdSetVec3 ( sgdVec3 dst, const SGDfloat x, const SGDfloat y, const SGDfloat z ) { dst [ 0 ] = x ; dst [ 1 ] = y ; dst [ 2 ] = z ; } inline void sgdSetVec4 ( sgdVec4 dst, const SGDfloat x, const SGDfloat y, const SGDfloat z, const SGDfloat w ) { dst [ 0 ] = x ; dst [ 1 ] = y ; dst [ 2 ] = z ; dst [ 3 ] = w ; } inline void sgdCopyVec2 ( sgdVec2 dst, const sgdVec2 src ) { dst [ 0 ] = src [ 0 ] ; dst [ 1 ] = src [ 1 ] ; } inline void sgdCopyVec3 ( sgdVec3 dst, const sgdVec3 src ) { dst [ 0 ] = src [ 0 ] ; dst [ 1 ] = src [ 1 ] ; dst [ 2 ] = src [ 2 ] ; } inline void sgdCopyVec4 ( sgdVec4 dst, const sgdVec4 src ) { dst [ 0 ] = src [ 0 ] ; dst [ 1 ] = src [ 1 ] ; dst [ 2 ] = src [ 2 ] ; dst [ 3 ] = src [ 3 ] ; } inline void sgdAddVec2 ( sgdVec2 dst, const sgdVec2 src ) { dst [ 0 ] += src [ 0 ] ; dst [ 1 ] += src [ 1 ] ; } inline void sgdAddVec3 ( sgdVec3 dst, const sgdVec3 src ) { dst [ 0 ] += src [ 0 ] ; dst [ 1 ] += src [ 1 ] ; dst [ 2 ] += src [ 2 ] ; } inline void sgdAddVec4 ( sgdVec4 dst, const sgdVec4 src ) { dst [ 0 ] += src [ 0 ] ; dst [ 1 ] += src [ 1 ] ; dst [ 2 ] += src [ 2 ] ; dst [ 3 ] += src [ 3 ] ; } inline void sgdAddVec2 ( sgdVec2 dst, const sgdVec2 src1, const sgdVec2 src2 ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; } inline void sgdAddVec3 ( sgdVec3 dst, const sgdVec3 src1, const sgdVec3 src2 ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] ; } inline void sgdAddVec4 ( sgdVec4 dst, const sgdVec4 src1, const sgdVec4 src2 ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] ; dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] ; dst [ 3 ] = src1 [ 3 ] + src2 [ 3 ] ; } inline void sgdSubVec2 ( sgdVec2 dst, const sgdVec2 src ) { dst [ 0 ] -= src [ 0 ] ; dst [ 1 ] -= src [ 1 ] ; } inline void sgdSubVec3 ( sgdVec3 dst, const sgdVec3 src ) { dst [ 0 ] -= src [ 0 ] ; dst [ 1 ] -= src [ 1 ] ; dst [ 2 ] -= src [ 2 ] ; } inline void sgdSubVec4 ( sgdVec4 dst, const sgdVec4 src ) { dst [ 0 ] -= src [ 0 ] ; dst [ 1 ] -= src [ 1 ] ; dst [ 2 ] -= src [ 2 ] ; dst [ 3 ] -= src [ 3 ] ; } inline void sgdSubVec2 ( sgdVec2 dst, const sgdVec2 src1, const sgdVec2 src2 ) { dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; } inline void sgdSubVec3 ( sgdVec3 dst, const sgdVec3 src1, const sgdVec3 src2 ) { dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; dst [ 2 ] = src1 [ 2 ] - src2 [ 2 ] ; } inline void sgdSubVec4 ( sgdVec4 dst, const sgdVec4 src1, const sgdVec4 src2 ) { dst [ 0 ] = src1 [ 0 ] - src2 [ 0 ] ; dst [ 1 ] = src1 [ 1 ] - src2 [ 1 ] ; dst [ 2 ] = src1 [ 2 ] - src2 [ 2 ] ; dst [ 3 ] = src1 [ 3 ] - src2 [ 3 ] ; } inline void sgdNegateVec2 ( sgdVec2 dst ) { dst [ 0 ] = -dst [ 0 ] ; dst [ 1 ] = -dst [ 1 ] ; } inline void sgdNegateVec3 ( sgdVec3 dst ) { dst [ 0 ] = -dst [ 0 ] ; dst [ 1 ] = -dst [ 1 ] ; dst [ 2 ] = -dst [ 2 ] ; } inline void sgdNegateVec4 ( sgdVec4 dst ) { dst [ 0 ] = -dst [ 0 ] ; dst [ 1 ] = -dst [ 1 ] ; dst [ 2 ] = -dst [ 2 ] ; dst [ 3 ] = -dst [ 3 ] ; } inline void sgdNegateVec2 ( sgdVec2 dst, const sgdVec2 src ) { dst [ 0 ] = -src [ 0 ] ; dst [ 1 ] = -src [ 1 ] ; } inline void sgdNegateVec3 ( sgdVec3 dst, const sgdVec3 src ) { dst [ 0 ] = -src [ 0 ] ; dst [ 1 ] = -src [ 1 ] ; dst [ 2 ] = -src [ 2 ] ; } inline void sgdNegateVec4 ( sgdVec4 dst, const sgdVec4 src ) { dst [ 0 ] = -src [ 0 ] ; dst [ 1 ] = -src [ 1 ] ; dst [ 2 ] = -src [ 2 ] ; dst [ 3 ] = -src [ 3 ] ; } inline void sgdScaleVec2 ( sgdVec2 dst, const SGDfloat s ) { dst [ 0 ] *= s ; dst [ 1 ] *= s ; } inline void sgdScaleVec3 ( sgdVec3 dst, const SGDfloat s ) { dst [ 0 ] *= s ; dst [ 1 ] *= s ; dst [ 2 ] *= s ; } inline void sgdScaleVec4 ( sgdVec4 dst, const SGDfloat s ) { dst [ 0 ] *= s ; dst [ 1 ] *= s ; dst [ 2 ] *= s ; dst [ 3 ] *= s ; } inline void sgdScaleVec2 ( sgdVec2 dst, const sgdVec2 src, const SGDfloat s ) { dst [ 0 ] = src [ 0 ] * s ; dst [ 1 ] = src [ 1 ] * s ; } inline void sgdScaleVec3 ( sgdVec3 dst, const sgdVec3 src, const SGDfloat s ) { dst [ 0 ] = src [ 0 ] * s ; dst [ 1 ] = src [ 1 ] * s ; dst [ 2 ] = src [ 2 ] * s ; } inline void sgdScaleVec4 ( sgdVec4 dst, const sgdVec4 src, const SGDfloat s ) { dst [ 0 ] = src [ 0 ] * s ; dst [ 1 ] = src [ 1 ] * s ; dst [ 2 ] = src [ 2 ] * s ; dst [ 3 ] = src [ 3 ] * s ; } inline void sgdAddScaledVec2 ( sgdVec2 dst, const sgdVec2 src, const SGDfloat s ) { dst [ 0 ] += src [ 0 ] * s ; dst [ 1 ] += src [ 1 ] * s ; } inline void sgdAddScaledVec3 ( sgdVec3 dst, const sgdVec3 src, const SGDfloat s ) { dst [ 0 ] += src [ 0 ] * s ; dst [ 1 ] += src [ 1 ] * s ; dst [ 2 ] += src [ 2 ] * s ; } inline void sgdAddScaledVec4 ( sgdVec4 dst, const sgdVec4 src, const SGDfloat s ) { dst [ 0 ] += src [ 0 ] * s ; dst [ 1 ] += src [ 1 ] * s ; dst [ 2 ] += src [ 2 ] * s ; dst [ 3 ] += src [ 3 ] * s ; } inline void sgdAddScaledVec2 ( sgdVec2 dst, const sgdVec2 src1, const sgdVec2 src2, const SGDfloat s ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; } inline void sgdAddScaledVec3 ( sgdVec3 dst, const sgdVec3 src1, const sgdVec3 src2, const SGDfloat s ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] * s ; } inline void sgdAddScaledVec4 ( sgdVec4 dst, const sgdVec4 src1, const sgdVec4 src2, const SGDfloat s ) { dst [ 0 ] = src1 [ 0 ] + src2 [ 0 ] * s ; dst [ 1 ] = src1 [ 1 ] + src2 [ 1 ] * s ; dst [ 2 ] = src1 [ 2 ] + src2 [ 2 ] * s ; dst [ 3 ] = src1 [ 3 ] + src2 [ 3 ] * s ; } inline int sgdCompareVec2 ( const sgdVec2 a, const sgdVec2 b, const SGDfloat tol ) { int val = 0 ; if ( ( val = sgdCompareFloat( a[0], b[0], tol ) ) != 0 ) return val ; if ( ( val = sgdCompareFloat( a[1], b[1], tol ) ) != 0 ) return val ; return 0 ; } inline int sgdCompareVec3 ( const sgdVec3 a, const sgdVec3 b, const SGDfloat tol ) { int val = 0 ; if ( ( val = sgdCompareFloat( a[0], b[0], tol ) ) != 0 ) return val ; if ( ( val = sgdCompareFloat( a[1], b[1], tol ) ) != 0 ) return val ; if ( ( val = sgdCompareFloat( a[2], b[2], tol ) ) != 0 ) return val ; return 0 ; } inline int sgdCompareVec4 ( const sgdVec4 a, const sgdVec4 b, const SGDfloat tol ) { int val = 0 ; if ( ( val = sgdCompareFloat( a[0], b[0], tol ) ) != 0 ) return val ; if ( ( val = sgdCompareFloat( a[1], b[1], tol ) ) != 0 ) return val ; if ( ( val = sgdCompareFloat( a[2], b[2], tol ) ) != 0 ) return val ; if ( ( val = sgdCompareFloat( a[3], b[3], tol ) ) != 0 ) return val ; return 0 ; } inline int sgdEqualVec2 ( const sgdVec2 a, const sgdVec2 b ) { return a[0] == b[0] && a[1] == b[1] ; } inline int sgdEqualVec3 ( const sgdVec3 a, const sgdVec3 b ) { return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] ; } inline int sgdEqualVec4 ( const sgdVec4 a, const sgdVec4 b ) { return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3] ; } inline SGDfloat sgdScalarProductVec2 ( const sgdVec2 a, const sgdVec2 b ) { return a[0]*b[0] + a[1]*b[1] ; } inline SGDfloat sgdScalarProductVec3 ( const sgdVec3 a, const sgdVec3 b ) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] ; } inline SGDfloat sgdScalarProductVec4 ( const sgdVec4 a, const sgdVec4 b ) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3] ; } extern void sgdVectorProductVec3 ( sgdVec3 dst, const sgdVec3 a, const sgdVec3 b ) ; inline void sgdLerpVec4 ( sgdVec4 dst, const sgdVec4 a, const sgdVec4 b, const SGDfloat f ) { dst[0] = a[0] + f * ( b[0] - a[0] ) ; dst[1] = a[1] + f * ( b[1] - a[1] ) ; dst[2] = a[2] + f * ( b[2] - a[2] ) ; dst[3] = a[3] + f * ( b[3] - a[3] ) ; } inline void sgdLerpVec3 ( sgdVec3 dst, const sgdVec3 a, const sgdVec3 b, const SGDfloat f ) { dst[0] = a[0] + f * ( b[0] - a[0] ) ; dst[1] = a[1] + f * ( b[1] - a[1] ) ; dst[2] = a[2] + f * ( b[2] - a[2] ) ; } inline void sgdLerpVec2 ( sgdVec2 dst, const sgdVec2 a, const sgdVec2 b, const SGDfloat f ) { dst[0] = a[0] + f * ( b[0] - a[0] ) ; dst[1] = a[1] + f * ( b[1] - a[1] ) ; } inline void sgdLerpAnglesVec3 ( sgdVec3 dst, const sgdVec3 a, const sgdVec3 b, const SGDfloat f ) { sgdVec3 tmp ; if ( b[0] - a[0] > 180.0 ) tmp[0] = a[0] + 360.0 ; else if ( b[0] - a[0] < -180.0 ) tmp[0] = a[0] - 360.0 ; else tmp[0] = a[0] ; if ( b[1] - a[1] > 180.0 ) tmp[1] = a[1] + 360.0 ; else if ( b[1] - a[1] < -180.0 ) tmp[1] = a[1] - 360.0 ; else tmp[1] = a[1] ; if ( b[2] - a[2] > 180.0 ) tmp[2] = a[2] + 360.0 ; else if ( b[2] - a[2] < -180.0 ) tmp[2] = a[2] - 360.0 ; else tmp[2] = a[2] ; dst[0] = tmp[0] + f * ( b[0] - tmp[0] ) ; dst[1] = tmp[1] + f * ( b[1] - tmp[1] ) ; dst[2] = tmp[2] + f * ( b[2] - tmp[2] ) ; } inline SGDfloat sgdDistanceSquaredVec2 ( const sgdVec2 a, const sgdVec2 b ) { return sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) ; } inline SGDfloat sgdDistanceSquaredVec3 ( const sgdVec3 a, const sgdVec3 b ) { return sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) + sgdSquare ( a[2]-b[2] ) ; } inline SGDfloat sgdDistanceSquaredVec4 ( const sgdVec4 a, const sgdVec4 b ) { return sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) + sgdSquare ( a[2]-b[2] ) + sgdSquare ( a[3]-b[3] ) ; } inline SGDfloat sgdDistanceVec2 ( const sgdVec2 a, const sgdVec2 b ) { return sgdSqrt ( sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) ) ; } inline SGDfloat sgdDistanceVec3 ( const sgdVec3 a, const sgdVec3 b ) { return sgdSqrt ( sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) + sgdSquare ( a[2]-b[2] ) ) ; } inline SGDfloat sgdDistanceVec4 ( const sgdVec4 a, const sgdVec4 b ) { return sgdSqrt ( sgdSquare ( a[0]-b[0] ) + sgdSquare ( a[1]-b[1] ) + sgdSquare ( a[2]-b[2] ) + sgdSquare ( a[3]-b[3] ) ) ; } inline SGDfloat sgdLengthVec2 ( sgdVec2 const src ) { return sgdSqrt ( sgdScalarProductVec2 ( src, src ) ) ; } inline SGDfloat sgdLengthVec3 ( sgdVec3 const src ) { return sgdSqrt ( sgdScalarProductVec3 ( src, src ) ) ; } inline SGDfloat sgdLengthVec4 ( sgdVec4 const src ) { return sgdSqrt ( sgdScalarProductVec4 ( src, src ) ) ; } inline SGDfloat sgdLengthSquaredVec2 ( sgdVec2 const src ) { return sgdScalarProductVec2 ( src, src ) ; } inline SGDfloat sgdLengthSquaredVec3 ( sgdVec3 const src ) { return sgdScalarProductVec3 ( src, src ) ; } inline SGDfloat sgdLengthSquaredVec4 ( sgdVec4 const src ) { return sgdScalarProductVec4 ( src, src ) ; } /* Anglo-US spelling issues. */ #define sgdNormalizeVec2 sgdNormaliseVec2 #define sgdNormalizeVec3 sgdNormaliseVec3 #define sgdNormalizeVec4 sgdNormaliseVec4 #define sgdNormalizeQuat sgdNormaliseQuat inline void sgdNormaliseVec2 ( sgdVec2 dst ) { sgdScaleVec2 ( dst, SGD_ONE / sgdLengthVec2 ( dst ) ) ; } inline void sgdNormaliseVec3 ( sgdVec3 dst ) { sgdScaleVec3 ( dst, SGD_ONE / sgdLengthVec3 ( dst ) ) ; } inline void sgdNormaliseVec4 ( sgdVec4 dst ) { sgdScaleVec4 ( dst, SGD_ONE / sgdLengthVec4 ( dst ) ) ; } inline void sgdNormaliseVec2 ( sgdVec2 dst, const sgdVec2 src ) { sgdScaleVec2 ( dst, src, SGD_ONE / sgdLengthVec2 ( src ) ) ; } inline void sgdNormaliseVec3 ( sgdVec3 dst, const sgdVec3 src ) { sgdScaleVec3 ( dst, src, SGD_ONE / sgdLengthVec3 ( src ) ) ; } inline void sgdNormaliseVec4 ( sgdVec4 dst, const sgdVec4 src ) { sgdScaleVec4 ( dst, src, SGD_ONE / sgdLengthVec4 ( src ) ) ; } inline void sgdZeroCoord ( sgdCoord *dst ) { sgdSetVec3 ( dst->xyz, SGD_ZERO, SGD_ZERO, SGD_ZERO ) ; sgdSetVec3 ( dst->hpr, SGD_ZERO, SGD_ZERO, SGD_ZERO ) ; } inline void sgdSetCoord ( sgdCoord *dst, const SGDfloat x, const SGDfloat y, const SGDfloat z, const SGDfloat h, const SGDfloat p, const SGDfloat r ) { sgdSetVec3 ( dst->xyz, x, y, z ) ; sgdSetVec3 ( dst->hpr, h, p, r ) ; } inline void sgdSetCoord ( sgdCoord *dst, const sgdVec3 xyz, const sgdVec3 hpr ) { sgdCopyVec3 ( dst->xyz, xyz ) ; sgdCopyVec3 ( dst->hpr, hpr ) ; } inline void sgdCopyCoord ( sgdCoord *dst, const sgdCoord *src ) { sgdCopyVec3 ( dst->xyz, src->xyz ) ; sgdCopyVec3 ( dst->hpr, src->hpr ) ; } inline void sgdCopyMat4 ( sgdMat4 dst, const sgdMat4 src ) { sgdCopyVec4 ( dst[ 0 ], src[ 0 ] ) ; sgdCopyVec4 ( dst[ 1 ], src[ 1 ] ) ; sgdCopyVec4 ( dst[ 2 ], src[ 2 ] ) ; sgdCopyVec4 ( dst[ 3 ], src[ 3 ] ) ; } inline void sgdScaleMat4 ( sgdMat4 dst, const sgdMat4 src, const SGDfloat scale ) { sgdScaleVec4 ( dst[0], src[0], scale ) ; sgdScaleVec4 ( dst[1], src[1], scale ) ; sgdScaleVec4 ( dst[2], src[2], scale ) ; sgdScaleVec4 ( dst[3], src[3], scale ) ; } inline void sgdMakeIdentMat4 ( sgdMat4 dst ) { sgdSetVec4 ( dst[0], SGD_ONE , SGD_ZERO, SGD_ZERO, SGD_ZERO ) ; sgdSetVec4 ( dst[1], SGD_ZERO, SGD_ONE , SGD_ZERO, SGD_ZERO ) ; sgdSetVec4 ( dst[2], SGD_ZERO, SGD_ZERO, SGD_ONE , SGD_ZERO ) ; sgdSetVec4 ( dst[3], SGD_ZERO, SGD_ZERO, SGD_ZERO, SGD_ONE ) ; } extern void sgdMakeTransMat4 ( sgdMat4 m, const SGDfloat x, const SGDfloat y, const SGDfloat z ) ; extern void sgdMakeTransMat4 ( sgdMat4 m, const sgdVec3 xyz ) ; extern void sgdMakeCoordMat4 ( sgdMat4 m, const SGDfloat x, const SGDfloat y, const SGDfloat z, const SGDfloat h, const SGDfloat p, const SGDfloat r ) ; extern void sgdMakeCoordMat4 ( sgdMat4 m, const sgdCoord *c ) ; extern int sgdCompare3DSqdDist ( const sgdVec3 a, const sgdVec3 b, const SGDfloat sqd_dist ) ; inline SGDfloat sgdDistToLineVec2 ( const sgdVec3 line, const sgdVec2 pnt ) { return sgdScalarProductVec2 ( line, pnt ) + line[2] ; } struct sgdLineSegment3 /* Bounded line segment */ { sgdVec3 a ; sgdVec3 b ; } ; struct sgdLine3 /* Infinite line */ { sgdVec3 point_on_line ; sgdVec3 direction_vector ; /* Should be a unit vector */ } ; inline void sgdLineSegment3ToLine3 ( sgdLine3 *line, const sgdLineSegment3 lineseg ) { sgdCopyVec3 ( line->point_on_line , lineseg.a ) ; sgdSubVec3 ( line->direction_vector, lineseg.b, lineseg.a ) ; sgdNormaliseVec3 ( line->direction_vector ) ; } SGDfloat sgdDistSquaredToLineVec3 ( const sgdLine3 line, const sgdVec3 pnt ) ; SGDfloat sgdDistSquaredToLineSegmentVec3 ( const sgdLineSegment3 line, const sgdVec3 pnt ) ; inline SGDfloat sgdDistToLineVec3 ( const sgdLine3 line, const sgdVec3 pnt ) { return sgdSqrt ( sgdDistSquaredToLineVec3 ( line, pnt ) ); } inline SGDfloat sgdDistToLineSegmentVec3 ( const sgdLineSegment3 line, const sgdVec3 pnt ) { return sgdSqrt ( sgdDistSquaredToLineSegmentVec3(line,pnt) ) ; } inline SGDfloat sgdDistToPlaneVec3 ( const sgdVec4 plane, const sgdVec3 pnt ) { return sgdScalarProductVec3 ( plane, pnt ) + plane[3] ; } inline SGDfloat sgdHeightAbovePlaneVec3 ( const sgdVec4 plane, const sgdVec3 pnt ) { return pnt[2] - sgdHeightOfPlaneVec2 ( plane, pnt ) ; } extern void sgdReflectInPlaneVec3 ( sgdVec3 dst, const sgdVec3 src, const sgdVec4 plane ) ; inline void sgdReflectInPlaneVec3 ( sgdVec3 dst, const sgdVec4 plane ) { sgdReflectInPlaneVec3 ( dst, dst, plane ) ; } extern void sgdMakeNormal ( sgdVec3 dst, const sgdVec3 a, const sgdVec3 b, const sgdVec3 c ) ; inline void sgdMake2DLine ( sgdVec3 dst, const sgdVec2 a, const sgdVec2 b ) { dst[0] = b[1]-a[1] ; dst[1] = -b[0]-a[0] ; sgdNormalizeVec2 ( dst ) ; dst[2] = - ( dst[0]*a[0] + dst[1]*a[1] ) ; } inline void sgdMakePlane ( sgdVec4 dst, const sgdVec3 normal, const sgdVec3 pnt ) { sgdCopyVec3 ( dst, normal ) ; dst [ 3 ] = - sgdScalarProductVec3 ( normal, pnt ) ; } inline void sgdMakePlane ( sgdVec4 dst, const sgdVec3 a, const sgdVec3 b, const sgdVec3 c ) { /* Ax + By + Cz + D == 0 ; D = - ( Ax + By + Cz ) = - ( A*a[0] + B*a[1] + C*a[2] ) = - sgdScalarProductVec3 ( normal, a ) ; */ sgdMakeNormal ( dst, a, b, c ) ; dst [ 3 ] = - sgdScalarProductVec3 ( dst, a ) ; } SGDfloat sgdTriArea( sgdVec3 p0, sgdVec3 p1, sgdVec3 p2 ); // Fast code. Result is in the range 0..180: inline SGDfloat sgdAngleBetweenNormalizedVec3 ( sgdVec3 v1, sgdVec3 v2 ) { SGDfloat f = sgdScalarProductVec3 ( v1, v2 ) ; return (float) acos ( ( f >= 1.0f ) ? 1.0f : ( f <= -1.0f ) ? -1.0f : f ) * SGD_RADIANS_TO_DEGREES ; } // Fast code. Result is in the range 0..180: SGDfloat sgdAngleBetweenVec3 ( sgdVec3 v1, sgdVec3 v2 ); // All three have to be normalized. Slow code. Result is in the range 0..360: SGDfloat sgdAngleBetweenNormalizedVec3 (sgdVec3 first, sgdVec3 second, sgdVec3 normal); // Normal has to be normalized. Slow code. Result is in the range 0..360: SGDfloat sgdAngleBetweenVec3 ( sgdVec3 v1, sgdVec3 v2, sgdVec3 normal ); class sgdSphere { public: sgdVec3 center ; SGDfloat radius ; const SGDfloat *getCenter (void) const { return center ; } void setCenter ( const sgdVec3 c ) { sgdCopyVec3 ( center, c ) ; } void setCenter ( const SGDfloat x, const SGDfloat y, const SGDfloat z ) { sgdSetVec3 ( center, x, y, z ) ; } SGDfloat getRadius (void) const { return radius ; } void setRadius ( const SGDfloat r ) { radius = r ; } int isEmpty (void) const { return radius < SGD_ZERO ; } void empty (void) { radius = - SGD_ONE ; } void orthoXform ( const sgdMat4 m ) { sgdXformPnt3 ( center, center, m ) ; // radius *= sgdLengthVec3 ( m[0] ) ; } void extend ( const sgdSphere *s ) ; void extend ( const sgdBox *b ) ; void extend ( const sgdVec3 v ) ; int intersects ( const sgdSphere *s ) const { return sgdCompare3DSqdDist ( center, s->getCenter(), sgdSquare ( radius + s->getRadius() ) ) <= 0 ; } int intersects ( const sgdVec4 plane ) const { return sgdAbs ( sgdDistToPlaneVec3 ( plane, center ) ) <= radius ; } int intersects ( const sgdBox *b ) const ; } ; class sgdBox { public: sgdVec3 min ; sgdVec3 max ; const SGDfloat *getMin (void) const { return min ; } const SGDfloat *getMax (void) const { return max ; } void setMin ( const SGDfloat x, const SGDfloat y, const SGDfloat z ) { sgdSetVec3 ( min, x, y, z ) ; } void setMin ( const sgdVec3 src ) { sgdCopyVec3 ( min, src ) ; } void setMax ( const SGDfloat x, const SGDfloat y, const SGDfloat z ) { sgdSetVec3 ( max, x, y, z ) ; } void setMax ( const sgdVec3 src ) { sgdCopyVec3 ( max, src ) ; } int isEmpty(void) const { return ( min[0] > max[0] || min[1] > max[1] || min[2] > max[2] ) ; } void empty (void) { sgdSetVec3 ( min, SGD_MAX, SGD_MAX, SGD_MAX ) ; sgdSetVec3 ( max, -SGD_MAX, -SGD_MAX, -SGD_MAX ) ; } void extend ( const sgdSphere *s ) ; void extend ( const sgdBox *b ) ; void extend ( const sgdVec3 v ) ; int intersects ( const sgdSphere *s ) const { return s -> intersects ( this ) ; } int intersects ( const sgdBox *b ) const { return min[0] <= b->getMax()[0] && max[0] >= b->getMin()[0] && min[1] <= b->getMax()[1] && max[1] >= b->getMin()[1] && min[2] <= b->getMax()[2] && max[2] >= b->getMin()[2] ; } int intersects ( const sgdVec4 plane ) const ; } ; class sgdFrustum { /* Is the projection orthographic (or perspective)? */ int ortho ; /* The parameters for glFrustum/glOrtho */ SGDfloat left, right, bot, top, nnear, ffar ; /* The computed projection matrix for this frustum */ sgdMat4 mat ; /* The A,B,C,D terms of the plane equations of the clip planes */ /* A point (x,y,z) is inside the frustum iff Ax + By + Cz + D >= 0 for all planes */ sgdVec4 plane [ 6 ] ; /* These two are only valid for simple frusta */ SGDfloat hfov ; /* Horizontal Field of View -or- Orthographic Width */ SGDfloat vfov ; /* Vertical Field of View -or- Orthographic Height */ void update (void) ; int getOutcode ( const sgdVec4 src ) const ; public: sgdFrustum (void) { ortho = FALSE ; nnear = SGD_ONE ; ffar = 1000000.0f ; hfov = SGD_45 ; vfov = SGD_45 ; update () ; } void setFrustum ( const SGDfloat l, const SGDfloat r, const SGDfloat b, const SGDfloat t, const SGDfloat n, const SGDfloat f ) { ortho = FALSE ; left = l ; right = r ; bot = b ; top = t ; nnear = n ; ffar = f ; hfov = vfov = SGD_ZERO ; update () ; } void setOrtho ( const SGDfloat l, const SGDfloat r, const SGDfloat b, const SGDfloat t, const SGDfloat n, const SGDfloat f ) { ortho = TRUE ; left = l ; right = r ; bot = b ; top = t ; nnear = n ; ffar = f ; hfov = vfov = SGD_ZERO ; update () ; } void getMat4 ( sgdMat4 dst ) { sgdCopyMat4 ( dst, mat ) ; } SGDfloat getLeft (void) const { return left ; } SGDfloat getRight(void) const { return right ; } SGDfloat getBot (void) const { return bot ; } SGDfloat getTop (void) const { return top ; } SGDfloat getNear (void) const { return nnear ; } SGDfloat getFar (void) const { return ffar ; } const SGDfloat *getPlane ( int i ) const { return plane [ i ] ; } SGDfloat getHFOV (void) const { return hfov ; } SGDfloat getVFOV (void) const { return vfov ; } void getFOV ( SGDfloat *h, SGDfloat *v ) const { if ( h != (SGDfloat *) 0 ) *h = hfov ; if ( v != (SGDfloat *) 0 ) *v = vfov ; } void setFOV ( const SGDfloat h, const SGDfloat v ) { ortho = FALSE ; hfov = ( h <= 0 ) ? ( v * SGD_FOUR / SGD_THREE ) : h ; vfov = ( v <= 0 ) ? ( h * SGD_THREE / SGD_FOUR ) : v ; update () ; } void getOrtho ( SGDfloat *w, SGDfloat *h ) const { if ( w != (SGDfloat *) 0 ) *w = right - left ; if ( h != (SGDfloat *) 0 ) *h = top - bot ; } void setOrtho ( const SGDfloat w, const SGDfloat h ) { ortho = TRUE ; hfov = ( w <= 0 ) ? ( h * SGD_FOUR / SGD_THREE ) : w ; vfov = ( h <= 0 ) ? ( w * SGD_FOUR / SGD_THREE ) : h ; update () ; } void getNearFar ( SGDfloat *n, SGDfloat *f ) const { if ( n != (SGDfloat *) 0 ) *n = nnear ; if ( f != (SGDfloat *) 0 ) *f = ffar ; } void setNearFar ( const SGDfloat n, const SGDfloat f ) { nnear = n ; ffar = f ; update () ; } int isOrtho (void) const { return ortho ; } int contains ( const sgdVec3 p ) const ; int contains ( const sgdSphere *s ) const ; int contains ( const sgdBox *b ) const ; } ; /* Quaternion routines are Copyright (C) 1999 Kevin B. Thompson Modified by Sylvan W. Clebsch Largely rewritten by "Negative0" */ /* Quaternion structure w = real, (x, y, z) = vector CHANGED sqQuat to float array so that syntax matches vector and matrix routines */ inline void sgdMakeIdentQuat ( sgdQuat dst ) { sgdSetVec4 ( dst, SGD_ZERO, SGD_ZERO, SGD_ZERO, SGD_ONE ) ; } inline void sgdSetQuat ( sgdQuat dst, const SGDfloat w, const SGDfloat x, const SGDfloat y, const SGDfloat z ) { sgdSetVec4 ( dst, x, y, z, w ) ; } inline void sgdCopyQuat ( sgdQuat dst, const sgdQuat src ) { sgdCopyVec4 ( dst, src ) ; } /* Construct a unit quaternion (length==1) */ inline void sgdNormaliseQuat ( sgdQuat dst, const sgdQuat src ) { SGDfloat d = sgdScalarProductVec4 ( src, src ) ; d = (d > SGD_ZERO) ? (SGD_ONE / sgdSqrt ( d )) : SGD_ONE ; sgdScaleVec4 ( dst, src, d ) ; } inline void sgdNormaliseQuat ( sgdQuat dst ) { sgdNormaliseQuat ( dst, dst ) ; } inline void sgdInvertQuat ( sgdQuat dst, const sgdQuat src ) { SGDfloat d = sgdScalarProductVec4 ( src, src ) ; d = ( d == SGD_ZERO ) ? SGD_ONE : ( SGD_ONE / d ) ; dst[SG_W] = src[SG_W] * d ; dst[SG_X] = -src[SG_X] * d ; dst[SG_Y] = -src[SG_Y] * d ; dst[SG_Z] = -src[SG_Z] * d ; } inline void sgdInvertQuat ( sgdQuat dst ) { sgdInvertQuat ( dst, dst ) ; } /* Make an angle and axis of rotation from a Quaternion. */ void sgdQuatToAngleAxis ( SGDfloat *angle, sgdVec3 axis, const sgdQuat src ) ; void sgdQuatToAngleAxis ( SGDfloat *angle, SGDfloat *x, SGDfloat *y, SGDfloat *z, const sgdQuat src ) ; /* Make a quaternion from a given angle and axis of rotation */ void sgdAngleAxisToQuat ( sgdQuat dst, const SGDfloat angle, const sgdVec3 axis ) ; void sgdAngleAxisToQuat ( sgdQuat dst, const SGDfloat angle, const SGDfloat x, const SGDfloat y, const SGDfloat z ); /* Convert a matrix to/from a quat */ void sgdMatrixToQuat ( sgdQuat quat, const sgdMat4 m ) ; void sgdQuatToMatrix ( sgdMat4 m, const sgdQuat quat ) ; /* Convert a set of eulers to/from a quat */ void sgdQuatToEuler( sgdVec3 hpr, const sgdQuat quat ) ; void sgdEulerToQuat( sgdQuat quat, const sgdVec3 hpr ) ; inline void sgdEulerToQuat( sgdQuat dst, SGDfloat h, SGDfloat p, SGDfloat r ) { sgdVec3 hpr ; sgdSetVec3 ( hpr, h, p, r ) ; sgdEulerToQuat( dst, hpr ) ; } inline void sgdHPRToQuat ( sgdQuat dst, SGDfloat h, SGDfloat p, SGDfloat r ) { sgdVec3 hpr; hpr[0] = h * SGD_DEGREES_TO_RADIANS ; hpr[1] = p * SGD_DEGREES_TO_RADIANS ; hpr[2] = r * SGD_DEGREES_TO_RADIANS ; sgdEulerToQuat( dst, hpr ) ; } inline void sgdHPRToQuat ( sgdQuat dst, const sgdVec3 hpr ) { sgdVec3 tmp ; sgdScaleVec3 ( tmp, hpr, SGD_DEGREES_TO_RADIANS ) ; sgdEulerToQuat ( dst, tmp ) ; } /* Multiply quaternions together (concatenate rotations) */ void sgdMultQuat ( sgdQuat dst, const sgdQuat a, const sgdQuat b ) ; inline void sgdPostMultQuat ( sgdQuat dst, const sgdQuat q ) { sgdQuat r ; sgdCopyQuat ( r, dst ) ; sgdMultQuat ( dst, r, q ) ; } inline void sgdPreMultQuat ( sgdQuat dst, const sgdQuat q ) { sgdQuat r ; sgdCopyQuat ( r, dst ) ; sgdMultQuat ( dst, q, r ) ; } /* Rotate a quaternion by a given angle and axis (convenience function) */ inline void sgdRotQuat ( sgdQuat dst, const SGDfloat angle, const sgdVec3 axis ) { sgdQuat q ; sgdAngleAxisToQuat ( q, angle, axis ) ; sgdPostMultQuat ( dst, q ) ; sgdNormaliseQuat ( dst ) ; } inline void sgdRotQuat ( sgdQuat dst, const SGDfloat angle, const SGDfloat x, const SGDfloat y, const SGDfloat z ) { sgdVec3 axis ; sgdSetVec3 ( axis, x, y, z ) ; sgdRotQuat ( dst, angle, axis ) ; } /* SWC - Interpolate between to quaternions */ extern void sgdSlerpQuat ( sgdQuat dst, const sgdQuat from, const sgdQuat to, const SGDfloat t ) ; /* Conversions between sg and sgd types. */ inline void sgSetVec2 ( sgVec2 dst, sgdVec2 src ) { dst [ 0 ] = (SGfloat) src [ 0 ] ; dst [ 1 ] = (SGfloat) src [ 1 ] ; } inline void sgSetVec3 ( sgVec3 dst, sgdVec3 src ) { dst [ 0 ] = (SGfloat) src [ 0 ] ; dst [ 1 ] = (SGfloat) src [ 1 ] ; dst [ 2 ] = (SGfloat) src [ 2 ] ; } inline void sgSetVec4 ( sgVec4 dst, sgdVec4 src ) { dst [ 0 ] = (SGfloat) src [ 0 ] ; dst [ 1 ] = (SGfloat) src [ 1 ] ; dst [ 2 ] = (SGfloat) src [ 2 ] ; dst [ 3 ] = (SGfloat) src [ 3 ] ; } inline void sgdSetVec2 ( sgdVec2 dst, sgVec2 src ) { dst [ 0 ] = (SGDfloat) src [ 0 ] ; dst [ 1 ] = (SGDfloat) src [ 1 ] ; } inline void sgdSetVec3 ( sgdVec3 dst, sgVec3 src ) { dst [ 0 ] = (SGDfloat) src [ 0 ] ; dst [ 1 ] = (SGDfloat) src [ 1 ] ; dst [ 2 ] = (SGDfloat) src [ 2 ] ; } inline void sgdSetVec4 ( sgdVec4 dst, sgVec4 src ) { dst [ 0 ] = (SGDfloat) src [ 0 ] ; dst [ 1 ] = (SGDfloat) src [ 1 ] ; dst [ 2 ] = (SGDfloat) src [ 2 ] ; dst [ 3 ] = (SGDfloat) src [ 3 ] ; } inline void sgSetMat4 ( sgMat4 dst, sgdMat4 src ) { sgSetVec4 ( dst [ 0 ], src [ 0 ] ) ; sgSetVec4 ( dst [ 1 ], src [ 1 ] ) ; sgSetVec4 ( dst [ 2 ], src [ 2 ] ) ; sgSetVec4 ( dst [ 3 ], src [ 3 ] ) ; } inline void sgdSetMat4 ( sgdMat4 dst, sgMat4 src ) { sgdSetVec4 ( dst [ 0 ], src [ 0 ] ) ; sgdSetVec4 ( dst [ 1 ], src [ 1 ] ) ; sgdSetVec4 ( dst [ 2 ], src [ 2 ] ) ; sgdSetVec4 ( dst [ 3 ], src [ 3 ] ) ; } inline void sgSetCoord ( sgCoord *dst, sgdCoord *src ) { sgSetVec3 ( dst->xyz, src->xyz ) ; sgSetVec3 ( dst->hpr, src->hpr ) ; } inline void sgdSetCoord ( sgdCoord *dst, sgCoord *src ) { sgdSetVec3 ( dst->xyz, src->xyz ) ; sgdSetVec3 ( dst->hpr, src->hpr ) ; } inline void sgSetQuat ( sgQuat dst, sgdQuat src ) { sgSetVec4 ( dst, src ) ; } inline void sgdSetQuat ( sgdQuat dst, sgQuat src ) { sgdSetVec4 ( dst, src ) ; } /* Function to rotate a vector through a given quaternion using the formula * R = Q r Q-1 -- this gives the components of a ROTATED vector in a STATIONARY * coordinate system. We assume that Q is a unit quaternion. */ void sgRotateVecQuat ( sgVec3 vec, sgQuat q ) ; void sgdRotateVecQuat ( sgdVec3 vec, sgdQuat q ) ; /* Function to rotate a vector through a given quaternion using the formula * R = Q-1 r Q -- this gives the components of a STATIONARY vector in a ROTATED * coordinate system. We assume that Q is a unit quaternion. */ void sgRotateCoordQuat ( sgVec3 vec, sgQuat q ) ; void sgdRotateCoordQuat ( sgdVec3 vec, sgdQuat q ) ; sgFloat sgDistSquaredToLineLineSegment ( const sgLineSegment3 seg, const sgLine3 line ) ; sgdFloat sgdDistSquaredToLineLineSegment ( const sgdLineSegment3 seg, const sgdLine3 line ) ; /* Intersection testing. */ int sgdIsectPlanePlane ( sgdVec3 point, sgdVec3 dir, sgdVec4 plane1, sgdVec4 plane2 ) ; int sgdIsectInfLinePlane ( sgdVec3 dst, sgdVec3 l_org, sgdVec3 l_vec, sgdVec4 plane ) ; int sgdIsectInfLineInfLine ( sgdVec3 dst, sgdVec3 l1_org, sgdVec3 l1_vec, sgdVec3 l2_org, sgdVec3 l2_vec ) ; SGDfloat sgdIsectLinesegPlane ( sgdVec3 dst, sgdVec3 v1, sgdVec3 v2, sgdVec4 plane ) ; bool sgdPointInTriangle ( sgdVec3 point, sgdVec3 tri[3] ); /* TRIANGLE SOLVERS - These work for any triangle. SSS == Side-lengths for all three sides. SAS == Side-lengths for two sides - plus the angle between them. ASA == Two angles plus the length of the Side between them. Area == The area of the triangle. */ SGfloat sgTriangleSolver_ASAtoArea ( SGfloat angA, SGfloat lenB, SGfloat angC ); SGfloat sgTriangleSolver_SAStoArea ( SGfloat lenA, SGfloat angB, SGfloat lenC ); SGfloat sgTriangleSolver_SSStoArea ( SGfloat lenA, SGfloat lenB, SGfloat lenC ); SGfloat sgTriangleSolver_SAAtoArea ( SGfloat lenA, SGfloat angB, SGfloat angA ); SGfloat sgTriangleSolver_ASStoArea ( SGfloat angB, SGfloat lenA, SGfloat lenB, int angA_is_obtuse ); void sgTriangleSolver_SSStoAAA ( SGfloat lenA, SGfloat lenB, SGfloat lenC, SGfloat *angA, SGfloat *angB, SGfloat *angC ) ; void sgTriangleSolver_SAStoASA ( SGfloat lenA, SGfloat angB, SGfloat lenC, SGfloat *angA, SGfloat *lenB, SGfloat *angC ) ; void sgTriangleSolver_ASAtoSAS ( SGfloat angA, SGfloat lenB, SGfloat angC, SGfloat *lenA, SGfloat *angB, SGfloat *lenC ) ; void sgTriangleSolver_SAAtoASS ( SGfloat lenA, SGfloat angB, SGfloat angA, SGfloat *angC, SGfloat *lenB, SGfloat *lenC ) ; void sgTriangleSolver_ASStoSAA ( SGfloat angB, SGfloat lenA, SGfloat lenB, int angA_is_obtuse, SGfloat *lenC, SGfloat *angA, SGfloat *angC ) ; SGDfloat sgdTriangleSolver_ASAtoArea ( SGDfloat angA, SGDfloat lenB, SGDfloat angC ); SGDfloat sgdTriangleSolver_SAStoArea ( SGDfloat lenA, SGDfloat angB, SGDfloat lenC ); SGDfloat sgdTriangleSolver_SSStoArea ( SGDfloat lenA, SGDfloat lenB, SGDfloat lenC ); SGDfloat sgdTriangleSolver_SAAtoArea ( SGDfloat lenA, SGDfloat angB, SGDfloat angA ); SGDfloat sgdTriangleSolver_ASStoArea ( SGDfloat angB, SGDfloat lenA, SGDfloat lenB, int angA_is_obtuse ); void sgdTriangleSolver_SSStoAAA ( SGDfloat lenA, SGDfloat lenB, SGDfloat lenC, SGDfloat *angA, SGDfloat *angB, SGDfloat *angC ) ; void sgdTriangleSolver_SAStoASA ( SGDfloat lenA, SGDfloat angB, SGDfloat lenC, SGDfloat *angA, SGDfloat *lenB, SGDfloat *angC ) ; void sgdTriangleSolver_ASAtoSAS ( SGDfloat angA, SGDfloat lenB, SGDfloat angC, SGDfloat *lenA, SGDfloat *angB, SGDfloat *lenC ) ; void sgdTriangleSolver_SAAtoASS ( SGDfloat lenA, SGDfloat angB, SGDfloat angA, SGDfloat *angC, SGDfloat *lenB, SGDfloat *lenC ) ; void sgdTriangleSolver_ASStoSAA ( SGDfloat angB, SGDfloat lenA, SGDfloat lenB, int angA_is_obtuse, SGDfloat *lenC, SGDfloat *angA, SGDfloat *angC ) ; /* SPRING-MASS-DAMPER (with simple Euler integrator) */ extern sgVec3 _sgGravity ; inline void sgSetGravity ( float g ) { sgSetVec3 ( _sgGravity, 0.0f, 0.0f, -g ) ; } inline void sgSetGravityVec3 ( sgVec3 g ) { sgCopyVec3 ( _sgGravity, g ) ; } inline float *sgGetGravityVec3 () { return _sgGravity ; } inline float sgGetGravity () { return - _sgGravity[2] ; } class sgParticle { float ooMass ; /* One-over-mass */ sgVec3 pos ; sgVec3 vel ; sgVec3 force ; public: sgParticle ( float mass, sgVec3 _pos ) { setMass ( mass ) ; sgCopyVec3 ( pos, _pos ) ; sgZeroVec3 ( vel ) ; sgZeroVec3 ( force ) ; } sgParticle ( float mass, float x = 0.0f, float y = 0.0f, float z = 0.0f ) { setMass ( mass ) ; sgSetVec3 ( pos, x, y, z ) ; sgZeroVec3 ( vel ) ; sgZeroVec3 ( force ) ; } SGfloat *getPos () { return pos ; } SGfloat *getVel () { return vel ; } SGfloat *getForce () { return force ; } const SGfloat *getPos () const { return pos ; } const SGfloat *getVel () const { return vel ; } const SGfloat *getForce () const { return force ; } float getOneOverMass () { return ooMass ; } float getMass () { return 1.0f / ooMass ; } void setPos ( sgVec3 p ) { sgCopyVec3 ( pos , p ) ; } void setVel ( sgVec3 v ) { sgCopyVec3 ( vel , v ) ; } void setForce ( sgVec3 f ) { sgCopyVec3 ( force, f ) ; } void setPos ( float x, float y, float z ) { sgSetVec3 ( pos ,x,y,z ) ; } void setVel ( float x, float y, float z ) { sgSetVec3 ( vel ,x,y,z ) ; } void setForce ( float x, float y, float z ) { sgSetVec3 ( force,x,y,z ) ; } void setOneOverMass ( float oom ) { ooMass = oom ; } void setMass ( float m ) { assert ( m > 0.0f ) ; ooMass = 1.0f / m ; } void zeroForce () { sgZeroVec3 ( force ) ; } void addForce ( sgVec3 f ) { sgAddVec3 ( force, f ) ; } void subForce ( sgVec3 f ) { sgSubVec3 ( force, f ) ; } void gravityOnly () { sgScaleVec3 ( force, sgGetGravityVec3 (), ooMass ) ; } void bounce ( sgVec3 normal, float coefRestitution ) { sgVec3 vn, vt ; sgScaleVec3 ( vn, normal, sgScalarProductVec3 ( normal, vel ) ) ; sgSubVec3 ( vt, vel, vn ) ; sgAddScaledVec3 ( vel, vt, vn, -coefRestitution ) ; } void update ( float dt ) { sgAddScaledVec3 ( vel, force, dt * ooMass ) ; sgAddScaledVec3 ( pos, vel, dt ) ; } } ; class sgSpringDamper { sgParticle *p0 ; sgParticle *p1 ; float restLength ; float stiffness ; float damping ; public: sgSpringDamper () { p0 = p1 = NULL ; stiffness = 1.0f ; damping = 1.0f ; restLength = 1.0f ; } sgSpringDamper ( sgParticle *_p0, sgParticle *_p1, float _stiffness, float _damping, float _restLength = -1.0f ) { p0 = _p0 ; p1 = _p1 ; stiffness = _stiffness ; damping = _damping ; if ( _restLength < 0.0f ) { if ( p0 != NULL && p1 != NULL ) restLength = sgDistanceVec3 ( p0->getPos(), p1->getPos() ) ; else restLength = _restLength ; } else restLength = 1.0f ; } float getRestLength () { return restLength ; } float getStiffness () { return stiffness ; } float getDamping () { return damping ; } sgParticle *getParticle ( int which ) { return ( which == 0 ) ? p0 : p1 ; } void setParticles ( sgParticle *_p0, sgParticle *_p1 ) { p0 = _p0 ; p1 = _p1 ; } void setParticle ( int which, sgParticle *p ) { if ( which == 0 ) p0 = p ; else p1 = p ; } void setRestLength () { restLength = sgDistanceVec3 ( p0->getPos(), p1->getPos() ) ; } void setRestLength ( float l ) { restLength = l ; } void setStiffness ( float s ) { stiffness = s ; } void setDamping ( float d ) { damping = d ; } void update () { sgVec3 dP ; sgSubVec3 ( dP, p0->getPos(), p1->getPos() ) ; sgVec3 dV ; sgSubVec3 ( dV, p0->getVel(), p1->getVel() ) ; float L = sgLengthVec3 ( dP ) ; if ( L == 0.0f ) L = 0.0000001f ; float H = ( L - restLength ) * stiffness ; float D = sgScalarProductVec3 ( dV, dP ) * damping / L ; sgVec3 F ; sgScaleVec3 ( F, dP, - ( H + D ) / L ) ; p0 -> addForce ( F ) ; p1 -> subForce ( F ) ; } } ; /* It must be true that (x % NOISE_WRAP_INDEX) == (x & NOISE_MOD_MASK) so NOISE_WRAP_INDEX must be a power of two, and NOISE_MOD_MASK must be that power of 2 - 1. as indices are implemented, as unsigned chars, NOISE_WRAP_INDEX shoud be less than or equal to 256. There's no good reason to change it from 256, really. NOISE_LARGE_PWR2 is a large power of 2, we'll go for 4096, to add to negative numbers in order to make them positive */ #define SG_PERLIN_NOISE_WRAP_INDEX 256 #define SG_PERLIN_NOISE_MOD_MASK 255 #define SG_PERLIN_NOISE_LARGE_PWR2 4096 class sgPerlinNoise_1D { private: SGfloat gradTable [ SG_PERLIN_NOISE_WRAP_INDEX * 2 + 2 ] ; public: sgPerlinNoise_1D () ; void regenerate () ; SGfloat getNoise ( SGfloat x ) ; } ; class sgPerlinNoise_2D { private: sgVec2 gradTable [ SG_PERLIN_NOISE_WRAP_INDEX * 2 + 2 ] ; public: sgPerlinNoise_2D () ; void regenerate () ; SGfloat getNoise ( sgVec2 pos ) ; SGfloat getNoise ( SGfloat x, SGfloat y ) { sgVec2 p ; sgSetVec2 ( p, x, y ) ; return getNoise ( p ) ; } } ; class sgPerlinNoise_3D { private: sgVec3 gradTable [ SG_PERLIN_NOISE_WRAP_INDEX * 2 + 2 ] ; public: sgPerlinNoise_3D () ; void regenerate () ; SGfloat getNoise ( sgVec3 pos ) ; SGfloat getNoise ( SGfloat x, SGfloat y, SGfloat z ) { sgVec3 p ; sgSetVec3 ( p, x, y, z ) ; return getNoise ( p ) ; } } ; #endif plib-1.8.5/src/sg/sgIsect.cxx0000644000175000001440000002271710765364434012742 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: sgIsect.cxx 1851 2004-02-02 01:35:15Z sjbaker $ */ #include "sg.h" /* Determine the origin and unit direction vector of a line formed by the intersection of two planes. Returned point will lie on axis that was used to determine intersection. Norman Vine - nhv@yahoo.com */ int sgIsectPlanePlane ( sgVec3 point, sgVec3 dir, sgVec4 plane1, sgVec4 plane2 ) { /* Determine intersection line direction. */ sgVectorProductVec3 ( dir, plane1, plane2 ) ; SGfloat dnorm = sgLengthVec3 ( dir ) ; /* If planes are parallel then fail */ if ( dnorm < FLT_EPSILON ) { sgZeroVec3 ( point ) ; sgZeroVec3 ( dir ) ; return FALSE ; } /* Determine intersection point with the best suited coordinate plane. */ SGfloat abs ; SGfloat maxabs = sgAbs(dir[0]); int index = 0; if ((abs = sgAbs(dir[1])) > maxabs) { maxabs = abs ; index = 1; } if ((abs = sgAbs(dir[2])) > maxabs) { maxabs = abs ; index = 2; } switch ( index ) { case 0: sgSetVec3( point, SG_ZERO, (plane1[2] * plane2[3] - plane2[2] * plane1[3]) / dir[0], (plane2[1] * plane1[3] - plane1[1] * plane2[3]) / dir[0] ); break; case 1: sgSetVec3( point, (plane2[2] * plane1[3] - plane1[2] * plane2[3]) / dir[1], SG_ZERO, (plane1[0] * plane2[3] - plane2[0] * plane1[3]) / dir[1] ); break; case 2: sgSetVec3( point, (plane1[1] * plane2[3] - plane2[1] * plane1[3]) / dir[2], (plane2[0] * plane1[3] - plane1[0] * plane2[3]) / dir[2], SG_ZERO ); break; default: return FALSE ; /* Impossible */ } /* Normalize the direction */ sgScaleVec3( dir, SG_ONE / dnorm ); return TRUE; } /* Find the intersection of an infinite line with a plane (the line being defined by a point and direction). Norman Vine -- nhv@yahoo.com (with hacks by Steve) */ int sgIsectInfLinePlane( sgVec3 dst, sgVec3 l_org, sgVec3 l_vec, sgVec4 plane ) { SGfloat tmp = sgScalarProductVec3 ( l_vec, plane ) ; /* Is line parallel to plane? */ if ( sgAbs ( tmp ) < FLT_EPSILON ) return FALSE ; sgScaleVec3 ( dst, l_vec, -( sgScalarProductVec3 ( l_org, plane ) + plane[3] ) / tmp ) ; sgAddVec3 ( dst, l_org ) ; return TRUE ; } /* Given the origin and direction vector for two lines find their intersection - or the point closest to both lines if they don't intersect. Norman Vine -- nhv@yahoo.com */ int sgIsectInfLineInfLine( sgVec3 dst, sgVec3 l1_org, sgVec3 l1_vec, sgVec3 l2_org, sgVec3 l2_vec ) { sgVec3 vec_l1, vec_l2 ; sgNormalizeVec3 ( vec_l1, l1_vec ) ; sgNormalizeVec3 ( vec_l2, l2_vec ) ; /* Connecting line 'C' is perpendicular to both */ sgVec3 perp ; sgVectorProductVec3 ( perp, vec_l1, vec_l2 ) ; /* check for near-parallel lines */ SGfloat dist = sgScalarProductVec3 ( perp, perp ) ; if ( dist < FLT_EPSILON ) { /* degenerate: lines parallel - any point will do. */ sgCopyVec3 ( dst, l2_org ) ; return TRUE ; } /* Form a plane containing the line A and C, and another containing B and C */ sgScaleVec3 ( perp, SG_ONE / sgSqrt( dist ) ) ; sgVec4 pa ; sgVec4 pb ; sgVec3 tmp ; sgVectorProductVec3 ( tmp, perp, vec_l1 ) ; sgNormalizeVec3 ( tmp ); sgMakePlane ( pa, tmp, l1_org ) ; sgVectorProductVec3 ( tmp, perp, vec_l2 ) ; sgNormalizeVec3 ( tmp ); sgMakePlane ( pb, tmp, l2_org ) ; sgVec3 tmp_org, tmp_vec ; if ( ! sgIsectPlanePlane( tmp_org, tmp_vec, pa, pb ) ) { /* This *shouldn't* ever happen because we already tested for parallel lines - but with roundoff errors, it *might* in borderline cases so... */ sgCopyVec3 ( dst, l2_org ) ; return FALSE ; } if ( ! sgIsectInfLinePlane ( dst, l2_org, vec_l2, pa ) ) { sgCopyVec3 ( dst, l2_org ) ; return FALSE ; } return TRUE ; } /* Intersect the line segment from v1->v2 with the 'plane'. 'dst' is the intersection point and the return result is in the range 0..1 if the intersection lies between v1 and v2, >1 if beyond v2 and <0 if before v1. FLT_MAX is returned if the vector does not intersect the plane. Steve Baker */ SGfloat sgIsectLinesegPlane ( sgVec3 dst, sgVec3 v1, sgVec3 v2, sgVec4 plane ) { sgVec3 delta ; sgSubVec3 ( delta, v2, v1 ) ; SGfloat p = sgScalarProductVec3 ( plane, delta ) ; if ( p == SG_ZERO ) { dst [ 0 ] = dst [ 1 ] = dst [ 2 ] = FLT_MAX ; return FLT_MAX ; } float s = - ( sgScalarProductVec3 ( plane, v1 ) + plane[3] ) / p ; sgScaleVec3 ( dst, delta, s ) ; sgAddVec3 ( dst, dst, v1 ) ; return s ; } // return the sign of a value static inline const int SG_SIGN( const SGfloat x ) { return x < 0 ? -1 : 1; } // return the minimum of two values static inline SGfloat SG_MIN2( const SGfloat a, const SGfloat b ) { return a < b ? a : b ; } // return the minimum of three values static inline SGfloat SG_MIN3 ( const SGfloat a, const SGfloat b, const SGfloat c ) { return ( a < b ? SG_MIN2(a, c) : SG_MIN2(b, c) ); } // return the minimum and maximum of three values static void SG_MIN_MAX3 ( SGfloat &min, SGfloat &max, const SGfloat &a, const SGfloat &b, const SGfloat &c ) { if( a > b ) { if( a > c ) { max = a; min = SG_MIN2( b, c ); } else { max = c; min = SG_MIN2( a, b ); } } else { if( b > c ) { max = b; min = SG_MIN2( a, c ); } else { max = c; min = SG_MIN2( a, b ); } } } /* * Given a point and a triangle lying on the same plane * check to see if the point is inside the triangle */ bool sgPointInTriangle3 ( sgVec3 point, sgVec3 tri[3] ) { sgVec3 dif ; /* Early-out if point is not in bounding cube of triangle */ for( int i = 0 ; i < 3 ; i++ ) { SGfloat min, max ; SG_MIN_MAX3 ( min, max, tri[0][i], tri[1][i], tri[2][i] ) ; if( point[i] < min || point[i] > max ) return false ; dif[i] = max - min ; /* Calc size of bounding cube */ } /* Drop the smallest dimension so we only have to work in 2d. */ sgVec2 p, a, b, c ; if ( dif[0] <= dif[1] && dif[0] <= dif[2] ) { p[0] = point[1] ; p[1] = point[2] ; a[0] = tri[0][1] ; a[1] = tri[0][2] ; b[0] = tri[1][1] ; b[1] = tri[1][2] ; c[0] = tri[2][1] ; c[1] = tri[2][2] ; } else if ( dif[1] <= dif[0] && dif[1] <= dif[2] ) { p[0] = point[0] ; p[1] = point[2] ; a[0] = tri[0][0] ; a[1] = tri[0][2] ; b[0] = tri[1][0] ; b[1] = tri[1][2] ; c[0] = tri[2][0] ; c[1] = tri[2][2] ; } else { p[0] = point[0] ; p[1] = point[1] ; a[0] = tri[0][0] ; a[1] = tri[0][1] ; b[0] = tri[1][0] ; b[1] = tri[1][1] ; c[0] = tri[2][0] ; c[1] = tri[2][1] ; } /* Check if the intersection point is on the same side of each edge of the triangle as the remaining point. */ sgVec3 le ; /* Line Equation */ sgMake2DLine ( le, a, b ) ; if ( SG_SIGN ( le[0]*c[0] + le[1]*c[1] + le[2] ) != SG_SIGN ( le[0]*p[0] + le[1]*p[1] + le[2] ) ) return false ; sgMake2DLine ( le, b, c ) ; if ( SG_SIGN ( le[0]*a[0] + le[1]*a[1] + le[2] ) != SG_SIGN ( le[0]*p[0] + le[1]*p[1] + le[2] ) ) return false ; sgMake2DLine ( le, c, a ) ; if ( SG_SIGN ( le[0]*b[0] + le[1]*b[1] + le[2] ) != SG_SIGN ( le[0]*p[0] + le[1]*p[1] + le[2] ) ) return false ; return true ; } bool sgPointInTriangle2 ( sgVec2 point, sgVec2 tri[3] ) { SGfloat min, max ; /* Early-out if outside bounding box */ SG_MIN_MAX3 ( min, max, tri[0][0], tri[1][0], tri[2][0] ); if ( point[0] < min || point[0] > max ) return false ; SG_MIN_MAX3 ( min, max, tri[0][1], tri[1][1], tri[2][1] ); if ( point[1] < min || point[1] > max ) return false ; sgVec2 a, b, c ; sgCopyVec2 ( a, tri[0] ) ; sgCopyVec2 ( b, tri[1] ) ; sgCopyVec2 ( c, tri[2] ) ; /* Check if the intersection point is on the same side of each edge of the triangle as the remaining point. */ sgVec3 le ; /* Line Equation */ sgMake2DLine ( le, a, b ) ; if ( SG_SIGN ( le[0]*c[0] + le[1]*c[1] + le[2] ) != SG_SIGN ( le[0]*point[0] + le[1]*point[1] + le[2] ) ) return false ; sgMake2DLine ( le, b, c ) ; if ( SG_SIGN ( le[0]*a[0] + le[1]*a[1] + le[2] ) != SG_SIGN ( le[0]*point[0] + le[1]*point[1] + le[2] ) ) return false ; sgMake2DLine ( le, c, a ) ; if ( SG_SIGN ( le[0]*b[0] + le[1]*b[1] + le[2] ) != SG_SIGN ( le[0]*point[0] + le[1]*point[1] + le[2] ) ) return false ; return true ; } plib-1.8.5/src/sg/Makefile.am0000644000175000001440000000040410765364434012636 00000000000000if BUILD_SG lib_LIBRARIES = libplibsg.a include_HEADERS = sg.h libplibsg_a_SOURCES = sg.cxx sgd.cxx \ sgIsect.cxx sgdIsect.cxx \ sgPerlinNoise.cxx INCLUDES = -I$(top_srcdir)/src/util endif EXTRA_DIST = sg.dsp plib-1.8.5/src/sg/sgdIsect.cxx0000755000175000001440000002127110765364434013103 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: sgdIsect.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "sg.h" /* Determine the origin and unit direction vector of a line formed by the intersection of two planes. Returned point will lie on axis that was used to determine intersection. Norman Vine - nhv@yahoo.com */ int sgdIsectPlanePlane ( sgdVec3 point, sgdVec3 dir, sgdVec4 plane1, sgdVec4 plane2 ) { /* Determine intersection line direction. */ sgdVectorProductVec3 ( dir, plane1, plane2 ) ; SGDfloat dnorm = sgdLengthVec3 ( dir ) ; /* If planes are parallel then fail */ if ( dnorm < DBL_EPSILON ) { sgdZeroVec3 ( point ) ; sgdZeroVec3 ( dir ) ; return FALSE ; } /* Determine intersection point with the best suited coordinate plane. */ SGDfloat abs ; SGDfloat maxabs = sgdAbs(dir[0]); int index = 0; if ((abs = sgdAbs(dir[1])) > maxabs) { maxabs = abs ; index = 1; } if ((abs = sgdAbs(dir[2])) > maxabs) { maxabs = abs ; index = 2; } switch ( index ) { case 0: sgdSetVec3( point, SGD_ZERO, (plane1[2] * plane2[3] - plane2[2] * plane1[3]) / dir[0], (plane2[1] * plane1[3] - plane1[1] * plane2[3]) / dir[0] ); break; case 1: sgdSetVec3( point, (plane2[2] * plane1[3] - plane1[2] * plane2[3]) / dir[1], SGD_ZERO, (plane1[0] * plane2[3] - plane2[0] * plane1[3]) / dir[1] ); break; case 2: sgdSetVec3( point, (plane1[1] * plane2[3] - plane2[1] * plane1[3]) / dir[2], (plane2[0] * plane1[3] - plane1[0] * plane2[3]) / dir[2], SGD_ZERO ); break; default: return FALSE ; /* Impossible */ } /* Normalize the direction */ sgdScaleVec3( dir, SGD_ONE / dnorm ); return TRUE; } /* Find the intersection of an infinite line with a plane (the line being defined by a point and direction). Norman Vine -- nhv@yahoo.com (with hacks by Steve) */ int sgdIsectInfLinePlane( sgdVec3 dst, sgdVec3 l_org, sgdVec3 l_vec, sgdVec4 plane ) { SGDfloat tmp = sgdScalarProductVec3 ( l_vec, plane ) ; /* Is line parallel to plane? */ if ( sgdAbs ( tmp ) < DBL_EPSILON ) return FALSE ; sgdScaleVec3 ( dst, l_vec, -( sgdScalarProductVec3 ( l_org, plane ) + plane[3] ) / tmp ) ; sgdAddVec3 ( dst, l_org ) ; return TRUE ; } /* Given the origin and direction vector for two lines find their intersection - or the point closest to both lines if they don't intersect. Norman Vine -- nhv@yahoo.com */ int sgdIsectInfLineInfLine( sgdVec3 dst, sgdVec3 l1_org, sgdVec3 l1_vec, sgdVec3 l2_org, sgdVec3 l2_vec ) { sgdVec3 vec_l1, vec_l2 ; sgdNormalizeVec3 ( vec_l1, l1_vec ) ; sgdNormalizeVec3 ( vec_l2, l2_vec ) ; /* Connecting line 'C' is perpendicular to both */ sgdVec3 perp ; sgdVectorProductVec3 ( perp, vec_l1, vec_l2 ) ; /* check for near-parallel lines */ SGDfloat dist = sgdScalarProductVec3 ( perp, perp ) ; if ( dist < DBL_EPSILON ) { /* degenerate: lines parallel - any point will do. */ sgdCopyVec3 ( dst, l2_org ) ; return TRUE ; } /* Form a plane containing the line A and C, and another containing B and C */ sgdScaleVec3 ( perp, SGD_ONE / sgdSqrt( dist ) ) ; sgdVec4 pa ; sgdVec4 pb ; sgdVec3 tmp ; sgdVectorProductVec3 ( tmp, perp, vec_l1 ) ; sgdNormalizeVec3 ( tmp ); sgdMakePlane ( pa, tmp, l1_org ) ; sgdVectorProductVec3 ( tmp, perp, vec_l2 ) ; sgdNormalizeVec3 ( tmp ); sgdMakePlane ( pb, tmp, l2_org ) ; sgdVec3 tmp_org, tmp_vec ; if ( ! sgdIsectPlanePlane( tmp_org, tmp_vec, pa, pb ) ) { /* This *shouldn't* ever happen because we already tested for parallel lines - but with roundoff errors, it *might* in borderline cases so... */ sgdCopyVec3 ( dst, l2_org ) ; return FALSE ; } if ( ! sgdIsectInfLinePlane ( dst, l2_org, vec_l2, pa ) ) { sgdCopyVec3 ( dst, l2_org ) ; return FALSE ; } return TRUE ; } /* Intersect the line segment from v1->v2 with the 'plane'. 'dst' is the intersection point and the return result is in the range 0..1 if the intersection lies between v1 and v2, >1 if beyond v2 and <0 if before v1. FLT_MAX is returned if the vector does not intersect the plane. Steve Baker */ SGDfloat sgdIsectLinesegPlane ( sgdVec3 dst, sgdVec3 v1, sgdVec3 v2, sgdVec4 plane ) { sgdVec3 delta ; sgdSubVec3 ( delta, v2, v1 ) ; SGDfloat p = sgdScalarProductVec3 ( plane, delta ) ; if ( p == SGD_ZERO ) { dst [ 0 ] = dst [ 1 ] = dst [ 2 ] = FLT_MAX ; return FLT_MAX ; } float s = (float) (- ( sgdScalarProductVec3 ( plane, v1 ) + plane[3] ) / p) ; sgdScaleVec3 ( dst, delta, s ) ; sgdAddVec3 ( dst, dst, v1 ) ; return s ; } // return the sign of a value static inline const int SGD_SIGN(const SGDfloat x) { return x < 0 ? -1 : 1; } // return the minimum of two values static inline SGDfloat SGD_MIN2(const SGDfloat a, const SGDfloat b) { return a < b ? a : b; } // return the minimum of three values static inline SGDfloat SGD_MIN3( const SGDfloat a, const SGDfloat b, const SGDfloat c) { return (a < b ? SGD_MIN2 (a, c) : SGD_MIN2 (b, c)); } // return the minimum and maximum of three values static void SGD_MIN_MAX3 ( SGDfloat &min, SGDfloat &max, const SGDfloat &a, const SGDfloat &b, const SGDfloat &c) { if( a > b ) { if( a > c ) { max = a; min = SGD_MIN2( b, c ); } else { max = c; min = SGD_MIN2( a, b ); } } else { if( b > c ) { max = b; min = SGD_MIN2( a, c ); } else { max = c; min = SGD_MIN2( a, b ); } } } /* * Given a point and a triangle lying on the same plane * check to see if the point is inside the triangle */ bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] ) { sgdVec3 dif; int i; for( i=0; i<3; i++ ) { SGDfloat min, max; SGD_MIN_MAX3 ( min, max, tri[0][i], tri[1][i], tri[2][i] ); // punt if outside bouding cube if( (point[i] < min) || (point[i] > max) ) return false; dif[i] = max - min; } // drop the smallest dimension so we only have to work in 2d. SGDfloat min_dim = SGD_MIN3 (dif[0], dif[1], dif[2]); SGDfloat x1, y1, x2, y2, x3, y3, rx, ry; if ( fabs(min_dim-dif[0]) <= DBL_EPSILON ) { // x is the smallest dimension x1 = point[1]; y1 = point[2]; x2 = tri[0][1]; y2 = tri[0][2]; x3 = tri[1][1]; y3 = tri[1][2]; rx = tri[2][1]; ry = tri[2][2]; } else if ( fabs(min_dim-dif[1]) <= DBL_EPSILON ) { // y is the smallest dimension x1 = point[0]; y1 = point[2]; x2 = tri[0][0]; y2 = tri[0][2]; x3 = tri[1][0]; y3 = tri[1][2]; rx = tri[2][0]; ry = tri[2][2]; } else if ( fabs(min_dim-dif[2]) <= DBL_EPSILON ) { // z is the smallest dimension x1 = point[0]; y1 = point[1]; x2 = tri[0][0]; y2 = tri[0][1]; x3 = tri[1][0]; y3 = tri[1][1]; rx = tri[2][0]; ry = tri[2][1]; } else { // all dimensions are really small so lets call it close // enough and return a successful match return true; } // check if intersection point is on the same side of p1 <-> p2 as p3 SGDfloat tmp = (y2 - y3) / (x2 - x3); int side1 = SGD_SIGN (tmp * (rx - x3) + y3 - ry); int side2 = SGD_SIGN (tmp * (x1 - x3) + y3 - y1); if ( side1 != side2 ) { // printf("failed side 1 check\n"); return false; } // check if intersection point is on correct side of p2 <-> p3 as p1 tmp = (y3 - ry) / (x3 - rx); side1 = SGD_SIGN (tmp * (x2 - rx) + ry - y2); side2 = SGD_SIGN (tmp * (x1 - rx) + ry - y1); if ( side1 != side2 ) { // printf("failed side 2 check\n"); return false; } // check if intersection point is on correct side of p1 <-> p3 as p2 tmp = (y2 - ry) / (x2 - rx); side1 = SGD_SIGN (tmp * (x3 - rx) + ry - y3); side2 = SGD_SIGN (tmp * (x1 - rx) + ry - y1); if ( side1 != side2 ) { // printf("failed side 3 check\n"); return false; } return true; } plib-1.8.5/src/sg/sgd.cxx0000644000175000001440000015573410765364434012124 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: sgd.cxx 1944 2004-08-05 01:07:09Z puggles $ */ #include "sg.h" sgdVec3 _sgdGravity = { 0.0f, 0.0f, -9.8f } ; void sgdVectorProductVec3 ( sgdVec3 dst, const sgdVec3 a, const sgdVec3 b ) { dst[0] = a[1] * b[2] - a[2] * b[1] ; dst[1] = a[2] * b[0] - a[0] * b[2] ; dst[2] = a[0] * b[1] - a[1] * b[0] ; } inline SGDfloat _sgdClampToUnity ( const SGDfloat x ) { if ( x > SGD_ONE ) return SGD_ONE ; if ( x < -SGD_ONE ) return -SGD_ONE ; return x ; } int sgdCompare3DSqdDist( const sgdVec3 v1, const sgdVec3 v2, const SGDfloat sqd_dist ) { sgdVec3 tmp ; sgdSubVec3 ( tmp, v2, v1 ) ; SGDfloat sqdist = tmp[0] * tmp[0] + tmp[1] * tmp[1] + tmp[2] * tmp[2] ; if ( sqdist > sqd_dist ) return 1 ; if ( sqdist < sqd_dist ) return -1 ; return 0 ; } void sgdMakeRotMat4( sgdMat4 mat, const SGDfloat angle, const sgdVec3 axis ) { sgdVec3 ax ; sgdNormalizeVec3 ( ax, axis ) ; SGDfloat temp_angle = angle * SGD_DEGREES_TO_RADIANS ; SGDfloat s = sin ( temp_angle ) ; SGDfloat c = cos ( temp_angle ) ; SGDfloat t = SGD_ONE - c ; mat[0][0] = t * ax[0] * ax[0] + c ; mat[0][1] = t * ax[0] * ax[1] + s * ax[2] ; mat[0][2] = t * ax[0] * ax[2] - s * ax[1] ; mat[0][3] = SGD_ZERO ; mat[1][0] = t * ax[1] * ax[0] - s * ax[2] ; mat[1][1] = t * ax[1] * ax[1] + c ; mat[1][2] = t * ax[1] * ax[2] + s * ax[0] ; mat[1][3] = SGD_ZERO ; mat[2][0] = t * ax[2] * ax[0] + s * ax[1] ; mat[2][1] = t * ax[2] * ax[1] - s * ax[0] ; mat[2][2] = t * ax[2] * ax[2] + c ; mat[2][3] = SGD_ZERO ; mat[3][0] = SGD_ZERO ; mat[3][1] = SGD_ZERO ; mat[3][2] = SGD_ZERO ; mat[3][3] = SGD_ONE ; } void sgdMakePickMatrix( sgdMat4 mat, sgdFloat x, sgdFloat y, sgdFloat width, sgdFloat height, sgdVec4 viewport ) { sgdFloat sx = viewport[2] / width ; sgdFloat sy = viewport[3] / height ; sgdFloat tx = ( viewport[2] + SGD_TWO * (viewport[0] - x) ) / width ; sgdFloat ty = ( viewport[3] + SGD_TWO * (viewport[1] - y) ) / height ; mat[0][0] = sx ; mat[0][1] = SGD_ZERO ; mat[0][2] = SGD_ZERO ; mat[0][3] = SGD_ZERO ; mat[1][0] = SGD_ZERO ; mat[1][1] = sy ; mat[1][2] = SGD_ZERO ; mat[1][3] = SGD_ZERO ; mat[2][0] = SGD_ZERO ; mat[2][1] = SGD_ZERO ; mat[2][2] = SGD_ONE ; mat[2][3] = SGD_ZERO ; mat[3][0] = tx ; mat[3][1] = ty ; mat[3][2] = SGD_ZERO ; mat[3][3] = SGD_ONE ; } void sgdMakeLookAtMat4 ( sgdMat4 dst, const sgdVec3 eye, const sgdVec3 center, const sgdVec3 up ) { // Caveats: // 1) In order to compute the line of sight, the eye point must not be equal // to the center point. // 2) The up vector must not be parallel to the line of sight from the eye // to the center point. /* Compute the direction vectors */ sgdVec3 x,y,z; /* Y vector = center - eye */ sgdSubVec3 ( y, center, eye ) ; /* Z vector = up */ sgdCopyVec3 ( z, up ) ; /* X vector = Y cross Z */ sgdVectorProductVec3 ( x, y, z ) ; /* Recompute Z = X cross Y */ sgdVectorProductVec3 ( z, x, y ) ; /* Normalize everything */ sgdNormaliseVec3 ( x ) ; sgdNormaliseVec3 ( y ) ; sgdNormaliseVec3 ( z ) ; /* Build the matrix */ sgdSetVec4 ( dst[0], x[0], x[1], x[2], SGD_ZERO ) ; sgdSetVec4 ( dst[1], y[0], y[1], y[2], SGD_ZERO ) ; sgdSetVec4 ( dst[2], z[0], z[1], z[2], SGD_ZERO ) ; sgdSetVec4 ( dst[3], eye[0], eye[1], eye[2], SGD_ONE ) ; } // -dw- inconsistent linkage! sgdFloat sgdTriArea( sgdVec3 p0, sgdVec3 p1, sgdVec3 p2 ) { /* From comp.graph.algorithms FAQ 2A(P) = abs(N.(sum_{i=0}^{n-1}(v_i x v_{i+1}))) This is an optimized version for a triangle but easily extended for planar polygon's with more sides by passing in the number of sides and the vv array sgdTriArea( int nsides, float **vv ) and changing the normal calculation and the for loop appropriately sgdMakeNormal( norm, vv[0], vv[1], vv[2] ) for( int i=0; i 0.99999 ) deltaAngle = SGD_PI*0.5; else deltaAngle = (SGDfloat)asin((double)myNorm); // deltaAngle is in the range -SGD_PI*0.5 to +SGD_PI*0.5 here // However, the correct result could also be // deltaAngleS := pi - deltaAngle // Please note that: // cos(deltaAngleS)=cos(pi-deltaAngle)=-cos(deltaAngle) // So, the question is whether + or - cos(deltaAngle) // is sgdScalarProductVec3(first, second) if ( deltaAngle < 0 ) deltaAngle = deltaAngle + 2*SGD_PI; // unnessecary? SProduct = sgdScalarProductVec3(first, second); myCos = (SGDfloat) cos(deltaAngle); abs1 = SProduct - myCos; abs2 = SProduct + myCos; if ( abs1 < 0 ) abs1 = -abs1 ; if ( abs2 < 0 ) abs2 = -abs2 ; assert( (abs1 < 0.1) || (abs2 < 0.1) ) ; if ( abs2 < abs1 ) { // deltaAngleS is the correct result if ( deltaAngle <= SGD_PI ) deltaAngle = SGD_PI - deltaAngle ; else deltaAngle = 3*SGD_PI - deltaAngle ; } assert ( deltaAngle >= 0.0 ) ; assert ( deltaAngle <= 2.0*SGD_PI ) ; return deltaAngle * SGD_RADIANS_TO_DEGREES ; } SGDfloat sgdAngleBetweenVec3 ( sgdVec3 v1, sgdVec3 v2, sgdVec3 normal ) { // nornmal has to be normalized. sgdVec3 nv1, nv2 ; sgdNormalizeVec3 ( nv1, v1 ) ; sgdNormalizeVec3 ( nv2, v2 ) ; return sgdAngleBetweenNormalizedVec3 ( nv1, nv2, normal ) ; } /*********************\ * sgdBox routines * \*********************/ void sgdBox::extend ( const sgdVec3 v ) { if ( isEmpty () ) { sgdCopyVec3 ( min, v ) ; sgdCopyVec3 ( max, v ) ; } else { if ( v[0] < min[0] ) min[0] = v[0] ; if ( v[1] < min[1] ) min[1] = v[1] ; if ( v[2] < min[2] ) min[2] = v[2] ; if ( v[0] > max[0] ) max[0] = v[0] ; if ( v[1] > max[1] ) max[1] = v[1] ; if ( v[2] > max[2] ) max[2] = v[2] ; } } void sgdBox::extend ( const sgdBox *b ) { if ( b -> isEmpty () ) return ; if ( isEmpty () ) { sgdCopyVec3 ( min, b->getMin() ) ; sgdCopyVec3 ( max, b->getMax() ) ; } else { extend ( b->getMin() ) ; extend ( b->getMax() ) ; } } void sgdBox::extend ( const sgdSphere *s ) { if ( s -> isEmpty () ) return ; /* In essence, this extends around a box around the sphere - which is still a perfect solution because both boxes are axially aligned. */ sgdVec3 x ; sgdSetVec3 ( x, s->getCenter()[0]+s->getRadius(), s->getCenter()[1]+s->getRadius(), s->getCenter()[2]+s->getRadius() ) ; extend ( x ) ; sgdSetVec3 ( x, s->getCenter()[0]-s->getRadius(), s->getCenter()[1]-s->getRadius(), s->getCenter()[2]-s->getRadius() ) ; extend ( x ) ; } int sgdBox::intersects ( const sgdVec4 plane ) const { /* Save multiplies by not redoing Ax+By+Cz+D for each point. */ SGDfloat Ax_min = plane[0] * min[0] ; SGDfloat By_min = plane[1] * min[1] ; SGDfloat Cz_min_plus_D = plane[2] * min[2] + plane[3] ; SGDfloat Ax_max = plane[0] * max[0] ; SGDfloat By_max = plane[1] * max[1] ; SGDfloat Cz_max_plus_D = plane[2] * max[2] + plane[3] ; /* Count the number of vertices on the positive side of the plane. */ int count = ( Ax_min + By_min + Cz_min_plus_D > SGD_ZERO ) + ( Ax_min + By_min + Cz_max_plus_D > SGD_ZERO ) + ( Ax_min + By_max + Cz_min_plus_D > SGD_ZERO ) + ( Ax_min + By_max + Cz_max_plus_D > SGD_ZERO ) + ( Ax_max + By_min + Cz_min_plus_D > SGD_ZERO ) + ( Ax_max + By_min + Cz_max_plus_D > SGD_ZERO ) + ( Ax_max + By_max + Cz_min_plus_D > SGD_ZERO ) + ( Ax_max + By_max + Cz_max_plus_D > SGD_ZERO ) ; /* The plane intersects the box unless all 8 are positive or none of them are positive. */ return count != 0 && count != 8 ; } /**********************\ * sgdSphere routines * \**********************/ void sgdSphere::extend ( const sgdVec3 v ) { if ( isEmpty () ) { sgdCopyVec3 ( center, v ) ; radius = SGD_ZERO ; return ; } SGDfloat d = sgdDistanceVec3 ( center, v ) ; if ( d <= radius ) /* Point is already inside sphere */ return ; SGDfloat new_radius = (radius + d) / SGD_TWO ; /* Grow radius */ SGDfloat ratio = (new_radius - radius) / d ; center[0] += (v[0]-center[0]) * ratio ; /* Move center */ center[1] += (v[1]-center[1]) * ratio ; center[2] += (v[2]-center[2]) * ratio ; radius = new_radius ; } void sgdSphere::extend ( const sgdBox *b ) { if ( b -> isEmpty () ) return ; if ( isEmpty() ) { sgdAddVec3 ( center, b->getMin(), b->getMax() ) ; sgdScaleVec3 ( center, SGD_HALF ) ; radius = sgdDistanceVec3 ( center, b->getMax() ) ; return ; } /* I can't think of a faster way to get an utterly minimal sphere. The tighter algorithm:- enclose each of eight vertices of the box in turn - it looks like being pretty costly. [8 sqrt()'s] The looser algorithm:- enclose the box with an empty sphere and then do a sphere-extend-sphere. This algorithm does well for close-to-cube boxes, but makes very poor spheres for long, thin boxes. [2 sqrt()'s] */ #ifdef DONT_REALLY_NEED_A_TIGHT_SPHERE_EXTEND_BOX /* LOOSER/FASTER sphere-around-sphere-around-box */ sgdSphere s ; s.empty () ; s.enclose ( b ) ; /* Fast because s is empty */ enclose ( s ) ; #else /* TIGHTER/EXPENSIVE sphere-around-eight-points */ sgdVec3 x ; extend ( b->getMin() ) ; sgdSetVec3 ( x, b->getMin()[0],b->getMin()[1],b->getMax()[2] ) ; extend ( x ) ; sgdSetVec3 ( x, b->getMin()[0],b->getMax()[1],b->getMin()[2] ) ; extend ( x ) ; sgdSetVec3 ( x, b->getMin()[0],b->getMax()[1],b->getMax()[2] ) ; extend ( x ) ; sgdSetVec3 ( x, b->getMax()[0],b->getMin()[1],b->getMin()[2] ) ; extend ( x ) ; sgdSetVec3 ( x, b->getMax()[0],b->getMin()[1],b->getMax()[2] ) ; extend ( x ) ; sgdSetVec3 ( x, b->getMax()[0],b->getMax()[1],b->getMin()[2] ) ; extend ( x ) ; extend ( b->getMax() ) ; #endif } void sgdSphere::extend ( const sgdSphere *s ) { if ( s->isEmpty () ) return ; if ( isEmpty () ) { sgdCopyVec3 ( center, s->getCenter() ) ; radius = s->getRadius() ; return ; } /* d == The distance between the sphere centers */ SGDfloat d = sgdDistanceVec3 ( center, s->getCenter() ) ; if ( d + s->getRadius() <= radius ) /* New sphere is already inside this one */ return ; if ( d + radius <= s->getRadius() ) /* New sphere completely contains this one */ { sgdCopyVec3 ( center, s->getCenter() ) ; radius = s->getRadius() ; return ; } /* Build a new sphere that completely contains the other two: The center point lies halfway along the line between the furthest points on the edges of the two spheres. Computing those two points is ugly - so we'll use similar triangles */ SGDfloat new_radius = (radius + d + s->getRadius() ) / SGD_TWO ; SGDfloat ratio = ( new_radius - radius ) / d ; center[0] += ( s->getCenter()[0] - center[0] ) * ratio ; center[1] += ( s->getCenter()[1] - center[1] ) * ratio ; center[2] += ( s->getCenter()[2] - center[2] ) * ratio ; radius = new_radius ; } int sgdSphere::intersects ( const sgdBox *b ) const { sgdVec3 closest ; if ( b->getMin()[0] > center[0] ) closest[0] = b->getMin()[0] ; else if ( b->getMax()[0] < center[0] ) closest[0] = b->getMax()[0] ; else closest[0] = center[0] ; if ( b->getMin()[1] > center[1] ) closest[1] = b->getMin()[1] ; else if ( b->getMax()[1] < center[1] ) closest[1] = b->getMax()[1] ; else closest[1] = center[1] ; if ( b->getMin()[2] > center[2] ) closest[2] = b->getMin()[2] ; else if ( b->getMax()[2] < center[2] ) closest[2] = b->getMax()[2] ; else closest[2] = center[2] ; return sgdCompare3DSqdDist ( closest, center, sgdSquare ( radius ) ) <= 0 ; } /************************\ * sgdFrustum routines * \************************/ void sgdFrustum::update () { if ( fabs ( ffar - nnear ) < 0.1 ) { ulSetError ( UL_WARNING, "sgdFrustum: Can't support depth of view <0.1 units."); return ; } if ( hfov != SGD_ZERO && vfov != SGD_ZERO ) { if ( fabs ( hfov ) < 0.1 || fabs ( vfov ) < 0.1 ) { ulSetError ( UL_WARNING, ortho ? "sgFrustum: Can't support width or height <0.1 units." : "sgFrustum: Can't support fields of view narrower than 0.1 degrees." ) ; return ; } if ( ortho ) { right = SGD_HALF * hfov ; top = SGD_HALF * vfov ; } else { right = nnear * tan ( hfov * SGD_DEGREES_TO_RADIANS / SGD_TWO ) ; top = nnear * tan ( vfov * SGD_DEGREES_TO_RADIANS / SGD_TWO ) ; } left = -right ; bot = -top ; } /* Compute the projection matrix */ SGDfloat width = right - left ; SGDfloat height = top - bot ; SGDfloat depth = ffar - nnear ; if ( ortho ) { /* orthographic */ mat[0][0] = SGD_TWO / width ; mat[0][1] = SGD_ZERO ; mat[0][2] = SGD_ZERO ; mat[0][3] = SGD_ZERO ; mat[1][0] = SGD_ZERO ; mat[1][1] = SGD_TWO / height ; mat[1][2] = SGD_ZERO ; mat[1][3] = SGD_ZERO ; mat[2][0] = SGD_ZERO ; mat[2][1] = SGD_ZERO ; mat[2][2] = -SGD_TWO / depth ; mat[2][3] = SGD_ZERO ; mat[3][0] = -( left + right ) / width ; mat[3][1] = -( bot + top ) / height ; mat[3][2] = -( nnear + ffar ) / depth ; mat[3][3] = SGD_ONE ; } else { /* perspective */ mat[0][0] = SGD_TWO * nnear / width ; mat[0][1] = SGD_ZERO ; mat[0][2] = SGD_ZERO ; mat[0][3] = SGD_ZERO ; mat[1][0] = SGD_ZERO ; mat[1][1] = SGD_TWO * nnear / height ; mat[1][2] = SGD_ZERO ; mat[1][3] = SGD_ZERO ; mat[2][0] = ( right + left ) / width ; mat[2][1] = ( top + bot ) / height ; mat[2][2] = -( ffar + nnear ) / depth ; mat[2][3] = -SGD_ONE ; mat[3][0] = SGD_ZERO ; mat[3][1] = SGD_ZERO ; mat[3][2] = -SGD_TWO * nnear * ffar / depth ; mat[3][3] = SGD_ZERO ; } /* * The clip planes are derived from the projection matrix. * * After projection (in clip coordinates), the clip planes are simply: * * left: ( 1, 0, 0, 1 ) * right: ( -1, 0, 0, 1 ) * bottom: ( 0, 1, 0, 1 ) * top: ( 0, -1, 0, 1 ) * near: ( 0, 0, 1, 1 ) * far: ( 0, 0, -1, 1 ) * * These can easily be transformed *backwards* by * multiplying by the transposed projection matrix, i.e: * * ( A ) ( A') * ( B ) = mat^T ( B') * ( C ) ( C') * ( D ) ( D') * * where (A',B',C',D') represents a plane in clip coordinates, * and (A,B,C,D) is the same plane expressed in eye coordinates. */ sgdSetVec4( plane[ SG_LEFT_PLANE ], SGD_ONE, SGD_ZERO, SGD_ZERO, SGD_ONE ); sgdSetVec4( plane[ SG_RIGHT_PLANE ], -SGD_ONE, SGD_ZERO, SGD_ZERO, SGD_ONE ); sgdSetVec4( plane[ SG_BOT_PLANE ], SGD_ZERO, SGD_ONE, SGD_ZERO, SGD_ONE ); sgdSetVec4( plane[ SG_TOP_PLANE ], SGD_ZERO, -SGD_ONE, SGD_ZERO, SGD_ONE ); sgdSetVec4( plane[ SG_NEAR_PLANE ], SGD_ZERO, SGD_ZERO, SGD_ONE, SGD_ONE ); sgdSetVec4( plane[ SG_FAR_PLANE ], SGD_ZERO, SGD_ZERO, -SGD_ONE, SGD_ONE ); for ( int i = 0 ; i < 6 ; i++ ) { sgdVec4 tmp ; for ( int j = 0 ; j < 4 ; j++ ) tmp[j] = sgdScalarProductVec4 ( plane[i], mat[j] ) ; sgdScaleVec4 ( plane[i], tmp, SGD_ONE / sgdLengthVec3 ( tmp ) ) ; } } #define OC_LEFT_SHIFT 0 #define OC_RIGHT_SHIFT 1 #define OC_TOP_SHIFT 2 #define OC_BOT_SHIFT 3 #define OC_NEAR_SHIFT 4 #define OC_FAR_SHIFT 5 #define OC_ALL_ON_SCREEN 0x3F #define OC_OFF_TRF ((1<= -tmp[3] ) << OC_LEFT_SHIFT ) | (( tmp[1] <= tmp[3] ) << OC_TOP_SHIFT ) | (( tmp[1] >= -tmp[3] ) << OC_BOT_SHIFT ) | (( tmp[2] <= tmp[3] ) << OC_FAR_SHIFT ) | (( tmp[2] >= -tmp[3] ) << OC_NEAR_SHIFT ) ; } int sgdFrustum::contains ( const sgdVec3 pt ) const { return getOutcode ( pt ) == OC_ALL_ON_SCREEN ; } int sgdFrustum::contains ( const sgdSphere *s ) const { const SGDfloat *center = s->getCenter() ; const SGDfloat radius = s->getRadius() ; /* Lop off half the database (roughly) with a quick near-plane test - and lop off a lot more with a quick far-plane test */ if ( -center[2] + radius < nnear || -center[2] - radius > ffar ) return SG_OUTSIDE ; /* OK, so the sphere lies between near and far. Measure the distance of the center point from the four sides of the frustum, if it's outside by more than the radius then it's history. It's tempting to do a quick test to see if the center point is onscreen using sgdFrustumContainsPt - but that takes a matrix transform which is 16 multiplies and 12 adds - versus this test which does the whole task using only 12 multiplies and 8 adds. */ /* A few operations are saved by observing that certain values in the plane equations are zero or one. These are specific to orthographic and perspective projections respectively. */ SGDfloat sp1, sp2, sp3, sp4 ; if ( ortho ) { /* left: ( 1, 0, 0, x ) right: ( -1, 0, 0, x ) bottom: ( 0, 1, 0, x ) top: ( 0, -1, 0, x ) */ sp1 = plane[ SG_LEFT_PLANE ][3] + center[0] ; sp2 = plane[ SG_RIGHT_PLANE ][3] - center[0] ; sp3 = plane[ SG_BOT_PLANE ][3] + center[1] ; sp4 = plane[ SG_TOP_PLANE ][3] - center[1] ; } else { /* left: ( x, 0, x, 0 ) right: ( x, 0, x, 0 ) bottom: ( 0, x, x, 0 ) top: ( 0, x, x, 0 ) */ sp1 = plane[ SG_LEFT_PLANE ][0] * center[0] + plane[ SG_LEFT_PLANE ][2] * center[2] ; sp2 = plane[ SG_RIGHT_PLANE ][0] * center[0] + plane[ SG_RIGHT_PLANE ][2] * center[2] ; sp3 = plane[ SG_BOT_PLANE ][1] * center[1] + plane[ SG_BOT_PLANE ][2] * center[2] ; sp4 = plane[ SG_TOP_PLANE ][1] * center[1] + plane[ SG_TOP_PLANE ][2] * center[2] ; } /* Note: in the general case, we would have to do: sp1 = sgdScalarProductVec3 ( left_plane, center ) + left_plane[3] ; sp2 = sgdScalarProductVec3 ( right_plane, center ) + right_plane[3] ; ... sp6 = sgdScalarProductVec3 ( far_plane, center ) + far_plane[3] ; */ if ( -sp1 > radius || -sp2 > radius || -sp3 > radius || -sp4 > radius ) return SG_OUTSIDE ; /* If it's inside by more than the radius then it's *completely* inside and we can save time elsewhere if we know that for sure. */ if ( sp1 >= radius && sp2 >= radius && sp3 >= radius && sp4 >= radius && -center[2] - radius >= nnear && -center[2] + radius <= ffar ) return SG_INSIDE ; return SG_STRADDLE ; } int sgdFrustum::contains ( const sgdBox *b ) const { sgdVec3 p[8] = { { b->getMin()[0], b->getMin()[1], b->getMin()[2] }, { b->getMax()[0], b->getMin()[1], b->getMin()[2] }, { b->getMin()[0], b->getMax()[1], b->getMin()[2] }, { b->getMax()[0], b->getMax()[1], b->getMin()[2] }, { b->getMin()[0], b->getMin()[1], b->getMax()[2] }, { b->getMax()[0], b->getMin()[1], b->getMax()[2] }, { b->getMin()[0], b->getMax()[1], b->getMax()[2] }, { b->getMax()[0], b->getMax()[1], b->getMax()[2] }, } ; int all = -1 ; int one = 0 ; for (int i = 0 ; i < 8 ; i++ ) { int tmp = ~ getOutcode ( p[i] ) ; all &= tmp ; one |= tmp ; } return ( all ? SG_OUTSIDE : one ? SG_STRADDLE : SG_INSIDE ) ; } SGDfloat sgdDistSquaredToLineVec3 ( const sgdLine3 line, const sgdVec3 pnt ) { sgdVec3 r ; sgdSubVec3 ( r, pnt, line.point_on_line ) ; return sgdScalarProductVec3 ( r, r ) - sgdScalarProductVec3 ( r, line.direction_vector ) ; } SGDfloat sgdDistSquaredToLineSegmentVec3 ( const sgdLineSegment3 line, const sgdVec3 pnt ) { sgdVec3 v ; sgdSubVec3 ( v, line.b, line.a ) ; sgdVec3 r1 ; sgdSubVec3 ( r1, pnt, line.a ) ; SGDfloat r1_dot_v = sgdScalarProductVec3 ( r1, v ) ; if ( r1_dot_v <= 0 ) /* Off the "A" end */ return sgdScalarProductVec3 ( r1, r1 ) ; sgdVec3 r2 ; sgdSubVec3 ( r2, pnt, line.b ) ; SGDfloat r2_dot_v = sgdScalarProductVec3 ( r2, v ) ; if ( r2_dot_v >= 0 ) /* Off the "B" end */ return sgdScalarProductVec3 ( r2, r2 ) ; /* Closest point on line is on the line segment */ return sgdScalarProductVec3 ( r1, r1 ) - r1_dot_v * r1_dot_v / sgdScalarProductVec3 ( v, v ) ; } void sgdMakeCoordMat4 ( sgdMat4 m, const SGDfloat x, const SGDfloat y, const SGDfloat z, const SGDfloat h, const SGDfloat p, const SGDfloat r ) { SGDfloat ch, sh, cp, sp, cr, sr, srsp, crsp, srcp ; if ( h == SGD_ZERO ) { ch = SGD_ONE ; sh = SGD_ZERO ; } else { sh = sgdSin( h ) ; ch = sgdCos( h ) ; } if ( p == SGD_ZERO ) { cp = SGD_ONE ; sp = SGD_ZERO ; } else { sp = sgdSin( p ) ; cp = sgdCos( p ) ; } if ( r == SGD_ZERO ) { cr = SGD_ONE ; sr = SGD_ZERO ; srsp = SGD_ZERO ; srcp = SGD_ZERO ; crsp = sp ; } else { sr = sgdSin( r ) ; cr = sgdCos( r ) ; srsp = sr * sp ; crsp = cr * sp ; srcp = sr * cp ; } m[0][0] = ch * cr - sh * srsp ; m[1][0] = -sh * cp ; m[2][0] = sr * ch + sh * crsp ; m[3][0] = x ; m[0][1] = cr * sh + srsp * ch ; m[1][1] = ch * cp ; m[2][1] = sr * sh - crsp * ch ; m[3][1] = y ; m[0][2] = -srcp ; m[1][2] = sp ; m[2][2] = cr * cp ; m[3][2] = z ; m[0][3] = SGD_ZERO ; m[1][3] = SGD_ZERO ; m[2][3] = SGD_ZERO ; m[3][3] = SGD_ONE ; } void sgdMakeTransMat4 ( sgdMat4 m, const sgdVec3 xyz ) { m[0][1] = m[0][2] = m[0][3] = m[1][0] = m[1][2] = m[1][3] = m[2][0] = m[2][1] = m[2][3] = SGD_ZERO ; m[0][0] = m[1][1] = m[2][2] = m[3][3] = SGD_ONE ; sgdCopyVec3 ( m[3], xyz ) ; } void sgdMakeTransMat4 ( sgdMat4 m, const SGDfloat x, const SGDfloat y, const SGDfloat z ) { m[0][1] = m[0][2] = m[0][3] = m[1][0] = m[1][2] = m[1][3] = m[2][0] = m[2][1] = m[2][3] = SGD_ZERO ; m[0][0] = m[1][1] = m[2][2] = m[3][3] = SGD_ONE ; sgdSetVec3 ( m[3], x, y, z ) ; } void sgdSetCoord ( sgdCoord *dst, const sgdMat4 src ) { sgdCopyVec3 ( dst->xyz, src[3] ) ; sgdMat4 mat ; SGDfloat s = sgdLengthVec3 ( src[0] ) ; if ( s <= 0.00001 ) { ulSetError ( UL_WARNING, "sgdMat4ToCoord: ERROR - Bad Matrix." ) ; sgdSetVec3 ( dst -> hpr, SGD_ZERO, SGD_ZERO, SGD_ZERO ) ; return ; } sgdScaleMat4 ( mat, src, SGD_ONE / s ) ; dst->hpr[1] = sgdASin ( _sgdClampToUnity ( mat[1][2] ) ) ; SGDfloat cp = sgdCos ( dst->hpr[1] ) ; /* If pointing nearly vertically up - then heading is ill-defined */ if ( cp > -0.00001 && cp < 0.00001 ) { SGDfloat cr = _sgdClampToUnity ( mat[0][1] ) ; SGDfloat sr = _sgdClampToUnity (-mat[2][1] ) ; dst->hpr[0] = SGD_ZERO ; dst->hpr[2] = sgdATan2 ( sr, cr ) ; } else { cp = SGD_ONE / cp ; SGDfloat sr = _sgdClampToUnity ( -mat[0][2] * cp ) ; SGDfloat cr = _sgdClampToUnity ( mat[2][2] * cp ) ; SGDfloat sh = _sgdClampToUnity ( -mat[1][0] * cp ) ; SGDfloat ch = _sgdClampToUnity ( mat[1][1] * cp ) ; if ( (sh == SGD_ZERO && ch == SGD_ZERO) || (sr == SGD_ZERO && cr == SGD_ZERO) ) { cr = _sgdClampToUnity ( mat[0][1] ) ; sr = _sgdClampToUnity (-mat[2][1] ) ; dst->hpr[0] = SGD_ZERO ; } else dst->hpr[0] = sgdATan2 ( sh, ch ) ; dst->hpr[2] = sgdATan2 ( sr, cr ) ; } } void sgdMakeNormal(sgdVec2 dst, const sgdVec2 a, const sgdVec2 b ) { sgdSubVec2 ( dst, b, a ) ; SGDfloat tmp = dst [ 0 ] ; dst [ 0 ] = -dst [ 1 ] ; dst [ 1 ] = tmp ; sgdNormaliseVec2 ( dst ) ; } void sgdMakeNormal(sgdVec3 dst, const sgdVec3 a, const sgdVec3 b, const sgdVec3 c ) { sgdVec3 ab ; sgdSubVec3 ( ab, b, a ) ; sgdVec3 ac ; sgdSubVec3 ( ac, c, a ) ; sgdVectorProductVec3 ( dst, ab,ac ) ; sgdNormaliseVec3 ( dst ) ; } void sgdPreMultMat4( sgdMat4 dst, const sgdMat4 src ) { sgdMat4 mat ; sgdMultMat4 ( mat, dst, src ) ; sgdCopyMat4 ( dst, mat ) ; } void sgdPostMultMat4( sgdMat4 dst, const sgdMat4 src ) { sgdMat4 mat ; sgdMultMat4 ( mat, src, dst ) ; sgdCopyMat4 ( dst, mat ) ; } void sgdMultMat4( sgdMat4 dst, const sgdMat4 m1, const sgdMat4 m2 ) { for ( int j = 0 ; j < 4 ; j++ ) { dst[0][j] = m2[0][0] * m1[0][j] + m2[0][1] * m1[1][j] + m2[0][2] * m1[2][j] + m2[0][3] * m1[3][j] ; dst[1][j] = m2[1][0] * m1[0][j] + m2[1][1] * m1[1][j] + m2[1][2] * m1[2][j] + m2[1][3] * m1[3][j] ; dst[2][j] = m2[2][0] * m1[0][j] + m2[2][1] * m1[1][j] + m2[2][2] * m1[2][j] + m2[2][3] * m1[3][j] ; dst[3][j] = m2[3][0] * m1[0][j] + m2[3][1] * m1[1][j] + m2[3][2] * m1[2][j] + m2[3][3] * m1[3][j] ; } } void sgdTransposeNegateMat4 ( sgdMat4 dst, const sgdMat4 src ) { /* Poor man's invert - can be used when matrix is a simple rotate-translate */ dst[0][0] = src[0][0] ; dst[1][0] = src[0][1] ; dst[2][0] = src[0][2] ; dst[3][0] = - sgdScalarProductVec3 ( src[3], src[0] ) ; dst[0][1] = src[1][0] ; dst[1][1] = src[1][1] ; dst[2][1] = src[1][2] ; dst[3][1] = - sgdScalarProductVec3 ( src[3], src[1] ) ; dst[0][2] = src[2][0] ; dst[1][2] = src[2][1] ; dst[2][2] = src[2][2] ; dst[3][2] = - sgdScalarProductVec3 ( src[3], src[2] ) ; dst[0][3] = SGD_ZERO ; dst[1][3] = SGD_ZERO ; dst[2][3] = SGD_ZERO ; dst[3][3] = SGD_ONE ; } void sgdTransposeNegateMat4 ( sgdMat4 dst ) { sgdMat4 src ; sgdCopyMat4 ( src, dst ) ; sgdTransposeNegateMat4 ( dst, src ) ; } void sgdInvertMat4 ( sgdMat4 dst, const sgdMat4 src ) { sgdMat4 tmp ; sgdCopyMat4 ( tmp, src ) ; sgdMakeIdentMat4 ( dst ) ; for ( int i = 0 ; i != 4 ; i++ ) { SGDfloat val = tmp[i][i] ; int ind = i ; int j ; for ( j = i + 1 ; j != 4 ; j++ ) { if ( fabs ( tmp[i][j] ) > fabs(val) ) { ind = j; val = tmp[i][j] ; } } if ( ind != i ) { /* swap columns */ for ( j = 0 ; j != 4 ; j++ ) { SGDfloat t ; t = dst[j][i]; dst[j][i] = dst[j][ind]; dst[j][ind] = t ; t = tmp[j][i]; tmp[j][i] = tmp[j][ind]; tmp[j][ind] = t ; } } // if ( val == SG_ZERO) if ( fabs(val) <= DBL_EPSILON ) { ulSetError ( UL_WARNING, "sg: ERROR - Singular matrix, no inverse!" ) ; sgdMakeIdentMat4 ( dst ) ; /* Do *something* */ return; } SGDfloat ival = SGD_ONE / val ; for ( j = 0 ; j != 4 ; j++ ) { tmp[j][i] *= ival ; dst[j][i] *= ival ; } for (j = 0; j != 4; j++) { if ( j == i ) continue ; val = tmp[i][j] ; for ( int k = 0 ; k != 4 ; k++ ) { tmp[k][j] -= tmp[k][i] * val ; dst[k][j] -= dst[k][i] * val ; } } } } void sgdXformVec3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) { SGDfloat t0 = src[ 0 ] ; SGDfloat t1 = src[ 1 ] ; SGDfloat t2 = src[ 2 ] ; dst[0] = ( t0 * mat[ 0 ][ 0 ] + t1 * mat[ 1 ][ 0 ] + t2 * mat[ 2 ][ 0 ] ) ; dst[1] = ( t0 * mat[ 0 ][ 1 ] + t1 * mat[ 1 ][ 1 ] + t2 * mat[ 2 ][ 1 ] ) ; dst[2] = ( t0 * mat[ 0 ][ 2 ] + t1 * mat[ 1 ][ 2 ] + t2 * mat[ 2 ][ 2 ] ) ; } void sgdXformPnt3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) { SGDfloat t0 = src[ 0 ] ; SGDfloat t1 = src[ 1 ] ; SGDfloat t2 = src[ 2 ] ; dst[0] = ( t0 * mat[ 0 ][ 0 ] + t1 * mat[ 1 ][ 0 ] + t2 * mat[ 2 ][ 0 ] + mat[ 3 ][ 0 ] ) ; dst[1] = ( t0 * mat[ 0 ][ 1 ] + t1 * mat[ 1 ][ 1 ] + t2 * mat[ 2 ][ 1 ] + mat[ 3 ][ 1 ] ) ; dst[2] = ( t0 * mat[ 0 ][ 2 ] + t1 * mat[ 1 ][ 2 ] + t2 * mat[ 2 ][ 2 ] + mat[ 3 ][ 2 ] ) ; } void sgdXformPnt4 ( sgdVec4 dst, const sgdVec4 src, const sgdMat4 mat ) { SGDfloat t0 = src[ 0 ] ; SGDfloat t1 = src[ 1 ] ; SGDfloat t2 = src[ 2 ] ; SGDfloat t3 = src[ 3 ] ; dst[0] = ( t0 * mat[ 0 ][ 0 ] + t1 * mat[ 1 ][ 0 ] + t2 * mat[ 2 ][ 0 ] + t3 * mat[ 3 ][ 0 ] ) ; dst[1] = ( t0 * mat[ 0 ][ 1 ] + t1 * mat[ 1 ][ 1 ] + t2 * mat[ 2 ][ 1 ] + t3 * mat[ 3 ][ 1 ] ) ; dst[2] = ( t0 * mat[ 0 ][ 2 ] + t1 * mat[ 1 ][ 2 ] + t2 * mat[ 2 ][ 2 ] + t3 * mat[ 3 ][ 2 ] ) ; dst[3] = ( t0 * mat[ 0 ][ 3 ] + t1 * mat[ 1 ][ 3 ] + t2 * mat[ 2 ][ 3 ] + t3 * mat[ 3 ][ 3 ] ) ; } void sgdFullXformPnt3 ( sgdVec3 dst, const sgdVec3 src, const sgdMat4 mat ) { sgdVec4 tmp ; tmp [ 0 ] = src [ 0 ] ; tmp [ 1 ] = src [ 1 ] ; tmp [ 2 ] = src [ 2 ] ; tmp [ 3 ] = SGD_ONE ; sgdXformPnt4 ( tmp, tmp, mat ) ; sgdScaleVec3 ( dst, tmp, SGD_ONE / tmp [ 3 ] ) ; } void sgdHPRfromVec3 ( sgdVec3 hpr, sgdVec3 src ) { sgdVec3 tmp ; sgdCopyVec3 ( tmp, src ) ; sgdNormaliseVec3 ( tmp ) ; hpr[0] = - sgdATan2 ( tmp [ 0 ], tmp [ 1 ] ) ; hpr[1] = - sgdATan2 ( tmp [ 2 ], sgdSqrt ( sgdSquare ( tmp [ 0 ] ) + sgdSquare ( tmp [ 1 ] ) ) ) ; hpr[2] = SGD_ZERO ; } /* Quaternion routines are Copyright (C) 1999 Kevin B. Thompson Modified by Sylvan W. Clebsch Largely rewritten by "Negative0" */ void sgdQuatToAngleAxis ( SGDfloat *angle, SGDfloat *x, SGDfloat *y, SGDfloat *z, const sgdQuat src ) { sgdVec3 axis ; sgdQuatToAngleAxis ( angle, axis, src ) ; *x = axis [ 0 ] ; *y = axis [ 1 ] ; *z = axis [ 2 ] ; } void sgdQuatToAngleAxis ( SGDfloat *angle, sgdVec3 axis, const sgdQuat src ) { SGDfloat a = (SGDfloat) acos ( src[SGD_W] ) ; SGDfloat s = (SGDfloat) sin ( a ) ; *angle = a * SGD_RADIANS_TO_DEGREES * SGD_TWO ; if ( s == SGD_ZERO ) sgdSetVec3 ( axis, SGD_ZERO, SGD_ZERO, SGD_ONE ); else { sgdSetVec3 ( axis, src[SGD_X], src[SGD_Y], src[SGD_Z] ) ; sgdScaleVec3 ( axis, SGD_ONE / s ) ; } } void sgdAngleAxisToQuat ( sgdQuat dst, const SGDfloat angle, const SGDfloat x, const SGDfloat y, const SGDfloat z ) { sgdVec3 axis ; sgdSetVec3 ( axis, x, y, z ) ; sgdAngleAxisToQuat ( dst, angle, axis ) ; } void sgdAngleAxisToQuat ( sgdQuat dst, const SGDfloat angle, const sgdVec3 axis ) { SGDfloat temp_angle = angle * SGD_DEGREES_TO_RADIANS / SGD_TWO ; sgdVec3 ax ; sgdNormaliseVec3 ( ax, axis ) ; SGDfloat s = - (SGDfloat) sin ( temp_angle ) ; dst[SGD_W] = (SGDfloat) cos ( temp_angle ) ; sgdScaleVec3 ( dst, ax, s ) ; } //from gamasutra.com //by nb void sgdMatrixToQuat( sgdQuat quat, const sgdMat4 m ) { SGDfloat tr, s, q[4] ; int i, j, k ; int nxt[3] = {1, 2, 0}; tr = m[0][0] + m[1][1] + m[2][2]; // check the diagonal if (tr > SGD_ZERO ) { s = (SGDfloat) sqrt (tr + SGD_ONE); quat[SGD_W] = s / SGD_TWO; s = SGD_HALF / s; quat[SGD_X] = (m[1][2] - m[2][1]) * s; quat[SGD_Y] = (m[2][0] - m[0][2]) * s; quat[SGD_Z] = (m[0][1] - m[1][0]) * s; } else { // diagonal is negative i = 0; if (m[1][1] > m[0][0]) i = 1; if (m[2][2] > m[i][i]) i = 2; j = nxt[i]; k = nxt[j]; s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + SGD_ONE); q[i] = s * SGD_HALF; if (s != SGD_ZERO) s = SGD_HALF / s; q[3] = (m[j][k] - m[k][j]) * s; q[j] = (m[i][j] + m[j][i]) * s; q[k] = (m[i][k] + m[k][i]) * s; quat[SGD_X] = q[0]; quat[SGD_Y] = q[1]; quat[SGD_Z] = q[2]; quat[SGD_W] = q[3]; } // seems to yield the inverse rotation, so: quat[SG_W] = - quat[SG_W]; } void sgdMultQuat ( sgdQuat dst, const sgdQuat a, const sgdQuat b ) { /* [ ww' - v.v', vxv' + wv' + v'w ] */ SGDfloat t[8]; t[0] = (a[SGD_W] + a[SGD_X]) * (b[SGD_W] + b[SGD_X]); t[1] = (a[SGD_Z] - a[SGD_Y]) * (b[SGD_Y] - b[SGD_Z]); t[2] = (a[SGD_X] - a[SGD_W]) * (b[SGD_Y] + b[SGD_Z]); t[3] = (a[SGD_Y] + a[SGD_Z]) * (b[SGD_X] - b[SGD_W]); t[4] = (a[SGD_X] + a[SGD_Z]) * (b[SGD_X] + b[SGD_Y]); t[5] = (a[SGD_X] - a[SGD_Z]) * (b[SGD_X] - b[SGD_Y]); t[6] = (a[SGD_W] + a[SGD_Y]) * (b[SGD_W] - b[SGD_Z]); t[7] = (a[SGD_W] - a[SGD_Y]) * (b[SGD_W] + b[SGD_Z]); dst[SGD_W] = t[1] + ((-t[4] - t[5] + t[6] + t[7]) * SGD_HALF); dst[SGD_X] = t[0] - (( t[4] + t[5] + t[6] + t[7]) * SGD_HALF); dst[SGD_Y] = -t[2] + (( t[4] - t[5] + t[6] - t[7]) * SGD_HALF); dst[SGD_Z] = -t[3] + (( t[4] - t[5] - t[6] + t[7]) * SGD_HALF); } //from gamasutra.com //by nb@netcom.ca void sgdMultQuat2 ( sgdQuat dst, const sgdQuat a, const sgdQuat b ) { SGDfloat A, B, C, D, E, F, G, H; A = (a[SGD_W] + a[SGD_X]) * (b[SGD_W] + b[SGD_X]) ; B = (a[SGD_Z] - a[SGD_Y]) * (b[SGD_Y] - b[SGD_Z]) ; C = (a[SGD_X] - a[SGD_W]) * (b[SGD_Y] + b[SGD_Z]) ; D = (a[SGD_Y] + a[SGD_Z]) * (b[SGD_X] - b[SGD_W]) ; E = (a[SGD_X] + a[SGD_Z]) * (b[SGD_X] + b[SGD_Y]) ; F = (a[SGD_X] - a[SGD_Z]) * (b[SGD_X] - b[SGD_Y]) ; G = (a[SGD_W] + a[SGD_Y]) * (b[SGD_W] - b[SGD_Z]) ; H = (a[SGD_W] - a[SGD_Y]) * (b[SGD_W] + b[SGD_Z]) ; dst[SGD_W] = B + (-E - F + G + H) / SGD_TWO ; dst[SGD_X] = A - ( E + F + G + H) / SGD_TWO ; dst[SGD_Y] = -C + ( E - F + G - H) / SGD_TWO ; dst[SGD_Z] = -D + ( E - F - G + H) / SGD_TWO ; } //from gamasutra.com //by nb@netcom.ca void sgdEulerToQuat(sgdQuat quat, const sgdVec3 hpr ) { SGDfloat cr, cp, cy, sr, sp, sy, cpcy, spsy; // calculate trig identities cr = (SGDfloat) cos(hpr[2]*SGD_DEGREES_TO_RADIANS/SGD_TWO); cp = (SGDfloat) cos(hpr[1]*SGD_DEGREES_TO_RADIANS/SGD_TWO); cy = (SGDfloat) cos(hpr[0]*SGD_DEGREES_TO_RADIANS/SGD_TWO); sr = (SGDfloat) sin(hpr[2]*SGD_DEGREES_TO_RADIANS/SGD_TWO); sp = (SGDfloat) sin(hpr[1]*SGD_DEGREES_TO_RADIANS/SGD_TWO); sy = (SGDfloat) sin(hpr[0]*SGD_DEGREES_TO_RADIANS/SGD_TWO); cpcy = cp * cy; spsy = sp * sy; quat[SGD_W] = cr * cpcy + sr * spsy; quat[SGD_X] = sr * cpcy - cr * spsy; quat[SGD_Y] = cr * sp * cy + sr * cp * sy; quat[SGD_Z] = cr * cp * sy - sr * sp * cy; } //from darwin3d.com // jeffl@darwin3d.com void sgdQuatToEuler( sgdVec3 hpr, const sgdQuat quat ) { SGDfloat matrix[3][3]; SGDfloat cx,sx; SGDfloat cy,sy; SGDfloat cz,sz; // CONVERT QUATERNION TO MATRIX - I DON'T REALLY NEED ALL OF IT matrix[0][0] = SGD_ONE - (SGD_TWO * quat[SGD_Y] * quat[SGD_Y]) - (SGD_TWO * quat[SGD_Z] * quat[SGD_Z]); //matrix[0][1] = (SGD_TWO * quat->x * quat->y) - (SGD_TWO * quat->w * quat->z); //matrix[0][2] = (SGD_TWO * quat->x * quat->z) + (SGD_TWO * quat->w * quat->y); matrix[1][0] = (SGD_TWO * quat[SGD_X] * quat[SGD_Y]) + (SGD_TWO * quat[SGD_W] * quat[SGD_Z]); //matrix[1][1] = SGD_ONE - (SGD_TWO * quat->x * quat->x) // - (SGD_TWO * quat->z * quat->z); //matrix[1][2] = (SGD_TWO * quat->y * quat->z) - (SGD_TWO * quat->w * quat->x); matrix[2][0] = (SGD_TWO * quat[SGD_X] * quat[SGD_Z]) - (SGD_TWO * quat[SGD_W] * quat[SGD_Y]); matrix[2][1] = (SGD_TWO * quat[SGD_Y] * quat[SGD_Z]) + (SGD_TWO * quat[SGD_W] * quat[SGD_X]); matrix[2][2] = SGD_ONE - (SGD_TWO * quat[SGD_X] * quat[SGD_X]) - (SGD_TWO * quat[SGD_Y] * quat[SGD_Y]); sy = -matrix[2][0]; cy = sgdSqrt(SGD_ONE - (sy * sy)); hpr[1] = sgdATan2( sy, cy ); // AVOID DIVIDE BY ZERO ERROR ONLY WHERE Y= +-90 or +-270 // NOT CHECKING cy BECAUSE OF PRECISION ERRORS if (sy != SGD_ONE && sy != -SGD_ONE) { cx = matrix[2][2] / cy; sx = matrix[2][1] / cy; hpr[0] = sgdATan2 ( sx, cx ); cz = matrix[0][0] / cy; sz = matrix[1][0] / cy; hpr[2] = sgdATan2 ( sz, cz ); } else { // SINCE Cos(Y) IS 0, I AM SCREWED. ADOPT THE STANDARD Z = 0 // I THINK THERE IS A WAY TO FIX THIS BUT I AM NOT SURE. EULERS SUCK // NEED SOME MORE OF THE MATRIX TERMS NOW matrix[1][1] = SGD_ONE - (SGD_TWO * quat[SGD_X] * quat[SGD_X]) - (SGD_TWO * quat[SGD_Z] * quat[SGD_Z]); matrix[1][2] = (SGD_TWO * quat[SGD_Y] * quat[SGD_Z]) - (SGD_TWO * quat[SGD_W] * quat[SGD_X]); cx = matrix[1][1]; sx = -matrix[1][2]; hpr[0] = sgdATan2 ( sx, cx ); cz = SGD_ONE ; sz = SGD_ZERO ; hpr[2] = sgdATan2 ( sz, cz ); } } void sgdQuatToMatrix ( sgdMat4 dst, const sgdQuat q ) { SGDfloat two_xx = q[SGD_X] * (q[SGD_X] + q[SGD_X]) ; SGDfloat two_xy = q[SGD_X] * (q[SGD_Y] + q[SGD_Y]) ; SGDfloat two_xz = q[SGD_X] * (q[SGD_Z] + q[SGD_Z]) ; SGDfloat two_wx = q[SGD_W] * (q[SGD_X] + q[SGD_X]) ; SGDfloat two_wy = q[SGD_W] * (q[SGD_Y] + q[SGD_Y]) ; SGDfloat two_wz = q[SGD_W] * (q[SGD_Z] + q[SGD_Z]) ; SGDfloat two_yy = q[SGD_Y] * (q[SGD_Y] + q[SGD_Y]) ; SGDfloat two_yz = q[SGD_Y] * (q[SGD_Z] + q[SGD_Z]) ; SGDfloat two_zz = q[SGD_Z] * (q[SGD_Z] + q[SGD_Z]) ; sgdSetVec4 ( dst[0], SGD_ONE-(two_yy+two_zz), two_xy-two_wz, two_xz+two_wy, SGD_ZERO ) ; sgdSetVec4 ( dst[1], two_xy+two_wz, SGD_ONE-(two_xx+two_zz), two_yz-two_wx, SGD_ZERO ) ; sgdSetVec4 ( dst[2], two_xz-two_wy, two_yz+two_wx, SGD_ONE-(two_xx+two_yy), SGD_ZERO ) ; sgdSetVec4 ( dst[3], SGD_ZERO, SGD_ZERO, SGD_ZERO, SGD_ONE ) ; } //from gamasutra.com //by nb@netcom.ca /************************************ DEPRECATED - use sgdQuatToMatrix instead. *************************************/ void sgdMakeRotMat42( sgdMat4 m, sgdQuat quat ){ SGDfloat wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; // calculate coefficients x2 = quat[SGD_X] + quat[SGD_X]; y2 = quat[SGD_Y] + quat[SGD_Y]; z2 = quat[SGD_Z] + quat[SGD_Z]; xx = quat[SGD_X] * x2; xy = quat[SGD_X] * y2; xz = quat[SGD_X] * z2; yy = quat[SGD_Y] * y2; yz = quat[SGD_Y] * z2; zz = quat[SGD_Z] * z2; wx = quat[SGD_W] * x2; wy = quat[SGD_W] * y2; wz = quat[SGD_W] * z2; m[0][0] = SGD_ONE- (yy + zz); m[0][1] = xy - wz; m[0][2] = xz + wy; m[0][3] = SGD_ZERO ; m[1][0] = xy + wz; m[1][1] = SGD_ONE- (xx + zz); m[1][2] = yz - wx; m[1][3] = SGD_ZERO ; m[2][0] = xz - wy; m[2][1] = yz + wx; m[2][2] = SGD_ONE- (xx + yy); m[2][3] = SGD_ZERO ; m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; } //from gamasutra.com //by nb@netcom.ca void sgdSlerpQuat2( sgdQuat dst, const sgdQuat from, const sgdQuat to, const SGDfloat t ) { SGDfloat to1[4]; SGDfloat omega, cosom, sinom, scale0, scale1; // calc cosine cosom = from[SGD_X] * to[SGD_X] + from[SGD_Y] * to[SGD_Y] + from[SGD_Z] * to[SGD_Z] + from[SGD_W] * to[SGD_W]; // adjust signs (if necessary) if ( cosom < SG_ZERO ) { cosom = -cosom; to1[0] = - to[SGD_X]; to1[1] = - to[SGD_Y]; to1[2] = - to[SGD_Z]; to1[3] = - to[SGD_W]; } else { to1[0] = to[SGD_X]; to1[1] = to[SGD_Y]; to1[2] = to[SGD_Z]; to1[3] = to[SGD_W]; } // calculate coefficients #define DELTA SGD_ZERO if ( (SGD_ONE- cosom) > DELTA ) { // standard case (slerp) omega = acos(cosom); sinom = sin(omega); scale0 = sin((SGD_ONE- t) * omega) / sinom; scale1 = sin(t * omega) / sinom; } else { // "from" and "to" quaternions are very close // ... so we can do a linear interpolation scale0 = SGD_ONE- t; scale1 = t; } // calculate final values dst[SGD_X] = scale0 * from[SGD_X] + scale1 * to1[0]; dst[SGD_Y] = scale0 * from[SGD_Y] + scale1 * to1[1]; dst[SGD_Z] = scale0 * from[SGD_Z] + scale1 * to1[2]; dst[SGD_W] = scale0 * from[SGD_W] + scale1 * to1[3]; } void sgdSlerpQuat( sgdQuat dst, const sgdQuat from, const sgdQuat to, const SGDfloat t ) { SGDfloat co, scale0, scale1; bool flip = false ; /* SWC - Interpolate between to quaternions */ co = sgdScalarProductVec4 ( from, to ) ; if ( co < SGD_ZERO ) { co = -co; flip = true ; } if ( co < SGD_ONE - (SGDfloat) 1e-6 ) { SGDfloat o = (SGDfloat) acos ( co ); SGDfloat so = SGD_ONE / (SGDfloat) sin ( o ); scale0 = (SGDfloat) sin ( (SGD_ONE - t) * o ) * so; scale1 = (SGDfloat) sin ( t * o ) * so; } else { scale0 = SGD_ONE - t; scale1 = t; } if ( flip ) { scale1 = -scale1 ; } dst[SGD_X] = scale0 * from[SGD_X] + scale1 * to[SGD_X] ; dst[SGD_Y] = scale0 * from[SGD_Y] + scale1 * to[SGD_Y] ; dst[SGD_Z] = scale0 * from[SGD_Z] + scale1 * to[SGD_Z] ; dst[SGD_W] = scale0 * from[SGD_W] + scale1 * to[SGD_W] ; } /* Function to rotate a vector through a given quaternion using the formula * R = Q r Q-1 -- this gives the components of a ROTATED vector in a STATIONARY * coordinate system. We assume that Q is a unit quaternion. */ void sgdRotateVecQuat ( sgdVec3 vec, sgdQuat q ) { sgdVec3 rot ; sgdFloat qwqw = q[SG_W] * q[SG_W] ; sgdFloat qwqx = q[SG_W] * q[SG_X] ; sgdFloat qwqy = q[SG_W] * q[SG_Y] ; sgdFloat qwqz = q[SG_W] * q[SG_Z] ; sgdFloat qxqx = q[SG_X] * q[SG_X] ; sgdFloat qxqy = q[SG_X] * q[SG_Y] ; sgdFloat qxqz = q[SG_X] * q[SG_Z] ; sgdFloat qyqy = q[SG_Y] * q[SG_Y] ; sgdFloat qyqz = q[SG_Y] * q[SG_Z] ; sgdFloat qzqz = q[SG_Z] * q[SG_Z] ; rot[SG_X] = ( qwqw + qxqx - qyqy - qzqz ) * vec[SG_X] + 2.0f * ( qxqy - qwqz ) * vec[SG_Y] + 2.0f * ( qxqz + qwqy ) * vec[SG_Z] ; rot[SG_Y] = ( qwqw - qxqx + qyqy - qzqz ) * vec[SG_Y] + 2.0f * ( qyqz - qwqx ) * vec[SG_Z] + 2.0f * ( qxqy + qwqz ) * vec[SG_X] ; rot[SG_Z] = ( qwqw - qxqx - qyqy + qzqz ) * vec[SG_Z] + 2.0f * ( qxqz - qwqy ) * vec[SG_X] + 2.0f * ( qyqz + qwqx ) * vec[SG_Y] ; sgdCopyVec3 ( vec, rot ) ; } /* Function to rotate a vector through a given quaternion using the formula * R = Q-1 r Q -- this gives the components of a STATIONARY vector in a ROTATED * coordinate system. We assume that Q is a unit quaternion. */ void sgdRotateCoordQuat ( sgdVec3 vec, sgdQuat q ) { sgdVec3 rot ; sgdFloat qwqw = q[SG_W] * q[SG_W] ; sgdFloat qwqx = q[SG_W] * q[SG_X] ; sgdFloat qwqy = q[SG_W] * q[SG_Y] ; sgdFloat qwqz = q[SG_W] * q[SG_Z] ; sgdFloat qxqx = q[SG_X] * q[SG_X] ; sgdFloat qxqy = q[SG_X] * q[SG_Y] ; sgdFloat qxqz = q[SG_X] * q[SG_Z] ; sgdFloat qyqy = q[SG_Y] * q[SG_Y] ; sgdFloat qyqz = q[SG_Y] * q[SG_Z] ; sgdFloat qzqz = q[SG_Z] * q[SG_Z] ; rot[SG_X] = ( qwqw + qxqx - qyqy - qzqz ) * vec[SG_X] + 2.0f * ( qxqy + qwqz ) * vec[SG_Y] + 2.0f * ( qxqz - qwqy ) * vec[SG_Z] ; rot[SG_Y] = ( qwqw - qxqx + qyqy - qzqz ) * vec[SG_Y] + 2.0f * ( qyqz + qwqx ) * vec[SG_Z] + 2.0f * ( qxqy - qwqz ) * vec[SG_X] ; rot[SG_Z] = ( qwqw - qxqx - qyqy + qzqz ) * vec[SG_Z] + 2.0f * ( qxqz + qwqy ) * vec[SG_X] + 2.0f * ( qyqz - qwqx ) * vec[SG_Y] ; sgdCopyVec3 ( vec, rot ) ; } sgdFloat sgdDistSquaredToLineLineSegment ( const sgdLineSegment3 seg, const sgdLine3 line ) { /* Convert the line segment to a line. We will deal with the segment limits later. */ sgdLine3 line2 ; sgdLineSegment3ToLine3 ( &line2, seg ) ; /* Get the dot product of the two direction vectors */ sgdFloat t1_dot_t2 = sgdScalarProductVec3 ( line.direction_vector, line2.direction_vector ) ; /* If the lines are parallel, distance is just the distance from a point to the other line */ if ( fabs ( t1_dot_t2 ) >= 1.0 ) return sgdDistSquaredToLineVec3 ( line, seg.a ) ; /* Get the parametric coordinates of the closest points on the two lines. The first line * is parameterized by r = r1 + t1 u while the second is parameterized by r = r2 + t2 v. * The square of the distance between them is [ ( r1 + t1 u ) - ( r2 + t2 v ) ] dot * [ ( r1 + t1 u ) - ( r2 + t2 v ) ]. Differentiating this dot product with respect to * u and v and setting the derivatives to zero gives a matrix equation: * [ 1 -(t1 dot t2) ] [ u ] = [ ( r1 - r2 ) dot t1 ] * [ -(t1 dot t2) 1 ] [ v ] [ -( r1 - r2 ) dot t2 ] * We invert the matrix to get the equations below. */ sgdVec3 r1_minus_r2 ; sgdSubVec3 ( r1_minus_r2, line.point_on_line, line2.point_on_line ) ; /* t1_t2_t2_minus_t1 = ( t1 dot t2 ) t2 - t1 * t2_minus_t1_t2_t1 = t2 - ( t1 dot t2 ) t1 */ sgdVec3 t1_t2_t2_minus_t1, t2_minus_t1_t2_t1 ; sgdAddScaledVec3 ( t1_t2_t2_minus_t1, line.direction_vector, line2.direction_vector, -t1_dot_t2 ) ; sgdNegateVec3 ( t1_t2_t2_minus_t1 ) ; sgdAddScaledVec3 ( t2_minus_t1_t2_t1, line2.direction_vector, line.direction_vector, -t1_dot_t2 ) ; sgdFloat u = sgdScalarProductVec3 ( r1_minus_r2, t1_t2_t2_minus_t1 ) / ( 1.0f - t1_dot_t2 * t1_dot_t2 ) ; sgdFloat v = sgdScalarProductVec3 ( r1_minus_r2, t2_minus_t1_t2_t1 ) / ( 1.0f - t1_dot_t2 * t1_dot_t2 ) ; /* Since line 2 is a line segment, we limit "v" to between 0 and the distance between the points. */ sgdFloat length = sgdDistanceVec3 ( seg.a, seg.b ) ; if ( v < 0.0 ) v = 0.0 ; if ( v > length ) v = length ; sgdVec3 point1, point2 ; sgdAddScaledVec3 ( point1, line.point_on_line, line.direction_vector, u ) ; sgdAddScaledVec3 ( point2, line2.point_on_line, line2.direction_vector, v ) ; return sgdDistanceSquaredVec3 ( point1, point2 ) ; } void sgdReflectInPlaneVec3 ( sgdVec3 dst, const sgdVec3 src, const sgdVec4 plane ) { SGDfloat src_dot_norm = sgdScalarProductVec3 ( src, plane ) ; sgdVec3 tmp ; sgdScaleVec3 ( tmp, plane, SGD_TWO * src_dot_norm ) ; sgdSubVec3 ( dst, src, tmp ) ; } int sgdClassifyMat4 ( const sgdMat4 m ) { const SGDfloat epsilon = 1e-6 ; int flags = 0 ; SGDfloat sx, sy, sz ; if ( m[0][1] == SGD_ZERO && m[0][2] == SGD_ZERO && m[1][0] == SGD_ZERO && m[1][2] == SGD_ZERO && m[2][0] == SGD_ZERO && m[2][1] == SGD_ZERO ) { int n = ( m[0][0] < 0 ) + ( m[1][1] < 0 ) + ( m[2][2] < 0 ) ; if ( n > 1 ) flags |= SG_ROTATION ; if ( n % 2 != 0 ) flags |= SG_MIRROR ; sx = m[0][0] * m[0][0] ; sy = m[1][1] * m[1][1] ; sz = m[2][2] * m[2][2] ; } else { flags |= SG_ROTATION ; if ( sgdAbs ( sgdScalarProductVec3 ( m[1], m[2] ) ) > epsilon || sgdAbs ( sgdScalarProductVec3 ( m[2], m[0] ) ) > epsilon || sgdAbs ( sgdScalarProductVec3 ( m[0], m[1] ) ) > epsilon ) { flags |= SG_NONORTHO ; } sgdVec3 temp ; sgdVectorProductVec3 ( temp, m[0], m[1] ) ; SGDfloat det = sgdScalarProductVec3 ( temp, m[2] ) ; if ( det < 0 ) flags |= SG_MIRROR ; sx = sgdScalarProductVec3 ( m[0], m[0] ) ; sy = sgdScalarProductVec3 ( m[1], m[1] ) ; sz = sgdScalarProductVec3 ( m[2], m[2] ) ; } if ( sgdAbs ( sx - sy ) > epsilon || sgdAbs ( sx - sz ) > epsilon ) { flags |= SG_NONORTHO ; flags |= SG_GENERAL_SCALE ; // also set general scale bit, though it may be deleted in the future } else { if ( sgdAbs ( sx - SGD_ONE ) > epsilon ) flags |= SG_SCALE ; } if ( m[3][0] != SGD_ZERO || m[3][1] != SGD_ZERO || m[3][2] != SGD_ZERO ) { flags |= SG_TRANSLATION ; } if ( m[0][3] != SGD_ZERO || m[1][3] != SGD_ZERO || m[2][3] != SGD_ZERO || m[3][3] != SGD_ONE ) { flags |= SG_PROJECTION ; } return flags ; } SGDfloat sgdTriangleSolver_ASAtoArea ( SGDfloat angA, SGDfloat lenB, SGDfloat angC ) { /* Get the third angle */ SGDfloat angB = SGD_180 - (angA + angC) ; /* Use Sine Rule to get length of a second side - then use SAStoArea. */ SGDfloat sinB = sgdSin ( angB ) ; if ( sinB == SGD_ZERO ) return SGD_ZERO ; SGDfloat lenA = lenB * sgdSin(angA) / sinB ; return sgdTriangleSolver_SAStoArea ( lenA, angC, lenB ) ; } SGDfloat sgdTriangleSolver_SAStoArea ( SGDfloat lenA, SGDfloat angB, SGDfloat lenC ) { return SGD_HALF * lenC * lenA * sgdSin ( angB ) ; } SGDfloat sgdTriangleSolver_SSStoArea ( SGDfloat lenA, SGDfloat lenB, SGDfloat lenC ) { /* Heron's formula */ SGDfloat s = ( lenA + lenB + lenC ) / SGD_TWO ; SGDfloat q = s * (s-lenA) * (s-lenB) * (s-lenC) ; /* Ikky illegal triangles generate zero areas. */ return ( q <= SGD_ZERO ) ? SGD_ZERO : sgdSqrt ( q ) ; } SGDfloat sgdTriangleSolver_ASStoArea ( SGDfloat angB, SGDfloat lenA, SGDfloat lenB, int angA_is_obtuse ) { SGDfloat lenC ; sgdTriangleSolver_ASStoSAA ( angB, lenA, lenB, angA_is_obtuse, &lenC, NULL, NULL ) ; return sgdTriangleSolver_SAStoArea ( lenA, angB, lenC ) ; } SGDfloat sgdTriangleSolver_SAAtoArea ( SGDfloat lenA, SGDfloat angB, SGDfloat angA ) { SGDfloat lenC ; sgdTriangleSolver_SAAtoASS ( lenA, angB, angA, NULL, NULL, &lenC ) ; return sgdTriangleSolver_SAStoArea ( lenA, angB, lenC ) ; } void sgdTriangleSolver_SSStoAAA ( SGDfloat lenA, SGDfloat lenB, SGDfloat lenC, SGDfloat *angA, SGDfloat *angB, SGDfloat *angC ) { SGDfloat aa, bb, cc ; int flag = ( lenA == SGD_ZERO ) | (( lenB == SGD_ZERO )<<1) | (( lenC == SGD_ZERO )<<2) ; /* Ikky zero-sized triangles generate zero/90 angles appropriately. */ /* Ikky triangles with all lengths zero generate 60 degree angles. */ /* Ikky impossible triangles generate all zero angles. */ switch ( flag ) { case 0 : /* no zero-lengthed sides */ /* Cosine law */ aa = sgdACos (( lenB*lenB + lenC*lenC - lenA*lenA )/(SGD_TWO*lenB*lenC)) ; bb = sgdACos (( lenA*lenA + lenC*lenC - lenB*lenB )/(SGD_TWO*lenA*lenC)) ; cc = sgdACos (( lenA*lenA + lenB*lenB - lenC*lenC )/(SGD_TWO*lenA*lenB)) ; break ; case 1 : /* lenA is zero */ aa = SGD_ZERO ; bb = cc = SGD_90 ; break ; case 2 : /* lenB is zero */ bb = SGD_ZERO ; aa = cc = SGD_90 ; break ; case 4 : /* lenC is zero */ cc = SGD_ZERO ; aa = bb = SGD_90 ; break ; case 3 : /* Two lengths are zero and the third isn't?!? */ case 5 : case 6 : aa = bb = cc = SGD_ZERO ; break ; default : /* All three sides are zero length */ aa = bb = cc = SGD_60 ; break ; } if ( angA ) *angA = aa ; if ( angB ) *angB = bb ; if ( angC ) *angC = cc ; } void sgdTriangleSolver_SAStoASA ( SGDfloat lenA, SGDfloat angB, SGDfloat lenC, SGDfloat *angA, SGDfloat *lenB, SGDfloat *angC ) { /* Get third side using Cosine Rule */ SGDfloat s = lenC * lenC + lenA * lenA - SGD_TWO * lenC * lenA * sgdCos( angB ) ; SGDfloat lb = ( s <= SGD_ZERO ) ? SGD_ZERO : (SGDfloat) sqrt ( s ) ; if ( lenB ) *lenB = lb ; sgdTriangleSolver_SSStoAAA ( lenA, lb, lenC, angA, NULL, angC ) ; } void sgdTriangleSolver_ASAtoSAS ( SGDfloat angA, SGDfloat lenB, SGDfloat angC, SGDfloat *lenA, SGDfloat *angB, SGDfloat *lenC ) { /* Find the missing angle */ SGDfloat bb = SGD_180 - (angA + angC) ; if ( angB ) *angB = bb ; /* Use Sine Rule */ SGDfloat sinB = sgdSin ( bb ) ; if ( sinB == SGD_ZERO ) { if ( lenA ) *lenA = lenB / SGD_TWO ; /* One valid interpretation */ if ( lenC ) *lenC = lenB / SGD_TWO ; } else { if ( lenA ) *lenA = lenB * sgdSin(angA) / sinB ; if ( lenC ) *lenC = lenB * sgdSin(angC) / sinB ; } } void sgdTriangleSolver_ASStoSAA ( SGDfloat angB, SGDfloat lenA, SGDfloat lenB, int angA_is_obtuse, SGDfloat *lenC, SGDfloat *angA, SGDfloat *angC ) { /* Sine law */ SGDfloat aa = (lenB == SGD_ZERO ) ? SGD_ZERO : sgdASin (lenA * sgdSin(angB)/lenB) ; if ( angA_is_obtuse ) aa = SGD_180 - aa ; if ( angA ) *angA = aa ; /* Find the missing angle */ SGDfloat cc = SGD_180 - (aa + angB) ; if ( angC ) *angC = cc ; /* Use SAStoASA to get the last length */ sgdTriangleSolver_SAStoASA ( lenA, cc, lenB, NULL, lenC, NULL ) ; } void sgdTriangleSolver_SAAtoASS ( SGDfloat lenA, SGDfloat angB, SGDfloat angA, SGDfloat *angC, SGDfloat *lenB, SGDfloat *lenC ) { /* Find the missing angle */ SGDfloat cc = SGD_180 - (angB + angA) ; if ( angC ) *angC = cc ; sgdTriangleSolver_ASAtoSAS ( cc, lenA, angB, lenC, NULL, lenB ) ; } plib-1.8.5/src/sg/Makefile.in0000644000175000001440000003667510765365023012665 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/sg DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibsg_a_AR = $(AR) $(ARFLAGS) libplibsg_a_LIBADD = am__libplibsg_a_SOURCES_DIST = sg.cxx sgd.cxx sgIsect.cxx sgdIsect.cxx \ sgPerlinNoise.cxx @BUILD_SG_TRUE@am_libplibsg_a_OBJECTS = sg.$(OBJEXT) sgd.$(OBJEXT) \ @BUILD_SG_TRUE@ sgIsect.$(OBJEXT) sgdIsect.$(OBJEXT) \ @BUILD_SG_TRUE@ sgPerlinNoise.$(OBJEXT) libplibsg_a_OBJECTS = $(am_libplibsg_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libplibsg_a_SOURCES) DIST_SOURCES = $(am__libplibsg_a_SOURCES_DIST) am__include_HEADERS_DIST = sg.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_SG_TRUE@lib_LIBRARIES = libplibsg.a @BUILD_SG_TRUE@include_HEADERS = sg.h @BUILD_SG_TRUE@libplibsg_a_SOURCES = sg.cxx sgd.cxx \ @BUILD_SG_TRUE@ sgIsect.cxx sgdIsect.cxx \ @BUILD_SG_TRUE@ sgPerlinNoise.cxx @BUILD_SG_TRUE@INCLUDES = -I$(top_srcdir)/src/util EXTRA_DIST = sg.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sg/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/sg/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibsg.a: $(libplibsg_a_OBJECTS) $(libplibsg_a_DEPENDENCIES) -rm -f libplibsg.a $(libplibsg_a_AR) libplibsg.a $(libplibsg_a_OBJECTS) $(libplibsg_a_LIBADD) $(RANLIB) libplibsg.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgIsect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgPerlinNoise.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgdIsect.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/sg/sgPerlinNoise.cxx0000644000175000001440000001730610765364434014120 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ /* sgPerlinNoise This is a class to implement coherent noise over 1, 2, or 3 dimensions. The implementation is based on the Ken Perlin's noise function and borrows heavily from Matt Zucker's implementation. */ #include #include #include #include "sg.h" static unsigned int *permTable = NULL ; static void initPermTable () { int i ; if ( permTable != NULL ) return ; permTable = new unsigned int [ SG_PERLIN_NOISE_WRAP_INDEX * 2 + 2 ] ; for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX ; i++ ) permTable[i] = i ; /* Shuffle permutation table up to SG_PERLIN_NOISE_WRAP_INDEX */ for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX ; i++ ) { int j = rand () & SG_PERLIN_NOISE_MOD_MASK ; int temp = permTable [ i ] ; permTable [ i ] = permTable [ j ] ; permTable [ j ] = temp ; } /* Add the rest of the table entries in, duplicating indices and entries so that they can effectively be indexed by unsigned chars. I think. Ask Perlin what this is really doing. */ for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX + 2 ; i++ ) permTable [ SG_PERLIN_NOISE_WRAP_INDEX + i ] = permTable [ i ] ; } /* S curve is (3x^2 - 2x^3) because it's quick to calculate though -cos(x * PI) * 0.5 + 0.5 would work too */ inline SGfloat easeCurve ( SGfloat t ) { return (SGfloat) (t * t * (3.0 - 2.0 * t)) ; } inline SGfloat dot2 ( SGfloat rx, SGfloat ry, sgVec2 q ) { return rx * q[0] + ry * q[1] ; } inline SGfloat dot3 ( SGfloat rx, SGfloat ry, SGfloat rz, sgVec3 q ) { return rx * q[0] + ry * q[1] + rz * q[2] ; } inline SGfloat randFloat () { return (SGfloat)(( rand() % ( SG_PERLIN_NOISE_WRAP_INDEX + SG_PERLIN_NOISE_WRAP_INDEX ) ) - SG_PERLIN_NOISE_WRAP_INDEX ) / SG_PERLIN_NOISE_WRAP_INDEX ; } inline void setupValues ( int axis, int *g0, int *g1, SGfloat *d0, SGfloat *d1, SGfloat *pos ) { SGfloat t = pos[axis] + SG_PERLIN_NOISE_LARGE_PWR2 ; int it = (int) t ; *g0 = it & SG_PERLIN_NOISE_MOD_MASK ; *g1 = (*g0 + 1) & SG_PERLIN_NOISE_MOD_MASK ; *d0 = t - it ; *d1 = *d0 - 1.0f ; } SGfloat sgPerlinNoise_1D::getNoise ( SGfloat pos ) { int gridL, gridR ; SGfloat distL, distR ; /* Find out neighboring grid points to pos and signed distances from pos to them. */ setupValues ( 0, &gridL, &gridR, &distL , &distR , &pos ) ; return sgLerp ( distL * gradTable [ permTable [ gridL ] ], distR * gradTable [ permTable [ gridR ] ], easeCurve ( distL ) ) ; } SGfloat sgPerlinNoise_2D::getNoise ( sgVec2 pos ) { int gridL, gridR, gridD, gridU ; SGfloat distL, distR, distD, distU ; /* Find out neighboring grid points to pos and signed distances from pos to them. */ setupValues ( 0, &gridL, &gridR, &distL, &distR, pos ) ; setupValues ( 1, &gridD, &gridU, &distD, &distU, pos ) ; /* Generate some temporary indexes associated with the left and right grid values */ int indexL = permTable [ gridL ] ; int indexR = permTable [ gridR ] ; /* Generate indexes in the permutation table for all 4 corners */ int indexLD = permTable [ indexL + gridD ] ; int indexRD = permTable [ indexR + gridD ] ; int indexLU = permTable [ indexL + gridU ] ; int indexRU = permTable [ indexR + gridU ] ; /* Get the s curves at the proper values */ SGfloat sX = easeCurve ( distL ) ; SGfloat sY = easeCurve ( distD ) ; return sgLerp ( sgLerp ( dot2 ( distL, distD, gradTable [ indexLD ] ), dot2 ( distR, distD, gradTable [ indexRD ] ), sX ), sgLerp ( dot2 ( distL, distU, gradTable [ indexLU ] ), dot2 ( distR, distU, gradTable [ indexRU ] ), sX ), sY ) ; } SGfloat sgPerlinNoise_3D::getNoise ( sgVec3 pos ) { int gridL, gridR, gridD, gridU, gridB, gridF ; SGfloat distL, distR, distD, distU, distB, distF ; /* Find out neighboring grid points to pos and signed distances from pos to them. */ setupValues ( 0, &gridL, &gridR, &distL, &distR, pos ) ; setupValues ( 1, &gridD, &gridU, &distD, &distU, pos ) ; setupValues ( 2, &gridB, &gridF, &distB, &distF, pos ) ; int indexL = permTable [ gridL ] ; int indexR = permTable [ gridR ] ; int indexLD = permTable [ indexL + gridD ] ; int indexRD = permTable [ indexR + gridD ] ; int indexLU = permTable [ indexL + gridU ] ; int indexRU = permTable [ indexR + gridU ] ; SGfloat sX = easeCurve ( distL ) ; SGfloat sY = easeCurve ( distD ) ; SGfloat sZ = easeCurve ( distB ) ; return sgLerp ( sgLerp ( sgLerp ( dot3 ( distL, distD, distB, gradTable [ indexLD + gridB ] ), dot3 ( distR, distD, distB, gradTable [ indexRD + gridB ] ), sX ), sgLerp ( dot3 ( distL, distU, distB, gradTable [ indexLU + gridB ] ), dot3 ( distR, distU, distB, gradTable [ indexRU + gridB ] ), sX ), sY ), sgLerp ( sgLerp ( dot3 ( distL, distD, distF, gradTable [ indexLD + gridF ] ), dot3 ( distR, distD, distF, gradTable [ indexRD + gridF ] ), sX ), sgLerp ( dot3 ( distL, distU, distF, gradTable [ indexLU + gridF ] ), dot3 ( distR, distU, distF, gradTable [ indexRU + gridF ] ), sX ), sY ), sZ ) ; } sgPerlinNoise_1D::sgPerlinNoise_1D () { regenerate () ; } void sgPerlinNoise_1D::regenerate () { int i ; for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX ; i++ ) gradTable [ i ] = randFloat () ; for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX + 2 ; i++ ) gradTable [ SG_PERLIN_NOISE_WRAP_INDEX + i ] = gradTable [ i ] ; initPermTable () ; } sgPerlinNoise_2D::sgPerlinNoise_2D () { regenerate () ; } void sgPerlinNoise_2D::regenerate () { int i ; for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX ; i++ ) { sgSetVec2 ( gradTable [ i ], randFloat(), randFloat() ) ; sgNormalizeVec2 ( gradTable [ i ] ) ; } for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX + 2 ; i++ ) { gradTable [ SG_PERLIN_NOISE_WRAP_INDEX + i ][ 0 ] = gradTable [ i ][ 0 ] ; gradTable [ SG_PERLIN_NOISE_WRAP_INDEX + i ][ 1 ] = gradTable [ i ][ 1 ] ; } initPermTable () ; } sgPerlinNoise_3D::sgPerlinNoise_3D () { regenerate () ; } void sgPerlinNoise_3D::regenerate () { int i ; for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX ; i++ ) { sgSetVec3 ( gradTable [ i ], randFloat(), randFloat(), randFloat() ) ; sgNormalizeVec3 ( gradTable [ i ] ) ; } for ( i = 0 ; i < SG_PERLIN_NOISE_WRAP_INDEX + 2 ; i++ ) { gradTable [ SG_PERLIN_NOISE_WRAP_INDEX + i ][ 0 ] = gradTable [ i ][ 0 ] ; gradTable [ SG_PERLIN_NOISE_WRAP_INDEX + i ][ 1 ] = gradTable [ i ][ 1 ] ; gradTable [ SG_PERLIN_NOISE_WRAP_INDEX + i ][ 2 ] = gradTable [ i ][ 2 ] ; } initPermTable () ; } plib-1.8.5/src/sg/sg.dsp0000644000175000001440000000637210765364434011735 00000000000000# Microsoft Developer Studio Project File - Name="sg" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=sg - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "sg.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "sg.mak" CFG="sg - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "sg - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "sg - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "sg - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\util" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy sg.h ..\..\sg.h # End Special Build Tool !ELSEIF "$(CFG)" == "sg - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\util" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\sg_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy sg.h ..\..\sg.h # End Special Build Tool !ENDIF # Begin Target # Name "sg - Win32 Release" # Name "sg - Win32 Debug" # Begin Source File SOURCE=.\sg.cxx # End Source File # Begin Source File SOURCE=.\sg.h # End Source File # Begin Source File SOURCE=.\sgd.cxx # End Source File # Begin Source File SOURCE=.\sgdIsect.cxx # End Source File # Begin Source File SOURCE=.\sgIsect.cxx # End Source File # Begin Source File SOURCE=.\sgPerlinNoise.cxx # End Source File # End Target # End Project plib-1.8.5/src/fnt/0000777000175000001440000000000010765365521011044 500000000000000plib-1.8.5/src/fnt/fnt.h0000644000175000001440000002417510765364434011733 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: fnt.h 1923 2004-04-06 12:53:17Z sjbaker $ */ #ifndef _FNT_H_ #define _FNT_H_ 1 #include #include "sg.h" #ifdef UL_MAC_OSX # include #else # include #endif #define FNTMAX_CHAR 256 #define FNT_TRUE 1 #define FNT_FALSE 0 class fntFont { public: fntFont () ; virtual ~fntFont () ; virtual void getBBox ( const char *s, float pointsize, float italic, float *left, float *right, float *bot , float *top ) = 0 ; virtual void putch ( sgVec3 curpos, float pointsize, float italic, char c ) = 0 ; virtual void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) = 0 ; virtual void begin () = 0 ; virtual void end () = 0 ; virtual int load ( const char *fname, GLenum mag = GL_NEAREST, GLenum min = GL_LINEAR_MIPMAP_LINEAR ) = 0 ; virtual void setFixedPitch ( int fix ) = 0 ; virtual int isFixedPitch () const = 0 ; virtual void setWidth ( float w ) = 0 ; virtual void setGap ( float g ) = 0 ; virtual float getWidth () const = 0 ; virtual float getGap () const = 0 ; virtual int hasGlyph ( char c ) const = 0 ; } ; class fntTexFont : public fntFont { private: GLuint texture ; int bound ; int fixed_pitch ; float width ; /* The width of a character in fixed-width mode */ float gap ; /* Set the gap between characters */ int exists [ FNTMAX_CHAR ] ; /* TRUE if character exists in tex-map */ /* The quadrilaterals that describe the characters in the font are drawn with the following texture and spatial coordinates. The texture coordinates are in (S,T) space, with (0,0) at the bottom left of the image and (1,1) at the top-right. The spatial coordinates are relative to the current 'cursor' position. They should be scaled such that 1.0 represent the height of a capital letter. Hence, characters like 'y' which have a descender will be given a negative v_bot. Most capitals will have v_bot==0.0 and v_top==1.0. */ /* Nominal baseline widths */ float widths [ FNTMAX_CHAR ] ; /* Texture coordinates */ float t_top [ FNTMAX_CHAR ] ; /* Top edge of each character [0..1] */ float t_bot [ FNTMAX_CHAR ] ; /* Bottom edge of each character [0..1] */ float t_left [ FNTMAX_CHAR ] ; /* Left edge of each character [0..1] */ float t_right [ FNTMAX_CHAR ] ; /* Right edge of each character [0..1] */ /* Vertex coordinates. */ float v_top [ FNTMAX_CHAR ] ; float v_bot [ FNTMAX_CHAR ] ; float v_left [ FNTMAX_CHAR ] ; float v_right [ FNTMAX_CHAR ] ; void bind_texture () { glEnable ( GL_TEXTURE_2D ) ; #ifdef GL_VERSION_1_1 glBindTexture ( GL_TEXTURE_2D, texture ) ; #else /* For ancient SGI machines */ glBindTextureEXT ( GL_TEXTURE_2D, texture ) ; #endif } float low_putch ( sgVec3 curpos, float pointsize, float italic, char c ) ; int loadTXF ( const char *fname, GLenum mag = GL_NEAREST, GLenum min = GL_LINEAR_MIPMAP_LINEAR ) ; public: fntTexFont () { bound = FNT_FALSE ; fixed_pitch = FNT_TRUE ; texture = 0 ; width = 1.0f ; gap = 0.1f ; memset ( exists, FNT_FALSE, FNTMAX_CHAR * sizeof(int) ) ; } fntTexFont ( const char *fname, GLenum mag = GL_NEAREST, GLenum min = GL_LINEAR_MIPMAP_LINEAR ) : fntFont () { bound = FNT_FALSE ; fixed_pitch = FNT_TRUE ; texture = 0 ; width = 1.0f ; gap = 0.1f ; memset ( exists, FNT_FALSE, FNTMAX_CHAR * sizeof(int) ) ; load ( fname, mag, min ) ; } ~fntTexFont () { if ( texture != 0 ) { #ifdef GL_VERSION_1_1 glDeleteTextures ( 1, &texture ) ; #else /* For ancient SGI machines */ glDeleteTexturesEXT ( 1, &texture ) ; #endif } } int load ( const char *fname, GLenum mag = GL_NEAREST, GLenum min = GL_LINEAR_MIPMAP_LINEAR ) ; void setFixedPitch ( int fix ) { fixed_pitch = fix ; } int isFixedPitch () const { return fixed_pitch ; } void setWidth ( float w ) { width = w ; } void setGap ( float g ) { gap = g ; } float getWidth () const { return width ; } float getGap () const { return gap ; } void setGlyph ( char c, float wid, float tex_left, float tex_right, float tex_bot , float tex_top , float vtx_left, float vtx_right, float vtx_bot , float vtx_top ) ; void setGlyph ( char c, float tex_left, float tex_right, float tex_bot , float tex_top , float vtx_left, float vtx_right, float vtx_bot , float vtx_top ) /* deprecated */ { setGlyph ( c, vtx_right, tex_left, tex_right, tex_bot, tex_top, vtx_left, vtx_right, vtx_bot, vtx_top ) ; } int getGlyph ( char c, float* wid, float *tex_left = NULL, float *tex_right = NULL, float *tex_bot = NULL, float *tex_top = NULL, float *vtx_left = NULL, float *vtx_right = NULL, float *vtx_bot = NULL, float *vtx_top = NULL) ; int getGlyph ( char c, float *tex_left = NULL, float *tex_right = NULL, float *tex_bot = NULL, float *tex_top = NULL, float *vtx_left = NULL, float *vtx_right = NULL, float *vtx_bot = NULL, float *vtx_top = NULL) /* deprecated */ { return getGlyph ( c, NULL, tex_left, tex_right, tex_bot, tex_top, vtx_left, vtx_right, vtx_bot, vtx_top ) ; } int hasGlyph ( char c ) const { return exists[ (GLubyte) c ] ; } void getBBox ( const char *s, float pointsize, float italic, float *left, float *right, float *bot , float *top ) ; void begin () { bind_texture () ; bound = FNT_TRUE ; } void end () { bound = FNT_FALSE ; } void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) ; void putch ( sgVec3 curpos, float pointsize, float italic, char c ) { if ( ! bound ) bind_texture () ; low_putch ( curpos, pointsize, italic, c ) ; } } ; class fntBitmapFont : public fntFont { protected: const GLubyte **data; int first; int count; int height; float xorig, yorig; int fix; float wid, gap; public: // data is a null-terminated list of glyph images: // data[i][0] - image width // data[i][1..n] - packed bitmap fntBitmapFont ( const GLubyte **data, int first, int height, float xorig, float yorig ) ; virtual ~fntBitmapFont () ; virtual void getBBox ( const char *s, float pointsize, float italic, float *left, float *right, float *bot , float *top ) ; virtual void putch ( sgVec3 curpos, float pointsize, float italic, char c ) ; virtual void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) ; virtual void begin () ; virtual void end () ; virtual int load ( const char *fname, GLenum mag, GLenum min ) { return -1; } virtual void setFixedPitch ( int f ) { fix = f; } virtual int isFixedPitch () const { return fix; } virtual void setWidth ( float w ) { wid = w; } virtual void setGap ( float g ) { gap = g; } virtual float getWidth () const { return wid; } virtual float getGap () const { return gap; } virtual int hasGlyph ( char c ) const ; }; /* Builtin Bitmap Fonts */ #define FNT_BITMAP_8_BY_13 0 #define FNT_BITMAP_9_BY_15 1 #define FNT_BITMAP_HELVETICA_10 2 #define FNT_BITMAP_HELVETICA_12 3 #define FNT_BITMAP_HELVETICA_18 4 #define FNT_BITMAP_TIMES_ROMAN_10 5 #define FNT_BITMAP_TIMES_ROMAN_24 6 fntBitmapFont *fntGetBitmapFont(int id); class fntRenderer { fntFont *font ; sgVec3 curpos ; float pointsize ; float italic ; public: fntRenderer () { start2f ( 0.0f, 0.0f ) ; font = NULL ; pointsize = 10 ; italic = 0 ; } void start3fv ( sgVec3 pos ) { sgCopyVec3 ( curpos, pos ) ; } void start2fv ( sgVec2 pos ) { sgCopyVec2 ( curpos, pos ) ; curpos[2]=0.0f ; } void start2f ( float x, float y ) { sgSetVec3 ( curpos, x, y, 0.0f ) ; } void start3f ( float x, float y, float z ) { sgSetVec3 ( curpos, x, y, z ) ; } void getCursor ( float *x, float *y, float *z ) const { if ( x != NULL ) *x = curpos [ 0 ] ; if ( y != NULL ) *y = curpos [ 1 ] ; if ( z != NULL ) *z = curpos [ 2 ] ; } void setFont ( fntFont *f ) { font = f ; } fntFont *getFont () const { return font ; } void setSlant ( float i ) { italic = i ; } void setPointSize ( float p ) { pointsize = p ; } float getSlant () const { return italic ; } float getPointSize () const { return pointsize ; } void begin () { font->begin () ; } void end () { font->end () ; } void putch ( char c ) { font->putch ( curpos, pointsize, italic, c ) ; } void puts ( const char *s ) { font->puts ( curpos, pointsize, italic, s ) ; } } ; void fntInit () ; #endif plib-1.8.5/src/fnt/fntTXF.cxx0000644000175000001440000002300010765364434012652 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: fntTXF.cxx 1735 2002-12-01 18:21:48Z sjbaker $ */ #include "fntLocal.h" #ifdef UL_MACINTOSH # include #elif defined(UL_MAC_OSX) # include #elif defined(UL_WIN32) /* Nothing */ #else # include #endif static bool glIsValidContext ( void ) { #if defined(CONSOLE) return true ; #elif defined(UL_WIN32) return ( wglGetCurrentContext () != NULL ) ; #elif defined(UL_MACINTOSH) return ( aglGetCurrentContext () != NULL ) ; #elif defined(UL_MAC_OSX) return ( CGLGetCurrentContext () != NULL ) ; #else return ( glXGetCurrentContext () != NULL ) ; #endif } FILE *_fntCurrImageFd ; int _fntIsSwapped = FALSE ; static void tex_make_mip_maps ( GLubyte *image, int xsize, int ysize, int zsize ) { GLubyte *texels [ 20 ] ; /* One element per level of MIPmap */ for ( int l = 0 ; l < 20 ; l++ ) texels [ l ] = NULL ; texels [ 0 ] = image ; int lev ; for ( lev = 0 ; (( xsize >> (lev+1) ) != 0 || ( ysize >> (lev+1) ) != 0 ) ; lev++ ) { /* Suffix '1' is the higher level map, suffix '2' is the lower level. */ int l1 = lev ; int l2 = lev+1 ; int w1 = xsize >> l1 ; int h1 = ysize >> l1 ; int w2 = xsize >> l2 ; int h2 = ysize >> l2 ; if ( w1 <= 0 ) w1 = 1 ; if ( h1 <= 0 ) h1 = 1 ; if ( w2 <= 0 ) w2 = 1 ; if ( h2 <= 0 ) h2 = 1 ; texels [ l2 ] = new GLubyte [ w2 * h2 * zsize ] ; for ( int x2 = 0 ; x2 < w2 ; x2++ ) for ( int y2 = 0 ; y2 < h2 ; y2++ ) for ( int c = 0 ; c < zsize ; c++ ) { int x1 = x2 + x2 ; int x1_1 = ( x1 + 1 ) % w1 ; int y1 = y2 + y2 ; int y1_1 = ( y1 + 1 ) % h1 ; int t1 = texels [ l1 ] [ (y1 * w1 + x1 ) * zsize + c ] ; int t2 = texels [ l1 ] [ (y1_1 * w1 + x1 ) * zsize + c ] ; int t3 = texels [ l1 ] [ (y1 * w1 + x1_1) * zsize + c ] ; int t4 = texels [ l1 ] [ (y1_1 * w1 + x1_1) * zsize + c ] ; texels [ l2 ] [ (y2 * w2 + x2) * zsize + c ] = ( t1 + t2 + t3 + t4 ) / 4 ; } } texels [ lev+1 ] = NULL ; if ( ! ((xsize & (xsize-1))==0) || ! ((ysize & (ysize-1))==0) ) { ulSetError ( UL_FATAL, "TXFloader: TXF Map is not a power-of-two in size!" ) ; } glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ) ; int map_level = 0 ; #ifdef PROXY_TEXTURES_ARE_NOT_BROKEN int ww ; do { glTexImage2D ( GL_PROXY_TEXTURE_2D, map_level, zsize, xsize, ysize, FALSE /* Border */, (zsize==1)?GL_LUMINANCE: (zsize==2)?GL_LUMINANCE_ALPHA: (zsize==3)?GL_RGB: GL_RGBA, GL_UNSIGNED_BYTE, NULL ) ; glGetTexLevelParameteriv ( GL_PROXY_TEXTURE_2D, 0,GL_TEXTURE_WIDTH, &ww ) ; if ( ww == 0 ) { delete [] texels [ 0 ] ; xsize >>= 1 ; ysize >>= 1 ; for ( int l = 0 ; texels [ l ] != NULL ; l++ ) texels [ l ] = texels [ l+1 ] ; if ( xsize < 64 && ysize < 64 ) { ulSetError ( UL_FATAL, "FNT: OpenGL will not accept a font texture?!?" ) ; } } } while ( ww == 0 ) ; #endif for ( int i = 0 ; texels [ i ] != NULL ; i++ ) { int w = xsize>>i ; int h = ysize>>i ; if ( w <= 0 ) w = 1 ; if ( h <= 0 ) h = 1 ; glTexImage2D ( GL_TEXTURE_2D, map_level, zsize, w, h, FALSE /* Border */, (zsize==1)?GL_LUMINANCE: (zsize==2)?GL_LUMINANCE_ALPHA: (zsize==3)?GL_RGB: GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) texels[i] ) ; map_level++ ; delete [] texels [ i ] ; } } int fntTexFont::loadTXF ( const char *fname, GLenum mag, GLenum min ) { if ( ! glIsValidContext () ) { ulSetError ( UL_FATAL, "FNT font loader called without a valid OpenGL context."); } FILE *fd ; if ( (fd = fopen ( fname, "rb" )) == NULL ) { ulSetError ( UL_WARNING, "fntLoadTXF: Failed to open '%s' for reading.", fname ) ; return FNT_FALSE ; } _fntCurrImageFd = fd ; unsigned char magic [ 4 ] ; if ( (int)fread ( &magic, sizeof (unsigned int), 1, fd ) != 1 ) { ulSetError ( UL_WARNING, "fntLoadTXF: '%s' an empty file!", fname ) ; return FNT_FALSE ; } if ( magic [ 0 ] != 0xFF || magic [ 1 ] != 't' || magic [ 2 ] != 'x' || magic [ 3 ] != 'f' ) { ulSetError ( UL_WARNING, "fntLoadTXF: '%s' is not a 'txf' font file.", fname ) ; return FNT_FALSE ; } _fntIsSwapped = FALSE ; int endianness = _fnt_readInt () ; _fntIsSwapped = ( endianness != 0x12345678 ) ; int format = _fnt_readInt () ; int tex_width = _fnt_readInt () ; int tex_height = _fnt_readInt () ; int max_height = _fnt_readInt () ; _fnt_readInt () ; int num_glyphs = _fnt_readInt () ; int w = tex_width ; int h = tex_height ; float xstep = 0.5f / (float) w ; float ystep = 0.5f / (float) h ; int i, j ; /* Load the TXF_Glyph array */ TXF_Glyph glyph ; for ( i = 0 ; i < num_glyphs ; i++ ) { glyph . ch = _fnt_readShort () ; glyph . w = _fnt_readByte () ; glyph . h = _fnt_readByte () ; glyph . x_off = _fnt_readByte () ; glyph . y_off = _fnt_readByte () ; glyph . step = _fnt_readByte () ; glyph . unknown = _fnt_readByte () ; glyph . x = _fnt_readShort () ; glyph . y = _fnt_readShort () ; setGlyph ( (char) glyph.ch, (float) glyph.step / (float) max_height, (float) glyph.x / (float) w + xstep, (float)( glyph.x + glyph.w ) / (float) w + xstep, (float) glyph.y / (float) h + ystep, (float)( glyph.y + glyph.h ) / (float) h + ystep, (float) glyph.x_off / (float) max_height, (float)( glyph.x_off + glyph.w ) / (float) max_height, (float) glyph.y_off / (float) max_height, (float)( glyph.y_off + glyph.h ) / (float) max_height ) ; } exists [ ' ' ] = FALSE ; /* Load the image part of the file */ int ntexels = w * h ; unsigned char *teximage ; unsigned char *texbitmap ; switch ( format ) { case FNT_BYTE_FORMAT: { unsigned char *orig = new unsigned char [ ntexels ] ; if ( (int)fread ( orig, 1, ntexels, fd ) != ntexels ) { ulSetError ( UL_WARNING, "fntLoadTXF: Premature EOF in '%s'.", fname ) ; return FNT_FALSE ; } teximage = new unsigned char [ 2 * ntexels ] ; for ( i = 0 ; i < ntexels ; i++ ) { teximage [ i*2 ] = orig [ i ] ; teximage [ i*2 + 1 ] = orig [ i ] ; } delete [] orig ; } break ; case FNT_BITMAP_FORMAT: { int stride = (w + 7) >> 3; texbitmap = new unsigned char [ stride * h ] ; if ( (int)fread ( texbitmap, 1, stride * h, fd ) != stride * h ) { delete [] texbitmap ; ulSetError ( UL_WARNING, "fntLoadTXF: Premature EOF in '%s'.", fname ) ; return FNT_FALSE ; } teximage = new unsigned char [ 2 * ntexels ] ; for ( i = 0 ; i < 2 * ntexels ; i++ ) teximage [ i ] = 0 ; for (i = 0; i < h; i++) for (j = 0; j < w; j++) if (texbitmap[i * stride + (j >> 3)] & (1 << (j & 7))) { teximage[(i * w + j) * 2 ] = 255; teximage[(i * w + j) * 2 + 1] = 255; } delete [] texbitmap ; } break ; default: ulSetError ( UL_WARNING, "fntLoadTXF: Unrecognised format type in '%s'.", fname ) ; return FNT_FALSE ; } fclose ( fd ) ; fixed_pitch = FALSE ; #ifdef GL_VERSION_1_1 glGenTextures ( 1, & texture ) ; glBindTexture ( GL_TEXTURE_2D, texture ) ; #else /* This is only useful on some ancient SGI hardware */ glGenTexturesEXT ( 1, & texture ) ; glBindTextureEXT ( GL_TEXTURE_2D, texture ) ; #endif tex_make_mip_maps ( teximage, w, h, 2 ) ; glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ; glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag ) ; glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min ) ; glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ) ; glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ) ; #ifdef GL_VERSION_1_1 glBindTexture ( GL_TEXTURE_2D, 0 ) ; #else glBindTextureEXT ( GL_TEXTURE_2D, 0 ) ; #endif return FNT_TRUE ; } plib-1.8.5/src/fnt/fnt.cxx0000644000175000001440000001510010765364434012272 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: fnt.cxx 1939 2004-08-05 00:41:53Z puggles $ */ #include "fntLocal.h" fntFont:: fntFont () {} fntFont::~fntFont () {} int fntTexFont::load ( const char *fname, GLenum mag, GLenum min ) { const char *p ; for ( p = & fname [ strlen ( fname ) -1 ] ; p != fname && *p != '.' && *p != '/' ; p-- ) /* Do nothing */ ; if ( strcmp ( p, ".txf" ) == 0 ) { return loadTXF ( fname, mag, min ) ; } else { ulSetError ( UL_WARNING, "fnt::load: Error - Unrecognised file format for '%s'", fname ) ; return FNT_FALSE ; } } float fntTexFont::low_putch ( sgVec3 curpos, float pointsize, float italic, char c ) { unsigned int cc = (unsigned char) c ; /* Auto case-convert if character is absent from font. */ if ( ! exists [ cc ] ) { if ( cc >= 'A' && cc <= 'Z' ) cc = cc - 'A' + 'a' ; else if ( cc >= 'a' && cc <= 'z' ) cc = cc - 'a' + 'A' ; if ( cc == ' ' ) { curpos [ 0 ] += pointsize / 2.0f ; return pointsize / 2.0f ; } } /* We might want to consider making some absent characters from others (if they exist): lowercase 'l' could be made into digit '1' or letter 'O' into digit '0'...or vice versa. We could also make 'b', 'd', 'p' and 'q' by mirror-imaging - this would save a little more texture memory in some fonts. */ if ( ! exists [ cc ] ) return 0.0f ; glBegin ( GL_TRIANGLE_STRIP ) ; glTexCoord2f ( t_left [cc], t_bot[cc] ) ; glVertex3f ( curpos[0] + v_left [cc] * pointsize, curpos[1] + v_bot [cc] * pointsize, curpos[2] ) ; glTexCoord2f ( t_left [cc], t_top[cc] ) ; glVertex3f ( curpos[0] + (italic + v_left [cc]) * pointsize, curpos[1] + v_top [cc] * pointsize, curpos[2] ) ; glTexCoord2f ( t_right[cc], t_bot[cc] ) ; glVertex3f ( curpos[0] + v_right[cc] * pointsize, curpos[1] + v_bot [cc] * pointsize, curpos[2] ) ; glTexCoord2f ( t_right[cc], t_top[cc] ) ; glVertex3f ( curpos[0] + (italic + v_right[cc]) * pointsize, curpos[1] + v_top [cc] * pointsize, curpos[2] ) ; glEnd () ; float ww = ( gap + ( fixed_pitch ? width : widths[cc] ) ) * pointsize ; curpos[0] += ww ; return ww ; } void fntTexFont::setGlyph ( char c, float wid, float tex_left, float tex_right, float tex_bot , float tex_top , float vtx_left, float vtx_right, float vtx_bot , float vtx_top ) { unsigned int cc = (unsigned char) c ; exists[cc] = FNT_TRUE ; widths[cc] = wid; t_left[cc] = tex_left ; t_right[cc] = tex_right ; t_bot [cc] = tex_bot ; t_top [cc] = tex_top ; v_left[cc] = vtx_left ; v_right[cc] = vtx_right ; v_bot [cc] = vtx_bot ; v_top [cc] = vtx_top ; } int fntTexFont::getGlyph ( char c, float* wid, float *tex_left, float *tex_right, float *tex_bot , float *tex_top , float *vtx_left, float *vtx_right, float *vtx_bot , float *vtx_top ) { unsigned int cc = (unsigned char) c ; if ( ! exists[cc] ) return FNT_FALSE ; if ( wid != NULL ) *wid = widths [cc] ; if ( tex_left != NULL ) *tex_left = t_left [cc] ; if ( tex_right != NULL ) *tex_right = t_right[cc] ; if ( tex_bot != NULL ) *tex_bot = t_bot [cc] ; if ( tex_top != NULL ) *tex_top = t_top [cc] ; if ( vtx_left != NULL ) *vtx_left = v_left [cc] ; if ( vtx_right != NULL ) *vtx_right = v_right[cc] ; if ( vtx_bot != NULL ) *vtx_bot = v_bot [cc] ; if ( vtx_top != NULL ) *vtx_top = v_top [cc] ; return FNT_TRUE ; } void fntTexFont::getBBox ( const char *s, float pointsize, float italic, float *left, float *right, float *bot , float *top ) { float h_pos = 0.0f ; float v_pos = 0.0f ; float l, r, b, t ; l = r = b = t = 0.0f ; while ( *s != '\0' ) { if ( *s == '\n' ) { h_pos = 0.0f ; v_pos -= 1.333f ; s++ ; continue ; } unsigned int cc = (unsigned char) *(s++) ; if ( ! exists [ cc ] ) { if ( cc >= 'A' && cc <= 'Z' ) cc = cc - 'A' + 'a' ; else if ( cc >= 'a' && cc <= 'z' ) cc = cc - 'a' + 'A' ; if ( cc == ' ' ) { r += 0.5f ; h_pos += 0.5f ; continue ; } } if ( ! exists [ cc ] ) continue ; if ( italic >= 0 ) { if ( l > h_pos + v_left [cc] ) l = h_pos + v_left [cc] ; if ( r < gap + h_pos + v_right[cc]+italic ) r = gap + h_pos + v_right[cc] + italic ; } else { if ( l > h_pos + v_left [cc]+italic ) l = h_pos + v_left [cc] + italic ; if ( r < gap + h_pos + v_right[cc] ) r = gap + h_pos + v_right[cc] ; } if ( b > v_pos + v_bot [cc] ) b = v_pos + v_bot [cc] ; if ( t < v_pos + v_top [cc] ) t = v_pos + v_top [cc] ; h_pos += gap + ( fixed_pitch ? width : widths[cc] ) ; } if ( left != NULL ) *left = l * pointsize ; if ( right != NULL ) *right = r * pointsize ; if ( top != NULL ) *top = t * pointsize ; if ( bot != NULL ) *bot = b * pointsize ; } void fntTexFont::puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) { SGfloat origx = curpos[0] ; if ( ! bound ) bind_texture () ; while ( *s != '\0' ) { if (*s == '\n') { curpos[0] = origx ; curpos[1] -= pointsize ; } else low_putch ( curpos, pointsize, italic, *s ) ; s++ ; } } void fntInit () { /* Empty right now */ } plib-1.8.5/src/fnt/fntBitmap.cxx0000644000175000001440000051132010765364434013434 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: fntBitmap.cxx 2036 2005-07-14 16:37:55Z fayjf $ */ #include "fnt.h" fntBitmapFont::fntBitmapFont( const GLubyte **_data, int _first, int _height, float _xorig, float _yorig ) { data = _data; first = _first; count = 0; height = _height; xorig = _xorig; yorig = _yorig; fix = 0; wid = 0; gap = 0; while (data[count] != NULL) count++; } fntBitmapFont::~fntBitmapFont() { } void fntBitmapFont::begin () { glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } void fntBitmapFont::end () { glPopClientAttrib(); } void fntBitmapFont::putch ( sgVec3 curpos, float pointsize, float italic, char c ) { if (c == '\n') { curpos[1] -= height; } else { glRasterPos2i(0,0); // beware - coordinate may be negative glBitmap(0, 0, 0, 0, curpos[0], curpos[1], NULL); int i = (GLubyte) c - first; if (i >= 0 && i < count) { glBitmap(data[i][0], height, xorig, yorig, (float) data[i][0], 0, data[i] + 1); curpos[0] += data[i][0]; } } } void fntBitmapFont::puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) { float x0 = curpos[0]; glRasterPos2i(0,0); // beware - coordinate may be negative glBitmap(0, 0, 0, 0, curpos[0], curpos[1], NULL); for (int i = 0; s[i] != '\0'; i++) { if (s[i] == '\n') { curpos[0] = x0; curpos[1] -= height; glRasterPos2i(0,0); // beware - coordinate may be negative glBitmap(0, 0, 0, 0, curpos[0], curpos[1], NULL); } else { int j = (GLubyte) s[i] - first; if (j >= 0 && j < count) { glBitmap(data[j][0], height, xorig, yorig, (float) data[j][0], 0, data[j] + 1); curpos[0] += data[j][0]; } } } } int fntBitmapFont::hasGlyph ( char c ) const { int i = (GLubyte) c - first; return i >= 0 && i < count && data[i][0] > 0; } void fntBitmapFont::getBBox ( const char *s, float pointsize, float italic, float *left, float *right, float *bot , float *top ) { float l, r, b, t; if (count > 0) { int x1 = 0, y1 = 0, x = 0, y = 0; for (int i = 0; s[i] != '\0'; i++) { if (s[i] == '\n') { if (x > x1) x1 = x; y -= height; x = 0; } else { int j = (GLubyte) s[i] - first; if (j >= 0 && j < count && data[j][0] > 0) { x += data[j][0]; y1 = y; } } } if (x > x1) x1 = x; l = - xorig; r = (float) x1 - xorig; b = (float) y1 - yorig; t = (float) height - yorig; } else { l = r = b = t = 0.0f; } if (left != NULL) *left = l; if (right != NULL) *right = r; if (bot != NULL) *bot = b; if (top != NULL) *top = t; } // This is to match the FreeGLUT definitions below struct SFG_Font { char* Name; /* The source font name */ int Quantity; /* Number of chars in font */ int Height; /* Height of the characters */ const GLubyte** Characters; /* The characters mapping */ float xorig, yorig; /* Relative origin of the character */ }; /* * Below is the font data taken from FreeGLUT. Nothing is changed except * the structures are made "static" to avoid namespace pollution. */ /* * freeglut_font_data.c * * This file has been automatically generated by the genfonts utility. * * Copyright (c) 1999-2000 by Pawel W. Olszta * Written by Pawel W. Olszta, * * 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 Sotware. * * 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 * PAWEL W. OLSZTA 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * Following fonts are defined in this file: * * 1. fgFontFixed8x13 <-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1> * 2. fgFontFixed9x15 <-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1> * 3. fgFontHelvetica10 <-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1> * 4. fgFontHelvetica12 <-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1> * 5. fgFontHelvetica18 <-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1> * 6. fgFontTimesRoman10 <-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1> * 7. fgFontTimesRoman24 <-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1> */ static const GLubyte Fixed8x13_Character_032[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* blank */ static const GLubyte Fixed8x13_Character_097[] = { 8, 0, 0,116,140,132,124, 4,120, 0, 0, 0, 0, 0}; /* "a" */ static const GLubyte Fixed8x13_Character_098[] = { 8, 0, 0,184,196,132,132,196,184,128,128,128, 0, 0}; static const GLubyte Fixed8x13_Character_099[] = { 8, 0, 0,120,132,128,128,132,120, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_100[] = { 8, 0, 0,116,140,132,132,140,116, 4, 4, 4, 0, 0}; static const GLubyte Fixed8x13_Character_101[] = { 8, 0, 0,120,132,128,252,132,120, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_102[] = { 8, 0, 0, 64, 64, 64, 64,248, 64, 64, 68, 56, 0, 0}; static const GLubyte Fixed8x13_Character_103[] = { 8,120,132,120,128,112,136,136,116, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_104[] = { 8, 0, 0,132,132,132,132,196,184,128,128,128, 0, 0}; static const GLubyte Fixed8x13_Character_105[] = { 8, 0, 0,248, 32, 32, 32, 32, 96, 0, 32, 0, 0, 0}; static const GLubyte Fixed8x13_Character_106[] = { 8,112,136,136, 8, 8, 8, 8, 24, 0, 8, 0, 0, 0}; static const GLubyte Fixed8x13_Character_107[] = { 8, 0, 0,132,136,144,224,144,136,128,128,128, 0, 0}; static const GLubyte Fixed8x13_Character_108[] = { 8, 0, 0,248, 32, 32, 32, 32, 32, 32, 32, 96, 0, 0}; static const GLubyte Fixed8x13_Character_109[] = { 8, 0, 0,130,146,146,146,146,236, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_110[] = { 8, 0, 0,132,132,132,132,196,184, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_111[] = { 8, 0, 0,120,132,132,132,132,120, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_112[] = { 8,128,128,128,184,196,132,196,184, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_113[] = { 8, 4, 4, 4,116,140,132,140,116, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_114[] = { 8, 0, 0, 64, 64, 64, 64, 68,184, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_115[] = { 8, 0, 0,120,132, 24, 96,132,120, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_116[] = { 8, 0, 0, 56, 68, 64, 64, 64,248, 64, 64, 0, 0, 0}; static const GLubyte Fixed8x13_Character_117[] = { 8, 0, 0,116,136,136,136,136,136, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_119[] = { 8, 0, 0, 68,170,146,146,130,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_118[] = { 8, 0, 0, 32, 80, 80,136,136,136, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_120[] = { 8, 0, 0,132, 72, 48, 48, 72,132, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_121[] = { 8,120,132, 4,116,140,132,132,132, 0, 0, 0, 0, 0}; static const GLubyte Fixed8x13_Character_122[] = { 8, 0, 0,252, 64, 32, 16, 8,252, 0, 0, 0, 0, 0}; /* "z" */ static const GLubyte Fixed8x13_Character_065[] = { 8, 0, 0,132,132,132,252,132,132,132, 72, 48, 0, 0}; /* "A" */ static const GLubyte Fixed8x13_Character_066[] = { 8, 0, 0,252, 66, 66, 66,124, 66, 66, 66,252, 0, 0}; static const GLubyte Fixed8x13_Character_067[] = { 8, 0, 0,120,132,128,128,128,128,128,132,120, 0, 0}; static const GLubyte Fixed8x13_Character_068[] = { 8, 0, 0,252, 66, 66, 66, 66, 66, 66, 66,252, 0, 0}; static const GLubyte Fixed8x13_Character_069[] = { 8, 0, 0,252,128,128,128,240,128,128,128,252, 0, 0}; static const GLubyte Fixed8x13_Character_070[] = { 8, 0, 0,128,128,128,128,240,128,128,128,252, 0, 0}; static const GLubyte Fixed8x13_Character_071[] = { 8, 0, 0,116,140,132,156,128,128,128,132,120, 0, 0}; static const GLubyte Fixed8x13_Character_072[] = { 8, 0, 0,132,132,132,132,252,132,132,132,132, 0, 0}; static const GLubyte Fixed8x13_Character_073[] = { 8, 0, 0,248, 32, 32, 32, 32, 32, 32, 32,248, 0, 0}; static const GLubyte Fixed8x13_Character_074[] = { 8, 0, 0,112,136, 8, 8, 8, 8, 8, 8, 60, 0, 0}; static const GLubyte Fixed8x13_Character_075[] = { 8, 0, 0,132,136,144,160,192,160,144,136,132, 0, 0}; static const GLubyte Fixed8x13_Character_076[] = { 8, 0, 0,252,128,128,128,128,128,128,128,128, 0, 0}; static const GLubyte Fixed8x13_Character_077[] = { 8, 0, 0,130,130,130,146,146,170,198,130,130, 0, 0}; static const GLubyte Fixed8x13_Character_078[] = { 8, 0, 0,132,132,132,140,148,164,196,132,132, 0, 0}; static const GLubyte Fixed8x13_Character_079[] = { 8, 0, 0,120,132,132,132,132,132,132,132,120, 0, 0}; static const GLubyte Fixed8x13_Character_080[] = { 8, 0, 0,128,128,128,128,248,132,132,132,248, 0, 0}; static const GLubyte Fixed8x13_Character_081[] = { 8, 0, 4,120,148,164,132,132,132,132,132,120, 0, 0}; static const GLubyte Fixed8x13_Character_082[] = { 8, 0, 0,132,136,144,160,248,132,132,132,248, 0, 0}; static const GLubyte Fixed8x13_Character_083[] = { 8, 0, 0,120,132, 4, 4,120,128,128,132,120, 0, 0}; static const GLubyte Fixed8x13_Character_084[] = { 8, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16,254, 0, 0}; static const GLubyte Fixed8x13_Character_085[] = { 8, 0, 0,120,132,132,132,132,132,132,132,132, 0, 0}; static const GLubyte Fixed8x13_Character_087[] = { 8, 0, 0, 68,170,146,146,146,130,130,130,130, 0, 0}; static const GLubyte Fixed8x13_Character_086[] = { 8, 0, 0, 16, 40, 40, 40, 68, 68, 68,130,130, 0, 0}; static const GLubyte Fixed8x13_Character_088[] = { 8, 0, 0,130,130, 68, 40, 16, 40, 68,130,130, 0, 0}; static const GLubyte Fixed8x13_Character_089[] = { 8, 0, 0, 16, 16, 16, 16, 16, 40, 68,130,130, 0, 0}; static const GLubyte Fixed8x13_Character_090[] = { 8, 0, 0,252,128,128, 64, 32, 16, 8, 4,252, 0, 0}; /* "Z" */ static const GLubyte Fixed8x13_Character_048[] = { 8, 0, 0, 48, 72,132,132,132,132,132, 72, 48, 0, 0}; /* "0" */ static const GLubyte Fixed8x13_Character_049[] = { 8, 0, 0,248, 32, 32, 32, 32, 32,160, 96, 32, 0, 0}; static const GLubyte Fixed8x13_Character_050[] = { 8, 0, 0,252,128, 64, 48, 8, 4,132,132,120, 0, 0}; static const GLubyte Fixed8x13_Character_051[] = { 8, 0, 0,120,132, 4, 4, 56, 16, 8, 4,252, 0, 0}; static const GLubyte Fixed8x13_Character_052[] = { 8, 0, 0, 8, 8,252,136,136, 72, 40, 24, 8, 0, 0}; static const GLubyte Fixed8x13_Character_053[] = { 8, 0, 0,120,132, 4, 4,196,184,128,128,252, 0, 0}; static const GLubyte Fixed8x13_Character_054[] = { 8, 0, 0,120,132,132,196,184,128,128, 64, 56, 0, 0}; static const GLubyte Fixed8x13_Character_055[] = { 8, 0, 0, 64, 64, 32, 32, 16, 16, 8, 4,252, 0, 0}; static const GLubyte Fixed8x13_Character_056[] = { 8, 0, 0,120,132,132,132,120,132,132,132,120, 0, 0}; static const GLubyte Fixed8x13_Character_057[] = { 8, 0, 0,112, 8, 4, 4,116,140,132,132,120, 0, 0}; /* "9" */ static const GLubyte Fixed8x13_Character_096[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 16, 96,224, 0, 0}; /* "`" */ static const GLubyte Fixed8x13_Character_126[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0,144,168, 72, 0, 0}; /* "~" */ static const GLubyte Fixed8x13_Character_033[] = { 8, 0, 0,128, 0,128,128,128,128,128,128,128, 0, 0}; /* "!" */ static const GLubyte Fixed8x13_Character_064[] = { 8, 0, 0,120,128,148,172,164,156,132,132,120, 0, 0}; /* "@" */ static const GLubyte Fixed8x13_Character_035[] = { 8, 0, 0, 0, 72, 72,252, 72,252, 72, 72, 0, 0, 0}; /* "#" */ static const GLubyte Fixed8x13_Character_036[] = { 8, 0, 0, 0, 32,240, 40,112,160,120, 32, 0, 0, 0}; /* "$" */ static const GLubyte Fixed8x13_Character_037[] = { 8, 0, 0,136, 84, 72, 32, 16, 16, 72,164, 68, 0, 0}; /* "%" */ static const GLubyte Fixed8x13_Character_094[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0,136, 80, 32, 0, 0}; /* "^" */ static const GLubyte Fixed8x13_Character_038[] = { 8, 0, 0,116,136,148, 96,144,144, 96, 0, 0, 0, 0}; /* "&" */ static const GLubyte Fixed8x13_Character_042[] = { 8, 0, 0, 0, 0, 72, 48,252, 48, 72, 0, 0, 0, 0}; /* "*" */ static const GLubyte Fixed8x13_Character_040[] = { 8, 0, 0, 32, 64, 64,128,128,128, 64, 64, 32, 0, 0}; /* "(" */ static const GLubyte Fixed8x13_Character_041[] = { 8, 0, 0,128, 64, 64, 32, 32, 32, 64, 64,128, 0, 0}; /* ")" */ static const GLubyte Fixed8x13_Character_045[] = { 8, 0, 0, 0, 0, 0, 0,252, 0, 0, 0, 0, 0, 0}; /* "-" */ static const GLubyte Fixed8x13_Character_095[] = { 8, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ static const GLubyte Fixed8x13_Character_061[] = { 8, 0, 0, 0, 0,252, 0, 0,252, 0, 0, 0, 0, 0}; /* "=" */ static const GLubyte Fixed8x13_Character_043[] = { 8, 0, 0, 0, 0, 32, 32,248, 32, 32, 0, 0, 0, 0}; /* "+" */ static const GLubyte Fixed8x13_Character_091[] = { 8, 0, 0,240,128,128,128,128,128,128,128,240, 0, 0}; /* "[" */ static const GLubyte Fixed8x13_Character_123[] = { 8, 0, 0, 56, 64, 64, 32,192, 32, 64, 64, 56, 0, 0}; /* "{" */ static const GLubyte Fixed8x13_Character_125[] = { 8, 0, 0,224, 16, 16, 32, 24, 32, 16, 16,224, 0, 0}; /* "}" */ static const GLubyte Fixed8x13_Character_093[] = { 8, 0, 0,240, 16, 16, 16, 16, 16, 16, 16,240, 0, 0}; /* "]" */ static const GLubyte Fixed8x13_Character_059[] = { 8, 0,128, 96,112, 0, 0, 32,112, 32, 0, 0, 0, 0}; /* ";" */ static const GLubyte Fixed8x13_Character_058[] = { 8, 0, 64,224, 64, 0, 0, 64,224, 64, 0, 0, 0, 0}; /* ":" */ static const GLubyte Fixed8x13_Character_044[] = { 8, 0,128, 96,112, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ static const GLubyte Fixed8x13_Character_046[] = { 8, 0, 64,224, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ static const GLubyte Fixed8x13_Character_060[] = { 8, 0, 0, 8, 16, 32, 64,128, 64, 32, 16, 8, 0, 0}; /* "<" */ static const GLubyte Fixed8x13_Character_062[] = { 8, 0, 0,128, 64, 32, 16, 8, 16, 32, 64,128, 0, 0}; /* ">" */ static const GLubyte Fixed8x13_Character_047[] = { 8, 0, 0,128,128, 64, 32, 16, 8, 4, 2, 2, 0, 0}; /* "/" */ static const GLubyte Fixed8x13_Character_063[] = { 8, 0, 0, 16, 0, 16, 16, 8, 4,132,132,120, 0, 0}; /* "?" */ static const GLubyte Fixed8x13_Character_092[] = { 8, 0, 0, 2, 2, 4, 8, 16, 32, 64,128,128, 0, 0}; /* "\" */ static const GLubyte Fixed8x13_Character_034[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0,144,144,144, 0, 0}; /* """ */ /* Missing Characters filled in by John Fay by hand ... */ static const GLubyte Fixed8x13_Character_039[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 0, 0}; /* """ */ static const GLubyte Fixed8x13_Character_124[] = { 8, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0}; /* """ */ /* The font characters mapping: */ static const GLubyte* Fixed8x13_Character_Map[] = {Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_032,Fixed8x13_Character_033,Fixed8x13_Character_034,Fixed8x13_Character_035,Fixed8x13_Character_036,Fixed8x13_Character_037,Fixed8x13_Character_038,Fixed8x13_Character_039,Fixed8x13_Character_040, Fixed8x13_Character_041,Fixed8x13_Character_042,Fixed8x13_Character_043,Fixed8x13_Character_044,Fixed8x13_Character_045,Fixed8x13_Character_046,Fixed8x13_Character_047,Fixed8x13_Character_048,Fixed8x13_Character_049,Fixed8x13_Character_050,Fixed8x13_Character_051,Fixed8x13_Character_052,Fixed8x13_Character_053,Fixed8x13_Character_054,Fixed8x13_Character_055,Fixed8x13_Character_056,Fixed8x13_Character_057,Fixed8x13_Character_058,Fixed8x13_Character_059,Fixed8x13_Character_060,Fixed8x13_Character_061,Fixed8x13_Character_062,Fixed8x13_Character_063,Fixed8x13_Character_064,Fixed8x13_Character_065,Fixed8x13_Character_066,Fixed8x13_Character_067,Fixed8x13_Character_068,Fixed8x13_Character_069,Fixed8x13_Character_070,Fixed8x13_Character_071,Fixed8x13_Character_072,Fixed8x13_Character_073,Fixed8x13_Character_074,Fixed8x13_Character_075,Fixed8x13_Character_076,Fixed8x13_Character_077,Fixed8x13_Character_078,Fixed8x13_Character_079,Fixed8x13_Character_080,Fixed8x13_Character_081,Fixed8x13_Character_082, Fixed8x13_Character_083,Fixed8x13_Character_084,Fixed8x13_Character_085,Fixed8x13_Character_086,Fixed8x13_Character_087,Fixed8x13_Character_088,Fixed8x13_Character_089,Fixed8x13_Character_090,Fixed8x13_Character_091,Fixed8x13_Character_092,Fixed8x13_Character_093,Fixed8x13_Character_094,Fixed8x13_Character_095,Fixed8x13_Character_096,Fixed8x13_Character_097,Fixed8x13_Character_098,Fixed8x13_Character_099,Fixed8x13_Character_100,Fixed8x13_Character_101,Fixed8x13_Character_102,Fixed8x13_Character_103,Fixed8x13_Character_104,Fixed8x13_Character_105,Fixed8x13_Character_106,Fixed8x13_Character_107,Fixed8x13_Character_108,Fixed8x13_Character_109,Fixed8x13_Character_110,Fixed8x13_Character_111,Fixed8x13_Character_112,Fixed8x13_Character_113,Fixed8x13_Character_114,Fixed8x13_Character_115,Fixed8x13_Character_116,Fixed8x13_Character_117,Fixed8x13_Character_118,Fixed8x13_Character_119,Fixed8x13_Character_120,Fixed8x13_Character_121,Fixed8x13_Character_122,Fixed8x13_Character_123,Fixed8x13_Character_124, Fixed8x13_Character_125,Fixed8x13_Character_126,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042, Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042, Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042, Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,NULL}; /* The font structure: */ static const SFG_Font fgFontFixed8x13 = { "-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1", 93, 13, Fixed8x13_Character_Map, -1.0f, 2.0f }; static const GLubyte Fixed9x15_Character_032[] = { 9, 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}; /* blank */ static const GLubyte Fixed9x15_Character_097[] = { 9, 0, 0, 0, 0, 0, 0,122, 0,134, 0,130, 0,126, 0, 2, 0, 2, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "a" */ static const GLubyte Fixed9x15_Character_098[] = { 9, 0, 0, 0, 0, 0, 0,188, 0,194, 0,130, 0,130, 0,130, 0,194, 0,188, 0,128, 0,128, 0,128, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_099[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,128, 0,128, 0,128, 0,130, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_100[] = { 9, 0, 0, 0, 0, 0, 0,122, 0,134, 0,130, 0,130, 0,130, 0,134, 0,122, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_101[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,128, 0,128, 0,254, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_102[] = { 9, 0, 0, 0, 0, 0, 0, 32, 0, 32, 0, 32, 0, 32, 0,248, 0, 32, 0, 32, 0, 34, 0, 34, 0, 28, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_103[] = { 9,124, 0,130, 0,130, 0,124, 0,128, 0,120, 0,132, 0,132, 0,132, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_104[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,130, 0,130, 0,194, 0,188, 0,128, 0,128, 0,128, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_105[] = { 9, 0, 0, 0, 0, 0, 0,248, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0,224, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_106[] = { 9,120, 0,132, 0,132, 0,132, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 28, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_107[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,140, 0,176, 0,192, 0,176, 0,140, 0,130, 0,128, 0,128, 0,128, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_108[] = { 9, 0, 0, 0, 0, 0, 0,248, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0,224, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_109[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,146, 0,146, 0,146, 0,146, 0,146, 0,236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_110[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,130, 0,130, 0,194, 0,188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_111[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_112[] = { 9,128, 0,128, 0,128, 0,188, 0,194, 0,130, 0,130, 0,130, 0,194, 0,188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_113[] = { 9, 2, 0, 2, 0, 2, 0,122, 0,134, 0,130, 0,130, 0,130, 0,134, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_114[] = { 9, 0, 0, 0, 0, 0, 0, 64, 0, 64, 0, 64, 0, 64, 0, 66, 0, 98, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_115[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0, 2, 0,124, 0,128, 0,130, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_116[] = { 9, 0, 0, 0, 0, 0, 0, 28, 0, 34, 0, 32, 0, 32, 0, 32, 0, 32, 0,252, 0, 32, 0, 32, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_117[] = { 9, 0, 0, 0, 0, 0, 0,122, 0,132, 0,132, 0,132, 0,132, 0,132, 0,132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_119[] = { 9, 0, 0, 0, 0, 0, 0, 68, 0,170, 0,146, 0,146, 0,146, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_118[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 40, 0, 40, 0, 68, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_120[] = { 9, 0, 0, 0, 0, 0, 0,130, 0, 68, 0, 40, 0, 16, 0, 40, 0, 68, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_121[] = { 9,120, 0,132, 0, 4, 0,116, 0,140, 0,132, 0,132, 0,132, 0,132, 0,132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_122[] = { 9, 0, 0, 0, 0, 0, 0,254, 0, 64, 0, 32, 0, 16, 0, 8, 0, 4, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "z" */ static const GLubyte Fixed9x15_Character_065[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,254, 0,130, 0,130, 0,130, 0, 68, 0, 40, 0, 16, 0, 0, 0, 0, 0}; /* "A" */ static const GLubyte Fixed9x15_Character_066[] = { 9, 0, 0, 0, 0, 0, 0,252, 0, 66, 0, 66, 0, 66, 0, 66, 0,124, 0, 66, 0, 66, 0, 66, 0,252, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_067[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,130, 0,124, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_068[] = { 9, 0, 0, 0, 0, 0, 0,252, 0, 66, 0, 66, 0, 66, 0, 66, 0, 66, 0, 66, 0, 66, 0, 66, 0,252, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_069[] = { 9, 0, 0, 0, 0, 0, 0,254, 0, 64, 0, 64, 0, 64, 0, 64, 0,120, 0, 64, 0, 64, 0, 64, 0,254, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_070[] = { 9, 0, 0, 0, 0, 0, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0,120, 0, 64, 0, 64, 0, 64, 0,254, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_071[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,142, 0,128, 0,128, 0,128, 0,130, 0,124, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_072[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,130, 0,130, 0,254, 0,130, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_073[] = { 9, 0, 0, 0, 0, 0, 0,248, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0,248, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_074[] = { 9, 0, 0, 0, 0, 0, 0,120, 0,132, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 30, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_075[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,132, 0,136, 0,144, 0,160, 0,224, 0,144, 0,136, 0,132, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_076[] = { 9, 0, 0, 0, 0, 0, 0,254, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_077[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,146, 0,146, 0,170, 0,170, 0,198, 0,130, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_078[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,134, 0,138, 0,146, 0,162, 0,194, 0,130, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_079[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_080[] = { 9, 0, 0, 0, 0, 0, 0,128, 0,128, 0,128, 0,128, 0,128, 0,252, 0,130, 0,130, 0,130, 0,252, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_081[] = { 9, 0, 0, 6, 0, 8, 0,124, 0,146, 0,162, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_082[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,132, 0,136, 0,144, 0,252, 0,130, 0,130, 0,130, 0,252, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_083[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0, 2, 0, 12, 0,112, 0,128, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_084[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0,254, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_085[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_087[] = { 9, 0, 0, 0, 0, 0, 0, 68, 0,170, 0,146, 0,146, 0,146, 0,146, 0,130, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_086[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 40, 0, 40, 0, 40, 0, 68, 0, 68, 0, 68, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_088[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0, 68, 0, 40, 0, 16, 0, 16, 0, 40, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_089[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 40, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_090[] = { 9, 0, 0, 0, 0, 0, 0,254, 0,128, 0,128, 0, 64, 0, 32, 0, 16, 0, 8, 0, 4, 0, 2, 0,254, 0, 0, 0, 0, 0}; /* "Z" */ static const GLubyte Fixed9x15_Character_048[] = { 9, 0, 0, 0, 0, 0, 0, 56, 0, 68, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0, 68, 0, 56, 0, 0, 0, 0, 0}; /* "0" */ static const GLubyte Fixed9x15_Character_049[] = { 9, 0, 0, 0, 0, 0, 0,254, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0,144, 0, 80, 0, 48, 0, 16, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_050[] = { 9, 0, 0, 0, 0, 0, 0,254, 0,128, 0, 64, 0, 48, 0, 8, 0, 4, 0, 2, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_051[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0, 2, 0, 2, 0, 2, 0, 28, 0, 8, 0, 4, 0, 2, 0,254, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_052[] = { 9, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0,254, 0,132, 0, 68, 0, 36, 0, 20, 0, 12, 0, 4, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_053[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0, 2, 0, 2, 0, 2, 0,194, 0,188, 0,128, 0,128, 0,254, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_054[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,194, 0,188, 0,128, 0,128, 0, 64, 0, 60, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_055[] = { 9, 0, 0, 0, 0, 0, 0, 64, 0, 64, 0, 32, 0, 32, 0, 16, 0, 8, 0, 4, 0, 2, 0, 2, 0,254, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_056[] = { 9, 0, 0, 0, 0, 0, 0, 56, 0, 68, 0,130, 0,130, 0, 68, 0, 56, 0, 68, 0,130, 0, 68, 0, 56, 0, 0, 0, 0, 0}; static const GLubyte Fixed9x15_Character_057[] = { 9, 0, 0, 0, 0, 0, 0,120, 0, 4, 0, 2, 0, 2, 0,122, 0,134, 0,130, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; /* "9" */ static const GLubyte Fixed9x15_Character_096[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 64, 0,192, 0, 0, 0, 0, 0}; /* "`" */ static const GLubyte Fixed9x15_Character_126[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 0,146, 0, 98, 0, 0, 0, 0, 0}; /* "~" */ static const GLubyte Fixed9x15_Character_033[] = { 9, 0, 0, 0, 0, 0, 0,128, 0,128, 0, 0, 0, 0, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0, 0, 0}; /* "!" */ static const GLubyte Fixed9x15_Character_064[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,128, 0,128, 0,154, 0,166, 0,162, 0,158, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; /* "@" */ static const GLubyte Fixed9x15_Character_035[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 72, 0,252, 0, 72, 0, 72, 0,252, 0, 72, 0, 72, 0, 0, 0, 0, 0, 0, 0}; /* "#" */ static const GLubyte Fixed9x15_Character_036[] = { 9, 0, 0, 0, 0, 16, 0,124, 0,146, 0, 18, 0, 18, 0, 20, 0, 56, 0, 80, 0,144, 0,146, 0,124, 0, 16, 0, 0, 0}; /* "$" */ static const GLubyte Fixed9x15_Character_037[] = { 9, 0, 0, 0, 0, 0, 0,132, 0, 74, 0, 74, 0, 36, 0, 16, 0, 16, 0, 72, 0,164, 0,164, 0, 66, 0, 0, 0, 0, 0}; /* "%" */ static const GLubyte Fixed9x15_Character_094[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130, 0, 68, 0, 40, 0, 16, 0, 0, 0, 0, 0}; /* "^" */ static const GLubyte Fixed9x15_Character_038[] = { 9, 0, 0, 0, 0, 0, 0, 98, 0,148, 0,136, 0,148, 0, 98, 0, 96, 0,144, 0,144, 0,144, 0, 96, 0, 0, 0, 0, 0}; /* "&" */ static const GLubyte Fixed9x15_Character_042[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0,146, 0, 84, 0, 56, 0, 84, 0,146, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "*" */ static const GLubyte Fixed9x15_Character_040[] = { 9, 0, 0, 0, 0, 32, 0, 64, 0, 64, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0, 64, 0, 64, 0, 32, 0, 0, 0}; /* "(" */ static const GLubyte Fixed9x15_Character_041[] = { 9, 0, 0, 0, 0,128, 0, 64, 0, 64, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 64, 0, 64, 0,128, 0, 0, 0}; /* ")" */ static const GLubyte Fixed9x15_Character_045[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ static const GLubyte Fixed9x15_Character_095[] = { 9, 0, 0, 0, 0,255, 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}; /* "_" */ static const GLubyte Fixed9x15_Character_061[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 0, 0, 0, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "=" */ static const GLubyte Fixed9x15_Character_043[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0,254, 0, 16, 0, 16, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "+" */ static const GLubyte Fixed9x15_Character_091[] = { 9, 0, 0, 0, 0,240, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,240, 0, 0, 0}; /* "[" */ static const GLubyte Fixed9x15_Character_123[] = { 9, 0, 0, 0, 0, 56, 0, 64, 0, 64, 0, 64, 0, 32, 0,192, 0,192, 0, 32, 0, 64, 0, 64, 0, 64, 0, 56, 0, 0, 0}; /* "{" */ static const GLubyte Fixed9x15_Character_125[] = { 9, 0, 0, 0, 0,224, 0, 16, 0, 16, 0, 16, 0, 32, 0, 24, 0, 24, 0, 32, 0, 16, 0, 16, 0, 16, 0,224, 0, 0, 0}; /* "}" */ static const GLubyte Fixed9x15_Character_093[] = { 9, 0, 0, 0, 0,240, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0,240, 0, 0, 0}; /* "]" */ static const GLubyte Fixed9x15_Character_059[] = { 9,128, 0, 64, 0, 64, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ";" */ static const GLubyte Fixed9x15_Character_058[] = { 9, 0, 0, 0, 0, 0, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ":" */ static const GLubyte Fixed9x15_Character_044[] = { 9,128, 0, 64, 0, 64, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ static const GLubyte Fixed9x15_Character_046[] = { 9, 0, 0, 0, 0, 0, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ static const GLubyte Fixed9x15_Character_060[] = { 9, 0, 0, 0, 0, 0, 0, 8, 0, 16, 0, 32, 0, 64, 0,128, 0,128, 0, 64, 0, 32, 0, 16, 0, 8, 0, 0, 0, 0, 0}; /* "<" */ static const GLubyte Fixed9x15_Character_062[] = { 9, 0, 0, 0, 0, 0, 0,128, 0, 64, 0, 32, 0, 16, 0, 8, 0, 8, 0, 16, 0, 32, 0, 64, 0,128, 0, 0, 0, 0, 0}; /* ">" */ static const GLubyte Fixed9x15_Character_047[] = { 9, 0, 0, 0, 0, 0, 0,128, 0, 64, 0, 64, 0, 32, 0, 16, 0, 16, 0, 8, 0, 4, 0, 4, 0, 2, 0, 0, 0, 0, 0}; /* "/" */ static const GLubyte Fixed9x15_Character_063[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 16, 0, 8, 0, 4, 0, 2, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; /* "?" */ static const GLubyte Fixed9x15_Character_092[] = { 9, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 4, 0, 8, 0, 16, 0, 16, 0, 32, 0, 64, 0, 64, 0,128, 0, 0, 0, 0, 0}; /* "\" */ static const GLubyte Fixed9x15_Character_034[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144, 0,144, 0,144, 0, 0, 0, 0, 0}; /* """ */ /* Missing Characters filled in by John Fay by hand ... */ static const GLubyte Fixed9x15_Character_039[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 32, 0, 32, 0, 32, 0, 0, 0, 0, 0}; /* "'" */ static const GLubyte Fixed9x15_Character_124[] = { 9, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 0, 0, 0, 0}; /* "|" */ /* The font characters mapping: */ static const GLubyte* Fixed9x15_Character_Map[] = {Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_032,Fixed9x15_Character_033,Fixed9x15_Character_034,Fixed9x15_Character_035,Fixed9x15_Character_036,Fixed9x15_Character_037,Fixed9x15_Character_038,Fixed9x15_Character_039,Fixed9x15_Character_040, Fixed9x15_Character_041,Fixed9x15_Character_042,Fixed9x15_Character_043,Fixed9x15_Character_044,Fixed9x15_Character_045,Fixed9x15_Character_046,Fixed9x15_Character_047,Fixed9x15_Character_048,Fixed9x15_Character_049,Fixed9x15_Character_050,Fixed9x15_Character_051,Fixed9x15_Character_052,Fixed9x15_Character_053,Fixed9x15_Character_054,Fixed9x15_Character_055,Fixed9x15_Character_056,Fixed9x15_Character_057,Fixed9x15_Character_058,Fixed9x15_Character_059,Fixed9x15_Character_060,Fixed9x15_Character_061,Fixed9x15_Character_062,Fixed9x15_Character_063,Fixed9x15_Character_064,Fixed9x15_Character_065,Fixed9x15_Character_066,Fixed9x15_Character_067,Fixed9x15_Character_068,Fixed9x15_Character_069,Fixed9x15_Character_070,Fixed9x15_Character_071,Fixed9x15_Character_072,Fixed9x15_Character_073,Fixed9x15_Character_074,Fixed9x15_Character_075,Fixed9x15_Character_076,Fixed9x15_Character_077,Fixed9x15_Character_078,Fixed9x15_Character_079,Fixed9x15_Character_080,Fixed9x15_Character_081,Fixed9x15_Character_082, Fixed9x15_Character_083,Fixed9x15_Character_084,Fixed9x15_Character_085,Fixed9x15_Character_086,Fixed9x15_Character_087,Fixed9x15_Character_088,Fixed9x15_Character_089,Fixed9x15_Character_090,Fixed9x15_Character_091,Fixed9x15_Character_092,Fixed9x15_Character_093,Fixed9x15_Character_094,Fixed9x15_Character_095,Fixed9x15_Character_096,Fixed9x15_Character_097,Fixed9x15_Character_098,Fixed9x15_Character_099,Fixed9x15_Character_100,Fixed9x15_Character_101,Fixed9x15_Character_102,Fixed9x15_Character_103,Fixed9x15_Character_104,Fixed9x15_Character_105,Fixed9x15_Character_106,Fixed9x15_Character_107,Fixed9x15_Character_108,Fixed9x15_Character_109,Fixed9x15_Character_110,Fixed9x15_Character_111,Fixed9x15_Character_112,Fixed9x15_Character_113,Fixed9x15_Character_114,Fixed9x15_Character_115,Fixed9x15_Character_116,Fixed9x15_Character_117,Fixed9x15_Character_118,Fixed9x15_Character_119,Fixed9x15_Character_120,Fixed9x15_Character_121,Fixed9x15_Character_122,Fixed9x15_Character_123,Fixed9x15_Character_124, Fixed9x15_Character_125,Fixed9x15_Character_126,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042, Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042, Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042, Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,NULL}; /* The font structure: */ static const SFG_Font fgFontFixed9x15 = { "-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1", 93, 15, Fixed9x15_Character_Map, -1.0f, 3.0f }; static const GLubyte Helvetica10_Character_032[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ static const GLubyte Helvetica10_Character_097[] = { 5, 0, 0,104,144,144,112, 16,224, 0, 0, 0, 0, 0}; /* "a" */ static const GLubyte Helvetica10_Character_098[] = { 6, 0, 0,176,200,136,136,200,176,128,128, 0, 0, 0}; /* "b" */ static const GLubyte Helvetica10_Character_099[] = { 5, 0, 0, 96,144,128,128,144, 96, 0, 0, 0, 0, 0}; /* "c" */ static const GLubyte Helvetica10_Character_100[] = { 6, 0, 0,104,152,136,136,152,104, 8, 8, 0, 0, 0}; /* "d" */ static const GLubyte Helvetica10_Character_101[] = { 5, 0, 0, 96,144,128,240,144, 96, 0, 0, 0, 0, 0}; /* "e" */ static const GLubyte Helvetica10_Character_102[] = { 4, 0, 0, 64, 64, 64, 64, 64,224, 64, 48, 0, 0, 0}; /* "f" */ static const GLubyte Helvetica10_Character_103[] = { 6,112, 8,104,152,136,136,152,104, 0, 0, 0, 0, 0}; /* "g" */ static const GLubyte Helvetica10_Character_104[] = { 6, 0, 0,136,136,136,136,200,176,128,128, 0, 0, 0}; /* "h" */ static const GLubyte Helvetica10_Character_105[] = { 2, 0, 0,128,128,128,128,128,128, 0,128, 0, 0, 0}; /* "i" */ static const GLubyte Helvetica10_Character_106[] = { 2, 0,128,128,128,128,128,128,128, 0,128, 0, 0, 0}; /* "j" */ static const GLubyte Helvetica10_Character_107[] = { 5, 0, 0,144,144,160,192,160,144,128,128, 0, 0, 0}; /* "k" */ static const GLubyte Helvetica10_Character_108[] = { 2, 0, 0,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "l" */ static const GLubyte Helvetica10_Character_109[] = { 8, 0, 0,146,146,146,146,146,236, 0, 0, 0, 0, 0}; /* "m" */ static const GLubyte Helvetica10_Character_110[] = { 6, 0, 0,136,136,136,136,200,176, 0, 0, 0, 0, 0}; /* "n" */ static const GLubyte Helvetica10_Character_111[] = { 6, 0, 0,112,136,136,136,136,112, 0, 0, 0, 0, 0}; /* "o" */ static const GLubyte Helvetica10_Character_112[] = { 6,128,128,176,200,136,136,200,176, 0, 0, 0, 0, 0}; /* "p" */ static const GLubyte Helvetica10_Character_113[] = { 6, 8, 8,104,152,136,136,152,104, 0, 0, 0, 0, 0}; /* "q" */ static const GLubyte Helvetica10_Character_114[] = { 4, 0, 0,128,128,128,128,192,160, 0, 0, 0, 0, 0}; /* "r" */ static const GLubyte Helvetica10_Character_115[] = { 5, 0, 0, 96,144, 16, 96,144, 96, 0, 0, 0, 0, 0}; /* "s" */ static const GLubyte Helvetica10_Character_116[] = { 4, 0, 0, 96, 64, 64, 64, 64,224, 64, 64, 0, 0, 0}; /* "t" */ static const GLubyte Helvetica10_Character_117[] = { 5, 0, 0,112,144,144,144,144,144, 0, 0, 0, 0, 0}; /* "u" */ static const GLubyte Helvetica10_Character_118[] = { 6, 0, 0, 32, 32, 80, 80,136,136, 0, 0, 0, 0, 0}; /* "v" */ static const GLubyte Helvetica10_Character_119[] = { 8, 0, 0, 40, 40, 84, 84,146,146, 0, 0, 0, 0, 0}; /* "w" */ static const GLubyte Helvetica10_Character_120[] = { 6, 0, 0,136,136, 80, 32, 80,136, 0, 0, 0, 0, 0}; /* "x" */ static const GLubyte Helvetica10_Character_121[] = { 5,128, 64, 64, 96,160,160,144,144, 0, 0, 0, 0, 0}; /* "y" */ static const GLubyte Helvetica10_Character_122[] = { 5, 0, 0,240,128, 64, 32, 16,240, 0, 0, 0, 0, 0}; /* "z" */ static const GLubyte Helvetica10_Character_065[] = { 7, 0, 0,130,130,124, 68, 40, 40, 16, 16, 0, 0, 0}; /* "A" */ static const GLubyte Helvetica10_Character_066[] = { 7, 0, 0,240,136,136,136,240,136,136,240, 0, 0, 0}; /* "B" */ static const GLubyte Helvetica10_Character_067[] = { 8, 0, 0,120,132,128,128,128,128,132,120, 0, 0, 0}; /* "C" */ static const GLubyte Helvetica10_Character_068[] = { 8, 0, 0,240,136,132,132,132,132,136,240, 0, 0, 0}; /* "D" */ static const GLubyte Helvetica10_Character_069[] = { 7, 0, 0,248,128,128,128,248,128,128,248, 0, 0, 0}; /* "E" */ static const GLubyte Helvetica10_Character_070[] = { 6, 0, 0,128,128,128,128,240,128,128,248, 0, 0, 0}; /* "F" */ static const GLubyte Helvetica10_Character_071[] = { 8, 0, 0,116,140,132,140,128,128,132,120, 0, 0, 0}; /* "G" */ static const GLubyte Helvetica10_Character_072[] = { 8, 0, 0,132,132,132,132,252,132,132,132, 0, 0, 0}; /* "H" */ static const GLubyte Helvetica10_Character_073[] = { 3, 0, 0,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "I" */ static const GLubyte Helvetica10_Character_074[] = { 5, 0, 0, 96,144, 16, 16, 16, 16, 16, 16, 0, 0, 0}; /* "J" */ static const GLubyte Helvetica10_Character_075[] = { 7, 0, 0,136,136,144,144,224,160,144,136, 0, 0, 0}; /* "K" */ static const GLubyte Helvetica10_Character_076[] = { 6, 0, 0,240,128,128,128,128,128,128,128, 0, 0, 0}; /* "L" */ static const GLubyte Helvetica10_Character_077[] = { 9, 0, 0, 0, 0,146, 0,146, 0,146, 0,170, 0,170, 0,198, 0,198, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "M" */ static const GLubyte Helvetica10_Character_078[] = { 8, 0, 0,140,140,148,148,164,164,196,196, 0, 0, 0}; /* "N" */ static const GLubyte Helvetica10_Character_079[] = { 8, 0, 0,120,132,132,132,132,132,132,120, 0, 0, 0}; /* "O" */ static const GLubyte Helvetica10_Character_080[] = { 7, 0, 0,128,128,128,128,240,136,136,240, 0, 0, 0}; /* "P" */ static const GLubyte Helvetica10_Character_081[] = { 8, 0, 2,124,140,148,132,132,132,132,120, 0, 0, 0}; /* "Q" */ static const GLubyte Helvetica10_Character_082[] = { 7, 0, 0,136,136,136,136,240,136,136,240, 0, 0, 0}; /* "R" */ static const GLubyte Helvetica10_Character_083[] = { 7, 0, 0,112,136,136, 8,112,128,136,112, 0, 0, 0}; /* "S" */ static const GLubyte Helvetica10_Character_084[] = { 5, 0, 0, 32, 32, 32, 32, 32, 32, 32,248, 0, 0, 0}; /* "T" */ static const GLubyte Helvetica10_Character_085[] = { 8, 0, 0,120,132,132,132,132,132,132,132, 0, 0, 0}; /* "U" */ static const GLubyte Helvetica10_Character_086[] = { 7, 0, 0, 16, 40, 40, 68, 68, 68,130,130, 0, 0, 0}; /* "V" */ static const GLubyte Helvetica10_Character_087[] = { 9, 0, 0, 0, 0, 34, 0, 34, 0, 34, 0, 85, 0, 73, 0, 73, 0,136,128,136,128, 0, 0, 0, 0, 0, 0}; /* "W" */ static const GLubyte Helvetica10_Character_088[] = { 7, 0, 0,136,136, 80, 80, 32, 80,136,136, 0, 0, 0}; /* "X" */ static const GLubyte Helvetica10_Character_089[] = { 7, 0, 0, 16, 16, 16, 40, 40, 68, 68,130, 0, 0, 0}; /* "Y" */ static const GLubyte Helvetica10_Character_090[] = { 7, 0, 0,248,128, 64, 32, 32, 16, 8,248, 0, 0, 0}; /* "Z" */ static const GLubyte Helvetica10_Character_048[] = { 6, 0, 0,112,136,136,136,136,136,136,112, 0, 0, 0}; /* "0" */ static const GLubyte Helvetica10_Character_049[] = { 6, 0, 0, 64, 64, 64, 64, 64, 64,192, 64, 0, 0, 0}; /* "1" */ static const GLubyte Helvetica10_Character_050[] = { 6, 0, 0,248,128, 64, 48, 8, 8,136,112, 0, 0, 0}; /* "2" */ static const GLubyte Helvetica10_Character_051[] = { 6, 0, 0,112,136, 8, 8, 48, 8,136,112, 0, 0, 0}; /* "3" */ static const GLubyte Helvetica10_Character_052[] = { 6, 0, 0, 16, 16,248,144, 80, 80, 48, 16, 0, 0, 0}; /* "4" */ static const GLubyte Helvetica10_Character_053[] = { 6, 0, 0,112,136, 8, 8,240,128,128,248, 0, 0, 0}; /* "5" */ static const GLubyte Helvetica10_Character_054[] = { 6, 0, 0,112,136,136,200,176,128,136,112, 0, 0, 0}; /* "6" */ static const GLubyte Helvetica10_Character_055[] = { 6, 0, 0, 64, 64, 32, 32, 16, 16, 8,248, 0, 0, 0}; /* "7" */ static const GLubyte Helvetica10_Character_056[] = { 6, 0, 0,112,136,136,136,112,136,136,112, 0, 0, 0}; /* "8" */ static const GLubyte Helvetica10_Character_057[] = { 6, 0, 0,112,136, 8,104,152,136,136,112, 0, 0, 0}; /* "9" */ static const GLubyte Helvetica10_Character_096[] = { 3, 0, 0, 0, 0, 0, 0, 0,128,128, 64, 0, 0, 0}; /* "`" */ static const GLubyte Helvetica10_Character_126[] = { 7, 0, 0, 0, 0, 0,152,100, 0, 0, 0, 0, 0, 0}; /* "~" */ static const GLubyte Helvetica10_Character_033[] = { 3, 0, 0,128, 0,128,128,128,128,128,128, 0, 0, 0}; /* "!" */ static const GLubyte Helvetica10_Character_064[] = { 11, 62, 0, 64, 0,155, 0,164,128,164,128,162, 64,146, 64, 77, 64, 32,128, 31, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ static const GLubyte Helvetica10_Character_035[] = { 6, 0, 0, 80, 80,248, 40,124, 40, 40, 0, 0, 0, 0}; /* "#" */ static const GLubyte Helvetica10_Character_036[] = { 6, 0, 32,112,168, 40,112,160,168,112, 32, 0, 0, 0}; /* "$" */ static const GLubyte Helvetica10_Character_037[] = { 9, 0, 0, 0, 0, 38, 0, 41, 0, 22, 0, 16, 0, 8, 0,104, 0,148, 0,100, 0, 0, 0, 0, 0, 0, 0}; /* "%" */ static const GLubyte Helvetica10_Character_094[] = { 6, 0, 0, 0, 0, 0,136, 80, 80, 32, 32, 0, 0, 0}; /* "^" */ static const GLubyte Helvetica10_Character_038[] = { 8, 0, 0,100,152,152,164, 96, 80, 80, 32, 0, 0, 0}; /* "&" */ static const GLubyte Helvetica10_Character_042[] = { 4, 0, 0, 0, 0, 0, 0, 0,160, 64,160, 0, 0, 0}; /* "*" */ static const GLubyte Helvetica10_Character_040[] = { 4, 32, 64, 64,128,128,128,128, 64, 64, 32, 0, 0, 0}; /* "(" */ static const GLubyte Helvetica10_Character_041[] = { 4,128, 64, 64, 32, 32, 32, 32, 64, 64,128, 0, 0, 0}; /* ")" */ static const GLubyte Helvetica10_Character_045[] = { 7, 0, 0, 0, 0, 0,248, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ static const GLubyte Helvetica10_Character_095[] = { 6,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ static const GLubyte Helvetica10_Character_061[] = { 5, 0, 0, 0, 0,240, 0,240, 0, 0, 0, 0, 0, 0}; /* "=" */ static const GLubyte Helvetica10_Character_043[] = { 6, 0, 0, 0, 32, 32,248, 32, 32, 0, 0, 0, 0, 0}; /* "+" */ static const GLubyte Helvetica10_Character_091[] = { 3,192,128,128,128,128,128,128,128,128,192, 0, 0, 0}; /* "[" */ static const GLubyte Helvetica10_Character_123[] = { 3, 32, 64, 64, 64, 64,128, 64, 64, 64, 32, 0, 0, 0}; /* "{" */ static const GLubyte Helvetica10_Character_125[] = { 3,128, 64, 64, 64, 64, 32, 64, 64, 64,128, 0, 0, 0}; /* "}" */ static const GLubyte Helvetica10_Character_093[] = { 3,192, 64, 64, 64, 64, 64, 64, 64, 64,192, 0, 0, 0}; /* "]" */ static const GLubyte Helvetica10_Character_059[] = { 3,128, 64, 64, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0}; /* ";" */ static const GLubyte Helvetica10_Character_058[] = { 3, 0, 0,128, 0, 0, 0, 0,128, 0, 0, 0, 0, 0}; /* ":" */ static const GLubyte Helvetica10_Character_044[] = { 3,128, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ static const GLubyte Helvetica10_Character_046[] = { 3, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ static const GLubyte Helvetica10_Character_060[] = { 6, 0, 0, 0, 32, 64,128, 64, 32, 0, 0, 0, 0, 0}; /* "<" */ static const GLubyte Helvetica10_Character_062[] = { 6, 0, 0, 0,128, 64, 32, 64,128, 0, 0, 0, 0, 0}; /* ">" */ static const GLubyte Helvetica10_Character_047[] = { 3, 0, 0,128,128, 64, 64, 64, 64, 32, 32, 0, 0, 0}; /* "/" */ static const GLubyte Helvetica10_Character_063[] = { 6, 0, 0, 64, 0, 64, 64, 32, 16,144, 96, 0, 0, 0}; /* "?" */ static const GLubyte Helvetica10_Character_092[] = { 3, 0, 0, 32, 32, 64, 64, 64, 64,128,128, 0, 0, 0}; /* "\" */ static const GLubyte Helvetica10_Character_034[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0,160,160, 0, 0, 0}; /* """ */ /* Missing Characters filled in by John Fay by hand ... */ static const GLubyte Helvetica10_Character_039[] = { 3, 0, 0, 0, 0, 0, 0, 0,128, 64, 64, 0, 0, 0}; /* "'" */ static const GLubyte Helvetica10_Character_124[] = { 3, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0}; /* "|" */ /* The font characters mapping: */ static const GLubyte* Helvetica10_Character_Map[] = {Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_032,Helvetica10_Character_033,Helvetica10_Character_034,Helvetica10_Character_035,Helvetica10_Character_036,Helvetica10_Character_037, Helvetica10_Character_038,Helvetica10_Character_039,Helvetica10_Character_040,Helvetica10_Character_041,Helvetica10_Character_042,Helvetica10_Character_043,Helvetica10_Character_044,Helvetica10_Character_045,Helvetica10_Character_046,Helvetica10_Character_047,Helvetica10_Character_048,Helvetica10_Character_049,Helvetica10_Character_050,Helvetica10_Character_051,Helvetica10_Character_052,Helvetica10_Character_053,Helvetica10_Character_054,Helvetica10_Character_055,Helvetica10_Character_056,Helvetica10_Character_057,Helvetica10_Character_058,Helvetica10_Character_059,Helvetica10_Character_060,Helvetica10_Character_061,Helvetica10_Character_062,Helvetica10_Character_063,Helvetica10_Character_064,Helvetica10_Character_065,Helvetica10_Character_066,Helvetica10_Character_067,Helvetica10_Character_068,Helvetica10_Character_069,Helvetica10_Character_070,Helvetica10_Character_071,Helvetica10_Character_072,Helvetica10_Character_073,Helvetica10_Character_074,Helvetica10_Character_075,Helvetica10_Character_076, Helvetica10_Character_077,Helvetica10_Character_078,Helvetica10_Character_079,Helvetica10_Character_080,Helvetica10_Character_081,Helvetica10_Character_082,Helvetica10_Character_083,Helvetica10_Character_084,Helvetica10_Character_085,Helvetica10_Character_086,Helvetica10_Character_087,Helvetica10_Character_088,Helvetica10_Character_089,Helvetica10_Character_090,Helvetica10_Character_091,Helvetica10_Character_092,Helvetica10_Character_093,Helvetica10_Character_094,Helvetica10_Character_095,Helvetica10_Character_096,Helvetica10_Character_097,Helvetica10_Character_098,Helvetica10_Character_099,Helvetica10_Character_100,Helvetica10_Character_101,Helvetica10_Character_102,Helvetica10_Character_103,Helvetica10_Character_104,Helvetica10_Character_105,Helvetica10_Character_106,Helvetica10_Character_107,Helvetica10_Character_108,Helvetica10_Character_109,Helvetica10_Character_110,Helvetica10_Character_111,Helvetica10_Character_112,Helvetica10_Character_113,Helvetica10_Character_114,Helvetica10_Character_115, Helvetica10_Character_116,Helvetica10_Character_117,Helvetica10_Character_118,Helvetica10_Character_119,Helvetica10_Character_120,Helvetica10_Character_121,Helvetica10_Character_122,Helvetica10_Character_123,Helvetica10_Character_124,Helvetica10_Character_125,Helvetica10_Character_126,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042, Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042, Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042, Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,NULL}; /* The font structure: */ static const SFG_Font fgFontHelvetica10 = { "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1", 93, 13, Helvetica10_Character_Map, -1.0f, 2.0f }; static const GLubyte Helvetica12_Character_032[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ static const GLubyte Helvetica12_Character_097[] = { 7, 0, 0, 0,116,136,136,120, 8,136,112, 0, 0, 0, 0, 0}; /* "a" */ static const GLubyte Helvetica12_Character_098[] = { 7, 0, 0, 0,176,200,136,136,136,200,176,128,128, 0, 0, 0}; /* "b" */ static const GLubyte Helvetica12_Character_099[] = { 7, 0, 0, 0,112,136,128,128,128,136,112, 0, 0, 0, 0, 0}; /* "c" */ static const GLubyte Helvetica12_Character_100[] = { 7, 0, 0, 0,104,152,136,136,136,152,104, 8, 8, 0, 0, 0}; /* "d" */ static const GLubyte Helvetica12_Character_101[] = { 7, 0, 0, 0,112,136,128,248,136,136,112, 0, 0, 0, 0, 0}; /* "e" */ static const GLubyte Helvetica12_Character_102[] = { 4, 0, 0, 0, 64, 64, 64, 64, 64, 64,224, 64, 48, 0, 0, 0}; /* "f" */ static const GLubyte Helvetica12_Character_103[] = { 7,112,136, 8,104,152,136,136,136,152,104, 0, 0, 0, 0, 0}; /* "g" */ static const GLubyte Helvetica12_Character_104[] = { 7, 0, 0, 0,136,136,136,136,136,200,176,128,128, 0, 0, 0}; /* "h" */ static const GLubyte Helvetica12_Character_105[] = { 3, 0, 0, 0,128,128,128,128,128,128,128, 0,128, 0, 0, 0}; /* "i" */ static const GLubyte Helvetica12_Character_106[] = { 4,128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 64, 0, 0, 0}; /* "j" */ static const GLubyte Helvetica12_Character_107[] = { 6, 0, 0, 0,136,144,160,192,192,160,144,128,128, 0, 0, 0}; /* "k" */ static const GLubyte Helvetica12_Character_108[] = { 3, 0, 0, 0,128,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "l" */ static const GLubyte Helvetica12_Character_109[] = { 9, 0, 0, 0, 0, 0, 0,146, 0,146, 0,146, 0,146, 0,146, 0,218, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "m" */ static const GLubyte Helvetica12_Character_110[] = { 7, 0, 0, 0,136,136,136,136,136,200,176, 0, 0, 0, 0, 0}; /* "n" */ static const GLubyte Helvetica12_Character_111[] = { 7, 0, 0, 0,112,136,136,136,136,136,112, 0, 0, 0, 0, 0}; /* "o" */ static const GLubyte Helvetica12_Character_112[] = { 7,128,128,128,176,200,136,136,136,200,176, 0, 0, 0, 0, 0}; /* "p" */ static const GLubyte Helvetica12_Character_113[] = { 7, 8, 8, 8,104,152,136,136,136,152,104, 0, 0, 0, 0, 0}; /* "q" */ static const GLubyte Helvetica12_Character_114[] = { 4, 0, 0, 0,128,128,128,128,128,192,160, 0, 0, 0, 0, 0}; /* "r" */ static const GLubyte Helvetica12_Character_115[] = { 6, 0, 0, 0, 96,144, 16, 96,128,144, 96, 0, 0, 0, 0, 0}; /* "s" */ static const GLubyte Helvetica12_Character_116[] = { 4, 0, 0, 0, 96, 64, 64, 64, 64, 64,224, 64, 64, 0, 0, 0}; /* "t" */ static const GLubyte Helvetica12_Character_117[] = { 7, 0, 0, 0,104,152,136,136,136,136,136, 0, 0, 0, 0, 0}; /* "u" */ static const GLubyte Helvetica12_Character_118[] = { 7, 0, 0, 0, 32, 32, 80, 80,136,136,136, 0, 0, 0, 0, 0}; /* "v" */ static const GLubyte Helvetica12_Character_119[] = { 10, 0, 0, 0, 0, 0, 0, 34, 0, 34, 0, 85, 0, 73, 0, 73, 0,136,128,136,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "w" */ static const GLubyte Helvetica12_Character_120[] = { 6, 0, 0, 0,132,132, 72, 48, 48, 72,132, 0, 0, 0, 0, 0}; /* "x" */ static const GLubyte Helvetica12_Character_121[] = { 7,128, 64, 32, 32, 80, 80,144,136,136,136, 0, 0, 0, 0, 0}; /* "y" */ static const GLubyte Helvetica12_Character_122[] = { 6, 0, 0, 0,240,128, 64, 64, 32, 16,240, 0, 0, 0, 0, 0}; /* "z" */ static const GLubyte Helvetica12_Character_065[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,124, 0, 68, 0, 68, 0, 40, 0, 40, 0, 16, 0, 0, 0, 0, 0, 0, 0}; /* "A" */ static const GLubyte Helvetica12_Character_066[] = { 8, 0, 0, 0,248,132,132,132,248,132,132,132,248, 0, 0, 0}; /* "B" */ static const GLubyte Helvetica12_Character_067[] = { 9, 0, 0, 0, 0, 0, 0, 60, 0, 66, 0,128, 0,128, 0,128, 0,128, 0,128, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "C" */ static const GLubyte Helvetica12_Character_068[] = { 9, 0, 0, 0, 0, 0, 0,248, 0,132, 0,130, 0,130, 0,130, 0,130, 0,130, 0,132, 0,248, 0, 0, 0, 0, 0, 0, 0}; /* "D" */ static const GLubyte Helvetica12_Character_069[] = { 8, 0, 0, 0,252,128,128,128,252,128,128,128,252, 0, 0, 0}; /* "E" */ static const GLubyte Helvetica12_Character_070[] = { 8, 0, 0, 0,128,128,128,128,248,128,128,128,252, 0, 0, 0}; /* "F" */ static const GLubyte Helvetica12_Character_071[] = { 9, 0, 0, 0, 0, 0, 0, 58, 0, 70, 0,130, 0,130, 0,142, 0,128, 0,128, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "G" */ static const GLubyte Helvetica12_Character_072[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,130, 0,254, 0,130, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "H" */ static const GLubyte Helvetica12_Character_073[] = { 3, 0, 0, 0,128,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "I" */ static const GLubyte Helvetica12_Character_074[] = { 7, 0, 0, 0,112,136,136, 8, 8, 8, 8, 8, 8, 0, 0, 0}; /* "J" */ static const GLubyte Helvetica12_Character_075[] = { 8, 0, 0, 0,130,132,136,144,224,160,144,136,132, 0, 0, 0}; /* "K" */ static const GLubyte Helvetica12_Character_076[] = { 7, 0, 0, 0,248,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "L" */ static const GLubyte Helvetica12_Character_077[] = { 11, 0, 0, 0, 0, 0, 0,136,128,136,128,148,128,148,128,162,128,162,128,193,128,193,128,128,128, 0, 0, 0, 0, 0, 0}; /* "M" */ static const GLubyte Helvetica12_Character_078[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,134, 0,138, 0,138, 0,146, 0,162, 0,162, 0,194, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "N" */ static const GLubyte Helvetica12_Character_079[] = { 10, 0, 0, 0, 0, 0, 0, 60, 0, 66, 0,129, 0,129, 0,129, 0,129, 0,129, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "O" */ static const GLubyte Helvetica12_Character_080[] = { 8, 0, 0, 0,128,128,128,128,248,132,132,132,248, 0, 0, 0}; /* "P" */ static const GLubyte Helvetica12_Character_081[] = { 10, 0, 0, 0, 0, 0, 0, 61, 0, 66, 0,133, 0,137, 0,129, 0,129, 0,129, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "Q" */ static const GLubyte Helvetica12_Character_082[] = { 8, 0, 0, 0,132,132,132,136,248,132,132,132,248, 0, 0, 0}; /* "R" */ static const GLubyte Helvetica12_Character_083[] = { 8, 0, 0, 0,120,132,132, 4, 24, 96,128,132,120, 0, 0, 0}; /* "S" */ static const GLubyte Helvetica12_Character_084[] = { 7, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16,254, 0, 0, 0}; /* "T" */ static const GLubyte Helvetica12_Character_085[] = { 8, 0, 0, 0,120,132,132,132,132,132,132,132,132, 0, 0, 0}; /* "U" */ static const GLubyte Helvetica12_Character_086[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 40, 0, 40, 0, 68, 0, 68, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "V" */ static const GLubyte Helvetica12_Character_087[] = { 11, 0, 0, 0, 0, 0, 0, 34, 0, 34, 0, 34, 0, 85, 0, 85, 0, 73, 0,136,128,136,128,136,128, 0, 0, 0, 0, 0, 0}; /* "W" */ static const GLubyte Helvetica12_Character_088[] = { 9, 0, 0, 0, 0, 0, 0,130, 0, 68, 0, 68, 0, 40, 0, 16, 0, 40, 0, 68, 0, 68, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "X" */ static const GLubyte Helvetica12_Character_089[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 0, 40, 0, 68, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "Y" */ static const GLubyte Helvetica12_Character_090[] = { 9, 0, 0, 0, 0, 0, 0,254, 0,128, 0, 64, 0, 32, 0, 16, 0, 8, 0, 4, 0, 2, 0,254, 0, 0, 0, 0, 0, 0, 0}; /* "Z" */ static const GLubyte Helvetica12_Character_048[] = { 7, 0, 0, 0,112,136,136,136,136,136,136,136,112, 0, 0, 0}; /* "0" */ static const GLubyte Helvetica12_Character_049[] = { 7, 0, 0, 0, 32, 32, 32, 32, 32, 32, 32,224, 32, 0, 0, 0}; /* "1" */ static const GLubyte Helvetica12_Character_050[] = { 7, 0, 0, 0,248,128,128, 64, 32, 16, 8,136,112, 0, 0, 0}; /* "2" */ static const GLubyte Helvetica12_Character_051[] = { 7, 0, 0, 0,112,136,136, 8, 8, 48, 8,136,112, 0, 0, 0}; /* "3" */ static const GLubyte Helvetica12_Character_052[] = { 7, 0, 0, 0, 8, 8,252,136, 72, 40, 40, 24, 8, 0, 0, 0}; /* "4" */ static const GLubyte Helvetica12_Character_053[] = { 7, 0, 0, 0,112,136,136, 8, 8,240,128,128,248, 0, 0, 0}; /* "5" */ static const GLubyte Helvetica12_Character_054[] = { 7, 0, 0, 0,112,136,136,136,200,176,128,136,112, 0, 0, 0}; /* "6" */ static const GLubyte Helvetica12_Character_055[] = { 7, 0, 0, 0, 64, 64, 32, 32, 32, 16, 16, 8,248, 0, 0, 0}; /* "7" */ static const GLubyte Helvetica12_Character_056[] = { 7, 0, 0, 0,112,136,136,136,136,112,136,136,112, 0, 0, 0}; /* "8" */ static const GLubyte Helvetica12_Character_057[] = { 7, 0, 0, 0,112,136, 8, 8,120,136,136,136,112, 0, 0, 0}; /* "9" */ static const GLubyte Helvetica12_Character_096[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,128, 64, 0, 0, 0}; /* "`" */ static const GLubyte Helvetica12_Character_126[] = { 8, 0, 0, 0, 0, 0, 0,152,100, 0, 0, 0, 0, 0, 0, 0}; /* "~" */ static const GLubyte Helvetica12_Character_033[] = { 3, 0, 0, 0,128, 0,128,128,128,128,128,128,128, 0, 0, 0}; /* "!" */ static const GLubyte Helvetica12_Character_064[] = { 12, 0, 0, 0, 0, 62, 0, 64, 0,155, 0,166,128,162, 64,162, 64,146, 64, 77, 64, 96,128, 31, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ static const GLubyte Helvetica12_Character_035[] = { 7, 0, 0, 0, 80, 80, 80,252, 40,252, 40, 40, 0, 0, 0, 0}; /* "#" */ static const GLubyte Helvetica12_Character_036[] = { 7, 0, 0, 32,112,168,168, 40,112,160,168,112, 32, 0, 0, 0}; /* "$" */ static const GLubyte Helvetica12_Character_037[] = { 11, 0, 0, 0, 0, 0, 0, 35, 0, 20,128, 20,128, 19, 0, 8, 0,104, 0,148, 0,148, 0, 98, 0, 0, 0, 0, 0, 0, 0}; /* "%" */ static const GLubyte Helvetica12_Character_094[] = { 6, 0, 0, 0, 0, 0, 0, 0, 0,136, 80, 32, 0, 0, 0, 0}; /* "^" */ static const GLubyte Helvetica12_Character_038[] = { 9, 0, 0, 0, 0, 0, 0,114, 0,140, 0,132, 0,138, 0, 80, 0, 48, 0, 72, 0, 72, 0, 48, 0, 0, 0, 0, 0, 0, 0}; /* "&" */ static const GLubyte Helvetica12_Character_042[] = { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 64,160, 0, 0, 0}; /* "*" */ static const GLubyte Helvetica12_Character_040[] = { 4, 32, 64, 64,128,128,128,128,128,128, 64, 64, 32, 0, 0, 0}; /* "(" */ static const GLubyte Helvetica12_Character_041[] = { 4,128, 64, 64, 32, 32, 32, 32, 32, 32, 64, 64,128, 0, 0, 0}; /* ")" */ static const GLubyte Helvetica12_Character_045[] = { 8, 0, 0, 0, 0, 0, 0,248, 0, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ static const GLubyte Helvetica12_Character_095[] = { 7, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ static const GLubyte Helvetica12_Character_061[] = { 7, 0, 0, 0, 0, 0,248, 0,248, 0, 0, 0, 0, 0, 0, 0}; /* "=" */ static const GLubyte Helvetica12_Character_043[] = { 7, 0, 0, 0, 0, 32, 32,248, 32, 32, 0, 0, 0, 0, 0, 0}; /* "+" */ static const GLubyte Helvetica12_Character_091[] = { 3,192,128,128,128,128,128,128,128,128,128,128,192, 0, 0, 0}; /* "[" */ static const GLubyte Helvetica12_Character_123[] = { 4, 48, 64, 64, 64, 64, 64,128, 64, 64, 64, 64, 48, 0, 0, 0}; /* "{" */ static const GLubyte Helvetica12_Character_125[] = { 4,192, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32,192, 0, 0, 0}; /* "}" */ static const GLubyte Helvetica12_Character_093[] = { 3,192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,192, 0, 0, 0}; /* "]" */ static const GLubyte Helvetica12_Character_059[] = { 3, 0,128, 64, 64, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0}; /* ";" */ static const GLubyte Helvetica12_Character_058[] = { 3, 0, 0, 0,128, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0}; /* ":" */ static const GLubyte Helvetica12_Character_044[] = { 4, 0,128, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ static const GLubyte Helvetica12_Character_046[] = { 3, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ static const GLubyte Helvetica12_Character_060[] = { 7, 0, 0, 0, 0, 12, 48,192, 48, 12, 0, 0, 0, 0, 0, 0}; /* "<" */ static const GLubyte Helvetica12_Character_062[] = { 7, 0, 0, 0, 0,192, 48, 12, 48,192, 0, 0, 0, 0, 0, 0}; /* ">" */ static const GLubyte Helvetica12_Character_047[] = { 4, 0, 0, 0,128,128,128, 64, 64, 64, 32, 32, 32, 0, 0, 0}; /* "/" */ static const GLubyte Helvetica12_Character_063[] = { 7, 0, 0, 0, 32, 0, 32, 32, 16, 16,136,136,112, 0, 0, 0}; /* "?" */ static const GLubyte Helvetica12_Character_092[] = { 4, 0, 0, 0, 32, 32, 32, 64, 64, 64,128,128,128, 0, 0, 0}; /* "\" */ static const GLubyte Helvetica12_Character_034[] = { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,160,160, 0, 0, 0}; /* """ */ /* Missing Characters filled in by John Fay by hand ... */ static const GLubyte Helvetica12_Character_039[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 64, 64, 0, 0}; /* "'" */ static const GLubyte Helvetica12_Character_124[] = { 3, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 0}; /* "|" */ /* The font characters mapping: */ static const GLubyte* Helvetica12_Character_Map[] = {Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_032,Helvetica12_Character_033,Helvetica12_Character_034,Helvetica12_Character_035,Helvetica12_Character_036,Helvetica12_Character_037, Helvetica12_Character_038,Helvetica12_Character_039,Helvetica12_Character_040,Helvetica12_Character_041,Helvetica12_Character_042,Helvetica12_Character_043,Helvetica12_Character_044,Helvetica12_Character_045,Helvetica12_Character_046,Helvetica12_Character_047,Helvetica12_Character_048,Helvetica12_Character_049,Helvetica12_Character_050,Helvetica12_Character_051,Helvetica12_Character_052,Helvetica12_Character_053,Helvetica12_Character_054,Helvetica12_Character_055,Helvetica12_Character_056,Helvetica12_Character_057,Helvetica12_Character_058,Helvetica12_Character_059,Helvetica12_Character_060,Helvetica12_Character_061,Helvetica12_Character_062,Helvetica12_Character_063,Helvetica12_Character_064,Helvetica12_Character_065,Helvetica12_Character_066,Helvetica12_Character_067,Helvetica12_Character_068,Helvetica12_Character_069,Helvetica12_Character_070,Helvetica12_Character_071,Helvetica12_Character_072,Helvetica12_Character_073,Helvetica12_Character_074,Helvetica12_Character_075,Helvetica12_Character_076, Helvetica12_Character_077,Helvetica12_Character_078,Helvetica12_Character_079,Helvetica12_Character_080,Helvetica12_Character_081,Helvetica12_Character_082,Helvetica12_Character_083,Helvetica12_Character_084,Helvetica12_Character_085,Helvetica12_Character_086,Helvetica12_Character_087,Helvetica12_Character_088,Helvetica12_Character_089,Helvetica12_Character_090,Helvetica12_Character_091,Helvetica12_Character_092,Helvetica12_Character_093,Helvetica12_Character_094,Helvetica12_Character_095,Helvetica12_Character_096,Helvetica12_Character_097,Helvetica12_Character_098,Helvetica12_Character_099,Helvetica12_Character_100,Helvetica12_Character_101,Helvetica12_Character_102,Helvetica12_Character_103,Helvetica12_Character_104,Helvetica12_Character_105,Helvetica12_Character_106,Helvetica12_Character_107,Helvetica12_Character_108,Helvetica12_Character_109,Helvetica12_Character_110,Helvetica12_Character_111,Helvetica12_Character_112,Helvetica12_Character_113,Helvetica12_Character_114,Helvetica12_Character_115, Helvetica12_Character_116,Helvetica12_Character_117,Helvetica12_Character_118,Helvetica12_Character_119,Helvetica12_Character_120,Helvetica12_Character_121,Helvetica12_Character_122,Helvetica12_Character_123,Helvetica12_Character_124,Helvetica12_Character_125,Helvetica12_Character_126,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042, Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042, Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042, Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,NULL}; /* The font structure: */ static const SFG_Font fgFontHelvetica12 = { "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1", 93, 15, Helvetica12_Character_Map, -1.0f, 3.0f }; static const GLubyte Helvetica18_Character_032[] = { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ static const GLubyte Helvetica18_Character_097[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0,118, 0,238, 0,198, 0,198, 0,230, 0,126, 0, 14, 0,198, 0,238, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "a" */ static const GLubyte Helvetica18_Character_098[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0,222, 0,255, 0,227, 0,193,128,193,128,193,128,193,128,227, 0,255, 0,222, 0,192, 0,192, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "b" */ static const GLubyte Helvetica18_Character_099[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0,127, 0, 99, 0,192, 0,192, 0,192, 0,192, 0, 99, 0,127, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "c" */ static const GLubyte Helvetica18_Character_100[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 99,128,127,128, 61,128, 1,128, 1,128, 1,128, 1,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "d" */ static const GLubyte Helvetica18_Character_101[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,127, 0,227, 0,192, 0,192, 0,255, 0,195, 0,195, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "e" */ static const GLubyte Helvetica18_Character_102[] = { 6, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48,252,252, 48, 48, 60, 28, 0, 0, 0, 0}; /* "f" */ static const GLubyte Helvetica18_Character_103[] = { 11, 28, 0,127, 0, 99, 0, 1,128, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 97,128,127,128, 61,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "g" */ static const GLubyte Helvetica18_Character_104[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,227, 0,223, 0,206, 0,192, 0,192, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "h" */ static const GLubyte Helvetica18_Character_105[] = { 4, 0, 0, 0, 0,192,192,192,192,192,192,192,192,192,192, 0, 0,192,192, 0, 0, 0, 0}; /* "i" */ static const GLubyte Helvetica18_Character_106[] = { 4,224,240, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 0, 0, 0, 0}; /* "j" */ static const GLubyte Helvetica18_Character_107[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0,199, 0,198, 0,206, 0,204, 0,216, 0,248, 0,240, 0,216, 0,204, 0,198, 0,192, 0,192, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "k" */ static const GLubyte Helvetica18_Character_108[] = { 4, 0, 0, 0, 0,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 0, 0, 0, 0}; /* "l" */ static const GLubyte Helvetica18_Character_109[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0,198, 48,198, 48,198, 48,198, 48,198, 48,198, 48,198, 48,231, 48,222,240,204, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "m" */ static const GLubyte Helvetica18_Character_110[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,227, 0,223, 0,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "n" */ static const GLubyte Helvetica18_Character_111[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0,127, 0, 99, 0,193,128,193,128,193,128,193,128, 99, 0,127, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "o" */ static const GLubyte Helvetica18_Character_112[] = { 11,192, 0,192, 0,192, 0,192, 0,222, 0,255, 0,227, 0,193,128,193,128,193,128,193,128,227, 0,255, 0,222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "p" */ static const GLubyte Helvetica18_Character_113[] = { 11, 1,128, 1,128, 1,128, 1,128, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 99,128,127,128, 61,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "q" */ static const GLubyte Helvetica18_Character_114[] = { 6, 0, 0, 0, 0,192,192,192,192,192,192,192,224,216,216, 0, 0, 0, 0, 0, 0, 0, 0}; /* "r" */ static const GLubyte Helvetica18_Character_115[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,252, 0,198, 0, 6, 0, 62, 0,252, 0,192, 0,198, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "s" */ static const GLubyte Helvetica18_Character_116[] = { 6, 0, 0, 0, 0, 24, 56, 48, 48, 48, 48, 48, 48,252,252, 48, 48, 48, 0, 0, 0, 0, 0}; /* "t" */ static const GLubyte Helvetica18_Character_117[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,115, 0,251, 0,199, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "u" */ static const GLubyte Helvetica18_Character_118[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 24, 0, 60, 0, 36, 0,102, 0,102, 0,102, 0,195, 0,195, 0,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "v" */ static const GLubyte Helvetica18_Character_119[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 25,128, 25,128, 57,192, 41, 64,105, 96,102, 96,102, 96,198, 48,198, 48,198, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "w" */ static const GLubyte Helvetica18_Character_120[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,231, 0,102, 0, 60, 0, 24, 0, 24, 0, 60, 0,102, 0,231, 0,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "x" */ static const GLubyte Helvetica18_Character_121[] = { 10,112, 0,112, 0, 24, 0, 24, 0, 24, 0, 24, 0, 60, 0, 36, 0,102, 0,102, 0,102, 0,195, 0,195, 0,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "y" */ static const GLubyte Helvetica18_Character_122[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0,254, 0,254, 0,192, 0, 96, 0, 48, 0, 24, 0, 12, 0, 6, 0,254, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "z" */ static const GLubyte Helvetica18_Character_065[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0,192, 48,192, 48, 96, 96, 96, 96,127,224, 63,192, 48,192, 48,192, 25,128, 25,128, 15, 0, 15, 0, 6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "A" */ static const GLubyte Helvetica18_Character_066[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,255,128,255,192,192,224,192, 96,192, 96,192,224,255,192,255,128,193,128,192,192,192,192,193,192,255,128,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "B" */ static const GLubyte Helvetica18_Character_067[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 15,128, 63,224,112,112, 96, 48,224, 0,192, 0,192, 0,192, 0,192, 0,224, 0, 96, 48,112,112, 63,224, 15,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "C" */ static const GLubyte Helvetica18_Character_068[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,255,128,193,192,192,192,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,192,193,192,255,128,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "D" */ static const GLubyte Helvetica18_Character_069[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0,255,128,255,128,192, 0,192, 0,192, 0,192, 0,255, 0,255, 0,192, 0,192, 0,192, 0,192, 0,255,128,255,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "E" */ static const GLubyte Helvetica18_Character_070[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,255, 0,255, 0,192, 0,192, 0,192, 0,192, 0,255,128,255,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "F" */ static const GLubyte Helvetica18_Character_071[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 15,176, 63,240,112,112, 96, 48,224, 48,193,240,193,240,192, 0,192, 0,224, 48, 96, 48,112,112, 63,224, 15,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "G" */ static const GLubyte Helvetica18_Character_072[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,255,224,255,224,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96, 0, 0, 0, 0, 0, 0, 0, 0}; /* "H" */ static const GLubyte Helvetica18_Character_073[] = { 6, 0, 0, 0, 0,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 0, 0, 0, 0}; /* "I" */ static const GLubyte Helvetica18_Character_074[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,231, 0,195, 0,195, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "J" */ static const GLubyte Helvetica18_Character_075[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,192,112,192,224,193,192,195,128,199, 0,206, 0,252, 0,248, 0,220, 0,206, 0,199, 0,195,128,193,192,192,224, 0, 0, 0, 0, 0, 0, 0, 0}; /* "K" */ static const GLubyte Helvetica18_Character_076[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,255, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "L" */ static const GLubyte Helvetica18_Character_077[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0,195, 12,195, 12,199,140,196,140,204,204,204,204,216,108,216,108,240, 60,240, 60,224, 28,224, 28,192, 12,192, 12, 0, 0, 0, 0, 0, 0, 0, 0}; /* "M" */ static const GLubyte Helvetica18_Character_078[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,192, 96,192,224,193,224,193,224,195, 96,198, 96,198, 96,204, 96,204, 96,216, 96,240, 96,240, 96,224, 96,192, 96, 0, 0, 0, 0, 0, 0, 0, 0}; /* "N" */ static const GLubyte Helvetica18_Character_079[] = { 15, 0, 0, 0, 0, 0, 0, 0, 0, 15,128, 63,224,112,112, 96, 48,224, 56,192, 24,192, 24,192, 24,192, 24,224, 56, 96, 48,112,112, 63,224, 15,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "O" */ static const GLubyte Helvetica18_Character_080[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,255, 0,255,128,193,192,192,192,192,192,193,192,255,128,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "P" */ static const GLubyte Helvetica18_Character_081[] = { 15, 0, 0, 0, 0, 0, 0, 0, 48, 15,176, 63,224,112,240, 97,176,225,184,192, 24,192, 24,192, 24,192, 24,224, 56, 96, 48,112,112, 63,224, 15,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Q" */ static const GLubyte Helvetica18_Character_082[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0,192,192,192,192,192,192,192,192,193,128,193,128,255, 0,255,128,193,192,192,192,192,192,193,192,255,128,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "R" */ static const GLubyte Helvetica18_Character_083[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,127,192,224,224,192, 96, 0, 96, 0,224, 3,192, 31, 0,124, 0,224, 0,192, 96,224,224,127,192, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "S" */ static const GLubyte Helvetica18_Character_084[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0,255,192,255,192, 0, 0, 0, 0, 0, 0, 0, 0}; /* "T" */ static const GLubyte Helvetica18_Character_085[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0,127,192, 96,192,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96, 0, 0, 0, 0, 0, 0, 0, 0}; /* "U" */ static const GLubyte Helvetica18_Character_086[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 15, 0, 15, 0, 25,128, 25,128, 25,128, 48,192, 48,192, 48,192, 96, 96, 96, 96, 96, 96,192, 48,192, 48, 0, 0, 0, 0, 0, 0, 0, 0}; /* "V" */ static const GLubyte Helvetica18_Character_087[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 24, 24, 0, 28, 56, 0, 52, 44, 0, 54,108, 0, 54,108, 0,102,102, 0,102,102, 0, 98, 70, 0, 99,198, 0,195,195, 0,193,131, 0,193,131, 0,193,131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "W" */ static const GLubyte Helvetica18_Character_088[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,192, 96,224,224, 96,192,113,192, 49,128, 27, 0, 14, 0, 14, 0, 27, 0, 49,128,113,192, 96,192,224,224,192, 96, 0, 0, 0, 0, 0, 0, 0, 0}; /* "X" */ static const GLubyte Helvetica18_Character_089[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 15, 0, 25,128, 48,192, 48,192, 96, 96, 96, 96,192, 48,192, 48, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Y" */ static const GLubyte Helvetica18_Character_090[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0,255,192,255,192,192, 0, 96, 0, 48, 0, 24, 0, 28, 0, 12, 0, 6, 0, 3, 0, 1,128, 0,192,255,192,255,192, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Z" */ static const GLubyte Helvetica18_Character_048[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,102, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,102, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "0" */ static const GLubyte Helvetica18_Character_049[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0,248, 0,248, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "1" */ static const GLubyte Helvetica18_Character_050[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,255, 0,192, 0,224, 0,112, 0, 56, 0, 28, 0, 14, 0, 7, 0, 3, 0,195, 0,254, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "2" */ static const GLubyte Helvetica18_Character_051[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,199, 0,195, 0, 3, 0, 7, 0, 30, 0, 28, 0, 6, 0,195, 0,195, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "3" */ static const GLubyte Helvetica18_Character_052[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0,255,128,255,128,195, 0, 99, 0, 51, 0, 51, 0, 27, 0, 15, 0, 7, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "4" */ static const GLubyte Helvetica18_Character_053[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,124, 0,254, 0,199, 0,195, 0, 3, 0, 3, 0,199, 0,254, 0,252, 0,192, 0,192, 0,254, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "5" */ static const GLubyte Helvetica18_Character_054[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,227, 0,195, 0,195, 0,195, 0,254, 0,220, 0,192, 0,192, 0, 99, 0,127, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "6" */ static const GLubyte Helvetica18_Character_055[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 96, 0, 48, 0, 48, 0, 48, 0, 24, 0, 24, 0, 12, 0, 12, 0, 6, 0, 3, 0,255, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "7" */ static const GLubyte Helvetica18_Character_056[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,231, 0,195, 0,195, 0,102, 0,126, 0,102, 0,195, 0,195, 0,231, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "8" */ static const GLubyte Helvetica18_Character_057[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,124, 0,254, 0,198, 0, 3, 0, 3, 0, 59, 0,127, 0,195, 0,195, 0,195, 0,199, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "9" */ static const GLubyte Helvetica18_Character_096[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,192,128,128, 64, 0, 0, 0, 0}; /* "`" */ static const GLubyte Helvetica18_Character_126[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 0,126, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "~" */ static const GLubyte Helvetica18_Character_033[] = { 6, 0, 0, 0, 0,192,192, 0, 0,128,128,192,192,192,192,192,192,192,192, 0, 0, 0, 0}; /* "!" */ static const GLubyte Helvetica18_Character_064[] = { 18, 0, 0, 0, 7,224, 0, 31,240, 0, 56, 0, 0,112, 0, 0,103,112, 0,207,248, 0,204,204, 0,204,102, 0,204,102, 0,204, 99, 0,198, 51, 0,103,115, 0, 99,179, 0, 48, 6, 0, 28, 14, 0, 15,252, 0, 3,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ static const GLubyte Helvetica18_Character_035[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 36, 0, 36, 0,255,128,255,128, 18, 0, 18, 0, 18, 0,127,192,127,192, 9, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "#" */ static const GLubyte Helvetica18_Character_036[] = { 10, 0, 0, 0, 0, 8, 0, 8, 0, 62, 0,127, 0,235,128,201,128, 9,128, 15, 0, 62, 0,120, 0,232, 0,200, 0,203, 0,127, 0, 62, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "$" */ static const GLubyte Helvetica18_Character_037[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 24,120, 24,252, 12,204, 12,204, 6,252, 6,120, 3, 0,123, 0,253,128,205,128,204,192,252,192,120, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "%" */ static const GLubyte Helvetica18_Character_094[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130, 0,198, 0,108, 0, 56, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "^" */ static const GLubyte Helvetica18_Character_038[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 60,112,126,224,231,192,195,128,195,192,198,192,238,192,124, 0, 60, 0,102, 0,102, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "&" */ static const GLubyte Helvetica18_Character_042[] = { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,112,112,248, 32, 32, 0, 0, 0, 0}; /* "*" */ static const GLubyte Helvetica18_Character_040[] = { 6, 16, 48, 96, 96,192,192,192,192,192,192,192,192,192,192, 96, 96, 48, 16, 0, 0, 0, 0}; /* "(" */ static const GLubyte Helvetica18_Character_041[] = { 6,128,192, 96, 96, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 96, 96,192,128, 0, 0, 0, 0}; /* ")" */ static const GLubyte Helvetica18_Character_045[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,255, 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}; /* "-" */ static const GLubyte Helvetica18_Character_095[] = { 10,255,248,255,248, 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}; /* "_" */ static const GLubyte Helvetica18_Character_061[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 0,254, 0, 0, 0, 0, 0,254, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "=" */ static const GLubyte Helvetica18_Character_043[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 24, 0, 24, 0, 24, 0,255, 0,255, 0, 24, 0, 24, 0, 24, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "+" */ static const GLubyte Helvetica18_Character_091[] = { 5,240,240,192,192,192,192,192,192,192,192,192,192,192,192,192,192,240,240, 0, 0, 0, 0}; /* "[" */ static const GLubyte Helvetica18_Character_123[] = { 7, 12, 24, 48, 48, 48, 48, 48, 48, 96,192, 96, 48, 48, 48, 48, 48, 24, 12, 0, 0, 0, 0}; /* "{" */ static const GLubyte Helvetica18_Character_125[] = { 7,192, 96, 48, 48, 48, 48, 48, 48, 24, 12, 24, 48, 48, 48, 48, 48, 96,192, 0, 0, 0, 0}; /* "}" */ static const GLubyte Helvetica18_Character_093[] = { 5,240,240, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,240,240, 0, 0, 0, 0}; /* "]" */ static const GLubyte Helvetica18_Character_059[] = { 5, 0,128, 64, 64,192,192, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0}; /* ";" */ static const GLubyte Helvetica18_Character_058[] = { 5, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0}; /* ":" */ static const GLubyte Helvetica18_Character_044[] = { 5, 0,128, 64, 64,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ static const GLubyte Helvetica18_Character_046[] = { 5, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ static const GLubyte Helvetica18_Character_060[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 15, 0, 60, 0,112, 0,192, 0,112, 0, 60, 0, 15, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "<" */ static const GLubyte Helvetica18_Character_062[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,192, 0,240, 0, 60, 0, 14, 0, 3, 0, 14, 0, 60, 0,240, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ">" */ static const GLubyte Helvetica18_Character_047[] = { 5, 0, 0, 0, 0,192,192, 64, 64, 96, 96, 32, 32, 48, 48, 16, 16, 24, 24, 0, 0, 0, 0}; /* "/" */ static const GLubyte Helvetica18_Character_063[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 48, 0, 0, 0, 0, 0, 48, 0, 48, 0, 48, 0, 56, 0, 28, 0, 14, 0,198, 0,198, 0,254, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "?" */ static const GLubyte Helvetica18_Character_092[] = { 5, 0, 0, 0, 0, 24, 24, 16, 16, 48, 48, 32, 32, 96, 96, 64, 64,192,192, 0, 0, 0, 0}; /* "\" */ static const GLubyte Helvetica18_Character_034[] = { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144,144,216,216,216, 0, 0, 0, 0}; /* """ */ /* Missing Characters filled in by John Fay by hand ... */ static const GLubyte Helvetica18_Character_039[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 64, 64,192,192, 0, 0, 0, 0}; /* "'" */ static const GLubyte Helvetica18_Character_124[] = { 4, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96}; /* "|" */ /* The font characters mapping: */ static const GLubyte* Helvetica18_Character_Map[] = {Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_032,Helvetica18_Character_033,Helvetica18_Character_034,Helvetica18_Character_035,Helvetica18_Character_036,Helvetica18_Character_037, Helvetica18_Character_038,Helvetica18_Character_039,Helvetica18_Character_040,Helvetica18_Character_041,Helvetica18_Character_042,Helvetica18_Character_043,Helvetica18_Character_044,Helvetica18_Character_045,Helvetica18_Character_046,Helvetica18_Character_047,Helvetica18_Character_048,Helvetica18_Character_049,Helvetica18_Character_050,Helvetica18_Character_051,Helvetica18_Character_052,Helvetica18_Character_053,Helvetica18_Character_054,Helvetica18_Character_055,Helvetica18_Character_056,Helvetica18_Character_057,Helvetica18_Character_058,Helvetica18_Character_059,Helvetica18_Character_060,Helvetica18_Character_061,Helvetica18_Character_062,Helvetica18_Character_063,Helvetica18_Character_064,Helvetica18_Character_065,Helvetica18_Character_066,Helvetica18_Character_067,Helvetica18_Character_068,Helvetica18_Character_069,Helvetica18_Character_070,Helvetica18_Character_071,Helvetica18_Character_072,Helvetica18_Character_073,Helvetica18_Character_074,Helvetica18_Character_075,Helvetica18_Character_076, Helvetica18_Character_077,Helvetica18_Character_078,Helvetica18_Character_079,Helvetica18_Character_080,Helvetica18_Character_081,Helvetica18_Character_082,Helvetica18_Character_083,Helvetica18_Character_084,Helvetica18_Character_085,Helvetica18_Character_086,Helvetica18_Character_087,Helvetica18_Character_088,Helvetica18_Character_089,Helvetica18_Character_090,Helvetica18_Character_091,Helvetica18_Character_092,Helvetica18_Character_093,Helvetica18_Character_094,Helvetica18_Character_095,Helvetica18_Character_096,Helvetica18_Character_097,Helvetica18_Character_098,Helvetica18_Character_099,Helvetica18_Character_100,Helvetica18_Character_101,Helvetica18_Character_102,Helvetica18_Character_103,Helvetica18_Character_104,Helvetica18_Character_105,Helvetica18_Character_106,Helvetica18_Character_107,Helvetica18_Character_108,Helvetica18_Character_109,Helvetica18_Character_110,Helvetica18_Character_111,Helvetica18_Character_112,Helvetica18_Character_113,Helvetica18_Character_114,Helvetica18_Character_115, Helvetica18_Character_116,Helvetica18_Character_117,Helvetica18_Character_118,Helvetica18_Character_119,Helvetica18_Character_120,Helvetica18_Character_121,Helvetica18_Character_122,Helvetica18_Character_123,Helvetica18_Character_124,Helvetica18_Character_125,Helvetica18_Character_126,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042, Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042, Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042, Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,NULL}; /* The font structure: */ static const SFG_Font fgFontHelvetica18 = { "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1", 93, 22, Helvetica18_Character_Map, -1.0f, 4.0f }; static const GLubyte TimesRoman10_Character_032[] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ static const GLubyte TimesRoman10_Character_097[] = { 4, 0, 0, 0,224,160, 96, 32,192, 0, 0, 0, 0, 0}; /* "a" */ static const GLubyte TimesRoman10_Character_098[] = { 5, 0, 0, 0,224,144,144,144,224,128,128, 0, 0, 0}; /* "b" */ static const GLubyte TimesRoman10_Character_099[] = { 4, 0, 0, 0, 96,128,128,128, 96, 0, 0, 0, 0, 0}; /* "c" */ static const GLubyte TimesRoman10_Character_100[] = { 5, 0, 0, 0,104,144,144,144,112, 16, 48, 0, 0, 0}; /* "d" */ static const GLubyte TimesRoman10_Character_101[] = { 4, 0, 0, 0, 96,128,192,160, 96, 0, 0, 0, 0, 0}; /* "e" */ static const GLubyte TimesRoman10_Character_102[] = { 4, 0, 0, 0,224, 64, 64, 64,224, 64, 48, 0, 0, 0}; /* "f" */ static const GLubyte TimesRoman10_Character_103[] = { 5, 0,224,144, 96, 64,160,160,112, 0, 0, 0, 0, 0}; /* "g" */ static const GLubyte TimesRoman10_Character_104[] = { 5, 0, 0, 0,216,144,144,144,224,128,128, 0, 0, 0}; /* "h" */ static const GLubyte TimesRoman10_Character_105[] = { 3, 0, 0, 0, 64, 64, 64, 64,192, 0, 64, 0, 0, 0}; /* "i" */ static const GLubyte TimesRoman10_Character_106[] = { 3, 0,128, 64, 64, 64, 64, 64,192, 0, 64, 0, 0, 0}; /* "j" */ static const GLubyte TimesRoman10_Character_107[] = { 5, 0, 0, 0,152,144,224,160,144,128,128, 0, 0, 0}; /* "k" */ static const GLubyte TimesRoman10_Character_108[] = { 4, 0, 0, 0,224, 64, 64, 64, 64, 64,192, 0, 0, 0}; /* "l" */ static const GLubyte TimesRoman10_Character_109[] = { 8, 0, 0, 0,219,146,146,146,236, 0, 0, 0, 0, 0}; /* "m" */ static const GLubyte TimesRoman10_Character_110[] = { 5, 0, 0, 0,216,144,144,144,224, 0, 0, 0, 0, 0}; /* "n" */ static const GLubyte TimesRoman10_Character_111[] = { 5, 0, 0, 0, 96,144,144,144, 96, 0, 0, 0, 0, 0}; /* "o" */ static const GLubyte TimesRoman10_Character_112[] = { 5, 0,192,128,224,144,144,144,224, 0, 0, 0, 0, 0}; /* "p" */ static const GLubyte TimesRoman10_Character_113[] = { 5, 0, 56, 16,112,144,144,144,112, 0, 0, 0, 0, 0}; /* "q" */ static const GLubyte TimesRoman10_Character_114[] = { 4, 0, 0, 0,224, 64, 64, 96,160, 0, 0, 0, 0, 0}; /* "r" */ static const GLubyte TimesRoman10_Character_115[] = { 4, 0, 0, 0,224, 32, 96,128,224, 0, 0, 0, 0, 0}; /* "s" */ static const GLubyte TimesRoman10_Character_116[] = { 4, 0, 0, 0, 48, 64, 64, 64,224, 64, 0, 0, 0, 0}; /* "t" */ static const GLubyte TimesRoman10_Character_117[] = { 5, 0, 0, 0,104,144,144,144,144, 0, 0, 0, 0, 0}; /* "u" */ static const GLubyte TimesRoman10_Character_118[] = { 5, 0, 0, 0, 32, 96, 80,144,216, 0, 0, 0, 0, 0}; /* "v" */ static const GLubyte TimesRoman10_Character_119[] = { 8, 0, 0, 0, 40,108, 84,146,219, 0, 0, 0, 0, 0}; /* "w" */ static const GLubyte TimesRoman10_Character_120[] = { 6, 0, 0, 0,216, 80, 32, 80,216, 0, 0, 0, 0, 0}; /* "x" */ static const GLubyte TimesRoman10_Character_121[] = { 5, 0, 64, 64, 32, 48, 80, 72,220, 0, 0, 0, 0, 0}; /* "y" */ static const GLubyte TimesRoman10_Character_122[] = { 5, 0, 0, 0,240,144, 64, 32,240, 0, 0, 0, 0, 0}; /* "z" */ static const GLubyte TimesRoman10_Character_065[] = { 8, 0, 0, 0,238, 68,124, 40, 40, 56, 16, 0, 0, 0}; /* "A" */ static const GLubyte TimesRoman10_Character_066[] = { 6, 0, 0, 0,240, 72, 72,112, 72, 72,240, 0, 0, 0}; /* "B" */ static const GLubyte TimesRoman10_Character_067[] = { 7, 0, 0, 0,120,196,128,128,128,196,124, 0, 0, 0}; /* "C" */ static const GLubyte TimesRoman10_Character_068[] = { 7, 0, 0, 0,248, 76, 68, 68, 68, 76,248, 0, 0, 0}; /* "D" */ static const GLubyte TimesRoman10_Character_069[] = { 6, 0, 0, 0,248, 72, 64,112, 64, 72,248, 0, 0, 0}; /* "E" */ static const GLubyte TimesRoman10_Character_070[] = { 6, 0, 0, 0,224, 64, 64,112, 64, 72,248, 0, 0, 0}; /* "F" */ static const GLubyte TimesRoman10_Character_071[] = { 7, 0, 0, 0,120,196,132,156,128,196,124, 0, 0, 0}; /* "G" */ static const GLubyte TimesRoman10_Character_072[] = { 8, 0, 0, 0,238, 68, 68,124, 68, 68,238, 0, 0, 0}; /* "H" */ static const GLubyte TimesRoman10_Character_073[] = { 4, 0, 0, 0,224, 64, 64, 64, 64, 64,224, 0, 0, 0}; /* "I" */ static const GLubyte TimesRoman10_Character_074[] = { 4, 0, 0, 0,192,160, 32, 32, 32, 32,112, 0, 0, 0}; /* "J" */ static const GLubyte TimesRoman10_Character_075[] = { 7, 0, 0, 0,236, 72, 80, 96, 80, 72,236, 0, 0, 0}; /* "K" */ static const GLubyte TimesRoman10_Character_076[] = { 6, 0, 0, 0,248, 72, 64, 64, 64, 64,224, 0, 0, 0}; /* "L" */ static const GLubyte TimesRoman10_Character_077[] = { 10, 0, 0, 0, 0, 0, 0,235,128, 73, 0, 85, 0, 85, 0, 99, 0, 99, 0,227,128, 0, 0, 0, 0, 0, 0}; /* "M" */ static const GLubyte TimesRoman10_Character_078[] = { 8, 0, 0, 0,228, 76, 76, 84, 84,100,238, 0, 0, 0}; /* "N" */ static const GLubyte TimesRoman10_Character_079[] = { 7, 0, 0, 0,120,204,132,132,132,204,120, 0, 0, 0}; /* "O" */ static const GLubyte TimesRoman10_Character_080[] = { 6, 0, 0, 0,224, 64, 64,112, 72, 72,240, 0, 0, 0}; /* "P" */ static const GLubyte TimesRoman10_Character_081[] = { 7, 0, 12, 24,112,204,132,132,132,204,120, 0, 0, 0}; /* "Q" */ static const GLubyte TimesRoman10_Character_082[] = { 7, 0, 0, 0,236, 72, 80,112, 72, 72,240, 0, 0, 0}; /* "R" */ static const GLubyte TimesRoman10_Character_083[] = { 5, 0, 0, 0,224,144, 16, 96,192,144,112, 0, 0, 0}; /* "S" */ static const GLubyte TimesRoman10_Character_084[] = { 6, 0, 0, 0,112, 32, 32, 32, 32,168,248, 0, 0, 0}; /* "T" */ static const GLubyte TimesRoman10_Character_085[] = { 8, 0, 0, 0, 56,108, 68, 68, 68, 68,238, 0, 0, 0}; /* "U" */ static const GLubyte TimesRoman10_Character_086[] = { 8, 0, 0, 0, 16, 16, 40, 40,108, 68,238, 0, 0, 0}; /* "V" */ static const GLubyte TimesRoman10_Character_087[] = { 10, 0, 0, 0, 0, 0, 0, 34, 0, 34, 0, 85, 0, 85, 0,201,128,136,128,221,192, 0, 0, 0, 0, 0, 0}; /* "W" */ static const GLubyte TimesRoman10_Character_088[] = { 8, 0, 0, 0,238, 68, 40, 16, 40, 68,238, 0, 0, 0}; /* "X" */ static const GLubyte TimesRoman10_Character_089[] = { 8, 0, 0, 0, 56, 16, 16, 40, 40, 68,238, 0, 0, 0}; /* "Y" */ static const GLubyte TimesRoman10_Character_090[] = { 6, 0, 0, 0,248,136, 64, 32, 16,136,248, 0, 0, 0}; /* "Z" */ static const GLubyte TimesRoman10_Character_048[] = { 5, 0, 0, 0, 96,144,144,144,144,144, 96, 0, 0, 0}; /* "0" */ static const GLubyte TimesRoman10_Character_049[] = { 5, 0, 0, 0,224, 64, 64, 64, 64,192, 64, 0, 0, 0}; /* "1" */ static const GLubyte TimesRoman10_Character_050[] = { 5, 0, 0, 0,240, 64, 32, 32, 16,144, 96, 0, 0, 0}; /* "2" */ static const GLubyte TimesRoman10_Character_051[] = { 5, 0, 0, 0,224, 16, 16, 96, 16,144, 96, 0, 0, 0}; /* "3" */ static const GLubyte TimesRoman10_Character_052[] = { 5, 0, 0, 0, 16, 16,248,144, 80, 48, 16, 0, 0, 0}; /* "4" */ static const GLubyte TimesRoman10_Character_053[] = { 5, 0, 0, 0,224,144, 16, 16,224, 64,112, 0, 0, 0}; /* "5" */ static const GLubyte TimesRoman10_Character_054[] = { 5, 0, 0, 0, 96,144,144,144,224, 64, 48, 0, 0, 0}; /* "6" */ static const GLubyte TimesRoman10_Character_055[] = { 5, 0, 0, 0, 64, 64, 64, 32, 32,144,240, 0, 0, 0}; /* "7" */ static const GLubyte TimesRoman10_Character_056[] = { 5, 0, 0, 0, 96,144,144, 96,144,144, 96, 0, 0, 0}; /* "8" */ static const GLubyte TimesRoman10_Character_057[] = { 5, 0, 0, 0,192, 32,112,144,144,144, 96, 0, 0, 0}; /* "9" */ static const GLubyte TimesRoman10_Character_096[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0,192,128, 0, 0, 0}; /* "`" */ static const GLubyte TimesRoman10_Character_126[] = { 7, 0, 0, 0, 0, 0,152,100, 0, 0, 0, 0, 0, 0}; /* "~" */ static const GLubyte TimesRoman10_Character_033[] = { 3, 0, 0, 0,128, 0,128,128,128,128,128, 0, 0, 0}; /* "!" */ static const GLubyte TimesRoman10_Character_064[] = { 9, 0, 0, 62, 0, 64, 0,146, 0,173, 0,165, 0,165, 0,157, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ static const GLubyte TimesRoman10_Character_035[] = { 5, 0, 0, 0, 80, 80,248, 80,248, 80, 80, 0, 0, 0}; /* "#" */ static const GLubyte TimesRoman10_Character_036[] = { 5, 0, 0, 32,224,144, 16, 96,128,144,112, 32, 0, 0}; /* "$" */ static const GLubyte TimesRoman10_Character_037[] = { 8, 0, 0, 0, 68, 42, 42, 86,168,164,126, 0, 0, 0}; /* "%" */ static const GLubyte TimesRoman10_Character_094[] = { 5, 0, 0, 0, 0, 0, 0, 0,160,160, 64, 0, 0, 0}; /* "^" */ static const GLubyte TimesRoman10_Character_038[] = { 8, 0, 0, 0,118,141,152,116,110, 80, 48, 0, 0, 0}; /* "&" */ static const GLubyte TimesRoman10_Character_042[] = { 5, 0, 0, 0, 0, 0, 0, 0,160, 64,160, 0, 0, 0}; /* "*" */ static const GLubyte TimesRoman10_Character_040[] = { 4, 0, 32, 64, 64,128,128,128, 64, 64, 32, 0, 0, 0}; /* "(" */ static const GLubyte TimesRoman10_Character_041[] = { 4, 0,128, 64, 64, 32, 32, 32, 64, 64,128, 0, 0, 0}; /* ")" */ static const GLubyte TimesRoman10_Character_045[] = { 7, 0, 0, 0, 0, 0,240, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ static const GLubyte TimesRoman10_Character_095[] = { 5,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ static const GLubyte TimesRoman10_Character_061[] = { 6, 0, 0, 0, 0,248, 0,248, 0, 0, 0, 0, 0, 0}; /* "=" */ static const GLubyte TimesRoman10_Character_043[] = { 6, 0, 0, 0, 32, 32,248, 32, 32, 0, 0, 0, 0, 0}; /* "+" */ static const GLubyte TimesRoman10_Character_091[] = { 3, 0,192,128,128,128,128,128,128,128,192, 0, 0, 0}; /* "[" */ static const GLubyte TimesRoman10_Character_123[] = { 4, 0, 32, 64, 64, 64,128, 64, 64, 64, 32, 0, 0, 0}; /* "{" */ static const GLubyte TimesRoman10_Character_125[] = { 4, 0,128, 64, 64, 64, 32, 64, 64, 64,128, 0, 0, 0}; /* "}" */ static const GLubyte TimesRoman10_Character_093[] = { 3, 0,192, 64, 64, 64, 64, 64, 64, 64,192, 0, 0, 0}; /* "]" */ static const GLubyte TimesRoman10_Character_059[] = { 3, 0,128,128,128, 0, 0, 0,128, 0, 0, 0, 0, 0}; /* ";" */ static const GLubyte TimesRoman10_Character_058[] = { 3, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0, 0, 0}; /* ":" */ static const GLubyte TimesRoman10_Character_044[] = { 3, 0,128,128,128, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ static const GLubyte TimesRoman10_Character_046[] = { 3, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ static const GLubyte TimesRoman10_Character_060[] = { 5, 0, 0, 0, 32, 64,128, 64, 32, 0, 0, 0, 0, 0}; /* "<" */ static const GLubyte TimesRoman10_Character_062[] = { 5, 0, 0, 0,128, 64, 32, 64,128, 0, 0, 0, 0, 0}; /* ">" */ static const GLubyte TimesRoman10_Character_047[] = { 3, 0, 0, 0,128,128, 64, 64, 64, 32, 32, 0, 0, 0}; /* "/" */ static const GLubyte TimesRoman10_Character_063[] = { 4, 0, 0, 0, 64, 0, 64, 64, 32,160,224, 0, 0, 0}; /* "?" */ static const GLubyte TimesRoman10_Character_092[] = { 3, 0, 0, 0, 32, 32, 64, 64, 64,128,128, 0, 0, 0}; /* "\" */ static const GLubyte TimesRoman10_Character_034[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0,160,160, 0, 0, 0}; /* """ */ /* Missing Characters filled in by John Fay by hand ... */ static const GLubyte TimesRoman10_Character_039[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0, 64, 64,192, 0, 0}; /* "'" */ static const GLubyte TimesRoman10_Character_124[] = { 2,128,128,128,128,128,128,128,128,128,128,128,128,128}; /* "|" */ /* The font characters mapping: */ static const GLubyte* TimesRoman10_Character_Map[] = {TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_032,TimesRoman10_Character_033,TimesRoman10_Character_034,TimesRoman10_Character_035, TimesRoman10_Character_036,TimesRoman10_Character_037,TimesRoman10_Character_038,TimesRoman10_Character_039,TimesRoman10_Character_040,TimesRoman10_Character_041,TimesRoman10_Character_042,TimesRoman10_Character_043,TimesRoman10_Character_044,TimesRoman10_Character_045,TimesRoman10_Character_046,TimesRoman10_Character_047,TimesRoman10_Character_048,TimesRoman10_Character_049,TimesRoman10_Character_050,TimesRoman10_Character_051,TimesRoman10_Character_052,TimesRoman10_Character_053,TimesRoman10_Character_054,TimesRoman10_Character_055,TimesRoman10_Character_056,TimesRoman10_Character_057,TimesRoman10_Character_058,TimesRoman10_Character_059,TimesRoman10_Character_060,TimesRoman10_Character_061,TimesRoman10_Character_062,TimesRoman10_Character_063,TimesRoman10_Character_064,TimesRoman10_Character_065,TimesRoman10_Character_066,TimesRoman10_Character_067,TimesRoman10_Character_068,TimesRoman10_Character_069,TimesRoman10_Character_070,TimesRoman10_Character_071,TimesRoman10_Character_072, TimesRoman10_Character_073,TimesRoman10_Character_074,TimesRoman10_Character_075,TimesRoman10_Character_076,TimesRoman10_Character_077,TimesRoman10_Character_078,TimesRoman10_Character_079,TimesRoman10_Character_080,TimesRoman10_Character_081,TimesRoman10_Character_082,TimesRoman10_Character_083,TimesRoman10_Character_084,TimesRoman10_Character_085,TimesRoman10_Character_086,TimesRoman10_Character_087,TimesRoman10_Character_088,TimesRoman10_Character_089,TimesRoman10_Character_090,TimesRoman10_Character_091,TimesRoman10_Character_092,TimesRoman10_Character_093,TimesRoman10_Character_094,TimesRoman10_Character_095,TimesRoman10_Character_096,TimesRoman10_Character_097,TimesRoman10_Character_098,TimesRoman10_Character_099,TimesRoman10_Character_100,TimesRoman10_Character_101,TimesRoman10_Character_102,TimesRoman10_Character_103,TimesRoman10_Character_104,TimesRoman10_Character_105,TimesRoman10_Character_106,TimesRoman10_Character_107,TimesRoman10_Character_108,TimesRoman10_Character_109, TimesRoman10_Character_110,TimesRoman10_Character_111,TimesRoman10_Character_112,TimesRoman10_Character_113,TimesRoman10_Character_114,TimesRoman10_Character_115,TimesRoman10_Character_116,TimesRoman10_Character_117,TimesRoman10_Character_118,TimesRoman10_Character_119,TimesRoman10_Character_120,TimesRoman10_Character_121,TimesRoman10_Character_122,TimesRoman10_Character_123,TimesRoman10_Character_124,TimesRoman10_Character_125,TimesRoman10_Character_126,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042, TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042, TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042, TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,NULL}; /* The font structure: */ static const SFG_Font fgFontTimesRoman10 = { "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1", 93, 13, TimesRoman10_Character_Map, 0.0f, 3.0f }; static const GLubyte TimesRoman24_Character_032[] = { 6, 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}; /* " " */ static const GLubyte TimesRoman24_Character_097[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113,128,251, 0,199, 0,195, 0,195, 0, 99, 0, 59, 0, 15, 0, 3, 0, 99, 0,103, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "a" */ static const GLubyte TimesRoman24_Character_098[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0,115,128, 97,128, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 97,128,115,128,110, 0, 96, 0, 96, 0, 96, 0, 96, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "b" */ static const GLubyte TimesRoman24_Character_099[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,127, 0,112,128,224, 0,192, 0,192, 0,192, 0,192, 0,192, 0, 65,128, 99,128, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "c" */ static const GLubyte TimesRoman24_Character_100[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,192,115,128, 97,128,193,128,193,128,193,128,193,128,193,128,193,128, 97,128,115,128, 29,128, 1,128, 1,128, 1,128, 1,128, 3,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "d" */ static const GLubyte TimesRoman24_Character_101[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,127, 0,112,128,224, 0,192, 0,192, 0,192, 0,255,128,193,128, 65,128, 99, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "e" */ static const GLubyte TimesRoman24_Character_102[] = { 7, 0, 0, 0, 0, 0, 0,120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,254, 48, 48, 48, 22, 14, 0, 0, 0, 0, 0}; /* "f" */ static const GLubyte TimesRoman24_Character_103[] = { 12, 0, 0, 63, 0,241,192,192, 96,192, 32, 96, 96, 63,192,127, 0, 96, 0, 48, 0, 62, 0, 51, 0, 97,128, 97,128, 97,128, 97,128, 51, 0, 31,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "g" */ static const GLubyte TimesRoman24_Character_104[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,224, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,113,192,111,128,103, 0, 96, 0, 96, 0, 96, 0, 96, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "h" */ static const GLubyte TimesRoman24_Character_105[] = { 6, 0, 0, 0, 0, 0, 0,240, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,224, 0, 0, 0, 96, 96, 0, 0, 0, 0, 0}; /* "i" */ static const GLubyte TimesRoman24_Character_106[] = { 6, 0,192,224, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,112, 0, 0, 0, 48, 48, 0, 0, 0, 0, 0}; /* "j" */ static const GLubyte TimesRoman24_Character_107[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,243,224, 97,192, 99,128,103, 0,110, 0,108, 0,120, 0,104, 0,100, 0,102, 0, 99, 0,103,192, 96, 0, 96, 0, 96, 0, 96, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "k" */ static const GLubyte TimesRoman24_Character_108[] = { 6, 0, 0, 0, 0, 0, 0,240, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,224, 0, 0, 0, 0, 0}; /* "l" */ static const GLubyte TimesRoman24_Character_109[] = { 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,227,192, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128,113,227,128,111,159, 0,231, 14, 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}; /* "m" */ static const GLubyte TimesRoman24_Character_110[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,224, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,113,192,111,128,231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "n" */ static const GLubyte TimesRoman24_Character_111[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,115,128, 97,128,192,192,192,192,192,192,192,192,192,192,192,192, 97,128,115,128, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "o" */ static const GLubyte TimesRoman24_Character_112[] = { 12, 0, 0,240, 0, 96, 0, 96, 0, 96, 0, 96, 0,110, 0,115,128, 97,128, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 97,128,115,128,238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "p" */ static const GLubyte TimesRoman24_Character_113[] = { 12, 0, 0, 3,192, 1,128, 1,128, 1,128, 1,128, 29,128,115,128, 97,128,193,128,193,128,193,128,193,128,193,128,193,128, 97,128,115,128, 29,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "q" */ static const GLubyte TimesRoman24_Character_114[] = { 8, 0, 0, 0, 0, 0, 0,240, 96, 96, 96, 96, 96, 96, 96, 96,118,110,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "r" */ static const GLubyte TimesRoman24_Character_115[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 0,198, 0,131, 0, 3, 0, 7, 0, 30, 0,124, 0,112, 0,224, 0,194, 0,102, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "s" */ static const GLubyte TimesRoman24_Character_116[] = { 7, 0, 0, 0, 0, 0, 0, 28, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48,254,112, 48, 16, 0, 0, 0, 0, 0, 0, 0}; /* "t" */ static const GLubyte TimesRoman24_Character_117[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,224, 62,192,113,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,225,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "u" */ static const GLubyte TimesRoman24_Character_118[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 14, 0, 14, 0, 26, 0, 25, 0, 25, 0, 49, 0, 48,128, 48,128, 96,128, 96,192,241,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "v" */ static const GLubyte TimesRoman24_Character_119[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 16, 0, 14, 56, 0, 14, 56, 0, 26, 40, 0, 26,100, 0, 25,100, 0, 49,100, 0, 48,194, 0, 48,194, 0, 96,194, 0, 96,195, 0,241,231,128, 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}; /* "w" */ static const GLubyte TimesRoman24_Character_120[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,224, 96,192, 33,128, 51,128, 27, 0, 14, 0, 12, 0, 26, 0, 57, 0, 49,128, 96,192,241,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "x" */ static const GLubyte TimesRoman24_Character_121[] = { 11, 0, 0,224, 0,240, 0, 24, 0, 8, 0, 12, 0, 4, 0, 14, 0, 14, 0, 26, 0, 25, 0, 25, 0, 49, 0, 48,128, 48,128, 96,128, 96,192,241,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "y" */ static const GLubyte TimesRoman24_Character_122[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,195, 0, 97, 0,112, 0, 48, 0, 56, 0, 24, 0, 28, 0, 14, 0,134, 0,195, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "z" */ static const GLubyte TimesRoman24_Character_065[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 31,128, 48, 6, 0, 16, 6, 0, 16, 12, 0, 24, 12, 0, 8, 12, 0, 15,248, 0, 12, 24, 0, 4, 24, 0, 4, 48, 0, 6, 48, 0, 2, 48, 0, 2, 96, 0, 1, 96, 0, 1,192, 0, 1,192, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "A" */ static const GLubyte TimesRoman24_Character_066[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,224, 48,120, 48, 24, 48, 12, 48, 12, 48, 12, 48, 24, 48, 56, 63,224, 48, 64, 48, 48, 48, 24, 48, 24, 48, 24, 48, 48, 48,112,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "B" */ static const GLubyte TimesRoman24_Character_067[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 30, 56, 56, 8, 96, 4, 96, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0, 96, 4, 96, 4, 56, 12, 28, 60, 7,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "C" */ static const GLubyte TimesRoman24_Character_068[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,192, 0, 48,112, 0, 48, 56, 0, 48, 12, 0, 48, 12, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 12, 0, 48, 12, 0, 48, 56, 0, 48,112, 0,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "D" */ static const GLubyte TimesRoman24_Character_069[] = { 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,248, 48, 24, 48, 8, 48, 8, 48, 0, 48, 0, 48, 64, 48, 64, 63,192, 48, 64, 48, 64, 48, 0, 48, 0, 48, 16, 48, 16, 48, 48,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "E" */ static const GLubyte TimesRoman24_Character_070[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 32, 48, 32, 63,224, 48, 32, 48, 32, 48, 0, 48, 0, 48, 16, 48, 16, 48, 48,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "F" */ static const GLubyte TimesRoman24_Character_071[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 0, 30, 56, 0, 56, 28, 0, 96, 12, 0, 96, 12, 0,192, 12, 0,192, 12, 0,192, 63, 0,192, 0, 0,192, 0, 0,192, 0, 0,192, 0, 0, 96, 4, 0, 96, 4, 0, 56, 12, 0, 28, 60, 0, 7,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "G" */ static const GLubyte TimesRoman24_Character_072[] = { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 31,128, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 63,254, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0,252, 31,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "H" */ static const GLubyte TimesRoman24_Character_073[] = { 8, 0, 0, 0, 0, 0, 0,252, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,252, 0, 0, 0, 0, 0}; /* "I" */ static const GLubyte TimesRoman24_Character_074[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,204, 0,198, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 31,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "J" */ static const GLubyte TimesRoman24_Character_075[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 31, 0, 48, 14, 0, 48, 28, 0, 48, 56, 0, 48,112, 0, 48,224, 0, 49,192, 0, 51,128, 0, 63, 0, 0, 62, 0, 0, 51, 0, 0, 49,128, 0, 48,192, 0, 48, 96, 0, 48, 48, 0, 48, 24, 0,252,126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "K" */ static const GLubyte TimesRoman24_Character_076[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,248, 48, 24, 48, 8, 48, 8, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "L" */ static const GLubyte TimesRoman24_Character_077[] = { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 33,248, 32, 96, 96, 32, 96, 96, 32,208, 96, 32,208, 96, 33,136, 96, 33,136, 96, 35, 8, 96, 35, 4, 96, 38, 4, 96, 38, 2, 96, 44, 2, 96, 44, 2, 96, 56, 1, 96, 56, 1, 96, 48, 0,224,240, 0,248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "M" */ static const GLubyte TimesRoman24_Character_078[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 12, 0, 32, 28, 0, 32, 28, 0, 32, 52, 0, 32,100, 0, 32,100, 0, 32,196, 0, 33,132, 0, 33,132, 0, 35, 4, 0, 38, 4, 0, 38, 4, 0, 44, 4, 0, 56, 4, 0, 56, 4, 0, 48, 4, 0,240, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "N" */ static const GLubyte TimesRoman24_Character_079[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 0, 28, 56, 0, 56, 28, 0, 96, 6, 0, 96, 6, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0, 96, 6, 0, 96, 6, 0, 56, 28, 0, 28, 56, 0, 7,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "O" */ static const GLubyte TimesRoman24_Character_080[] = { 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 63,192, 48,112, 48, 48, 48, 24, 48, 24, 48, 24, 48, 48, 48,112,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "P" */ static const GLubyte TimesRoman24_Character_081[] = { 18, 0, 0, 0, 0, 15, 0, 0, 56, 0, 0,112, 0, 0,224, 0, 1,192, 0, 7,224, 0, 28, 56, 0, 56, 28, 0, 96, 6, 0, 96, 6, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0, 96, 6, 0, 96, 6, 0, 56, 28, 0, 28, 56, 0, 7,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Q" */ static const GLubyte TimesRoman24_Character_082[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 30, 48, 28, 48, 56, 48,112, 48, 96, 48,192, 49,192, 51,128, 63,192, 48,112, 48, 48, 48, 56, 48, 24, 48, 56, 48, 48, 48,112,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "R" */ static const GLubyte TimesRoman24_Character_083[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,158, 0,241,128,192,192,128, 96,128, 96, 0, 96, 0,224, 3,192, 15,128, 30, 0,120, 0,224, 0,192, 64,192, 64,192,192, 99,192, 30, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "S" */ static const GLubyte TimesRoman24_Character_084[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15,192, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,131, 4,131, 4,195, 12,255,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "T" */ static const GLubyte TimesRoman24_Character_085[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 0, 28, 48, 0, 24, 8, 0, 48, 8, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0,252, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "U" */ static const GLubyte TimesRoman24_Character_086[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,128, 0, 1,128, 0, 1,128, 0, 3,192, 0, 3, 64, 0, 3, 96, 0, 6, 32, 0, 6, 32, 0, 6, 48, 0, 12, 16, 0, 12, 24, 0, 24, 8, 0, 24, 8, 0, 24, 12, 0, 48, 4, 0, 48, 6, 0,252, 31,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "V" */ static const GLubyte TimesRoman24_Character_087[] = { 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,131, 0, 1,131, 0, 1,131,128, 3,135,128, 3, 70,128, 3, 70,192, 6, 70, 64, 6, 76, 64, 6, 76, 96, 12, 44, 96, 12, 44, 32, 24, 44, 32, 24, 24, 48, 24, 24, 16, 48, 24, 16, 48, 24, 24,252,126,126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "W" */ static const GLubyte TimesRoman24_Character_088[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 15,192, 48, 3,128, 24, 7, 0, 8, 14, 0, 4, 12, 0, 6, 24, 0, 2, 56, 0, 1,112, 0, 0,224, 0, 0,192, 0, 1,192, 0, 3,160, 0, 3, 16, 0, 6, 8, 0, 14, 12, 0, 28, 6, 0,126, 15,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "X" */ static const GLubyte TimesRoman24_Character_089[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 1,128, 1,128, 1,128, 1,128, 1,128, 1,128, 3,192, 3, 64, 6, 96, 6, 32, 12, 48, 28, 16, 24, 24, 56, 8, 48, 12,252, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Y" */ static const GLubyte TimesRoman24_Character_090[] = { 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,248,224, 24,112, 8, 48, 8, 56, 0, 24, 0, 28, 0, 14, 0, 6, 0, 7, 0, 3, 0, 3,128, 1,192,128,192,128,224,192,112,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Z" */ static const GLubyte TimesRoman24_Character_048[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 51, 0, 97,128, 97,128,225,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 97,128, 97,128, 51, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "0" */ static const GLubyte TimesRoman24_Character_049[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0,120, 0, 24, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "1" */ static const GLubyte TimesRoman24_Character_050[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,128,255,192, 96, 64, 48, 0, 24, 0, 12, 0, 4, 0, 6, 0, 3, 0, 3, 0, 1,128, 1,128,129,128,129,128, 67,128,127, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "2" */ static const GLubyte TimesRoman24_Character_051[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,230, 0,195, 0, 1, 0, 1,128, 1,128, 1,128, 3,128, 7, 0, 30, 0, 12, 0, 6, 0,131, 0,131, 0, 71, 0,126, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "3" */ static const GLubyte TimesRoman24_Character_052[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 3, 0,255,192,255,192,195, 0, 67, 0, 99, 0, 35, 0, 51, 0, 19, 0, 27, 0, 11, 0, 7, 0, 7, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "4" */ static const GLubyte TimesRoman24_Character_053[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 0,227,128,193,128, 0,192, 0,192, 0,192, 0,192, 1,192, 3,128, 15,128,126, 0,120, 0, 96, 0, 32, 0, 32, 0, 31,128, 31,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "5" */ static const GLubyte TimesRoman24_Character_054[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,123,128, 97,128,224,192,192,192,192,192,192,192,192,192,193,128,243,128,238, 0, 96, 0,112, 0, 48, 0, 24, 0, 14, 0, 3,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "6" */ static const GLubyte TimesRoman24_Character_055[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 24, 0, 12, 0, 12, 0, 12, 0, 4, 0, 6, 0, 6, 0, 2, 0, 3, 0, 3, 0, 1, 0, 1,128,129,128,192,192,255,192,127,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "7" */ static const GLubyte TimesRoman24_Character_056[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,115,128,225,128,192,192,192,192,192,192, 65,192, 97,128, 55, 0, 30, 0, 30, 0, 51, 0, 97,128, 97,128, 97,128, 51, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "8" */ static const GLubyte TimesRoman24_Character_057[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 28, 0, 6, 0, 3, 0, 3,128, 1,128, 29,128,115,192, 97,192,192,192,192,192,192,192,192,192,193,192, 97,128,119,128, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "9" */ static const GLubyte TimesRoman24_Character_096[] = { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,224,128,192, 96, 0, 0, 0, 0, 0}; /* "`" */ static const GLubyte TimesRoman24_Character_126[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,131,128,199,192,124, 96, 56, 32, 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}; /* "~" */ static const GLubyte TimesRoman24_Character_033[] = { 8, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0,192,192,192,192,192,192,192,192,192,192,192,192, 0, 0, 0, 0, 0}; /* "!" */ static const GLubyte TimesRoman24_Character_064[] = { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,240, 0, 14, 12, 0, 24, 0, 0, 48, 0, 0, 97,222, 0, 99,123, 0,198, 57,128,198, 24,128,198, 24,192,198, 24, 64,198, 12, 64,195, 12, 64,195,140, 64,225,252, 64, 96,236,192,112, 0,128, 56, 1,128, 28, 3, 0, 15, 14, 0, 3,248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ static const GLubyte TimesRoman24_Character_035[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 34, 0, 34, 0, 34, 0, 34, 0,255,192,255,192, 17, 0, 17, 0, 17, 0,127,224,127,224, 8,128, 8,128, 8,128, 8,128, 8,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "#" */ static const GLubyte TimesRoman24_Character_036[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 63, 0,229,192,196,192,132, 96,132, 96, 4, 96, 4,224, 7,192, 7,128, 30, 0, 60, 0,116, 0,100, 0,100, 32,100, 96, 52,224, 31,128, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0}; /* "$" */ static const GLubyte TimesRoman24_Character_037[] = { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 60, 0, 24,114, 0, 12, 97, 0, 4, 96,128, 6, 96,128, 3, 48,128, 1, 25,128, 1,143, 0,120,192, 0,228, 64, 0,194, 96, 0,193, 48, 0,193, 16, 0, 97, 24, 0, 51,252, 0, 30, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "%" */ static const GLubyte TimesRoman24_Character_094[] = { 11, 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,128,128,193,128, 65, 0, 99, 0, 34, 0, 54, 0, 20, 0, 28, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "^" */ static const GLubyte TimesRoman24_Character_038[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 0,127,126, 0,225,225, 0,192,192, 0,193,192, 0,193,160, 0, 99, 32, 0, 55, 16, 0, 30, 24, 0, 14, 62, 0, 15, 0, 0, 29,128, 0, 24,192, 0, 24, 64, 0, 24, 64, 0, 12,192, 0, 7,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "&" */ static const GLubyte TimesRoman24_Character_042[] = { 12, 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, 8, 0, 28, 0,201,128,235,128, 28, 0,235,128,201,128, 28, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "*" */ static const GLubyte TimesRoman24_Character_040[] = { 8, 0, 4, 8, 16, 48, 32, 96, 96,192,192,192,192,192,192,192,192, 96, 96, 32, 48, 16, 8, 4, 0, 0, 0, 0, 0}; /* "(" */ static const GLubyte TimesRoman24_Character_041[] = { 8, 0,128, 64, 32, 48, 16, 24, 24, 12, 12, 12, 12, 12, 12, 12, 12, 24, 24, 16, 48, 32, 64,128, 0, 0, 0, 0, 0}; /* ")" */ static const GLubyte TimesRoman24_Character_045[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,240,255,240, 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}; /* "-" */ static const GLubyte TimesRoman24_Character_095[] = { 13, 0, 0,255,248,255,248, 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}; /* "_" */ static const GLubyte TimesRoman24_Character_061[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,240,255,240, 0, 0, 0, 0,255,240,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "=" */ static const GLubyte TimesRoman24_Character_043[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0,255,240,255,240, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "+" */ static const GLubyte TimesRoman24_Character_091[] = { 8, 0, 0,248,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,248, 0, 0, 0, 0, 0}; /* "[" */ static const GLubyte TimesRoman24_Character_123[] = { 10, 0, 0, 7, 0, 12, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 16, 0, 48, 0, 32, 0,192, 0, 32, 0, 48, 0, 16, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 12, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "{" */ static const GLubyte TimesRoman24_Character_125[] = { 10, 0, 0,224, 0, 48, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 8, 0, 12, 0, 4, 0, 3, 0, 4, 0, 12, 0, 8, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 48, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "}" */ static const GLubyte TimesRoman24_Character_093[] = { 8, 0, 0,248, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,248, 0, 0, 0, 0, 0}; /* "]" */ static const GLubyte TimesRoman24_Character_059[] = { 7, 0, 0, 0,192, 96, 32,224,192, 0, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ";" */ static const GLubyte TimesRoman24_Character_058[] = { 6, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ":" */ static const GLubyte TimesRoman24_Character_044[] = { 7, 0, 0, 0,192, 96, 32,224,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ static const GLubyte TimesRoman24_Character_046[] = { 6, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ static const GLubyte TimesRoman24_Character_060[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 1,192, 7, 0, 28, 0,112, 0,192, 0,112, 0, 28, 0, 7, 0, 1,192, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "<" */ static const GLubyte TimesRoman24_Character_062[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 0,112, 0, 28, 0, 7, 0, 1,192, 0, 96, 1,192, 7, 0, 28, 0,112, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ">" */ static const GLubyte TimesRoman24_Character_047[] = { 7, 0, 0, 0,192,192,192, 96, 96, 32, 48, 48, 16, 24, 24, 8, 12, 12, 4, 6, 6, 3, 3, 3, 0, 0, 0, 0, 0}; /* "/" */ static const GLubyte TimesRoman24_Character_063[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 48, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 24, 0, 24, 0, 12, 0, 14, 0, 7, 0,195, 0,195, 0,131, 0,198, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "?" */ static const GLubyte TimesRoman24_Character_092[] = { 7, 0, 0, 0, 0, 0, 0, 6, 6, 4, 12, 12, 8, 24, 24, 16, 48, 48, 32, 96, 96, 64,192,192, 0, 0, 0, 0, 0}; /* "\" */ static const GLubyte TimesRoman24_Character_034[] = { 10, 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,136, 0,204, 0,204, 0,204, 0,204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* """ */ /* Missing Characters filled in by John Fay by hand ... */ static const GLubyte TimesRoman24_Character_039[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 96, 32,224,192, 0, 0, 0, 0, 0}; /* "'" */ static const GLubyte TimesRoman24_Character_124[] = { 6, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0}; /* "|" */ /* The font characters mapping: */ static const GLubyte* TimesRoman24_Character_Map[] = {TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_032,TimesRoman24_Character_033,TimesRoman24_Character_034,TimesRoman24_Character_035, TimesRoman24_Character_036,TimesRoman24_Character_037,TimesRoman24_Character_038,TimesRoman24_Character_039,TimesRoman24_Character_040,TimesRoman24_Character_041,TimesRoman24_Character_042,TimesRoman24_Character_043,TimesRoman24_Character_044,TimesRoman24_Character_045,TimesRoman24_Character_046,TimesRoman24_Character_047,TimesRoman24_Character_048,TimesRoman24_Character_049,TimesRoman24_Character_050,TimesRoman24_Character_051,TimesRoman24_Character_052,TimesRoman24_Character_053,TimesRoman24_Character_054,TimesRoman24_Character_055,TimesRoman24_Character_056,TimesRoman24_Character_057,TimesRoman24_Character_058,TimesRoman24_Character_059,TimesRoman24_Character_060,TimesRoman24_Character_061,TimesRoman24_Character_062,TimesRoman24_Character_063,TimesRoman24_Character_064,TimesRoman24_Character_065,TimesRoman24_Character_066,TimesRoman24_Character_067,TimesRoman24_Character_068,TimesRoman24_Character_069,TimesRoman24_Character_070,TimesRoman24_Character_071,TimesRoman24_Character_072, TimesRoman24_Character_073,TimesRoman24_Character_074,TimesRoman24_Character_075,TimesRoman24_Character_076,TimesRoman24_Character_077,TimesRoman24_Character_078,TimesRoman24_Character_079,TimesRoman24_Character_080,TimesRoman24_Character_081,TimesRoman24_Character_082,TimesRoman24_Character_083,TimesRoman24_Character_084,TimesRoman24_Character_085,TimesRoman24_Character_086,TimesRoman24_Character_087,TimesRoman24_Character_088,TimesRoman24_Character_089,TimesRoman24_Character_090,TimesRoman24_Character_091,TimesRoman24_Character_092,TimesRoman24_Character_093,TimesRoman24_Character_094,TimesRoman24_Character_095,TimesRoman24_Character_096,TimesRoman24_Character_097,TimesRoman24_Character_098,TimesRoman24_Character_099,TimesRoman24_Character_100,TimesRoman24_Character_101,TimesRoman24_Character_102,TimesRoman24_Character_103,TimesRoman24_Character_104,TimesRoman24_Character_105,TimesRoman24_Character_106,TimesRoman24_Character_107,TimesRoman24_Character_108,TimesRoman24_Character_109, TimesRoman24_Character_110,TimesRoman24_Character_111,TimesRoman24_Character_112,TimesRoman24_Character_113,TimesRoman24_Character_114,TimesRoman24_Character_115,TimesRoman24_Character_116,TimesRoman24_Character_117,TimesRoman24_Character_118,TimesRoman24_Character_119,TimesRoman24_Character_120,TimesRoman24_Character_121,TimesRoman24_Character_122,TimesRoman24_Character_123,TimesRoman24_Character_124,TimesRoman24_Character_125,TimesRoman24_Character_126,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042, TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042, TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042, TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,NULL}; /* The font structure: */ static const SFG_Font fgFontTimesRoman24 = { "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1", 93, 28, TimesRoman24_Character_Map, -1.0f, 6.0f }; /* * End of code from FreeGLUT. */ #define ARGS(X) (X.Characters, 1, X.Height, X.xorig, X.yorig) static fntBitmapFont fntFixed8x13 ARGS( fgFontFixed8x13 ); static fntBitmapFont fntFixed9x15 ARGS( fgFontFixed9x15 ); static fntBitmapFont fntHelvetica10 ARGS( fgFontHelvetica10 ); static fntBitmapFont fntHelvetica12 ARGS( fgFontHelvetica12 ); static fntBitmapFont fntHelvetica18 ARGS( fgFontHelvetica18 ); static fntBitmapFont fntTimesRoman10 ARGS( fgFontTimesRoman10 ); static fntBitmapFont fntTimesRoman24 ARGS( fgFontTimesRoman24 ); fntBitmapFont *fntGetBitmapFont(int id) { fntBitmapFont *fnt = NULL; switch (id) { case FNT_BITMAP_8_BY_13: fnt = &fntFixed8x13; break; case FNT_BITMAP_9_BY_15: fnt = &fntFixed9x15; break; case FNT_BITMAP_HELVETICA_10: fnt = &fntHelvetica10; break; case FNT_BITMAP_HELVETICA_12: fnt = &fntHelvetica12; break; case FNT_BITMAP_HELVETICA_18: fnt = &fntHelvetica18; break; case FNT_BITMAP_TIMES_ROMAN_10: fnt = &fntTimesRoman10; break; case FNT_BITMAP_TIMES_ROMAN_24: fnt = &fntTimesRoman24; break; } return fnt; } plib-1.8.5/src/fnt/fnt.dsp0000644000175000001440000000633710765364434012272 00000000000000# Microsoft Developer Studio Project File - Name="fnt" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=fnt - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "fnt.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "fnt.mak" CFG="fnt - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "fnt - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "fnt - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "fnt - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\sg" /I "..\util" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy fnt.h ..\..\fnt.h # End Special Build Tool !ELSEIF "$(CFG)" == "fnt - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\sg" /I "..\util" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\fnt_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy fnt.h ..\..\fnt.h # End Special Build Tool !ENDIF # Begin Target # Name "fnt - Win32 Release" # Name "fnt - Win32 Debug" # Begin Source File SOURCE=.\fnt.cxx # End Source File # Begin Source File SOURCE=.\fnt.h # End Source File # Begin Source File SOURCE=.\fntLocal.h # End Source File # Begin Source File SOURCE=.\fntTXF.cxx # End Source File # Begin Source File SOURCE=.\fntBitmap.cxx # End Source File # End Target # End Project plib-1.8.5/src/fnt/Makefile.am0000644000175000001440000000034210765364434013015 00000000000000if BUILD_FNT lib_LIBRARIES = libplibfnt.a include_HEADERS = fnt.h libplibfnt_a_SOURCES = fnt.cxx fntTXF.cxx fntLocal.h fntBitmap.cxx INCLUDES = -I$(top_srcdir)/src/sg -I$(top_srcdir)/src/util endif EXTRA_DIST = fnt.dsp plib-1.8.5/src/fnt/Makefile.in0000644000175000001440000003660110765365022013027 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/fnt DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibfnt_a_AR = $(AR) $(ARFLAGS) libplibfnt_a_LIBADD = am__libplibfnt_a_SOURCES_DIST = fnt.cxx fntTXF.cxx fntLocal.h \ fntBitmap.cxx @BUILD_FNT_TRUE@am_libplibfnt_a_OBJECTS = fnt.$(OBJEXT) \ @BUILD_FNT_TRUE@ fntTXF.$(OBJEXT) fntBitmap.$(OBJEXT) libplibfnt_a_OBJECTS = $(am_libplibfnt_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libplibfnt_a_SOURCES) DIST_SOURCES = $(am__libplibfnt_a_SOURCES_DIST) am__include_HEADERS_DIST = fnt.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_FNT_TRUE@lib_LIBRARIES = libplibfnt.a @BUILD_FNT_TRUE@include_HEADERS = fnt.h @BUILD_FNT_TRUE@libplibfnt_a_SOURCES = fnt.cxx fntTXF.cxx fntLocal.h fntBitmap.cxx @BUILD_FNT_TRUE@INCLUDES = -I$(top_srcdir)/src/sg -I$(top_srcdir)/src/util EXTRA_DIST = fnt.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/fnt/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/fnt/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibfnt.a: $(libplibfnt_a_OBJECTS) $(libplibfnt_a_DEPENDENCIES) -rm -f libplibfnt.a $(libplibfnt_a_AR) libplibfnt.a $(libplibfnt_a_OBJECTS) $(libplibfnt_a_LIBADD) $(RANLIB) libplibfnt.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fntBitmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fntTXF.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/fnt/fntLocal.h0000644000175000001440000000505410765364434012701 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: fntLocal.h 1727 2002-11-09 21:27:21Z ude $ */ #include "fnt.h" extern int _fntIsSwapped ; extern FILE *_fntCurrImageFd ; inline void _fnt_swab_short ( unsigned short *x ) { if ( _fntIsSwapped ) *x = (( *x >> 8 ) & 0x00FF ) | (( *x << 8 ) & 0xFF00 ) ; } inline void _fnt_swab_int ( unsigned int *x ) { if ( _fntIsSwapped ) *x = (( *x >> 24 ) & 0x000000FF ) | (( *x >> 8 ) & 0x0000FF00 ) | (( *x << 8 ) & 0x00FF0000 ) | (( *x << 24 ) & 0xFF000000 ) ; } inline void _fnt_swab_int_array ( int *x, int leng ) { if ( ! _fntIsSwapped ) return ; for ( int i = 0 ; i < leng ; i++ ) { *x = (( *x >> 24 ) & 0x000000FF ) | (( *x >> 8 ) & 0x0000FF00 ) | (( *x << 8 ) & 0x00FF0000 ) | (( *x << 24 ) & 0xFF000000 ) ; x++ ; } } inline unsigned char _fnt_readByte () { unsigned char x ; fread ( & x, sizeof(unsigned char), 1, _fntCurrImageFd ) ; return x ; } inline unsigned short _fnt_readShort () { unsigned short x ; fread ( & x, sizeof(unsigned short), 1, _fntCurrImageFd ) ; _fnt_swab_short ( & x ) ; return x ; } inline unsigned int _fnt_readInt () { unsigned int x ; fread ( & x, sizeof(unsigned int), 1, _fntCurrImageFd ) ; _fnt_swab_int ( & x ) ; return x ; } #define FNT_BYTE_FORMAT 0 #define FNT_BITMAP_FORMAT 1 struct TXF_Glyph { unsigned short ch ; unsigned char w ; unsigned char h ; signed char x_off ; signed char y_off ; signed char step ; signed char unknown ; short x ; short y ; sgVec2 tx0 ; sgVec2 vx0 ; sgVec2 tx1 ; sgVec2 vx1 ; sgVec2 tx2 ; sgVec2 vx2 ; sgVec2 tx3 ; sgVec2 vx3 ; } ; plib-1.8.5/src/js/0000777000175000001440000000000010765365517010676 500000000000000plib-1.8.5/src/js/js.h0000644000175000001440000000612010765364435011374 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: js.h 2067 2006-01-30 07:36:01Z bram $ */ #ifndef __INCLUDED_JS_H__ #define __INCLUDED_JS_H__ 1 #define JS_NEW #include "ul.h" #include #include #include // -dw- for memcpy #define _JS_MAX_AXES 16 #define _JS_MAX_BUTTONS 32 #define _JS_MAX_HATS 4 #define JS_TRUE 1 #define JS_FALSE 0 class jsJoystick { int id ; protected: struct os_specific_s *os ; friend struct os_specific_s ; int error ; char name [ 128 ] ; int num_axes ; int num_buttons ; float dead_band [ _JS_MAX_AXES ] ; float saturate [ _JS_MAX_AXES ] ; float center [ _JS_MAX_AXES ] ; float max [ _JS_MAX_AXES ] ; float min [ _JS_MAX_AXES ] ; void open () ; void close () ; float fudge_axis ( float value, int axis ) const ; public: jsJoystick ( int ident = 0 ) ; ~jsJoystick () { close () ; } const char* getName () const { return name ; } int getNumAxes () const { return num_axes ; } int getNumButtons () const { return num_buttons; } int notWorking () const { return error ; } void setError () { error = JS_TRUE ; } float getDeadBand ( int axis ) const { return dead_band [ axis ] ; } void setDeadBand ( int axis, float db ) { dead_band [ axis ] = db ; } float getSaturation ( int axis ) const { return saturate [ axis ] ; } void setSaturation ( int axis, float st ) { saturate [ axis ] = st ; } void setMinRange ( float *axes ) { memcpy ( min , axes, num_axes * sizeof(float) ) ; } void setMaxRange ( float *axes ) { memcpy ( max , axes, num_axes * sizeof(float) ) ; } void setCenter ( float *axes ) { memcpy ( center, axes, num_axes * sizeof(float) ) ; } void getMinRange ( float *axes ) const { memcpy ( axes, min , num_axes * sizeof(float) ) ; } void getMaxRange ( float *axes ) const { memcpy ( axes, max , num_axes * sizeof(float) ) ; } void getCenter ( float *axes ) const { memcpy ( axes, center, num_axes * sizeof(float) ) ; } void read ( int *buttons, float *axes ) ; void rawRead ( int *buttons, float *axes ) ; // bool SetForceFeedBack ( int axe, float force ); } ; extern void jsInit () ; #endif plib-1.8.5/src/js/jsBSD.cxx0000644000175000001440000003050710765364435012306 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: jsBSD.cxx 2063 2006-01-05 21:21:55Z fayjf $ */ /* * Inspired by the X-Mame USB HID joystick driver for NetBSD and * FreeBSD by Krister Walfridsson . * Incorporates the original analog joystick driver for BSD by * Stephen Montgomery-Smith , with * NetBSD mods courtesy of Rene Hexel. * * Bert Driehuis * * Notes: * Hats are mapped to two axes for now. A cleaner implementation requires * an API extension, and to be useful for my devious purposes, FlightGear * would need to understand that. */ #include "js.h" #if defined (UL_BSD) #if defined(__NetBSD__) || defined(__FreeBSD__) #define HAVE_USB_JS 1 #endif #include #include #include #if defined(__FreeBSD__) # include #else # include // For analog joysticks #endif #ifdef HAVE_USB_JS #if defined(__NetBSD__) #ifdef HAVE_USBHID_H #include #else #include #endif #elif defined(__FreeBSD__) extern "C" { # if __FreeBSD_version < 500000 # include # else # define HAVE_USBHID_H 1 # include # endif } #endif #include #include /* Compatibility with older usb.h revisions */ #if !defined(USB_MAX_DEVNAMES) && defined(MAXDEVNAMES) #define USB_MAX_DEVNAMES MAXDEVNAMES #endif #endif static int hatmap_x[9] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 }; static int hatmap_y[9] = { 0, 1, 1, 0, -1, -1, -1, 0, 1 }; struct os_specific_s { char fname [128 ]; int fd; int is_analog; // The following structure members are specific to analog joysticks struct joystick ajs; #ifdef HAVE_USB_JS // The following structure members are specific to USB joysticks struct hid_item *hids; int hid_dlen; int hid_offset; char *hid_data_buf; int axes_usage [ _JS_MAX_AXES ] ; #endif // We keep button and axes state ourselves, as they might not be updated // on every read of a USB device int cache_buttons ; float cache_axes [ _JS_MAX_AXES ] ; }; // Idents lower than USB_IDENT_OFFSET are for analog joysticks. #define USB_IDENT_OFFSET 2 #define USBDEV "/dev/usb" #define UHIDDEV "/dev/uhid" #define AJSDEV "/dev/joy" #ifdef HAVE_USB_JS /* * findusbdev (and its helper, walkusbdev) try to locate the full name * of a USB device. If /dev/usbN isn't readable, we punt and return the * uhidN device name. We warn the user of this situation once. */ static char * walkusbdev(int f, char *dev, char *out, int outlen) { struct usb_device_info di; int i, a; char *cp; for (a = 1; a < USB_MAX_DEVICES; a++) { di.udi_addr = a; if (ioctl(f, USB_DEVICEINFO, &di) != 0) return NULL; for (i = 0; i < USB_MAX_DEVNAMES; i++) if (di.udi_devnames[i][0] && strcmp(di.udi_devnames[i], dev) == 0) { cp = new char[strlen(di.udi_vendor) + strlen(di.udi_product) + 2]; strcpy(cp, di.udi_vendor); strcat(cp, " "); strcat(cp, di.udi_product); strncpy(out, cp, outlen - 1); out[outlen - 1] = 0; delete cp; return out; } } return NULL; } static int findusbdev(char *name, char *out, int outlen) { int i, f; char buf[50]; char *cp; static int protection_warned = 0; for (i = 0; i < 16; i++) { sprintf(buf, "%s%d", USBDEV, i); f = open(buf, O_RDONLY); if (f >= 0) { cp = walkusbdev(f, name, out, outlen); close(f); if (cp) return 1; } else if (errno == EACCES) { if (!protection_warned) { fprintf(stderr, "Can't open %s for read!\n", buf); protection_warned = 1; } } } return 0; } static int joy_initialize_hid(struct os_specific_s *os, int *num_axes, int *num_buttons) { int size, is_joystick; #ifdef HAVE_USBHID_H int report_id = 0; #endif struct hid_data *d; struct hid_item h; report_desc_t rd; if ((rd = hid_get_report_desc(os->fd)) == 0) { fprintf(stderr, "error: %s: %s", os->fname, strerror(errno)); return FALSE; } os->hids = NULL; #ifdef HAVE_USBHID_H if (ioctl(os->fd, USB_GET_REPORT_ID, &report_id) < 0) { fprintf(stderr, "error: %s: %s", os->fname, strerror(errno)); return FALSE; } size = hid_report_size(rd, hid_input, report_id); #else size = hid_report_size(rd, 0, hid_input); #endif os->hid_data_buf = new char[size]; os->hid_dlen = size; is_joystick = 0; #ifdef HAVE_USBHID_H d = hid_start_parse(rd, 1 << hid_input, report_id); #else d = hid_start_parse(rd, 1 << hid_input); #endif while (hid_get_item(d, &h)) { int usage, page, interesting_hid; page = HID_PAGE(h.usage); usage = HID_USAGE(h.usage); /* This test is somewhat too simplistic, but this is how MicroSoft * does, so I guess it works for all joysticks/game pads. */ is_joystick = is_joystick || (h.kind == hid_collection && page == HUP_GENERIC_DESKTOP && (usage == HUG_JOYSTICK || usage == HUG_GAME_PAD)); if (h.kind != hid_input) continue; if (!is_joystick) continue; interesting_hid = TRUE; if (page == HUP_GENERIC_DESKTOP) { switch(usage) { case HUG_X: case HUG_RX: case HUG_Y: case HUG_RY: case HUG_Z: case HUG_RZ: case HUG_SLIDER: if (*num_axes < _JS_MAX_AXES) { os->axes_usage[*num_axes] = usage; (*num_axes)++; } break; case HUG_HAT_SWITCH: if (*num_axes + 1 < _JS_MAX_AXES) // Allocate two axes for a hat { os->axes_usage[*num_axes] = usage; (*num_axes)++; os->axes_usage[*num_axes] = usage; (*num_axes)++; } break; default: interesting_hid = FALSE; } } else if (page == HUP_BUTTON) { interesting_hid = (usage > 0) && (usage <= _JS_MAX_BUTTONS); if (interesting_hid && usage - 1 > *num_buttons) { *num_buttons = usage - 1; } } if (interesting_hid) { h.next = os->hids; os->hids = new struct hid_item; *os->hids = h; } } hid_end_parse(d); return (os->hids != NULL); } #endif void jsJoystick::open () { char *cp; name [0] = '\0' ; for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) os->cache_axes [ i ] = 0.0f ; os->cache_buttons = 0 ; os->fd = ::open ( os->fname, O_RDONLY | O_NONBLOCK) ; if (os->fd < 0 && errno == EACCES) fprintf(stderr, "%s exists but is not readable by you\n", os->fname); error = ( os->fd < 0 ) ; if ( error ) return ; num_axes = 0; num_buttons = 0; if ( os->is_analog ) { num_axes = 2 ; num_buttons = 32 ; FILE *joyfile ; char joyfname [ 1024 ] ; int noargs, in_no_axes ; float axes [ _JS_MAX_AXES ] ; int buttons [ _JS_MAX_AXES ] ; rawRead ( buttons, axes ) ; error = axes[0] < -1000000000.0f && axes[1] < -1000000000.0f ; if ( error ) return ; sprintf( joyfname, "%s/.joy%drc", ::getenv ( "HOME" ), id ) ; joyfile = fopen ( joyfname, "r" ) ; error = ( joyfile == NULL ) ; if ( error ) { ulSetError ( UL_WARNING, "unable to open calibration file %s (%s), joystick %i disabled (you can generate the calibration file with the plib-jscal utility)", joyfname, strerror ( errno ), id + 1 ); return ; } noargs = fscanf ( joyfile, "%d%f%f%f%f%f%f", &in_no_axes, &min [ 0 ], ¢er [ 0 ], &max [ 0 ], &min [ 1 ], ¢er [ 1 ], &max [ 1 ] ) ; error = noargs != 7 || in_no_axes != _JS_MAX_AXES ; fclose ( joyfile ) ; if ( error ) return ; for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) { dead_band [ i ] = 0.0f ; saturate [ i ] = 1.0f ; } return; // End of analog code } #ifdef HAVE_USB_JS if ( !joy_initialize_hid(os, &num_axes, &num_buttons ) ) { ::close(os->fd); error = 1; return; } cp = strrchr(os->fname, '/'); if (cp) { if (findusbdev(&cp[1], name, sizeof(name)) == 0) strcpy(name, &cp[1]); } if ( num_axes > _JS_MAX_AXES ) num_axes = _JS_MAX_AXES ; for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) { // We really should get this from the HID, but that data seems // to be quite unreliable for analog-to-USB converters. Punt for // now. if ( os->axes_usage [ i ] == HUG_HAT_SWITCH ) { max [ i ] = 1.0f ; center [ i ] = 0.0f ; min [ i ] = -1.0f ; } else { max [ i ] = 255.0f ; center [ i ] = 127.0f ; min [ i ] = 0.0f ; } dead_band [ i ] = 0.0f ; saturate [ i ] = 1.0f ; } #endif } void jsJoystick::close () { if (os) { if ( ! error ) ::close ( os->fd ) ; #ifdef HAVE_USB_JS if (os->hids) delete os->hids; if (os->hid_data_buf) delete os->hid_data_buf; #endif delete os; } } jsJoystick::jsJoystick ( int ident ) { id = ident ; error = 0; os = new struct os_specific_s; memset(os, 0, sizeof(struct os_specific_s)); if (ident < USB_IDENT_OFFSET) os->is_analog = 1; if (os->is_analog) sprintf(os->fname, "%s%d", AJSDEV, ident); else sprintf(os->fname, "%s%d", UHIDDEV, ident - USB_IDENT_OFFSET); open () ; } void jsJoystick::rawRead ( int *buttons, float *axes ) { int len, usage, page, d; struct hid_item *h; if ( error ) { if ( buttons ) *buttons = 0 ; if ( axes ) for ( int i = 0 ; i < num_axes ; i++ ) axes[i] = 1500.0f ; return ; } if ( os->is_analog ) { int status = ::read ( os->fd, &os->ajs, sizeof(os->ajs) ); if ( status != sizeof(os->ajs) ) { perror ( os->fname ) ; setError () ; return ; } if ( buttons != NULL ) *buttons = ( os->ajs.b1 ? 1 : 0 ) | ( os->ajs.b2 ? 2 : 0 ) ; if ( axes != NULL ) { if ( os->ajs.x >= -1000000000 ) os->cache_axes[0] = os->ajs.x; if ( os->ajs.y >= -1000000000 ) os->cache_axes[1] = os->ajs.y; axes[0] = os->cache_axes[0]; axes[1] = os->cache_axes[1]; } return; } #ifdef HAVE_USB_JS while ((len = ::read(os->fd, os->hid_data_buf, os->hid_dlen)) == os->hid_dlen) { for (h = os->hids; h; h = h->next) { d = hid_get_data(os->hid_data_buf, h); page = HID_PAGE(h->usage); usage = HID_USAGE(h->usage); if (page == HUP_GENERIC_DESKTOP) { for (int i = 0; i < num_axes; i++) if (os->axes_usage[i] == usage) { if (usage == HUG_HAT_SWITCH) { if (d < 0 || d > 8) d = 0; // safety os->cache_axes[i] = (float)hatmap_x[d]; os->cache_axes[i + 1] = (float)hatmap_y[d]; } else { os->cache_axes[i] = (float)d; } break; } } else if (page == HUP_BUTTON) { if (usage > 0 && usage < _JS_MAX_BUTTONS + 1) { if (d) os->cache_buttons |= (1 << usage - 1) ; else os->cache_buttons &= ~(1 << usage - 1) ; } } } } if (len < 0 && errno != EAGAIN) { perror( os->fname ) ; setError () ; error = 1; } if ( buttons != NULL ) *buttons = os->cache_buttons ; if ( axes != NULL ) memcpy ( axes, os->cache_axes, sizeof(float) * num_axes ) ; #endif } void jsInit () {} #endif plib-1.8.5/src/js/jsNone.cxx0000644000175000001440000000256710765364435012602 00000000000000/* Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: jsNone.cxx 1960 2004-09-21 11:45:55Z smokydiamond $ */ #include "js.h" #if defined(UL_IRIX) || defined(UL_SOLARIS) || defined (UL_HPUX) struct os_specific_s ; void jsJoystick::open () { error = TRUE ; num_axes = num_buttons = 0 ; } void jsJoystick::close () { error = TRUE ; } jsJoystick::jsJoystick ( int ident ) { error = TRUE ; num_axes = num_buttons = 0 ; os = NULL; } void jsJoystick::rawRead ( int *buttons, float *axes ) { if ( buttons != NULL ) *buttons = 0 ; } void jsInit () {} #endif plib-1.8.5/src/js/README0000644000175000001440000000106210765364435011467 00000000000000 Joystick interfaces are horribly non-portable. Using conditional compilation on a line-by-line basis became FAR too complex after more than a couple of OS's were supported so now there is on standard interface header: js.h ...one set of common routines: js.cxx ...and a bunch of OS-specific code: jsLinux.cxx jsLinuxOld.cxx jsWindows.cxx jsBSD.cxx jsMacOS.cxx ...for OS's (eg IRIX and SOLARIS) without standard joystick functionality, we add: jsNone.cxx ...which safely returns error status with no buttons or axes provided. plib-1.8.5/src/js/jsLinux.cxx0000644000175000001440000001134410765364435012773 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: jsLinux.cxx 2017 2005-02-21 07:37:25Z bram $ */ #include "js.h" #if defined (UL_LINUX) #include #if defined(JS_VERSION) && JS_VERSION >= 0x010000 #include #include #include struct os_specific_s { js_event js ; int tmp_buttons ; float tmp_axes [ _JS_MAX_AXES ] ; char fname [ 128 ] ; int fd ; }; void jsInit () {} void jsJoystick::open () { name [0] = '\0' ; for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) os->tmp_axes [ i ] = 0.0f ; os->tmp_buttons = 0 ; os->fd = ::open ( os->fname, O_RDONLY ) ; error = ( os->fd < 0 ) ; if ( error ) return ; /* Set the correct number of axes for the linux driver */ /* Melchior Franz's fixes for big-endian Linuxes since writing * to the upper byte of an uninitialized word doesn't work. * 9 April 2003 */ unsigned char u ; ioctl ( os->fd, JSIOCGAXES , &u ) ; num_axes = u ; ioctl ( os->fd, JSIOCGBUTTONS, &u ) ; num_buttons = u ; ioctl ( os->fd, JSIOCGNAME ( sizeof(name) ), name ) ; fcntl ( os->fd, F_SETFL , O_NONBLOCK ) ; int all_axes = num_axes; if ( num_axes > _JS_MAX_AXES ) num_axes = _JS_MAX_AXES ; // Remove any deadband value already done in the kernel. // Since we have our own deadband management this is save to do so. struct js_corr* corr = new js_corr[ all_axes ] ; ioctl ( os->fd, JSIOCGCORR, corr ); for ( int i = 0; i < num_axes ; ++i ) { if ( corr[ i ] . type == JS_CORR_BROKEN ) { int nodeadband = ( corr[ i ] . coef[ 0 ] + corr[ i ] . coef[ 1 ] ) / 2 ; corr[ i ] . coef[ 0 ] = nodeadband ; corr[ i ] . coef[ 1 ] = nodeadband ; } } ioctl ( os->fd, JSIOCSCORR, corr ); delete [] corr; for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) { max [ i ] = 32767.0f ; center [ i ] = 0.0f ; min [ i ] = -32767.0f ; dead_band [ i ] = 0.0f ; saturate [ i ] = 1.0f ; } } void jsJoystick::close () { if ( ! error ) ::close ( os->fd ) ; delete os; } jsJoystick::jsJoystick ( int ident ) { id = ident ; os = new struct os_specific_s; sprintf ( os->fname, "/dev/input/js%d", ident ) ; if ( access ( os->fname, F_OK ) != 0 ) sprintf ( os->fname, "/dev/js%d", ident ) ; open () ; } void jsJoystick::rawRead ( int *buttons, float *axes ) { if ( error ) { if ( buttons ) *buttons = 0 ; if ( axes ) for ( int i = 0 ; i < num_axes ; i++ ) axes[i] = 1500.0f ; return ; } while (1) { int status = ::read ( os->fd, &(os->js), sizeof(js_event) ) ; if ( status != sizeof(js_event) ) { /* use the old values */ if ( buttons != NULL ) *buttons = os->tmp_buttons ; if ( axes != NULL ) memcpy ( axes, os->tmp_axes, sizeof(float) * num_axes ) ; if ( errno == EAGAIN ) return ; perror( os->fname ) ; setError () ; return ; } switch ( os->js.type & ~JS_EVENT_INIT ) { case JS_EVENT_BUTTON : if ( os->js.value == 0 ) /* clear the flag */ os->tmp_buttons &= ~(1 << os->js.number) ; else os->tmp_buttons |= (1 << os->js.number) ; break ; case JS_EVENT_AXIS: if ( os->js.number < num_axes ) { os->tmp_axes [ os->js.number ] = (float) os->js.value ; if ( axes ) memcpy ( axes, os->tmp_axes, sizeof(float) * num_axes ) ; } break ; default: ulSetError ( UL_WARNING, "PLIB_JS: Unrecognised /dev/js return!?!" ) ; /* use the old values */ if ( buttons != NULL ) *buttons = os->tmp_buttons ; if ( axes != NULL ) memcpy ( axes, os->tmp_axes, sizeof(float) * num_axes ) ; return ; } if ( buttons != NULL ) *buttons = os->tmp_buttons ; } } #endif #endif plib-1.8.5/src/js/Makefile.am0000644000175000001440000000047110765364435012646 00000000000000if BUILD_JS lib_LIBRARIES = libplibjs.a include_HEADERS = js.h libplibjs_a_SOURCES = js.cxx jsLinux.cxx jsLinuxOld.cxx jsMacOS.cxx \ jsMacOSX.cxx jsWindows.cxx jsBSD.cxx \ jsNone.cxx INCLUDES = -I$(top_srcdir)/src/util endif EXTRA_DIST = js.dsp plib-1.8.5/src/js/js.cxx0000644000175000001440000000440110765364435011747 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "js.h" float jsJoystick::fudge_axis ( float value, int axis ) const { if ( value < center[axis] ) { float xx = ( value - center[ axis ] ) / ( center [ axis ] - min [ axis ] ) ; if ( xx < -saturate [ axis ] ) return -1.0f ; if ( xx > -dead_band [ axis ] ) return 0.0f ; xx = ( xx + dead_band [ axis ] ) / ( saturate [ axis ] - dead_band [ axis ] ) ; return ( xx < -1.0f ) ? -1.0f : xx ; } else { float xx = ( value - center [ axis ] ) / ( max [ axis ] - center [ axis ] ) ; if ( xx > saturate [ axis ] ) return 1.0f ; if ( xx < dead_band [ axis ] ) return 0.0f ; xx = ( xx - dead_band [ axis ] ) / ( saturate [ axis ] - dead_band [ axis ] ) ; return ( xx > 1.0f ) ? 1.0f : xx ; } } void jsJoystick::read ( int *buttons, float *axes ) { if ( error ) { if ( buttons ) *buttons = 0 ; if ( axes ) for ( int i = 0 ; i < num_axes ; i++ ) axes[i] = 0.0f ; return ; } float raw_axes [ _JS_MAX_AXES ] ; rawRead ( buttons, raw_axes ) ; if ( axes ) for ( int i = 0 ; i < num_axes ; i++ ) axes[i] = fudge_axis ( raw_axes[i], i ) ; } plib-1.8.5/src/js/Makefile.in0000644000175000001440000003747110765365022012662 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/js DIST_COMMON = README $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibjs_a_AR = $(AR) $(ARFLAGS) libplibjs_a_LIBADD = am__libplibjs_a_SOURCES_DIST = js.cxx jsLinux.cxx jsLinuxOld.cxx \ jsMacOS.cxx jsMacOSX.cxx jsWindows.cxx jsBSD.cxx jsNone.cxx @BUILD_JS_TRUE@am_libplibjs_a_OBJECTS = js.$(OBJEXT) jsLinux.$(OBJEXT) \ @BUILD_JS_TRUE@ jsLinuxOld.$(OBJEXT) jsMacOS.$(OBJEXT) \ @BUILD_JS_TRUE@ jsMacOSX.$(OBJEXT) jsWindows.$(OBJEXT) \ @BUILD_JS_TRUE@ jsBSD.$(OBJEXT) jsNone.$(OBJEXT) libplibjs_a_OBJECTS = $(am_libplibjs_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libplibjs_a_SOURCES) DIST_SOURCES = $(am__libplibjs_a_SOURCES_DIST) am__include_HEADERS_DIST = js.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_JS_TRUE@lib_LIBRARIES = libplibjs.a @BUILD_JS_TRUE@include_HEADERS = js.h @BUILD_JS_TRUE@libplibjs_a_SOURCES = js.cxx jsLinux.cxx jsLinuxOld.cxx jsMacOS.cxx \ @BUILD_JS_TRUE@ jsMacOSX.cxx jsWindows.cxx jsBSD.cxx \ @BUILD_JS_TRUE@ jsNone.cxx @BUILD_JS_TRUE@INCLUDES = -I$(top_srcdir)/src/util EXTRA_DIST = js.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/js/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/js/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibjs.a: $(libplibjs_a_OBJECTS) $(libplibjs_a_DEPENDENCIES) -rm -f libplibjs.a $(libplibjs_a_AR) libplibjs.a $(libplibjs_a_OBJECTS) $(libplibjs_a_LIBADD) $(RANLIB) libplibjs.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/js.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jsBSD.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jsLinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jsLinuxOld.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jsMacOS.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jsMacOSX.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jsNone.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jsWindows.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/js/jsMacOSX.cxx0000644000175000001440000003153310765364435012770 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: jsMacOSX.cxx 2118 2007-09-14 22:23:32Z fayjf $ */ #include "js.h" #if defined (UL_MAC_OSX) #include #include #include #include #include #include #include #ifdef MACOS_10_0_4 # include #else /* The header was moved here in MacOS X 10.1 */ # include #endif static const int kNumDevices = 32; static int numDevices = -1; static io_object_t ioDevices[kNumDevices]; static int NS_hat[8] = {1, 1, 0, -1, -1, -1, 0, 1}; static int WE_hat[8] = {0, 1, 1, 1, 0, -1, -1, -1}; struct os_specific_s { IOHIDDeviceInterface ** hidDev; IOHIDElementCookie buttonCookies[41]; IOHIDElementCookie axisCookies[_JS_MAX_AXES]; IOHIDElementCookie hatCookies[_JS_MAX_HATS]; int num_hats; long hat_min[_JS_MAX_HATS]; long hat_max[_JS_MAX_HATS]; void enumerateElements(jsJoystick* joy, CFTypeRef element); static void elementEnumerator( const void *element, void* vjs); /// callback for CFArrayApply void parseElement(jsJoystick* joy, CFDictionaryRef element); void addAxisElement(jsJoystick* joy, CFDictionaryRef axis); void addButtonElement(jsJoystick* joy, CFDictionaryRef button); void addHatElement(jsJoystick* joy, CFDictionaryRef hat); }; static void findDevices(mach_port_t); static CFDictionaryRef getCFProperties(io_object_t); void jsInit() { if (numDevices < 0) { numDevices = 0; mach_port_t masterPort; IOReturn rv = IOMasterPort(bootstrap_port, &masterPort); if (rv != kIOReturnSuccess) { ulSetError(UL_WARNING, "error getting master Mach port"); return; } findDevices(masterPort); } } /** open the IOKit connection, enumerate all the HID devices, add their interface references to the static array. We then use the array index as the device number when we come to open() the joystick. */ static void findDevices(mach_port_t masterPort) { CFMutableDictionaryRef hidMatch = NULL; IOReturn rv = kIOReturnSuccess; io_iterator_t hidIterator; // build a dictionary matching HID devices hidMatch = IOServiceMatching(kIOHIDDeviceKey); rv = IOServiceGetMatchingServices(masterPort, hidMatch, &hidIterator); if (rv != kIOReturnSuccess || !hidIterator) { ulSetError(UL_WARNING, "no joystick (HID) devices found"); return; } // iterate io_object_t ioDev; while ((ioDev = IOIteratorNext(hidIterator))) { // filter out keyboard and mouse devices CFDictionaryRef properties = getCFProperties(ioDev); long usage, page; CFTypeRef refPage = CFDictionaryGetValue (properties, CFSTR(kIOHIDPrimaryUsagePageKey)); CFTypeRef refUsage = CFDictionaryGetValue (properties, CFSTR(kIOHIDPrimaryUsageKey)); CFNumberGetValue((CFNumberRef) refUsage, kCFNumberLongType, &usage); CFNumberGetValue((CFNumberRef) refPage, kCFNumberLongType, &page); // keep only joystick devices if ( (page == kHIDPage_GenericDesktop) && ((usage == kHIDUsage_GD_Joystick) || (usage == kHIDUsage_GD_GamePad) // || (usage == kHIDUsage_GD_MultiAxisController) // || (usage == kHIDUsage_GD_Hatswitch) ) ) { // add it to the array ioDevices[numDevices++] = ioDev; } } IOObjectRelease(hidIterator); } jsJoystick::jsJoystick(int ident) : id(ident), os(NULL), error(JS_FALSE), num_axes(0), num_buttons(0) { if (ident >= numDevices) { setError(); return; } os = new struct os_specific_s; os->num_hats = 0; // get the name now too CFDictionaryRef properties = getCFProperties(ioDevices[id]); CFTypeRef ref = CFDictionaryGetValue (properties, CFSTR(kIOHIDProductKey)); if (!ref) ref = CFDictionaryGetValue (properties, CFSTR("USB Product Name")); if (!ref || !CFStringGetCString ((CFStringRef) ref, name, 128, CFStringGetSystemEncoding ())) { ulSetError(UL_WARNING, "error getting device name"); name[0] = '\0'; } //printf("Joystick name: %s \n", name); open(); } void jsJoystick::open() { #if 0 // test already done in the constructor if (id >= numDevices) { ulSetError(UL_WARNING, "device index out of range in jsJoystick::open"); return; } #endif // create device interface IOReturn rv; SInt32 score; IOCFPlugInInterface **plugin; rv = IOCreatePlugInInterfaceForService(ioDevices[id], kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); if (rv != kIOReturnSuccess) { ulSetError(UL_WARNING, "error creting plugin for io device"); return; } HRESULT pluginResult = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID*)&(os->hidDev) ); if (pluginResult != S_OK) ulSetError(UL_WARNING, "QI-ing IO plugin to HID Device interface failed"); (*plugin)->Release(plugin); // don't leak a ref if (os->hidDev == NULL) return; // store the interface in this instance rv = (*(os->hidDev))->open(os->hidDev, 0); if (rv != kIOReturnSuccess) { ulSetError(UL_WARNING, "error opening device interface"); return; } CFDictionaryRef props = getCFProperties(ioDevices[id]); // recursively enumerate all the bits (buttons, axes, hats, ...) CFTypeRef topLevelElement = CFDictionaryGetValue (props, CFSTR(kIOHIDElementKey)); os->enumerateElements(this, topLevelElement); CFRelease(props); // for hats to be implemented as axes: must be the last axes: for (int h = 0; h<2*os->num_hats; h++) { int index = num_axes++; dead_band [ index ] = 0.0f ; saturate [ index ] = 1.0f ; center [ index ] = 0.0f; max [ index ] = 1.0f; min [ index ] = -1.0f; } } CFDictionaryRef getCFProperties(io_object_t ioDev) { IOReturn rv; CFMutableDictionaryRef cfProperties; #if 0 // comment copied from darwin/SDL_sysjoystick.c /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties */ io_registry_entry_t parent1, parent2; rv = IORegistryEntryGetParentEntry (ioDev, kIOServicePlane, &parent1); if (rv != kIOReturnSuccess) { ulSetError(UL_WARNING, "error getting device entry parent"); return NULL; } rv = IORegistryEntryGetParentEntry (parent1, kIOServicePlane, &parent2); if (rv != kIOReturnSuccess) { ulSetError(UL_WARNING, "error getting device entry parent 2"); return NULL; } #endif rv = IORegistryEntryCreateCFProperties( ioDev /*parent2*/, &cfProperties, kCFAllocatorDefault, kNilOptions); if (rv != kIOReturnSuccess || !cfProperties) { ulSetError(UL_WARNING, "error getting device properties"); return NULL; } return cfProperties; } void jsJoystick::close() { if (os->hidDev != NULL) (*(os->hidDev))->close(os->hidDev); if (os) delete os; } /** element enumerator function : pass NULL for top-level*/ void os_specific_s::enumerateElements(jsJoystick* joy, CFTypeRef element) { assert(CFGetTypeID(element) == CFArrayGetTypeID()); CFRange range = {0, CFArrayGetCount ((CFArrayRef)element)}; CFArrayApplyFunction((CFArrayRef) element, range, &elementEnumerator, joy); } void os_specific_s::elementEnumerator( const void *element, void* vjs) { if (CFGetTypeID((CFTypeRef) element) != CFDictionaryGetTypeID()) { ulSetError(UL_WARNING, "element enumerator passed non-dictionary value"); return; } static_cast(vjs)-> os->parseElement( static_cast(vjs), (CFDictionaryRef) element); } void os_specific_s::parseElement(jsJoystick* joy, CFDictionaryRef element) { CFTypeRef refPage = CFDictionaryGetValue ((CFDictionaryRef) element, CFSTR(kIOHIDElementUsagePageKey)); CFTypeRef refUsage = CFDictionaryGetValue ((CFDictionaryRef) element, CFSTR(kIOHIDElementUsageKey)); long type, page, usage; CFNumberGetValue((CFNumberRef) CFDictionaryGetValue ((CFDictionaryRef) element, CFSTR(kIOHIDElementTypeKey)), kCFNumberLongType, &type); switch (type) { case kIOHIDElementTypeInput_Misc: case kIOHIDElementTypeInput_Axis: case kIOHIDElementTypeInput_Button: //printf("got input element..."); CFNumberGetValue((CFNumberRef) refUsage, kCFNumberLongType, &usage); CFNumberGetValue((CFNumberRef) refPage, kCFNumberLongType, &page); if (page == kHIDPage_GenericDesktop) { switch (usage) /* look at usage to determine function */ { case kHIDUsage_GD_X: case kHIDUsage_GD_Y: case kHIDUsage_GD_Z: case kHIDUsage_GD_Rx: case kHIDUsage_GD_Ry: case kHIDUsage_GD_Rz: case kHIDUsage_GD_Slider: // for throttle / trim controls case kHIDUsage_GD_Dial: //printf(" axis\n"); /*joy->os->*/addAxisElement(joy, (CFDictionaryRef) element); break; case kHIDUsage_GD_Hatswitch: //printf(" hat\n"); /*joy->os->*/addHatElement(joy, (CFDictionaryRef) element); break; default: ulSetError(UL_WARNING, "input type element has weird usage (%lx)\n", usage); break; } } else if (page == kHIDPage_Button) { //printf(" button\n"); /*joy->os->*/addButtonElement(joy, (CFDictionaryRef) element); } else ulSetError(UL_WARNING, "input type element has weird usage (%lx)\n", usage); break; case kIOHIDElementTypeCollection: /*joy->os->*/enumerateElements(joy, CFDictionaryGetValue(element, CFSTR(kIOHIDElementKey)) ); break; default: break; } } void os_specific_s::addAxisElement(jsJoystick* joy, CFDictionaryRef axis) { long cookie, lmin, lmax; CFNumberGetValue ((CFNumberRef) CFDictionaryGetValue (axis, CFSTR(kIOHIDElementCookieKey)), kCFNumberLongType, &cookie); int index = joy->num_axes++; /*joy->os->*/axisCookies[index] = (IOHIDElementCookie) cookie; CFNumberGetValue ((CFNumberRef) CFDictionaryGetValue (axis, CFSTR(kIOHIDElementMinKey)), kCFNumberLongType, &lmin); CFNumberGetValue ((CFNumberRef) CFDictionaryGetValue (axis, CFSTR(kIOHIDElementMaxKey)), kCFNumberLongType, &lmax); joy->min[index] = lmin; joy->max[index] = lmax; joy->dead_band[index] = 0.0; joy->saturate[index] = 1.0; joy->center[index] = (lmax - lmin) * 0.5 + lmin; } void os_specific_s::addButtonElement(jsJoystick* joy, CFDictionaryRef button) { long cookie; CFNumberGetValue ((CFNumberRef) CFDictionaryGetValue (button, CFSTR(kIOHIDElementCookieKey)), kCFNumberLongType, &cookie); /*joy->os->*/buttonCookies[joy->num_buttons++] = (IOHIDElementCookie) cookie; // anything else for buttons? } void os_specific_s::addHatElement(jsJoystick* joy, CFDictionaryRef hat) { long cookie, lmin, lmax; CFNumberGetValue ((CFNumberRef) CFDictionaryGetValue (hat, CFSTR(kIOHIDElementCookieKey)), kCFNumberLongType, &cookie); int index = /*joy->*/num_hats++; /*joy->os->*/hatCookies[index] = (IOHIDElementCookie) cookie; CFNumberGetValue ((CFNumberRef) CFDictionaryGetValue (hat, CFSTR(kIOHIDElementMinKey)), kCFNumberLongType, &lmin); CFNumberGetValue ((CFNumberRef) CFDictionaryGetValue (hat, CFSTR(kIOHIDElementMaxKey)), kCFNumberLongType, &lmax); hat_min[index] = lmin; hat_max[index] = lmax; // do we map hats to axes or buttons? // axes; there is room for that: Buttons are limited to 32. // (a joystick with 2 hats will use 16 buttons!) } void jsJoystick::rawRead(int *buttons, float *axes) { *buttons = 0; IOHIDEventStruct hidEvent; for (int b=0; bhidDev))->getElementValue(os->hidDev, os->buttonCookies[b], &hidEvent); if (hidEvent.value) *buttons |= 1 << b; } // real axes: int real_num_axes = num_axes - 2*os->num_hats; for (int a=0; ahidDev))->getElementValue(os->hidDev, os->axisCookies[a], &hidEvent); axes[a] = hidEvent.value; } // hats: for (int h=0; h < os->num_hats; ++h) { (*(os->hidDev))->getElementValue(os->hidDev, os->hatCookies[h], &hidEvent); long result = ( hidEvent.value - os->hat_min[h] ) * 8; result /= ( os->hat_max[h] - os->hat_min[h] + 1 ); if ( (result>=0) && (result<8) ) { axes[h+real_num_axes+1] = NS_hat[result]; axes[h+real_num_axes] = WE_hat[result]; } else { axes[h+real_num_axes] = 0; axes[h+real_num_axes+1] = 0; } } } #endif plib-1.8.5/src/js/jsMacOS.cxx0000644000175000001440000001711710765364435012642 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: jsMacOS.cxx 1960 2004-09-21 11:45:55Z smokydiamond $ */ #include "js.h" #if defined (UL_MACINTOSH) #include //#define _JS_MAX_AXES_MAC 9 #define isp_num_axis 9 #define isp_num_needs 41 struct os_specific_s { ISpElementReference isp_elem [ isp_num_needs ] ; ISpNeed isp_needs [ isp_num_needs ] ; }; void jsJoystick::open () { name [0] = '\0' ; /* FIXME: get joystick name in Mac */ OSStatus err ; err = ISpStartup () ; if ( err == noErr ) { #define ISP_CHECK_ERR(x) if ( x != noErr ) { setError () ; return ; } setError () ; // initialize the needs structure ISpNeed temp_isp_needs[isp_num_needs] = { { "\pX-Axis", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pY-Axis", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pZ-Axis", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pR-Axis", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pAxis 4", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pAxis 5", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pAxis 6", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pAxis 7", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pAxis 8", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, { "\pButton 0", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 1", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 2", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 3", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 4", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 5", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 6", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 7", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 8", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 9", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 10", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 11", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 12", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 13", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 14", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 15", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 16", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 17", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 18", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 19", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 20", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 21", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 22", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 23", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 24", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 25", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 26", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 27", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 28", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 29", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 30", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, { "\pButton 31", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, } ; memcpy ( os->isp_needs, temp_isp_needs, sizeof(temp_isp_needs) ) ; // next two calls allow keyboard and mouse to emulate other input // devices (gamepads, joysticks, etc) /* err = ISpDevices_ActivateClass ( kISpDeviceClass_Keyboard ) ; ISP_CHECK_ERR(err) err = ISpDevices_ActivateClass ( kISpDeviceClass_Mouse ) ; ISP_CHECK_ERR(err) */ err = ISpElement_NewVirtualFromNeeds ( isp_num_needs, os->isp_needs, os->isp_elem, 0 ) ; ISP_CHECK_ERR(err) err = ISpInit ( isp_num_needs, os->isp_needs, os->isp_elem, 'PLIB', nil, 0, 128, 0 ) ; ISP_CHECK_ERR(err) num_buttons = isp_num_needs - isp_num_axis ; num_axes = isp_num_axis ; for ( int i = 0 ; i < num_axes ; i++ ) { dead_band [ i ] = 0 ; saturate [ i ] = 1 ; center [ i ] = kISpAxisMiddle ; max [ i ] = kISpAxisMaximum ; min [ i ] = kISpAxisMinimum ; } error = false ; } else { setError () ; num_buttons = num_axes = 0 ; } } void jsJoystick::close () { ISpSuspend () ; ISpStop () ; ISpShutdown () ; delete os; } jsJoystick::jsJoystick ( int ident ) { id = ident ; os = new struct os_specific_s; // sprintf ( fname, "/dev/js%d", ident ) ; /* FIXME */ open () ; } void jsJoystick::rawRead ( int *buttons, float *axes ) { if ( error ) { if ( buttons ) *buttons = 0 ; if ( axes ) for ( int i = 0 ; i < num_axes ; i++ ) axes[i] = 1500.0f ; return ; } int i ; int err ; UInt32 state ; if ( buttons != NULL ) { *buttons = 0; for ( i = 0 ; i < num_buttons ; i++ ) { err = ISpElement_GetSimpleState ( os->isp_elem [ i + isp_num_axis ], &state) ; ISP_CHECK_ERR(err) *buttons |= state << i ; } } if ( axes != NULL ) { for ( i = 0 ; i < num_axes ; i++ ) { err = ISpElement_GetSimpleState ( os->isp_elem [ i ], &state ) ; ISP_CHECK_ERR(err) axes [i] = (float) state ; } } } void jsInit() {} #endif plib-1.8.5/src/js/jsLinuxOld.cxx0000644000175000001440000000573110765364435013435 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: jsLinuxOld.cxx 2039 2005-07-16 17:27:51Z fayjf $ */ #include "js.h" #if defined (UL_LINUX) #include #if !defined(JS_VERSION) || JS_VERSION < 0x010000 #include #include struct os_specific_s { JS_DATA_TYPE js ; char fname [ 128 ] ; int fd ; }; void jsJoystick::open () { name [0] = '\0' ; num_axes = 2 ; /* Default for older Linux systems. */ num_buttons = 32 ; os->fd = ::open ( os->fname, O_RDONLY ) ; error = ( os->fd < 0 ) ; if ( error ) return ; /* The Linux driver seems to return 512 for all axes when no stick is present - but there is a chance that could happen by accident - so it's gotta happen on both axes for at least 100 attempts. */ int counter = 0 ; do { rawRead ( NULL, center ) ; counter++ ; } while ( ! error && counter < 100 && center[0] == 512.0f && center[1] == 512.0f ) ; if ( counter >= 100 ) setError() ; for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) { max [ i ] = center [ i ] * 2.0f ; min [ i ] = 0.0f ; dead_band [ i ] = 0.0f ; saturate [ i ] = 1.0f ; } } void jsJoystick::close () { if ( ! error ) ::close ( os->fd ) ; delete os; } jsJoystick::jsJoystick ( int ident ) { id = ident ; os = new struct os_specific_s; sprintf ( os->fname, "/dev/input/js%d", ident ) ; if ( access ( os->fname, F_OK ) != 0 ) sprintf ( os->fname, "/dev/js%d", ident ) ; open () ; } void jsJoystick::rawRead ( int *buttons, float *axes ) { if ( error ) { if ( buttons ) *buttons = 0 ; if ( axes ) for ( int i = 0 ; i < num_axes ; i++ ) axes[i] = 1500.0f ; return ; } int status = ::read ( os->fd, &(os->js), JS_RETURN ) ; if ( status != JS_RETURN ) { perror ( os->fname ) ; setError () ; return ; } if ( buttons != NULL ) *buttons = os->js.buttons ; if ( axes != NULL ) { axes[0] = (float) os->js.x ; axes[1] = (float) os->js.y ; } } void jsInit() {} #endif #endif plib-1.8.5/src/js/js.dsp0000644000175000001440000000656710765364435011752 00000000000000# Microsoft Developer Studio Project File - Name="js" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=js - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "js.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "js.mak" CFG="js - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "js - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "js - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "js - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\util" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy js.h ..\..\js.h # End Special Build Tool !ELSEIF "$(CFG)" == "js - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\util" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\js_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy js.h ..\..\js.h # End Special Build Tool !ENDIF # Begin Target # Name "js - Win32 Release" # Name "js - Win32 Debug" # Begin Source File SOURCE=.\js.cxx # End Source File # Begin Source File SOURCE=.\js.h # End Source File # Begin Source File SOURCE=.\jsBSD.cxx # End Source File # Begin Source File SOURCE=.\jsLinux.cxx # End Source File # Begin Source File SOURCE=.\jsMacOS.cxx # End Source File # Begin Source File SOURCE=.\jsMacOSX.cxx # End Source File # Begin Source File SOURCE=.\jsNone.cxx # End Source File # Begin Source File SOURCE=.\jsWindows.cxx # End Source File # End Target # End Project plib-1.8.5/src/js/jsWindows.cxx0000644000175000001440000001604410765364435013330 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: jsWindows.cxx 2114 2006-12-21 20:53:13Z fayjf $ */ #include "js.h" #if defined (UL_WIN32) #define _JS_MAX_AXES_WIN 8 /* X,Y,Z,R,U,V,POV_X,POV_Y */ struct os_specific_s { JOYCAPS jsCaps ; JOYINFOEX js ; UINT js_id ; static bool getOEMProductName ( jsJoystick* joy, char *buf, int buf_sz ) ; }; // Inspired by // http://msdn.microsoft.com/archive/en-us/dnargame/html/msdn_sidewind3d.asp bool os_specific_s::getOEMProductName ( jsJoystick* joy, char *buf, int buf_sz ) { if ( joy->error ) return false ; union { char key [ 256 ] ; char value [ 256 ] ; } ; char OEMKey [ 256 ] ; HKEY hKey ; DWORD dwcb ; LONG lr ; // Open .. MediaResources\CurrentJoystickSettings sprintf ( key, "%s\\%s\\%s", REGSTR_PATH_JOYCONFIG, joy->os->jsCaps.szRegKey, REGSTR_KEY_JOYCURR ) ; lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, &hKey) ; if ( lr != ERROR_SUCCESS ) return false ; // Get OEM Key name dwcb = sizeof(OEMKey) ; // JOYSTICKID1-16 is zero-based; registry entries for VJOYD are 1-based. sprintf ( value, "Joystick%d%s", joy->os->js_id + 1, REGSTR_VAL_JOYOEMNAME ) ; lr = RegQueryValueEx ( hKey, value, 0, 0, (LPBYTE) OEMKey, &dwcb); RegCloseKey ( hKey ) ; if ( lr != ERROR_SUCCESS ) return false ; // Open OEM Key from ...MediaProperties sprintf ( key, "%s\\%s", REGSTR_PATH_JOYOEM, OEMKey ) ; lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, &hKey ) ; if ( lr != ERROR_SUCCESS ) return false ; // Get OEM Name dwcb = buf_sz ; lr = RegQueryValueEx ( hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buf, &dwcb ) ; RegCloseKey ( hKey ) ; if ( lr != ERROR_SUCCESS ) return false ; return true ; } void jsJoystick::open () { name [0] = '\0' ; os->js . dwFlags = JOY_RETURNALL ; os->js . dwSize = sizeof ( os->js ) ; memset ( &(os->jsCaps), 0, sizeof(os->jsCaps) ) ; error = ( joyGetDevCaps( os->js_id, &(os->jsCaps), sizeof(os->jsCaps) ) != JOYERR_NOERROR ) ; num_buttons = os->jsCaps.wNumButtons ; if ( os->jsCaps.wNumAxes == 0 ) { num_axes = 0 ; setError () ; } else { // Device name from jsCaps is often "Microsoft PC-joystick driver", // at least for USB. Try to get the real name from the registry. if ( ! os->getOEMProductName ( this, name, sizeof(name) ) ) { ulSetError ( UL_WARNING, "JS: Failed to read joystick name from registry" ) ; strncpy ( name, os->jsCaps.szPname, sizeof(name) ) ; } // Windows joystick drivers may provide any combination of // X,Y,Z,R,U,V,POV - not necessarily the first n of these. if ( os->jsCaps.wCaps & JOYCAPS_HASPOV ) { num_axes = _JS_MAX_AXES_WIN ; min [ 7 ] = -1.0 ; max [ 7 ] = 1.0 ; // POV Y min [ 6 ] = -1.0 ; max [ 6 ] = 1.0 ; // POV X } else num_axes = 6 ; min [ 5 ] = (float) os->jsCaps.wVmin ; max [ 5 ] = (float) os->jsCaps.wVmax ; min [ 4 ] = (float) os->jsCaps.wUmin ; max [ 4 ] = (float) os->jsCaps.wUmax ; min [ 3 ] = (float) os->jsCaps.wRmin ; max [ 3 ] = (float) os->jsCaps.wRmax ; min [ 2 ] = (float) os->jsCaps.wZmin ; max [ 2 ] = (float) os->jsCaps.wZmax ; min [ 1 ] = (float) os->jsCaps.wYmin ; max [ 1 ] = (float) os->jsCaps.wYmax ; min [ 0 ] = (float) os->jsCaps.wXmin ; max [ 0 ] = (float) os->jsCaps.wXmax ; } for ( int i = 0 ; i < num_axes ; i++ ) { center [ i ] = ( max[i] + min[i] ) / 2.0f ; dead_band [ i ] = 0.0f ; saturate [ i ] = 1.0f ; } } void jsJoystick::close () { delete os; } jsJoystick::jsJoystick ( int ident ) { id = ident ; os = new struct os_specific_s; if (ident >= 0 && ident < (int)joyGetNumDevs()) { os->js_id = JOYSTICKID1 + ident; open(); } else { num_axes = 0; setError(); } } void jsJoystick::rawRead ( int *buttons, float *axes ) { if ( error ) { if ( buttons ) *buttons = 0 ; if ( axes ) for ( int i = 0 ; i < num_axes ; i++ ) axes[i] = 1500.0f ; return ; } MMRESULT status = joyGetPosEx ( os->js_id, &(os->js) ) ; if ( status != JOYERR_NOERROR ) { setError() ; return ; } if ( buttons != NULL ) *buttons = (int) os->js.dwButtons ; if ( axes != NULL ) { /* WARNING - Fall through case clauses!! */ switch ( num_axes ) { case 8: // Generate two POV axes from the POV hat angle. // Low 16 bits of js.dwPOV gives heading (clockwise from ahead) in // hundredths of a degree, or 0xFFFF when idle. if ( ( os->js.dwPOV & 0xFFFF ) == 0xFFFF ) { axes [ 6 ] = 0.0 ; axes [ 7 ] = 0.0 ; } else { // This is the contentious bit: how to convert angle to X/Y. // wk: I know of no define for PI that we could use here: // SG_PI would pull in sg, M_PI is undefined for MSVC // But the accuracy of the value of PI is very unimportant at // this point. float s = (float) sin ( ( os->js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180 ) ) ; float c = (float) cos ( ( os->js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180 ) ) ; // Convert to coordinates on a square so that North-East // is (1,1) not (.7,.7), etc. // s and c cannot both be zero so we won't divide by zero. if ( fabs ( s ) < fabs ( c ) ) { axes [ 6 ] = ( c < 0.0 ) ? -s/c : s/c ; axes [ 7 ] = ( c < 0.0 ) ? -1.0f : 1.0f ; } else { axes [ 6 ] = ( s < 0.0 ) ? -1.0f : 1.0f ; axes [ 7 ] = ( s < 0.0 ) ? -c/s : c/s ; } } case 6: axes[5] = (float) os->js . dwVpos ; case 5: axes[4] = (float) os->js . dwUpos ; case 4: axes[3] = (float) os->js . dwRpos ; case 3: axes[2] = (float) os->js . dwZpos ; case 2: axes[1] = (float) os->js . dwYpos ; case 1: axes[0] = (float) os->js . dwXpos ; break; default: ulSetError ( UL_WARNING, "PLIB_JS: Wrong num_axes. Joystick input is now invalid" ) ; } } } void jsInit() {} #endif plib-1.8.5/src/puAux/0000777000175000001440000000000010765365520011356 500000000000000plib-1.8.5/src/puAux/puAuxCompass.cxx0000644000175000001440000005514410765364434014462 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. Copyright (C) 1998,2002,2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxCompass.cxx 1942 2004-08-05 01:03:49Z puggles $ */ #include "puAuxLocal.h" #ifdef UL_MAC_OSX # include #else # include #endif UL_RTTI_DEF1(puaCompass,puObject) #define SET_ARC_COLOUR1(value) \ if ( getIntegerValue () == value ) \ glColor4fv ( colour [ PUCOL_LEGEND ] ) ; \ else \ glColor4fv ( colour [ PUCOL_FOREGROUND ] ) #define SET_ARC_COLOUR2(value1,value2) \ if ( ( getIntegerValue () == value1 ) || ( getIntegerValue () == value2 ) ) \ glColor4fv ( colour [ PUCOL_LEGEND ] ) ; \ else \ glColor4fv ( colour [ PUCOL_FOREGROUND ] ) #define SET_ARC_COLOUR3(value1,value2,value3) \ if ( ( getIntegerValue () == value1 ) || ( getIntegerValue () == value2 ) || ( getIntegerValue () == value3 ) ) \ glColor4fv ( colour [ PUCOL_LEGEND ] ) ; \ else \ glColor4fv ( colour [ PUCOL_FOREGROUND ] ) void puaCompass::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; // Draw the frame surrounding the compass // if ( ( style == PUSTYLE_BEVELLED ) || // ( style == PUSTYLE_SHADED ) ) // abox.draw ( dx, dy, -PUSTYLE_BOXED, colour, FALSE, 2 ) ; // else // abox.draw ( dx, dy, -style, colour, FALSE, border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { float xsize = float(abox.max[0] - abox.min[0]) ; float ysize = float(abox.max[1] - abox.min[1]) ; float xcenter = float(dx + abox.min[0]) + xsize / 2.0f ; float ycenter = float(dy + abox.min[1]) + ysize / 2.0f ; float size = ( ( xsize > ysize ) ? ysize : xsize ) / 2.5f ; glMatrixMode ( GL_MODELVIEW ) ; glPushMatrix () ; glLoadIdentity () ; glTranslatef ( xcenter, ycenter, 0 ) ; glScalef ( size, size, size ) ; /* Make the points circular instead of square */ glEnable ( GL_POINT_SMOOTH ) ; glPointSize ( point_size ) ; /* Ideally, we would be able to use a "glRotate" to rotate the compass. * Unfortunately, PUI widgets are all 2-d and so our z-coordinate will cause * the widget to be clipped. Our solution is to rotate all the compass * components into the widget plane and just plot with a z-coordinate of zero. */ glColor4fv ( colour [ PUCOL_LEGEND ] ) ; sgVec3 pt ; /* The points */ glBegin ( GL_POINTS ) ; SET_ARC_COLOUR1 ( PUACOMPASS_RESET ) ; glVertex3f ( 0.0, 0.0, 0.0 ) ; /* the origin */ SET_ARC_COLOUR1 ( PUACOMPASS_ROTATE_Y_Z ) ; if ( getIntegerValue () != PUACOMPASS_ROTATE_Y_Z ) // Set x-point red for now since point size doesn't seem to work glColor4f ( 1.0, 0.0, 0.0, 1.0 ) ; sgSetVec3 ( pt, 1.0, 0.0, 0.0 ) ; /* x-axis point */ sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; SET_ARC_COLOUR1 ( PUACOMPASS_ROTATE_Z_X ) ; if ( getIntegerValue () != PUACOMPASS_ROTATE_Z_X ) // Set y-point green for now since point size doesn't seem to work glColor4f ( 0.0, 1.0, 0.0, 1.0 ) ; sgSetVec3 ( pt, 0.0, 1.0, 0.0 ) ; /* y-axis point */ sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; SET_ARC_COLOUR1 ( PUACOMPASS_ROTATE_X_Y ) ; if ( getIntegerValue () != PUACOMPASS_ROTATE_X_Y ) // Set z-point blue for now since point size doesn't seem to work glColor4f ( 0.0, 0.0, 1.0, 1.0 ) ; sgSetVec3 ( pt, 0.0, 0.0, 1.0 ) ; /* z-axis point */ sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; glEnd () ; glLineWidth ( 3 ) ; /* The axis lines */ glBegin ( GL_LINES ) ; SET_ARC_COLOUR3 ( PUACOMPASS_TRANSLATE_X, PUACOMPASS_TRANSLATE_X_Y, PUACOMPASS_TRANSLATE_Z_X ) ; sgSetVec3 ( pt, 0.0, 0.0, 0.0 ) ; sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; sgSetVec3 ( pt, 1.0, 0.0, 0.0 ) ; /* x-axis */ sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; SET_ARC_COLOUR3 ( PUACOMPASS_TRANSLATE_Y, PUACOMPASS_TRANSLATE_X_Y, PUACOMPASS_TRANSLATE_Y_Z ) ; sgSetVec3 ( pt, 0.0, 0.0, 0.0 ) ; sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; sgSetVec3 ( pt, 0.0, 1.0, 0.0 ) ; /* y-axis */ sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; SET_ARC_COLOUR3 ( PUACOMPASS_TRANSLATE_Z, PUACOMPASS_TRANSLATE_Y_Z, PUACOMPASS_TRANSLATE_Z_X ) ; sgSetVec3 ( pt, 0.0, 0.0, 0.0 ) ; sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; sgSetVec3 ( pt, 0.0, 0.0, 1.0 ) ; /* z-axis */ sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; glEnd () ; /* The quarter-arcs */ int num_points = 13 ; float coords[13] = { .000000f, .130526f, .258819f, .382683f, .500000f, .608761f, .707107f, .793353f, .866025f, .923879f, .965926f, .991445f, 1.0f } ; int i ; glBegin ( GL_LINE_STRIP ) ; SET_ARC_COLOUR2 ( PUACOMPASS_ROTATE_Z, PUACOMPASS_TRANSLATE_X_Y ) ; for ( i = 0; i < num_points; i++ ) { sgSetVec3 ( pt, coords[i], coords[num_points-1-i], 0.0 ) ; sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; } glEnd () ; glBegin ( GL_LINE_STRIP ) ; SET_ARC_COLOUR2 ( PUACOMPASS_ROTATE_Y, PUACOMPASS_TRANSLATE_Z_X ) ; for ( i = 0; i < num_points; i++ ) { sgSetVec3 ( pt, coords[i], 0.0, coords[num_points-1-i] ) ; sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; } glEnd () ; glBegin ( GL_LINE_STRIP ) ; SET_ARC_COLOUR2 ( PUACOMPASS_ROTATE_X, PUACOMPASS_TRANSLATE_Y_Z ) ; for ( i = 0; i < num_points; i++ ) { sgSetVec3 ( pt, 0.0, coords[i], coords[num_points-1-i] ) ; sgRotateVecQuat ( pt, rotation ) ; glVertex3f ( pt[SG_X], pt[SG_Y], 0.0f ) ; } glEnd () ; glMatrixMode ( GL_MODELVIEW ) ; glPopMatrix () ; draw_legend ( dx, dy ) ; } draw_label ( dx, dy ) ; } void puaCompass::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } float xsize = float(abox.max[0] - abox.min[0]) ; float ysize = float(abox.max[1] - abox.min[1]) ; float size = ( ( xsize > ysize ) ? ysize : xsize ) / 2.5f ; /* Set the "prev_rotation" quaternion. This will stop being updated after the downclick. * We use it in the transformation so that the transformation "freezes" on the downclick. * In the meantime, the actual rotation continues to change and updates the widget "look." */ if ( button_state == PU_UP ) sgCopyQuat ( prev_rotation, rotation ) ; /* The mouse position forms a line in 3-space. The equation of this line in window * coordinates is (xm,ym,0) + u k, where "xm" and "ym" are the mouse position (x and y), * "u" is a parametric coordinate along the line, and "k" is the unit vector in the z- * direction. We rotate these into the compass coordinate system to get the mouse click * somewhere on a line R = R0 + u T, where R0 is (xm,ym,0) rotated and T is "k" rotated. */ sgLine3 mouse_click_line ; mouse_click_line.direction_vector[0] = 2.0f * ( -prev_rotation[SG_W] * prev_rotation[SG_Y] + prev_rotation[SG_X] * prev_rotation[SG_Z] ) ; mouse_click_line.direction_vector[1] = 2.0f * ( prev_rotation[SG_W] * prev_rotation[SG_X] + prev_rotation[SG_Y] * prev_rotation[SG_Z] ) ; mouse_click_line.direction_vector[2] = prev_rotation[SG_W] * prev_rotation[SG_W] + prev_rotation[SG_Z] * prev_rotation[SG_Z] - prev_rotation[SG_X] * prev_rotation[SG_X] - prev_rotation[SG_Y] * prev_rotation[SG_Y] ; float xm = float(x - abox.min[0]) - xsize / 2.0f ; float ym = float(y - abox.min[1]) - ysize / 2.0f ; sgSetVec3 ( mouse_click_line.point_on_line, xm, ym, 0.0f ) ; sgRotateCoordQuat ( mouse_click_line.point_on_line, prev_rotation ) ; /* If the button state is up (whether moving or down-clicking), find the * nearest element in the compass (if any) to activate it. */ if ( button_state == PU_UP ) { /* Set the widget value to zero. Then perform thirteen tests, each one figuring out whether * the mouse is over (or has clicked on) so that we can activate the appropriate part of * the widget. */ setValue ( PUACOMPASS_INACTIVE ) ; sgVec3 point ; /* Minimum distance (squared) from the points (1,0,0), (0,1,0), and (0,0,1) to the mouse click line */ sgSetVec3 ( point, size, 0.0, 0.0 ) ; float dmin2 = sgDistSquaredToLineVec3 ( mouse_click_line, point ) ; if ( dmin2 < point_size * point_size ) setValue ( PUACOMPASS_ROTATE_Y_Z ) ; if ( getIntegerValue () == PUACOMPASS_INACTIVE ) { sgSetVec3 ( point, 0.0, size, 0.0 ) ; dmin2 = sgDistSquaredToLineVec3 ( mouse_click_line, point ) ; if ( dmin2 < point_size * point_size ) setValue ( PUACOMPASS_ROTATE_Z_X ) ; } if ( getIntegerValue () == PUACOMPASS_INACTIVE ) { sgSetVec3 ( point, 0.0, 0.0, size ) ; dmin2 = sgDistSquaredToLineVec3 ( mouse_click_line, point ) ; if ( dmin2 < point_size * point_size ) setValue ( PUACOMPASS_ROTATE_X_Y ) ; } /* Minimum distance (squared) from the origin */ if ( getIntegerValue () == PUACOMPASS_INACTIVE ) { sgSetVec3 ( point, 0.0, 0.0, 0.0 ) ; dmin2 = sgDistSquaredToLineVec3 ( mouse_click_line, point ) ; if ( dmin2 < point_size * point_size ) setValue ( PUACOMPASS_RESET ) ; } /* Minimum distance (squared) from the three axis segments */ sgLineSegment3 axis ; sgSetVec3 ( axis.a, 0.0, 0.0, 0.0 ) ; if ( getIntegerValue () == PUACOMPASS_INACTIVE ) { sgSetVec3 ( axis.b, size, 0.0, 0.0 ) ; dmin2 = sgDistSquaredToLineLineSegment ( axis, mouse_click_line ) ; if ( dmin2 < point_size * point_size ) setValue ( PUACOMPASS_TRANSLATE_X ) ; } if ( getIntegerValue () == PUACOMPASS_INACTIVE ) { sgSetVec3 ( axis.b, 0.0, size, 0.0 ) ; dmin2 = sgDistSquaredToLineLineSegment ( axis, mouse_click_line ) ; if ( dmin2 < point_size * point_size ) setValue ( PUACOMPASS_TRANSLATE_Y ) ; } if ( getIntegerValue () == PUACOMPASS_INACTIVE ) { sgSetVec3 ( axis.b, 0.0, 0.0, size ) ; dmin2 = sgDistSquaredToLineLineSegment ( axis, mouse_click_line ) ; if ( dmin2 < point_size * point_size ) setValue ( PUACOMPASS_TRANSLATE_Z ) ; } /* Project the mouse click line on to each of the coordinate planes. If it intersects * within the given radius (size +- point_size) of the origin, highlight the arc. */ sgFloat xydist2 = 0.0 ; sgFloat xyplane_xint = 0.0, xyplane_yint = 0.0 ; if ( ( getIntegerValue () == PUACOMPASS_INACTIVE ) && ( mouse_click_line.direction_vector[2] != 0.0 ) ) { xyplane_xint = mouse_click_line.point_on_line[0] - mouse_click_line.point_on_line[2] * mouse_click_line.direction_vector[0] / mouse_click_line.direction_vector[2] ; xyplane_yint = mouse_click_line.point_on_line[1] - mouse_click_line.point_on_line[2] * mouse_click_line.direction_vector[1] / mouse_click_line.direction_vector[2] ; xydist2 = xyplane_xint * xyplane_xint + xyplane_yint * xyplane_yint ; if ( ( xyplane_xint > 0.0 ) && ( xyplane_yint > 0.0 ) ) { if ( fabs ( xydist2 - size * size ) < 2.0f * size * point_size ) { setValue ( PUACOMPASS_ROTATE_Z ) ; xint = xyplane_xint ; yint = xyplane_yint ; } } } sgFloat yzdist2 = 0.0 ; sgFloat yzplane_yint = 0.0, yzplane_zint = 0.0 ; if ( ( getIntegerValue () == PUACOMPASS_INACTIVE ) && ( mouse_click_line.direction_vector[0] != 0.0 ) ) { yzplane_yint = mouse_click_line.point_on_line[1] - mouse_click_line.point_on_line[0] * mouse_click_line.direction_vector[1] / mouse_click_line.direction_vector[0] ; yzplane_zint = mouse_click_line.point_on_line[2] - mouse_click_line.point_on_line[0] * mouse_click_line.direction_vector[2] / mouse_click_line.direction_vector[0] ; yzdist2 = yzplane_yint * yzplane_yint + yzplane_zint * yzplane_zint ; if ( ( yzplane_yint > 0.0 ) && ( yzplane_zint > 0.0 ) ) { if ( fabs ( yzdist2 - size * size ) < 2.0f * size * point_size ) { setValue ( PUACOMPASS_ROTATE_X ) ; yint = yzplane_yint ; zint = yzplane_zint ; } } } sgFloat zxdist2 = 0.0 ; sgFloat zxplane_zint = 0.0, zxplane_xint = 0.0 ; if ( ( getIntegerValue () == PUACOMPASS_INACTIVE ) && ( mouse_click_line.direction_vector[1] != 0.0 ) ) { zxplane_zint = mouse_click_line.point_on_line[2] - mouse_click_line.point_on_line[1] * mouse_click_line.direction_vector[2] / mouse_click_line.direction_vector[1] ; zxplane_xint = mouse_click_line.point_on_line[0] - mouse_click_line.point_on_line[1] * mouse_click_line.direction_vector[0] / mouse_click_line.direction_vector[1] ; zxdist2 = zxplane_zint * zxplane_zint + zxplane_xint * zxplane_xint ; if ( ( zxplane_zint > 0.0 ) && ( zxplane_xint > 0.0 ) ) { if ( fabs ( zxdist2 - size * size ) < 2.0f * size * point_size ) { setValue ( PUACOMPASS_ROTATE_Y ) ; zint = zxplane_zint ; xint = zxplane_xint ; } } } /* If we missed the arc (meaning that the value is still INACTIVE), check whether we * got inside the quadrants. */ if ( ( getIntegerValue () == PUACOMPASS_INACTIVE ) && ( mouse_click_line.direction_vector[2] != 0.0 ) ) { if ( ( xydist2 < size * size ) && ( xyplane_xint > 0.0 ) && ( xyplane_yint > 0.0 ) ) { setValue ( PUACOMPASS_TRANSLATE_X_Y ) ; xint = xyplane_xint ; yint = xyplane_yint ; } } if ( ( getIntegerValue () == PUACOMPASS_INACTIVE ) && ( mouse_click_line.direction_vector[0] != 0.0 ) ) { if ( ( yzdist2 < size * size ) && ( yzplane_yint > 0.0 ) && ( yzplane_zint > 0.0 ) ) { setValue ( PUACOMPASS_TRANSLATE_Y_Z ) ; yint = yzplane_yint ; zint = yzplane_zint ; } } if ( ( getIntegerValue () == PUACOMPASS_INACTIVE ) && ( mouse_click_line.direction_vector[1] != 0.0 ) ) { if ( ( zxdist2 < size * size ) && ( zxplane_zint > 0.0 ) && ( zxplane_xint > 0.0 ) ) { setValue ( PUACOMPASS_TRANSLATE_Z_X ) ; zint = zxplane_zint ; xint = zxplane_xint ; } } } if ( button != getTriggerButton () ) return ; if ( updown == PU_DOWN ) { if ( getIntegerValue () == PUACOMPASS_ROTATE_X ) prev_angle = sgATan2 ( zint, yint ) ; else if ( getIntegerValue () == PUACOMPASS_ROTATE_Y ) prev_angle = sgATan2 ( xint, zint ) ; else if ( getIntegerValue () == PUACOMPASS_ROTATE_Z ) prev_angle = sgATan2 ( yint, xint ) ; mouse_x = xm ; mouse_y = ym ; button_state = PU_DOWN ; // If we are rotating about two axes, we need to mouse z-coordinate for future reference. if ( ( getIntegerValue () == PUACOMPASS_ROTATE_Y_Z ) || ( getIntegerValue () == PUACOMPASS_ROTATE_Z_X ) || ( getIntegerValue () == PUACOMPASS_ROTATE_X_Y ) ) { sgVec3 temp ; sgCopyVec3 ( temp, mouse_click_line.point_on_line ) ; // Parametric coordinate of point on line closest to origin float u_origin = -sgScalarProductVec3 ( temp, mouse_click_line.direction_vector ) ; float u = 0.0 ; if ( getIntegerValue () == PUACOMPASS_ROTATE_Y_Z ) { temp[SG_X] -= size ; u = -sgScalarProductVec3 ( temp, mouse_click_line.direction_vector ) ; } else if ( getIntegerValue () == PUACOMPASS_ROTATE_Z_X ) { temp[SG_Y] -= size ; u = -sgScalarProductVec3 ( temp, mouse_click_line.direction_vector ) ; } else if ( getIntegerValue () == PUACOMPASS_ROTATE_X_Y ) { temp[SG_Z] -= size ; u = -sgScalarProductVec3 ( temp, mouse_click_line.direction_vector ) ; } mouse_z = size * size - xm * xm - ym * ym ; if ( mouse_z < 0.0 ) mouse_z = 0.0 ; mouse_z = sgSqrt ( mouse_z ) ; if ( u < u_origin ) mouse_z = -mouse_z ; } } else if ( updown == PU_UP ) { if ( getIntegerValue () == PUACOMPASS_RESET ) { sgSetQuat ( rotation, 1.0f, 0.0f, 0.0f, 0.0f ) ; sgSetQuat ( prev_rotation, 1.0f, 0.0f, 0.0f, 0.0f ) ; sgSetVec3 ( translation, 0.0f, 0.0f, 0.0f ) ; setValue ( PUACOMPASS_INACTIVE ) ; } button_state = PU_UP ; } else if ( updown == PU_DRAG ) { float zm = size * size - xm * xm - ym * ym ; if ( zm < 0.0 ) zm = 0.0 ; zm = ( mouse_z >= 0.0 ) ? sgSqrt ( zm ) : -sgSqrt ( zm ) ; float new_size = sgSqrt ( xm * xm + ym * ym + zm * zm ) ; float cosang = ( xm * mouse_x + ym * mouse_y + zm * mouse_z ) / ( size * new_size ) ; cosang = sgSqrt ( ( 1.0f + cosang ) / 2.0f ) ; sgVec3 displacement ; sgSetVec3 ( displacement, xm - mouse_x, ym - mouse_y, 0.0f ) ; sgRotateVecQuat ( displacement, prev_rotation ) ; sgQuat rot ; sgSetQuat ( rot, 2.0f, 2.0f, 2.0f, 2.0f ) ; /* Values will change if we have a rotation */ sgFloat angle = prev_angle ; switch ( getIntegerValue () ) { case PUACOMPASS_INACTIVE : break ; case PUACOMPASS_RESET : break ; case PUACOMPASS_ROTATE_Y_Z : // rot[SG_X] = 0.0 ; // rot[SG_Y] = -displacement[2] / size ; // rot[SG_Z] = displacement[1] / size ; // rot[SG_W] = sgSqrt ( 1.0f - rot[SG_Y] * rot[SG_Y] - rot[SG_Z] * rot[SG_Z] ) ; // sgPostMultQuat ( rotation, rot ) ; // break ; case PUACOMPASS_ROTATE_Z_X : // rot[SG_X] = displacement[2] / size ; // rot[SG_Y] = 0.0 ; // rot[SG_Z] = -displacement[0] / size ; // rot[SG_W] = sgSqrt ( 1.0f - rot[SG_X] * rot[SG_X] - rot[SG_Z] * rot[SG_Z] ) ; // sgPostMultQuat ( rotation, rot ) ; // break ; case PUACOMPASS_ROTATE_X_Y : // rot[SG_X] = -displacement[1] / size ; // rot[SG_Y] = displacement[0] / size ; // rot[SG_Z] = 0.0 ; // rot[SG_W] = sgSqrt ( 1.0f - rot[SG_X] * rot[SG_X] - rot[SG_Y] * rot[SG_Y] ) ; rot[SG_W] = cosang ; rot[SG_X] = ( mouse_y * zm - mouse_z * ym ) * 0.5f / ( size * new_size * cosang ) ; rot[SG_Y] = ( mouse_z * xm - mouse_x * zm ) * 0.5f / ( size * new_size * cosang ) ; rot[SG_Z] = ( mouse_x * ym - mouse_y * xm ) * 0.5f / ( size * new_size * cosang ) ; sgRotateVecQuat ( rot, prev_rotation ) ; printf ( "Rotation %f %f %f %f %f %f %f %f\n", prev_angle, xm, ym, zm, rot[SG_W], rot[SG_X], rot[SG_Y], rot[SG_Z] ) ; sgPreMultQuat ( rotation, rot ) ; break ; case PUACOMPASS_TRANSLATE_X : translation[0] += translation_sensitivity * displacement[0] ; break ; case PUACOMPASS_TRANSLATE_Y : translation[1] += translation_sensitivity * displacement[1] ; break ; case PUACOMPASS_TRANSLATE_Z : translation[2] += translation_sensitivity * displacement[2] ; break ; case PUACOMPASS_ROTATE_Z : xint = mouse_click_line.point_on_line[0] - mouse_click_line.point_on_line[2] * mouse_click_line.direction_vector[0] / mouse_click_line.direction_vector[2] ; yint = mouse_click_line.point_on_line[1] - mouse_click_line.point_on_line[2] * mouse_click_line.direction_vector[1] / mouse_click_line.direction_vector[2] ; angle = sgATan2 ( yint, xint ) - prev_angle ; rot[SG_X] = 0.0 ; rot[SG_Y] = 0.0 ; rot[SG_Z] = sgSin ( angle / 2.0f ) ; rot[SG_W] = sgCos ( angle / 2.0f ) ; sgPostMultQuat ( rotation, rot ) ; prev_angle += angle ; break ; case PUACOMPASS_ROTATE_X : yint = mouse_click_line.point_on_line[1] - mouse_click_line.point_on_line[0] * mouse_click_line.direction_vector[1] / mouse_click_line.direction_vector[0] ; zint = mouse_click_line.point_on_line[2] - mouse_click_line.point_on_line[0] * mouse_click_line.direction_vector[2] / mouse_click_line.direction_vector[0] ; angle = sgATan2 ( zint, yint ) - prev_angle ; rot[SG_X] = sgSin ( angle / 2.0f ) ; rot[SG_Y] = 0.0 ; rot[SG_Z] = 0.0 ; rot[SG_W] = sgCos ( angle / 2.0f ) ; sgPostMultQuat ( rotation, rot ) ; prev_angle += angle ; break ; case PUACOMPASS_ROTATE_Y : zint = mouse_click_line.point_on_line[2] - mouse_click_line.point_on_line[1] * mouse_click_line.direction_vector[2] / mouse_click_line.direction_vector[1] ; xint = mouse_click_line.point_on_line[0] - mouse_click_line.point_on_line[1] * mouse_click_line.direction_vector[0] / mouse_click_line.direction_vector[1] ; angle = sgATan2 ( xint, zint ) - prev_angle ; rot[SG_X] = 0.0 ; rot[SG_Y] = sgSin ( angle / 2.0f ) ; rot[SG_Z] = 0.0 ; rot[SG_W] = sgCos ( angle / 2.0f ) ; sgPostMultQuat ( rotation, rot ) ; prev_angle += angle ; break ; case PUACOMPASS_TRANSLATE_X_Y : translation[0] += translation_sensitivity * displacement[0] ; translation[1] += translation_sensitivity * displacement[1] ; break ; case PUACOMPASS_TRANSLATE_Y_Z : translation[1] += translation_sensitivity * displacement[1] ; translation[2] += translation_sensitivity * displacement[2] ; break ; case PUACOMPASS_TRANSLATE_Z_X : translation[2] += translation_sensitivity * displacement[2] ; translation[0] += translation_sensitivity * displacement[0] ; break ; } mouse_x = xm * size / new_size ; mouse_y = ym * size / new_size ; mouse_z = zm * size / new_size ; // if ( rot[0] < 1.5 ) // { // sgPostMultQuat ( rotation, rot ) ; // prev_angle += angle ; // printf ( "Rotation %f %f %f %f %f\n", prev_angle, rotation[SG_W], rotation[SG_X], rotation[SG_Y], rotation[SG_Z] ) ; // } } } plib-1.8.5/src/puAux/puAuxLargeInput.cxx0000644000175000001440000012641210765364434015124 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxLargeInput.cxx 2068 2006-03-20 15:17:35Z fayjf $ */ #include "puAuxLocal.h" UL_RTTI_DEF2(puaLargeInput,puInputBase,puGroup) // Callbacks from the internal widgets static void puaLargeInputHandleRightSlider ( puObject *slider ) { float val = ((puaScrollBar *)slider)->getMaxValue () - slider->getFloatValue () ; puaLargeInput* text = (puaLargeInput*) slider->getUserData () ; //int lines_in_window = text->getLinesInWindow () ; int num_lines = text->getNumLines () ; if ( num_lines > 0 ) text->setTopLineInWindow ( int ( val + 0.5f ) ) ; } // Private function from the widget itself void puaLargeInput::normalizeCursors ( void ) { puInputBase::normalizeCursors () ; // Set the top line in the window so that the last line is at the bottom of the window if ( top_line_in_window > num_lines - lines_in_window + 2 ) top_line_in_window = num_lines - lines_in_window + 2 ; if ( top_line_in_window < 0 ) top_line_in_window = 0 ; } void puaLargeInput::removeSelectRegion ( void ) { puInputBase::removeSelectRegion () ; wrapText () ; } // Public functions from the widget itself puaLargeInput::puaLargeInput ( int x, int y, int w, int h, int arrows, int sl_width, int wrap_text ) : puInputBase (), puGroup ( x, y ) { setColour ( PUCOL_MISC, 0.1f, 0.1f, 1.0f ) ; // Colour of the 'I' bar cursor // Set the variables type |= PUCLASS_LARGEINPUT ; num_lines = 1 ; slider_width = sl_width ; lines_in_window = ( h - (bottom_slider?slider_width:0) ) / ( getLegendFont().getStringHeight() + getLegendFont().getStringDescender() + 1 ) ; top_line_in_window = 0 ; max_width = 0 ; widget = this ; // Set up the widgets frame = new puFrame ( 0, 0, w, h ); if ( wrap_text ) bottom_slider = (puSlider *)NULL ; else { bottom_slider = new puSlider ( 0, 0, w - slider_width, FALSE, slider_width ) , bottom_slider->setValue ( 0.0f ) ; // All the way to the left // bottom_slider->setDelta(0.1f); // Commented out CBModes and Deltas for these sliders to increase response time and to ensure the sliders react properly even when first selected - JCJ 13 Jun 2002 bottom_slider->setSliderFraction (1.0f) ; // bottom_slider->setCBMode( PUSLIDER_DELTA ); } right_slider = new puaScrollBar ( w - slider_width, (bottom_slider?slider_width:0), h - (bottom_slider?slider_width:0), arrows, TRUE, slider_width ) , right_slider->setValue ( 1.0f ) ; // All the way to the top // right_slider->setDelta(0.1f); right_slider->setSliderFraction (1.0f) ; right_slider->setStepSize ( 1.0f ) ; // right_slider->setCBMode( PUSLIDER_DELTA ); right_slider->setUserData ( this ) ; right_slider->setCallback ( puaLargeInputHandleRightSlider ) ; setValue ( "\n" ) ; close () ; reveal () ; } void puaLargeInput::setSize ( int w, int h ) { // Resize the frame: frame->setSize ( w, h ) ; // Resize and reposition the sliders if ( bottom_slider ) bottom_slider->setSize ( w - slider_width, slider_width ) ; else // No bottom slider, rewrap the text wrapText () ; right_slider->setPosition ( w-slider_width, (bottom_slider?slider_width:0) ) ; right_slider->setSize ( slider_width, h-(bottom_slider?slider_width:0) ) ; lines_in_window = ( h - (bottom_slider?slider_width:0) ) / ( getLegendFont().getStringHeight() + getLegendFont().getStringDescender() + 1 ) ; int line_size = legendFont.getStringHeight () + // Height of a line legendFont.getStringDescender() ; // of text, in pixels int box_height = ( abox.max[1] - abox.min[1] - slider_width ) / line_size ; int right_slider_max = num_lines - lines_in_window + 1 ; if ( right_slider_max < 1 ) right_slider_max = 1 ; right_slider->setSliderFraction ( float(box_height) / float(right_slider_max) ) ; right_slider->setMaxValue ( float(right_slider_max) ) ; } void puaLargeInput::setSelectRegion ( int s, int e ) { select_start_position = s ; select_end_position = e ; char *lin_ptr = ( bottom_slider ? getStringValue () : getDisplayedText () ) ; char *text_start = lin_ptr ; if ( num_lines > lines_in_window ) { int select_start_line = 0 ; while ( lin_ptr && ( lin_ptr <= text_start + select_start_position ) ) // Count the lines { select_start_line++ ; lin_ptr = strchr ( lin_ptr+1, '\n' ) ; } int select_end_line = select_start_line ; while ( lin_ptr && ( lin_ptr <= text_start + select_end_position ) ) // Count the lines { select_end_line++ ; lin_ptr = strchr ( lin_ptr+1, '\n' ) ; } if ( select_end_line > top_line_in_window + lines_in_window ) top_line_in_window = select_end_line - lines_in_window - 1 ; if ( select_start_line < top_line_in_window ) top_line_in_window = select_start_line - 1 ; if ( top_line_in_window < 0 ) top_line_in_window = 0 ; right_slider->setValue ( num_lines - lines_in_window - top_line_in_window ) ; } } void puaLargeInput::selectEntireLine ( void ) { char *temp_text = ( bottom_slider ? getStringValue () : getDisplayedText () ) ; if ( select_start_position < 0 ) select_start_position = 0 ; if ( ( *(temp_text + select_start_position + 1) != '\n' ) && ( *(temp_text + select_start_position) != '\0' ) ) select_start_position ++ ; while ( ( select_start_position > 0 ) && ( *(temp_text + select_start_position) != '\n' ) ) select_start_position -- ; if ( select_start_position > 0 ) select_start_position++ ; select_end_position = int ( strchr ( temp_text + select_end_position, '\n' ) + 1 - temp_text) ; if ( select_end_position <= 1 ) select_end_position = strlen ( temp_text ) ; //else select_end_position = int ( select_end_position - temp_text ) ;/** Needs real fixing **/ puPostRefresh () ; } void puaLargeInput::addNewLine ( const char *l ) { char *text = getStringValue () ; if ( cursor_position > 0 ) // If not at start of line, go to start of next line cursor_position = int (strchr ( text + cursor_position - 1, '\n' ) - text + 1) ; select_end_position = select_start_position = cursor_position ; addText ( l ) ; } void puaLargeInput::addText ( const char *l ) { char *text = getStringValue () ; if ( l == NULL ) return ; int l_len = strlen ( l ) ; int text_len = strlen ( text ) ; int length = l_len + text_len /* Length of the final string */ + select_start_position - select_end_position + 2 ; if ( *(l+l_len-1) == '\n' ) length -- ; // Decrement "length" for each final if ( text[select_end_position] == '\n' ) length -- ; // carriage return already there char *temp_text = new char [ length ] ; memcpy ( temp_text, text, select_start_position ) ; memcpy ( temp_text + select_start_position, l, l_len + 1 ) ; /* Plus one to get the final '\0' */ int temp_text_len = select_start_position + l_len ; if ( ( *(l+l_len-1) == '\n' ) && ( text[select_end_position] == '\n' ) ) { temp_text[temp_text_len-1] = '\0' ; /* Erase the duplicate carriage return */ temp_text_len -- ; } else if ( ( *(l+l_len-1) != '\n' ) && ( text[select_end_position] != '\n' ) ) { strcpy ( temp_text + temp_text_len, "\n" ) ; /* Add a carriage return */ temp_text_len ++ ; } memcpy ( temp_text + temp_text_len, text + select_end_position, text_len - select_end_position + 1 ) ; int temp_select_start = select_start_position ; setValue ( temp_text ) ; delete [] temp_text ; setSelectRegion ( temp_select_start, temp_select_start + strlen(l) ) ; setCursor ( select_end_position ) ; } void puaLargeInput::appendText ( const char *l ) { if ( !l ) return ; int str_val_len = strlen ( getStringValue () ) ; int l_len = strlen ( l ) ; if ( str_val_len == 1 ) str_val_len = 0 ; /* Don't want null line at the beginning */ int length = str_val_len + l_len + 2 ; if ( *(l+l_len-1) == '\n' ) length -- ; /* Already have a trailing carriage return, decrement the length */ char *temp_text = new char [ length ] ; int temp_text_len ; if ( str_val_len > 0 ) /* More than just the empty carriage return */ { memcpy ( temp_text, getStringValue (), str_val_len ) ; temp_text_len = str_val_len ; } else temp_text_len = 0 ; memcpy ( temp_text + temp_text_len, l, l_len + 1 ) ; /* Plus one to get the final '\0' */ temp_text_len += l_len ; if ( *(l+l_len-1) != '\n' ) { strcpy ( temp_text + temp_text_len, "\n" ) ; temp_text_len ++ ; } setValue ( temp_text ) ; setSelectRegion ( str_val_len, temp_text_len ) ; setCursor ( str_val_len ) ; delete [] temp_text ; } void puaLargeInput::removeText ( int start, int end ) { int str_val_len = strlen ( getStringValue () ) ; char *temp_text = new char [ str_val_len + start - end + 1 ] ; memcpy ( temp_text, getStringValue (), start ) ; memcpy ( temp_text + start, getStringValue ()+end, str_val_len - end + 1 ) ; /* Plus one to get the final '\0' */ setValue ( temp_text ) ; setCursor ( start ) ; setSelectRegion ( start, start ) ; delete [] temp_text ; } void puaLargeInput::setValue ( const char *s ) { if ( bottom_slider ) bottom_slider->setSliderFraction ( 0.0f ) ; right_slider->setSliderFraction ( 0.0f ) ; if ( s == NULL ) { puValue::setValue ( "\n" ) ; num_lines = 0 ; cursor_position = select_start_position = select_end_position = 0 ; return ; } int s_len = strlen ( s ) ; int length = s_len + 2 ; if ( ( s_len > 0 ) && ( *(s+s_len-1) == '\n' ) ) length -- ; /* Already have a trailing carriage return, don't need to add one */ char *text = new char [ length ] ; memcpy ( text, s, s_len + 1 ) ; /* Plus one to get the final '\0' */ if ( ( s [ 0 ] == '\0' ) || ( *(s+s_len-1) != '\n' ) ) strcpy ( text + s_len, "\n" ) ; puValue::setValue ( text ) ; delete [] text ; // Find the greatest width of a line max_width = 0 ; float line_width = 0.0f ; // Width of current line if ( !bottom_slider ) wrapText () ; char *this_char = ( bottom_slider ? getStringValue () : getDisplayedText () ) ; // Pointer to character in text num_lines = 0 ; while ( *this_char != '\0' ) { char *line_end = strchr ( this_char, '\n' ) ; if ( line_end ) // Found an end-of-line { *line_end = '\0' ; // Temporary break in line line_width = legendFont.getFloatStringWidth ( this_char ) ; *line_end = '\n' ; // Reset the carriage return if ( max_width < line_width ) max_width = line_width ; num_lines++ ; // Increment line counter this_char = line_end + 1 ; } else // No carriage return. Since a carriage return should be the last character, this_char++ ; // we should not get here. } if ( max_width < line_width ) max_width = line_width ; // Set slider fractions int line_size = legendFont.getStringHeight () + // Height of a line legendFont.getStringDescender() ; // of text, in pixels int box_width = abox.max[0] - abox.min[0] - slider_width ; // Input box width, in pixels int box_height = ( abox.max[1] - abox.min[1] - slider_width ) / line_size ; // Input box height, in lines if ( bottom_slider ) bottom_slider->setSliderFraction ( float(box_width) / float(max_width) ) ; int right_slider_max = num_lines - lines_in_window + 1 ; if ( right_slider_max < 1 ) right_slider_max = 1 ; right_slider->setSliderFraction ( float(box_height) / float(right_slider_max) ) ; right_slider->setMaxValue ( float(right_slider_max) ) ; // Normalize the cursors normalizeCursors () ; } void puaLargeInput::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; normalizeCursors () ; // 3D Input boxes look nicest if they are always in inverse style. abox.draw ( dx, dy, ( (style==PUSTYLE_SMALL_BEVELLED || style==PUSTYLE_SMALL_SHADED) ) ? -style : (accepting ? -style : style ), colour, FALSE, border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { // Calculate window parameters: int xwidget = abox.min[0] + dx ; int ywidget = abox.min[1] + dy ; int line_size = legendFont.getStringHeight () + // Height of a line legendFont.getStringDescender() + 1 ; // of text, in pixels int xx = int(legendFont.getFloatStringWidth ( " " )) ; int yy = int( abox.max[1] - abox.min[1] - legendFont.getStringHeight () * 1.5f ) ; int box_width = abox.max[0] - abox.min[0] - slider_width - xx - xx ; // Input box width, in pixels int box_height = ( abox.max[1] - abox.min[1] - (bottom_slider?slider_width:0) ) / line_size ; // Input box height, in lines float bottom_value = bottom_slider ? bottom_slider->getFloatValue () : 0.0f ; int beg_pos // Position in window of start of line, in pixels = int(( box_width - max_width ) * bottom_value ) ; //// int end_pos // Position in window of end of line, in pixels //// = beg_pos + max_width - 1 ; if ( top_line_in_window < 0 ) top_line_in_window = 0 ; int end_lin // Position on line count of bottom of window, in lines = top_line_in_window + box_height ; /* Removed IF statement to permit highlighting to remain even when widget not active - JCJ 13 Jun 2002 */ char *val = bottom_slider ? getStringValue () : getDisplayedText () ; // Highlight the select area if ( select_end_position > 0 && select_end_position != select_start_position ) { // First: find the positions on the window of the selection start and end char temp_char = val[ select_start_position ] ; val [ select_start_position ] = '\0' ; xx = dx + abox.min[0] + int(legendFont.getFloatStringWidth ( " " )) ; yy = (int)( abox.max[1] - abox.min[1] - legendFont.getStringHeight () * 1.5f + top_line_in_window * line_size ) ; // Offset y-coord for unprinted lines char *end_of_line = strchr ( val, '\n' ) ; char *start_of_line = val; // Step down the lines until you reach the line with the selection start int select_start_line = 0 ; while ( end_of_line ) { select_start_line++ ; start_of_line = end_of_line + 1 ; yy -= line_size ; end_of_line = strchr ( start_of_line, '\n' ) ; } int start_pos = int(legendFont.getFloatStringWidth ( start_of_line )) + xx + beg_pos ; // Start of selection val [ select_start_position ] = temp_char ; // Now repeat the process for the end of the selection. temp_char = val[ select_end_position ] ; val [ select_end_position ] = '\0' ; end_of_line = strchr ( start_of_line, '\n' ) ; // Step down the lines until you reach the line with the selection end int select_end_line = select_start_line ; while ( end_of_line ) { select_end_line++ ; start_of_line = end_of_line + 1 ; end_of_line = strchr ( start_of_line, '\n' ) ; } int end_pos = int(legendFont.getFloatStringWidth ( start_of_line )) + xx + beg_pos ; // End of selection val [ select_end_position ] = temp_char ; // Now draw the selection area. for ( int line_count = select_start_line ; ( ( line_count <= select_end_line ) && ( line_count <= end_lin ) ) ; line_count++ ) { if ( line_count >= top_line_in_window ) { int x_start, x_end ; if ( line_count == select_start_line ) x_start = ( start_pos > xx ) ? start_pos : xx ; else x_start = xx ; x_start = ( x_start < abox.max[0] + dx ) ? x_start : abox.max[0] + dx ; if ( line_count == select_end_line ) x_end = ( end_pos < abox.max[0] + dx ) ? end_pos : abox.max[0] + dx ; else x_end = abox.max[0] + dx ; x_end = ( x_end > xx ) ? x_end : xx ; int top = dy + abox.min[1] + yy + legendFont.getStringHeight () ; int bot = dy + abox.min[1] + yy - legendFont.getStringDescender() ; glColor3f ( 1.0f, 1.0f, 0.7f ) ; glRecti ( x_start, bot, x_end, top ) ; } yy -= line_size ; if ( line_count == end_lin ) break ; } } // Draw the text { // If greyed out then halve the opacity when drawing the text if ( active ) glColor4fv ( colour [ PUCOL_LEGEND ] ) ; else glColor4f ( colour [ PUCOL_LEGEND ][0], colour [ PUCOL_LEGEND ][1], colour [ PUCOL_LEGEND ][2], colour [ PUCOL_LEGEND ][3] / 2.0f ) ; // 50% more transparent char *val ; // Pointer to the actual text in the box val = bottom_slider ? getStringValue () : getDisplayedText () ; if ( val ) { char *end_of_line = strchr (val, '\n') ; int line_count = 0; xx = int(legendFont.getFloatStringWidth ( " " )) ; yy = int( abox.max[1] - abox.min[1] - legendFont.getStringHeight () * 1.5f ) ; while ( end_of_line ) // While there is a carriage return in the string { if ( line_count < top_line_in_window ) { // Before the start of the window val = end_of_line + 1 ; end_of_line = strchr (val, '\n') ; // Just go to the next line } else if ( line_count <= end_lin ) // Within the window, draw it { char temp_char = *end_of_line ; // Temporary holder for last char on line *end_of_line = '\0' ; // Make end-of-line be an end-of-string int start_pos = beg_pos ; int end_pos // Position in window of end of line, in pixels = start_pos + int(legendFont.getFloatStringWidth ( val )) ; if ( end_pos > start_pos ) // If we actually have text in the line { char * lastonleft = val ; char * firstonright = end_of_line ; int leftpos = start_pos ; int rightpos = end_pos ; while ( lastonleft < firstonright - 1 ) { int chpos = -leftpos * ( firstonright - lastonleft ) / ( rightpos - leftpos ) + 1; if ( chpos >= firstonright - lastonleft ) chpos = firstonright - lastonleft - 1 ; char placeholder = *(lastonleft + chpos) ; *(lastonleft + chpos) = '\0' ; int strwidth = legendFont.getStringWidth ( val ) ; *(lastonleft + chpos) = placeholder ; if ( strwidth + start_pos < 0 ) /* Still to the left of the window */ { lastonleft = lastonleft + chpos ; placeholder = *lastonleft ; *lastonleft = '\0' ; leftpos = start_pos + legendFont.getStringWidth ( val ) ; *lastonleft = placeholder ; } else { firstonright = lastonleft + chpos ; placeholder = *firstonright ; *firstonright = '\0' ; rightpos = start_pos + legendFont.getStringWidth ( val ) ; *firstonright = placeholder ; } } if ( leftpos >= 0 ) { val = lastonleft ; start_pos = leftpos ; } else { val = firstonright ; start_pos = rightpos ; } } while ( end_pos > box_width ) // Step up the line until it is in the window { *end_of_line = temp_char ; end_of_line-- ; temp_char = *end_of_line ; *end_of_line = '\0' ; end_pos = start_pos + legendFont.getStringWidth ( val ) ; } if ( val < end_of_line ) // If any text shows in the window, legendFont.drawString ( val, // draw it. dx + abox.min[0] + xx + start_pos, dy + abox.min[1] + yy ) ; *end_of_line = temp_char ; // Restore the end-of-line character if ( temp_char != '\n' ) // If we had to step up from the end of end_of_line = strchr (val, '\n') ; // the line, go back to the actual end yy -= line_size ; val = end_of_line + 1 ; end_of_line = strchr (val, '\n') ; // On to the next line } else if ( line_count > end_lin ) // Have gone beyond window, end process end_of_line = NULL ; line_count++ ; } // while ( end_of_line ) } // if ( val ) } if ( accepting ) { char *val ; // Pointer to the actual text in the box val = bottom_slider ? getStringValue () : getDisplayedText () ; // Draw the 'I' bar cursor. if ( val && ( cursor_position >= 0 ) ) { char temp_char = val[ cursor_position ] ; val [ cursor_position ] = '\0' ; xx = int(legendFont.getFloatStringWidth ( " " )) ; yy = int( abox.max[1] - abox.min[1] - legendFont.getStringHeight () * 1.5f ) + top_line_in_window * line_size ; // Offset y-coord for unprinted lines char *end_of_line = strchr ( val, '\n' ) ; char *start_of_line = val ; // Step down the lines until you reach the line with the cursor int line_count = 1 ; while ( end_of_line ) { line_count++ ; start_of_line = end_of_line + 1 ; yy -= line_size ; end_of_line = strchr ( start_of_line, '\n' ) ; } if ( ( line_count > top_line_in_window ) && ( line_count <= end_lin ) ) { int begpos // Position in window of start of line, in pixels = int( ( box_width - max_width ) * bottom_value ) ; int cpos = int( legendFont.getFloatStringWidth ( start_of_line ) + xx + abox.min[0] + begpos ) ; int top = int( abox.min[1] + yy + legendFont.getStringHeight () ) ; int bot = int( abox.min[1] + yy - legendFont.getStringDescender () ) ; if ( ( cpos > abox.min[0] ) && ( cpos < abox.max[0] ) ) { glColor4fv ( colour [ PUCOL_MISC ] ) ; glBegin ( GL_LINES ) ; glVertex2i ( dx + cpos , dy + bot ) ; glVertex2i ( dx + cpos , dy + top ) ; glVertex2i ( dx + cpos - 1, dy + bot ) ; glVertex2i ( dx + cpos - 1, dy + top ) ; glVertex2i ( dx + cpos - 4, dy + bot ) ; glVertex2i ( dx + cpos + 3, dy + bot ) ; glVertex2i ( dx + cpos - 4, dy + top ) ; glVertex2i ( dx + cpos + 3, dy + top ) ; glEnd () ; } } val[ cursor_position ] = temp_char ; } } // Draw the other widgets in the large input box if ( bottom_slider ) bottom_slider->draw ( xwidget, ywidget ) ; right_slider->draw ( xwidget, ywidget ) ; } draw_label ( dx, dy ) ; } int puaLargeInput::checkHit ( int button, int updown, int x, int y ) { int xwidget = x - abox.min[0] ; int ywidget = y - abox.min[1] ; if ( bottom_slider ) { if ( bottom_slider->checkHit ( button, updown, xwidget, ywidget ) ) return TRUE ; } if ( right_slider->checkHit ( button, updown, xwidget, ywidget ) ) return TRUE ; // If the user has clicked within the bottom slider or to its right, don't activate. if ( y < slider_width ) return FALSE ; if ( puObject::checkHit ( button, updown, x, y ) ) return TRUE ; return FALSE ; } void puaLargeInput::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { // Active widget exists and is not this one; call its down callback if it exists puActiveWidget()->invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); if ( button == active_mouse_button ) { // Most GUI's activate a button on button-UP not button-DOWN. // Text and window parameters: int line_size = legendFont.getStringHeight () + // Height of a line legendFont.getStringDescender() + 1 ; // of text, in pixels int box_width = abox.max[0] - abox.min[0] - slider_width ; // Input box width, in pixels // int box_height = ( abox.max[1] - abox.min[1] ) / line_size ; // Input box height, in lines float bottom_value = bottom_slider ? bottom_slider->getFloatValue () : 0.0f ; int beg_pos // Position in window of start of line, in pixels = int( ( box_width - max_width ) * bottom_value ) ; // int end_pos // Position in window of end of line, in pixels // = (int)( beg_pos + max_width - 1 ) ; if ( top_line_in_window < 0 ) top_line_in_window = 0 ; // int end_lin // Position on line count of bottom of window, in lines // = top_line_in_window + box_height - 1 ; // int xx = legendFont.getStringWidth ( " " ) ; int yy = int( abox.max[1] - legendFont.getStringHeight () * 1.5f + top_line_in_window * line_size ) ; // Offset y-coord for unprinted lines // Get the line number and position on the line of the mouse char *strval = bottom_slider ? getStringValue () : getDisplayedText () ; char *tmpval = ulStrDup ( strval ) ; int i = strlen ( tmpval ) ; char *end_of_line = strchr ( tmpval, '\n' ) ; char *start_of_line = tmpval; // Step down the lines until the y-coordinate is less than the mouse int line_count = 0 ; while ( ( yy > y ) && end_of_line ) { line_count++ ; start_of_line = end_of_line + 1 ; yy -= line_size ; end_of_line = strchr ( start_of_line, '\n' ) ; } if ( end_of_line ) { *end_of_line = '\0' ; i = strlen ( tmpval ) ; int length, prev_length = 0 ; while ( x <= (length = legendFont.getStringWidth ( start_of_line ) + abox.min[0] + beg_pos) && i > 0 ) { prev_length = length ; tmpval[--i] = '\0' ; } if ( ( x - length ) < ( prev_length - x ) ) i-- ; // Mouse is closer to previous character than next character } // Now process the mouse click itself. if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN ) { lowlight () ; accepting = TRUE ; cursor_position = i ; normalizeCursors () ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } else if ( updown == PU_DOWN ) { // We get here if the active edge is not down but the mouse button has // been pressed. Start a selection. select_start_position = i ; select_end_position = i ; } else if ( updown == PU_DRAG ) { // Drag -- extend the selection. if ( (select_end_position - i) > (i - select_start_position) ) select_start_position = i ; // Cursor closer to start than to end else select_end_position = i ; // Cursor closer to end than to start if (select_start_position > select_end_position) { i = select_end_position ; select_end_position = select_start_position ; select_start_position = i ; } } else highlight () ; delete [] tmpval ; } else lowlight () ; } int puaLargeInput::checkKey ( int key, int updown ) { if ( updown == PU_UP || !isAcceptingInput () || !isActive () || !isVisible () || ( window != puGetWindow () ) ) return FALSE ; if ( puActiveWidget() && ( this != puActiveWidget() ) ) { // Active widget exists and is not this one; call its down callback if it exists puActiveWidget()->invokeDownCallback () ; puDeactivateWidget () ; } normalizeCursors () ; //char *old_text = getStringValue () ; char *old_text = bottom_slider ? getStringValue () : getDisplayedText () ; int lines_in_window = getLinesInWindow () ; /* Added lines_in_window and num_lines to allow for "END" */ int num_lines = getNumLines () ; /* and PGUP/DOWN to work properly - JCJ 20 Jun 2002 */ int line_width = 0 ; /* Width of current line (for bottomslider) */ int line_width_to_cursor = 0 ; /* Width of current line up to the cursor position */ int prev_line_width = 0 ; /* Width of previous line (for left mouse arrow) */ int i = 1; /* Happy useful variable */ int line_counter = 0 ; /* Happy useful variable #2 */ int box_width = abox.max[0] - abox.min[0] - slider_width ; /* Text box width */ int tmp_cursor_position = cursor_position ; /* Temporary cursor position for counting without moving the cursor */ int bottom_line_in_window = 0; /* # of bottom line in window */ int current_line_in_window = 0; /* Current line # in window */ char *line_end = 0 ; char* p = new char[ strlen(old_text)+1 ] ; float bottom_value = bottom_slider ? bottom_slider->getFloatValue () : 0.0f ; /* Value of the bottom slider */ if ( old_text[1] != '\0' ) /* Ensure that we don't delete something that doesn't exist! - JCJ 22 July 2002 */ { /*Count how many characters from the beginning of the line the cursor is*/ while ( ( old_text [ cursor_position - i ] != '\n' ) && ( i < cursor_position ) ) i++ ; /* Step back to the beginning of the line */ if ( i < cursor_position ) i-- ; /*Find the length of the current line*/ while ( ( old_text [ tmp_cursor_position ] != '\n' ) && ( tmp_cursor_position > 0) ) tmp_cursor_position-- ; strcpy ( p, ( old_text + tmp_cursor_position + 1 ) ) ; if ( bottom_slider ) { line_end = strchr ( p, '\n' ) ; if ( line_end ) // Found an end-of-line { *line_end = '\0' ; // Temporary break in line line_width = int(legendFont.getFloatStringWidth ( p )) ; *line_end = '\n' ; // Reset the carriage return } /*Now delete all characters in the string beyond i, and re-find its width*/ p [i+1] = '\0' ; line_width_to_cursor = int(legendFont.getFloatStringWidth ( p )) ; } /* Now find the length of the previous line */ tmp_cursor_position-- ; while ( ( old_text [ tmp_cursor_position ] != '\n' ) && ( tmp_cursor_position > 0) ) tmp_cursor_position-- ; strcpy ( p, ( old_text + tmp_cursor_position + 1 ) ) ; if ( bottom_slider ) { line_end = strchr ( p, '\n' ) ; if ( line_end ) /*Actually, we KNOW there's a line after this one, but hey, let's be safe, eh? - JCJ 21 Jun 2002 */ { *line_end = '\0' ; // Temporary break in line prev_line_width = legendFont.getStringWidth ( p ) ; *line_end = '\n' ; // Reset the carriage return } } delete [] p ; p = NULL ; } bool done = true ; switch ( key ) { case PU_KEY_PAGE_UP : while ( old_text [ cursor_position ] != '\0' ) /* Move the cursor to the top of the data */ cursor_position-- ; select_start_position = select_end_position = cursor_position ; setTopLineInWindow ( top_line_in_window - lines_in_window + 2 ) ; right_slider->setValue (1.0f - float(top_line_in_window) / num_lines ) ; break; case PU_KEY_PAGE_DOWN : while ( old_text [ cursor_position ] != '\0' ) /* Move the cursor to the end of the data */ cursor_position++ ; select_start_position = select_end_position = cursor_position ; setTopLineInWindow ( top_line_in_window + lines_in_window - 2 ) ; /* Plus two for consistency - JCJ 20 Jun 2002 */ right_slider->setValue (1.0f - float(top_line_in_window) / num_lines ) ; break; case PU_KEY_INSERT : return FALSE ; case PU_KEY_UP : case PU_KEY_DOWN : /* Determine the current line, the line at the top of the window, and the line at the bottom.*/ bottom_line_in_window = top_line_in_window + getLinesInWindow() ; while ( line_counter < cursor_position) { if ( old_text [ line_counter ] == '\n' ) current_line_in_window++ ; line_counter++ ; } if ( key == PU_KEY_UP ) { // Step backwards to the beginning of the previous line cursor_position -= (i + 2) ; while ( ( old_text [ cursor_position ] != '\n' ) && ( cursor_position > 0 ) ) cursor_position-- ; if ( cursor_position > 0 ) cursor_position++ ; // Step down the line "i" spaces or to the end of the line while ( ( old_text [ cursor_position ] != '\n' ) && ( i > 0 ) ) { cursor_position++ ; i-- ; } if (current_line_in_window <= top_line_in_window) { setTopLineInWindow ( top_line_in_window - 1 ); /* Go up - JCJ 21 Jun 2002 */ right_slider->setValue (1.0f - float(top_line_in_window) / num_lines ) ; } } else // Down-arrow key { // Skip to beginning of next line while ( old_text [ cursor_position ] != '\n' && old_text [ cursor_position ] != '\0' ) cursor_position++ ; cursor_position++ ; // Step down the line "i" spaces or to the end of the line // or to the end of the text while ( ( old_text [ cursor_position ] != '\n' ) && ( cursor_position < (int)strlen ( old_text ) ) && ( i > 0 ) ) { cursor_position++ ; i-- ; } if ((current_line_in_window+1) >= bottom_line_in_window) { setTopLineInWindow ( top_line_in_window + 1 ); /* Go down - JCJ 21 Jun 2002 */ right_slider->setValue (1.0f - float(top_line_in_window) / num_lines ) ; } } select_start_position = select_end_position = cursor_position ; break ; case 0x1B : // ESC case '\t' : // TAB -- End of input rejectInput () ; normalizeCursors () ; invokeCallback () ; puDeactivateWidget () ; break ; case PU_KEY_HOME : while ( ( old_text [ cursor_position-1 ] != '\n' ) && ( cursor_position > 0 ) ) /* Move the cursor to the start of the line, but minus one so */ cursor_position-- ; /* it does not find a \n immediately if located at the end. */ select_start_position = select_end_position = cursor_position ; /* Also corrects overshoots. - JCJ 20 Jun 2002 */ if ( bottom_slider ) bottom_slider->setValue ( 0.0f ) ; break ; case PU_KEY_END : if (bottom_slider) { bottom_slider->setValue ( ( (line_width - box_width)<0 ) ? 0.0f : float(line_width+10) / max_width); } while ( old_text [ cursor_position ] != '\n' ) /* Move the cursor to the end of the line - JCJ 20 Jun 2002 */ cursor_position++ ; select_start_position = select_end_position = cursor_position ; break ; case PU_KEY_LEFT : case PU_KEY_RIGHT : if ( key == PU_KEY_LEFT ) { /* This stops it crashing out sometimes when wrappable text is used. * Since there is no bottom scrollbar when wrapped text is turned on, the bottom * slider code could make the application die when the user pressed the left * cursor key before they began the first line. * Fix by Simon */ cursor_position-- ; /* Left key pressed */ if ( bottom_slider ) { if (old_text [ cursor_position ] == '\n') bottom_slider->setValue( ( (prev_line_width - box_width)<0 ) ? 0.0f : float(prev_line_width+10) /max_width); /* If the cursor is going off the left edge of the box, scroll left. */ else if ((bottom_value*max_width) > line_width_to_cursor+5) { bottom_slider->setValue( ((bottom_value*max_width)-(box_width/2)-5)<0 ? 0.0f : ((bottom_value*max_width)-(box_width/2)-5)/max_width ) ; } } } else { cursor_position++ ; /* Right key pressed */ if ( bottom_slider ) { if (old_text [ cursor_position-1 ] == '\n') bottom_slider->setValue(0.0f) ; else if ((bottom_value*max_width)+(box_width) < line_width_to_cursor+5) { bottom_slider->setValue( ((bottom_value*max_width)+(box_width/2)+5)/max_width ) ; } } } select_start_position = select_end_position = cursor_position ; break ; default : done = false ; break ; } if ( ! done && ! input_disabled ) { char *p = NULL ; int temp_cursor = cursor_position ; switch ( key ) { case '\b' : // Backspace if ( select_start_position != select_end_position ) removeSelectRegion () ; else if ( cursor_position > 0 ) { p = new char [ strlen(old_text) ] ; memcpy ( p, old_text, cursor_position ) ; --cursor_position ; strcpy ( p + cursor_position, old_text + cursor_position + 1 ) ; setValue ( p ) ; setCursor ( temp_cursor - 1 ) ; delete [] p ; } break ; case 0x7F : // DEL if ( select_start_position != select_end_position ) removeSelectRegion () ; else if (cursor_position != (int)strlen ( old_text ) ) { p = new char [ strlen(old_text) ] ; memcpy ( p, old_text, cursor_position ) ; strcpy ( p + cursor_position, old_text + cursor_position + 1 ) ; setValue ( p ) ; setCursor ( temp_cursor ) ; delete [] p ; } break ; case 0x15 /* ^U */ : getStringValue () [ 0 ] = '\0' ; break ; case 0x03 /* ^C */ : case 0x18 /* ^X */ : /* Cut or copy selected text */ if ( select_start_position != select_end_position ) { extern void puSetPasteBuffer ( const char *ch ) ; p = getStringValue () ; char ch = p[select_end_position] ; p[select_end_position] = '\0' ; puSetPasteBuffer ( p + select_start_position ) ; p[select_end_position] = ch ; if ( key == 0x18 ) /* Cut, remove text from string */ removeSelectRegion () ; } break ; case 0x16 /* ^V */ : /* Paste buffer into text */ { extern char *puGetPasteBuffer () ; if ( select_start_position != select_end_position ) removeSelectRegion () ; if ( puGetPasteBuffer () ) // Make sure something has been cut previously! { int str_val_len = strlen ( getStringValue () ) ; int paste_len = strlen ( puGetPasteBuffer () ) ; p = new char [ str_val_len + paste_len + 1 ] ; memcpy ( p, getStringValue (), cursor_position ) ; memcpy ( p + cursor_position, puGetPasteBuffer (), paste_len ) ; memcpy ( p + cursor_position + paste_len, getStringValue() + cursor_position, str_val_len - cursor_position + 1 ) ; temp_cursor += paste_len ; setValue ( p ) ; setCursor ( temp_cursor ) ; delete [] p ; } } break ; default: if ( ( key < ' ' || key > 127 ) && ( key != '\n' ) && ( key != '\r' ) ) return FALSE ; if ( key == '\r' ) key = '\n' ; if ( valid_data ) { if ( !strchr ( valid_data, key ) ) return TRUE ; } if ( select_start_position != select_end_position ) // remove selected text { temp_cursor -= ( select_end_position - select_start_position ) ; removeSelectRegion () ; } p = new char [ strlen(old_text) + 2 ] ; memcpy ( p, old_text, cursor_position ) ; p [ cursor_position ] = key ; strcpy ( p + cursor_position + 1, ( old_text + cursor_position ) ) ; bottom_line_in_window = top_line_in_window + getLinesInWindow() ; /* If running off the screen, scroll right. - JCJ 28 Jun 2002 */ if ((bottom_value*max_width)+(box_width) < line_width_to_cursor+5) { bottom_slider->setValue( ((bottom_value*max_width)+(box_width/2)+5)/max_width ) ; } if (key == '\n') { /* If pressing enter, figure out which line this is. */ while ( line_counter < cursor_position) { if ( old_text [ line_counter ] == '\n' ) current_line_in_window++ ; line_counter++ ; } /* If hitting enter at the bottom of the screen, scroll down. - JCJ 28 Jun 2002 */ if ( (current_line_in_window+1) >= bottom_line_in_window ) { setTopLineInWindow ( top_line_in_window + 1 ); right_slider->setValue (1.0f - float(top_line_in_window) / num_lines ) ; } } setValue ( p ) ; setCursor ( temp_cursor + 1 ) ; delete [] p ; break ; } } normalizeCursors () ; return TRUE ; } void puaLargeInput::wrapText ( void ) { // Wrap the text in "text" and put it in "displayed_text" delete [] displayed_text ; displayed_text = ulStrDup ( getStringValue () ) ; char *displayed_text_wp = displayed_text, *space_ptr, *old_space_ptr ; /* Somewhat inspired by tuxracer */ while ( *displayed_text_wp != '\0' ) { old_space_ptr = NULL ; space_ptr = strchr ( displayed_text_wp, ' ' ) ; while (1) { if ( space_ptr != NULL ) *space_ptr = '\0' ; if ( legendFont.getStringWidth ( displayed_text_wp ) > ( ( abox.max[0] - abox.min[0] ) - slider_width - PUSTR_LGAP - ( getStyle () == PUSTYLE_BOXED ? getBorderThickness () : 0 ) - PUSTR_RGAP ) ) break ; old_space_ptr = space_ptr ; if ( space_ptr == NULL ) /* Entire string fits in widget */ break ; // Check for carriage return in the original string if ( strrchr ( displayed_text_wp, '\n' ) > displayed_text_wp ) displayed_text_wp = strrchr ( displayed_text_wp, '\n' ) + 1 ; *space_ptr = ' ' ; space_ptr = strchr ( space_ptr+1, ' ' ) ; } if ( old_space_ptr == NULL ) /* Either string is too wide for area, or the entire remaining portion of string fits in area (space_ptr == NULL). */ { displayed_text_wp += strlen (displayed_text_wp) ; if ( space_ptr != NULL ) /* Advance past the NULL since there's more string left */ displayed_text_wp += 1 ; } else { if ( space_ptr != NULL ) *space_ptr = ' ' ; *old_space_ptr = '\n' ; displayed_text_wp = old_space_ptr + 1 ; } } } plib-1.8.5/src/puAux/puAuxVerticalMenu.cxx0000644000175000001440000001164410765364434015450 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxVerticalMenu.cxx 2022 2005-05-06 18:39:18Z fayjf $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaVerticalMenu,puGroup) extern void puMenuBar_drop_down_the_menu ( puObject *b ); /* If there is only one entry in a vmenu, just act as if clicking the menu clicks the oneshot underneath it. */ void puaVerticalMenu::add_submenu ( const char *str, char *items[], puCallback _cb[], void *_user_data[] ) { int w, h ; getSize ( &w, &h ) ; if (items[1] != NULL) { // More than one entry in the submenu, set the callback to drop down the menu // and make the mouse activation edge up or down. Create the popup menu // and load the items into it. puOneShot *b = new puOneShot ( w+10, 0, str ) ; b -> setStyle ( PUSTYLE_SPECIAL_UNDERLINED ) ; b -> setColourScheme ( colour[PUCOL_FOREGROUND][0], colour[PUCOL_FOREGROUND][1], colour[PUCOL_FOREGROUND][2], colour[PUCOL_FOREGROUND][3] ) ; b -> setCallback ( puMenuBar_drop_down_the_menu ) ; b -> setActiveDirn ( PU_UP_AND_DOWN ) ; puPopupMenu *p = new puPopupMenu ( w+10, 0 ) ; p->setActiveButton ( active_mouse_button ) ; b -> setUserData ( p ) ; if ( _user_data != NULL ) for ( int i = 0 ; items[i] != NULL ; i++ ) p -> add_item ( items[i], _cb[i], _user_data[i] ) ; else for ( int i = 0 ; items[i] != NULL ; i++ ) p -> add_item ( items[i], _cb[i] ) ; p->close () ; } else { // Only one entry in the submenu, set the callback to the entry's callback // and make the mouse activation edge up only. Set the user data to null. puOneShot *b = new puOneShot ( w+10, 0, str ) ; b -> setStyle ( PUSTYLE_SPECIAL_UNDERLINED ) ; b -> setColourScheme ( colour[PUCOL_FOREGROUND][0], colour[PUCOL_FOREGROUND][1], colour[PUCOL_FOREGROUND][2], colour[PUCOL_FOREGROUND][3] ) ; b -> setCallback ( _cb[0] ); b -> setActiveDirn ( PU_UP ) ; b -> setUserData ( NULL ) ; } recalc_bbox () ; } void puaVerticalMenu::close (void) { puGroup::close () ; if ( dlist == NULL ) return ; int height = 0 ; int fullheight; puObject *ob ; // Use alternate objects - which gets the puOneShot/puPopupMenu pairs // If the "puOneShot" has a user data of null, it is a single entry and its // puPopup item is missing. for ( ob = dlist ; ob != NULL ; ob = ob -> getNextObject() ) { int w, h ; // Reposition the button so it looks nice ob -> getSize ( &w, &h ) ; ob -> setPosition ( 0, height ) ; if (ob -> getUserData () ) { ob = ob -> getNextObject() ; // Reposition the submenu so it sits under the button int w2, h2 ; ob -> getSize ( &w2, &h2 ) ; ob -> setPosition ( 0, height-h2 ) ; } // Next please! fullheight = height; height -= h ; } // Now step through the list again, adding the final value of "height" to // all the vertical positions so that the (0,0) point will be the lower left- // hand corner. for ( ob = dlist ; ob != NULL ; ob = ob -> getNextObject() ) { int x, y ; // Reposition the button so it looks nice ob -> getPosition ( &x, &y ) ; ob -> setPosition ( x, y-fullheight ) ; if (ob -> getUserData () ) { ob = ob -> getNextObject() ; // Reposition the submenu so it sits under the button ob -> getPosition ( &x, &y ) ; ob -> setPosition ( x, y-fullheight ) ; } } recalc_bbox () ; // If in its own window (its window number is not the same as its parent's // window number), then resize the window if (window != parent -> getWindow () ) { int temp_window = puGetWindow () ; puSetWindow ( window ) ; puSetWindowSize ( bbox.max[0] - bbox.min[0], bbox.max[1] - bbox.min[1] ) ; setPosition ( 0, 0 ) ; puSetWindow ( temp_window ) ; } } plib-1.8.5/src/puAux/puAuxChooser.cxx0000644000175000001440000000525210765364434014452 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. Copyright (C) 1998,2002,2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxChooser.cxx 1942 2004-08-05 01:03:49Z puggles $ */ #include "puAuxLocal.h" UL_RTTI_DEF(puaChooser) puaChooser::puaChooser ( int _x1, int _y1, int _x2, int _y2, char *legend ) { x1 = _x1 ; x2 = _x2 ; y1 = _y1 ; y2 = _y2 ; chooser_button = new puButton ( x1, y1, x2, y2 ) ; chooser_button->setValue ( FALSE ) ; chooser_button->setLegend ( legend ) ; chooser_button->setUserData ( this ) ; chooser_button->setCallback ( static_popup_cb ) ; popup_menu = new puPopupMenu ( x1, y1 ) ; popup_menu -> setUserData ( this ) ; popup_menu -> setCallback ( static_menu_cb ) ; } void puaChooser::add_item ( char *str, puCallback _cb, void *_user_data ) { popup_menu -> add_item ( str, _cb, _user_data ) ; } void puaChooser::close () { popup_menu -> close () ; // int x, y, w, h ; // popup_menu -> getPosition ( &x, &y ) ; // popup_menu -> getSize ( &w, &h ) ; popup_menu -> setPosition ( x1, y2 ) ; } void puaChooser::popup_cb () { chooser_button -> setValue ( TRUE ) ; if ( popup_menu -> isVisible () ) popup_menu -> hide () ; else popup_menu -> reveal () ; } void puaChooser::menuCleanup ( const char *s ) { popup_menu -> hide () ; chooser_button -> setValue ( FALSE ) ; if ( s != NULL ) chooser_button -> setLegend ( s ) ; } void puaChooser::menuCleanup ( puObject *ob ) { puObject *p = ob -> getParent () ; ((puaChooser*)( p -> getUserData () )) -> menuCleanup ( ob -> getLegend () ) ; } void puaChooser::static_popup_cb ( puObject *ob ) { ((puaChooser*)( ob -> getUserData () )) -> popup_cb () ; } void puaChooser::static_menu_cb ( puObject *ob ) { ((puaChooser*)( ob -> getUserData () )) -> menuCleanup ( (const char *)NULL ) ; } plib-1.8.5/src/puAux/puAux.cxx0000644000175000001440000000205110765364434013121 00000000000000 /* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAux.cxx 1902 2004-03-21 19:03:23Z sjbaker $ */ #include "puAuxLocal.h" void puaInit () { /* Nothing to see here - move along. */ } plib-1.8.5/src/puAux/puAuxFileSelector.cxx0000644000175000001440000004150410765364434015430 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxFileSelector.cxx 1902 2004-03-21 19:03:23Z sjbaker $ */ /**** * NAME * puaFileSelector * * DESCRIPTION * PUI dialog for selecting files * * AUTHOR * Dave McClurg * * CREATION DATE * August 2000 * * MODIFICATION HISTORY * John Fay - many improvements * Steve Baker - moved from FilePicker to FileSelector due to * key API change. ****/ #include "puAuxLocal.h" UL_RTTI_DEF1(puaFileSelector,puDialogBox) #ifdef UL_MSVC #define DOTDOTSLASH "..\\" #define SLASH "\\" #else #define DOTDOTSLASH "../" #define SLASH "/" #endif #define SLASH_LEN 1 static void puaFileSelectorHandleSlider ( puObject * slider ) { float val ; slider -> getValue ( &val ) ; val = 1.0f - val ; puListBox* list_box = (puListBox*) slider -> getUserData () ; int idx = int ( list_box -> getNumItems () * val ) ; list_box -> setTopItem ( idx ) ; } static void puaFileSelectorHandleArrow ( puObject *arrow ) { puSlider *slider = (puSlider *) arrow->getUserData () ; puListBox* list_box = (puListBox*) slider -> getUserData () ; int type = ((puArrowButton *)arrow)->getArrowType() ; int inc = ( type == PUARROW_DOWN ) ? 1 : ( type == PUARROW_UP ) ? -1 : ( type == PUARROW_FASTDOWN ) ? 10 : ( type == PUARROW_FASTUP ) ? -10 : 0 ; float val ; slider -> getValue ( &val ) ; val = 1.0f - val ; int num_items = list_box->getNumItems () - 1 ; if ( num_items > 0 ) { int idx = int ( num_items * val + 0.5f ) + inc ; if ( idx > num_items ) idx = num_items ; if ( idx < 0 ) idx = 0 ; slider -> setValue ( 1.0f - (float)idx / num_items ) ; list_box -> setTopItem ( idx ) ; } } static bool is_slash ( char ch ) { #ifdef UL_WIN32 /* win32 can use back or forward slash */ return ch == '\\' || ch == '/' ; #else return ch == SLASH[0] ; #endif } static void chop_file ( char *fname ) { /* removes everything back to the last '/' */ for ( int i = strlen(fname)-1 ; ! is_slash ( fname[i] ) && i >= 0 ; i-- ) fname[i] = '\0' ; } static void go_up_one_directory ( char *fname ) { /* removes everything back to the last but one '/' */ chop_file ( fname ) ; if ( fname[0] == '\0' ) { /* Empty string! We must be at the root. */ strcpy ( fname, SLASH ) ; return ; } /* Otherwise, just delete the last element of the path. */ /* Remove the trailing slash - then remove the rest as if it was a file name */ fname [ strlen(fname)-1 ] = '\0' ; chop_file ( fname ) ; } void puaFileSelector::input_entered ( puObject* inp ) { puaFileSelector* file_selector = (puaFileSelector*) (inp -> getUserData ()) ; /* If the input selector is empty - do nothing */ if ( inp -> getStringValue() [ 0 ] == '\0' ) return ; if ( ulIsAbsolutePathName ( inp -> getStringValue () ) ) file_selector -> setValue ( inp -> getStringValue () ) ; else { char *s = new char [ strlen ( file_selector->__getStartDir() ) + strlen ( SLASH ) + strlen ( inp -> getStringValue () ) + 1 ] ; ulMakePath ( s, file_selector -> __getStartDir(), inp -> getStringValue () ) ; file_selector -> setValue ( s ) ; delete [] s ; } /* If he typed a valid directory name - then refresh the contents of the browser window */ ulDir *d = ulOpenDir ( file_selector->getStringValue() ) ; ulCloseDir ( d ) ; if ( d != NULL ) file_selector -> find_files () ; } void puaFileSelector::handle_select ( puObject* l_box ) { puaFileSelector* file_selector = (puaFileSelector*) l_box -> getUserData () ; int selected ; l_box -> getValue ( &selected ) ; if ( selected >= 0 && selected < file_selector -> num_files ) { char *dst = file_selector -> getStringValue () ; char *src = file_selector -> files [ selected ] ; chop_file ( dst ) ; if ( strcmp ( src, "[..]" ) == 0 ) { /* Do back up one level - so refresh. */ go_up_one_directory ( dst ) ; file_selector -> find_files () ; file_selector -> __getInput() -> setValue ( dst ) ; return ; } if ( file_selector -> dflag [ selected ] ) { /* If this is a directory - then descend into it and refresh */ src++ ; /* Remove leading '[' */ int dst_len = strlen ( dst ) ; int src_len = strlen ( src ) ; char *new_dst = new char [ dst_len + src_len + 1 ] ; memcpy ( new_dst, dst, dst_len ) ; memcpy ( new_dst + dst_len, src, src_len + 1 ) ; /* Copy trailing '\0' */ /* Replace trailing ']' with slash */ new_dst [ dst_len + src_len - 1 ] = SLASH[0] ; file_selector -> __getInput() -> setValue ( new_dst ) ; file_selector -> setValue ( new_dst ) ; delete [] new_dst ; file_selector -> find_files () ; return ; } /* If this is a regular file - then just append it to the string */ int dst_len = strlen ( dst ) ; int src_len = strlen ( src ) ; char *new_dst = new char [ dst_len + src_len + 1 ] ; memcpy ( new_dst, dst, dst_len ) ; memcpy ( new_dst + dst_len, src, src_len + 1 ) ; /* Copy trailing '\0' */ file_selector -> __getInput() -> setValue ( new_dst ) ; file_selector -> setValue ( new_dst ) ; delete [] new_dst ; } else { /* The user clicked on blank screen - maybe we should refresh just in case some other process created the file. */ file_selector -> find_files () ; } } static void puaFileSelectorHandleCancel ( puObject* b ) { puaFileSelector* file_selector = (puaFileSelector*) b -> getUserData () ; file_selector -> setValue ( "" ) ; file_selector -> invokeCallback () ; } static void puaFileSelectorHandleOk ( puObject* b ) { puaFileSelector* file_selector = (puaFileSelector*) b -> getUserData () ; file_selector -> invokeCallback () ; } void puaFileSelector::setSize ( int w, int h ) { // Resize the frame widget frame->setSize ( w, h ) ; // Resize and position the slider slider->setPosition ( w-30, 40+20*arrow_count ) ; slider->setSize ( 20, h-60-40*arrow_count ) ; // Position the arrow buttons if ( up_arrow ) { up_arrow->setPosition ( w-30, h-20-20*arrow_count ) ; down_arrow->setPosition ( w-30, 20+20*arrow_count ) ; } if ( fastup_arrow ) { fastup_arrow->setPosition ( w-30, h-40 ) ; fastdown_arrow->setPosition ( w-30, 40 ) ; } // Resize the list box list_box->setSize ( w-40, h-80 ) ; // Resoze and position the buttons cancel_button->setSize ( (w<170)?(w/2-15):70, 20 ) ; ok_button->setSize ( (w<170)?(w/2-15):70, 20 ) ; ok_button->setPosition ( (w<170)?(w/2+5):90, 10 ) ; } puaFileSelector::~puaFileSelector () { delete [] startDir ; if ( files != NULL ) { for ( int i=0; i 2 ) arrows = 2 ; if ( arrows < 0 ) arrows = 0 ; arrow_count = arrows ; frame = new puFrame ( 0, 0, w, h ); slider = new puSlider (w-30,40+20*arrows,h-60-40*arrows,TRUE,20); slider->setValue(1.0f); slider->setSliderFraction (0.2f) ; slider->setCBMode( PUSLIDER_DELTA ); list_box = new puListBox ( 10, 60, w-40, h-20 ) ; list_box -> setLabel ( title ); list_box -> setLabelPlace ( PUPLACE_TOP_LEFT ) ; list_box -> setStyle ( -PUSTYLE_SMALL_SHADED ) ; list_box -> setUserData ( this ) ; list_box -> setCallback ( handle_select ) ; list_box -> setValue ( 0 ) ; find_files () ; handle_select ( list_box ) ; slider -> setUserData ( list_box ) ; slider -> setCallback ( puaFileSelectorHandleSlider ) ; input = new puInput ( 10, 40, w-40, 60 ) ; input -> setValue ( startDir ) ; input -> setUserData ( this ) ; input -> setCallback ( input_entered ) ; input -> setDownCallback ( input_entered ) ; cancel_button = new puOneShot ( 10, 10, (w<170)?(w/2-5):80, 30 ) ; cancel_button -> setLegend ( "Cancel" ) ; cancel_button -> setUserData ( this ) ; cancel_button -> setCallback ( puaFileSelectorHandleCancel ) ; ok_button = new puOneShot ( (w<170)?(w/2+5):90, 10, (w<170)?(w-10):160, 30 ) ; ok_button -> setLegend ( "Ok" ) ; ok_button -> setUserData ( this ) ; ok_button -> setCallback ( puaFileSelectorHandleOk ) ; up_arrow = down_arrow = NULL ; fastup_arrow = fastdown_arrow = NULL ; if ( arrows > 0 ) { down_arrow = new puArrowButton ( w-30, 20+20*arrows, w-10, 40+20*arrows, PUARROW_DOWN ) ; down_arrow->setUserData ( slider ) ; down_arrow->setCallback ( puaFileSelectorHandleArrow ) ; up_arrow = new puArrowButton ( w-30, h-20-20*arrows, w-10, h-20*arrows, PUARROW_UP ) ; up_arrow->setUserData ( slider ) ; up_arrow->setCallback ( puaFileSelectorHandleArrow ) ; } if ( arrows == 2 ) { fastdown_arrow = new puArrowButton ( w-30, 40, w-10, 60, PUARROW_FASTDOWN ) ; fastdown_arrow->setUserData ( slider ) ; fastdown_arrow->setCallback ( puaFileSelectorHandleArrow ) ; fastup_arrow = new puArrowButton ( w-30, h-40, w-10, h-20, PUARROW_FASTUP ) ; fastup_arrow->setUserData ( slider ) ; fastup_arrow->setCallback ( puaFileSelectorHandleArrow ) ; } close () ; reveal () ; } static int puaFileSelectorStringCompare ( const char *s1, const char *s2, const char f1, const char f2 ) { if ( f1 > f2 ) /* Directories before regular files. */ return -1 ; if ( f1 < f2 ) return 1 ; while ( 1 ) { char c1 = s1? (*s1++): 0 ; char c2 = s2? (*s2++): 0 ; //end of string? if ( !c1 || !c2 ) { if ( c1 ) return 1 ; //s1 is longer if ( c2 ) return -1 ; //s1 is shorter return 0 ; } if ( c1 == c2 ) continue ; /* Windoze users are case-insensitive - so they presumably want case ignored in the sorting. UNIX users, however, do things like calling their makefiles 'Makefile' so as to force them to the start of the directory listing. */ #ifdef UL_MSVC if ( c1 >= 'a' && c1 <= 'z' ) c1 = c1 - ('a'-'A') ; if ( c2 >= 'a' && c2 <= 'z' ) c2 = c2 - ('a'-'A') ; #endif if ( c1 != c2 ) { if ( c1 < c2 ) return -1 ; return 1 ; } } return 0 ; } void puaFileSelector::setInitialValue ( const char *s ) { if ( ulIsAbsolutePathName ( s ) ) { input -> setValue ( s ) ; input -> invokeCallback () ; } else { int str_val_len = strlen ( input->getStringValue () ) ; int s_len = strlen ( s ) ; char *s_new = new char [ str_val_len + s_len + 1 ] ; memcpy ( s_new, input->getStringValue (), str_val_len ) ; memcpy ( s_new + str_val_len, s, s_len + 1 ) ; /* Plus one to get the final '\0' */ input->setValue ( s_new ) ; delete [] s_new ; input -> invokeCallback () ; } } static void puaFileSelectorSort ( char** list, char *flags, int size ) // // comb sort - a modified bubble sort // taken from BYTE, April 1991, ppg 315-320 // { int switches ; int gap = size ; do { gap = ((gap * 197) >> 8); // gap /= 1.3; switch (gap) { case 0: // the smallest gap is 1 -- bubble sort gap = 1; break; case 9: // this is what makes this Combsort11 case 10: gap = 11; break; } switches = 0 ; // dirty pass flag int top = size - gap; for ( int i=0; i 0 ) { char* temp = list[i] ; list[i] = list[j] ; list[j] = temp ; char tmp2 = flags[i] ; flags[i] = flags[j] ; flags[j] = tmp2 ; ++switches; } } } while ( switches || gap > 1 ) ; } void puaFileSelector::find_files ( void ) { if ( files != NULL ) { for ( int i = 0 ; i < num_files ; i++ ) delete [] files[i] ; delete [] files ; delete [] dflag ; } num_files = 0 ; int str_val_len = strlen ( getStringValue () ) ; if ( ! is_slash ( getStringValue () [ str_val_len - 1 ] ) ) /* Someone forgot a trailing '/' */ { char *new_dir = new char [ str_val_len + SLASH_LEN + 1 ] ; memcpy ( new_dir, getStringValue (), str_val_len ) ; memcpy ( new_dir + str_val_len, SLASH, SLASH_LEN + 1 ) ; /* Plus one to include the trailing '\0' */ setValue ( new_dir ) ; delete [] new_dir ; } int ifile = 0 ; char *dir = getStringValue () ; ulDir *dirp = ulOpenDir ( dir ) ; ulDirEnt *dp ; if ( dirp == NULL ) { perror ("puaFileSelector") ; ulSetError ( UL_WARNING, "PUI:puaFileSelector - can't open directory '%s'", dir ) ; num_files = 0 ; return ; } /* Count the number of files - skipping "." */ while ( ( dp = ulReadDir(dirp) ) != NULL ) if ( strcmp ( dp->d_name, "." ) != 0 ) ifile++ ; ulCloseDir ( dirp ) ; num_files = ifile ; if ( num_files > 5 ) slider -> setDelta ( 0.5f / num_files ) ; else slider -> setDelta ( 0.1f ) ; if ( num_files == 0 ) { ulSetError ( UL_WARNING, "PUI:puaFileSelector - no entries in directory '%s'?!", dir ) ; return ; } files = new char* [ num_files+1 ] ; dflag = new char [ num_files+1 ] ; dirp = ulOpenDir ( dir ) ; if ( dirp == NULL ) { perror ("puaFileSelector") ; ulSetError ( UL_WARNING, "PUI:puaFileSelector - can't re-open directory '%s'", dir ) ; num_files = 0 ; return ; } ifile = 0 ; while ( (dp = ulReadDir(dirp)) != NULL && ifile < num_files ) { /* Skip over the "." entry... */ if ( strcmp ( dp->d_name, "." ) != 0 ) { dflag[ ifile ] = dp->d_isdir ; int name_len = strlen ( dp->d_name ) ; if ( dflag[ ifile ] ) { files[ ifile ] = new char[ name_len + 3 ] ; files [ ifile ] [ 0 ] = '[' ; memcpy ( files [ ifile ] + 1, dp->d_name, name_len ) ; strcpy ( files [ ifile ] + 1 + name_len, "]" ) ; } else { files[ ifile ] = new char[ name_len + 1 ] ; memcpy ( files [ ifile ], dp->d_name, name_len + 1 ) ; /* Plus one to include the final '\0' */ } ifile++ ; } } files [ ifile ] = NULL ; ulCloseDir ( dirp ) ; puaFileSelectorSort( files, dflag, num_files ) ; list_box -> newList ( files ) ; } plib-1.8.5/src/puAux/puAuxBiSlider.cxx0000644000175000001440000001146510765364434014550 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. Copyright (C) 1998,2002,2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxBiSlider.cxx 2022 2005-05-06 18:39:18Z fayjf $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaBiSlider,puSlider) void puaBiSlider::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; // Draw the slider box itself if ( ( style == PUSTYLE_BEVELLED ) || ( style == PUSTYLE_SHADED ) ) abox.draw ( dx, dy, -PUSTYLE_BOXED, colour, FALSE, 2 ) ; else abox.draw ( dx, dy, -style, colour, FALSE, border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { // Draw the current_max slider and label it float val ; if ( getMaxValue() > getMinValue() ) val = (float)(getCurrentMax() - getMinValue()) / (float)(getMaxValue() - getMinValue()) ; else val = 1.0f ; char str_value[10] ; sprintf (str_value, "%g", getCurrentMax() ) ; draw_slider_box ( dx, dy, abox, val, str_value ) ; // Draw the current_min slider and label it if ( getMaxValue() > getMinValue() ) val = (float)(getCurrentMin() - getMinValue()) / (float)(getMaxValue() - getMinValue()) ; else val = 0.0f ; sprintf (str_value, "%g", getCurrentMin() ) ; draw_slider_box ( dx, dy, abox, val, str_value ) ; draw_legend ( dx, dy ) ; } draw_label ( dx, dy ) ; } void puaBiSlider::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); if ( ( button == active_mouse_button ) && ( updown == PU_UP ) ) { setActiveButton ( 0 ) ; puDeactivateWidget () ; return ; } if ( button == active_mouse_button ) { int sd = isVertical() ; int sz = abox.max [sd] - abox.min [sd] ; int coord = isVertical() ? y : x ; float next_value ; if ( sz == 0 ) next_value = 0.5f ; else { next_value = ( (float)coord - (float)abox.min[sd] - (float)sz * slider_fraction / 2.0f ) / ( (float) sz * (1.0f - slider_fraction) ) ; } next_value = (next_value < 0.0f) ? 0.0f : (next_value > 1.0) ? 1.0f : next_value ; float new_value = getMinValue() + next_value * ( getMaxValue() - getMinValue() ) ; if ( ( getActiveButton() == 0 ) || ( updown == PU_DOWN ) ) // No currently-active slider, set whichever is closest { if ( (new_value-getCurrentMin()) < (getCurrentMax()-new_value) ) // Closest to current_min { setCurrentMin ( checkStep(new_value) ) ; setActiveButton ( 1 ) ; } else // Closest to current_max { setCurrentMax ( checkStep(new_value) ) ; setActiveButton ( 2 ) ; } } else if ( getActiveButton() == 1 ) // Currently moving current_min { setCurrentMin ( checkStep(new_value) ) ; if ( getCurrentMax() < getCurrentMin() ) setCurrentMax ( getCurrentMin() ) ; } else if ( getActiveButton() == 2 ) // Currently moving current_max { setCurrentMax ( checkStep(new_value) ) ; if ( getCurrentMax() < getCurrentMin() ) setCurrentMin ( getCurrentMax() ) ; } switch ( cb_mode ) { case PUSLIDER_CLICK : if ( updown == active_mouse_edge ) { last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_DELTA :/* Deprecated! */ if ( fabs ( last_cb_value - next_value ) >= cb_delta ) { last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_ALWAYS : default : last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; break ; } } } plib-1.8.5/src/puAux/Makefile.am0000644000175000001440000000205310765364434013331 00000000000000if BUILD_PUAUX lib_LIBRARIES = libplibpuaux.a include_HEADERS = puAux.h puAuxLocal.h libplibpuaux_a_SOURCES = puAux.cxx \ puAuxBiSlider.cxx \ puAuxBiSliderWithEnds.cxx \ puAuxComboBox.cxx \ puAuxCompass.cxx \ puAuxFileSelector.cxx \ puAuxLargeInput.cxx \ puAuxList.cxx \ puAuxScrollBar.cxx \ puAuxSelectBox.cxx \ puAuxSliderWithInput.cxx \ puAuxSpinBox.cxx \ puAuxTriSlider.cxx \ puAuxVerticalMenu.cxx \ puAuxChooser.cxx INCLUDES = -I$(top_srcdir)/src/sg \ -I$(top_srcdir)/src/pui \ -I$(top_srcdir)/src/fnt \ -I$(top_srcdir)/src/util endif EXTRA_DIST = puAux.dsp plib-1.8.5/src/puAux/puAuxBiSliderWithEnds.cxx0000644000175000001440000000611110765364434016206 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. Copyright (C) 1998,2002,2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxBiSliderWithEnds.cxx 2076 2006-04-13 16:20:23Z bram $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaBiSliderWithEnds,puGroup) void puaBiSliderWithEnds::handle_slider ( puObject *obj ) { puaBiSliderWithEnds *bisl = (puaBiSliderWithEnds *)obj->getUserData () ; bisl->__setMax ( ((puaBiSlider *)obj)->getCurrentMax () ) ; bisl->__setMin ( ((puaBiSlider *)obj)->getCurrentMin () ) ; bisl->invokeCallback () ; } void puaBiSliderWithEnds::handle_max ( puObject *obj ) { puaBiSliderWithEnds *bisl = (puaBiSliderWithEnds *)obj->getUserData () ; bisl->setCurrentMax ( obj->getFloatValue () ) ; bisl->invokeCallback () ; } void puaBiSliderWithEnds::handle_min ( puObject *obj ) { puaBiSliderWithEnds *bisl = (puaBiSliderWithEnds *)obj->getUserData () ; bisl->setCurrentMin ( obj->getFloatValue () ) ; bisl->invokeCallback () ; } puaBiSliderWithEnds::puaBiSliderWithEnds ( int minx, int miny, int maxx, int maxy ) : puGroup ( minx, miny ) { type |= PUCLASS_BISLIDERWITHENDS ; slider = new puaBiSlider ( (maxx - minx)/2-10, 22, maxy-miny-44, TRUE ) ; min_box = new puInput ( 0, 0, maxx-minx, 20 ) ; max_box = new puInput ( 0, maxy-miny-20, maxx-minx, maxy-miny ) ; min_box->setValue ( 0 ) ; max_box->setValue ( 1 ) ; slider->setUserData ( this ) ; slider->setCallback ( handle_slider ) ; max_box->setUserData ( this ) ; max_box->setCallback ( handle_max ) ; min_box->setUserData ( this ) ; min_box->setCallback ( handle_min ) ; close () ; } void puaBiSliderWithEnds::setSize ( int w, int h ) { slider->setSize ( 20, h-44 ) ; slider->setPosition ( w/2-10, 22 ) ; min_box->setSize ( w, 20 ) ; max_box->setSize ( w, 20 ) ; max_box->setPosition ( 0, h-20 ) ; } void puaBiSliderWithEnds::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; draw_label ( dx, dy ) ; puGroup::draw ( dx, dy ) ; } int puaBiSliderWithEnds::checkKey ( int key, int updown ) { if ( ! isVisible () || ! isActive () || ( window != puGetWindow () ) ) return FALSE ; return ( max_box->checkKey ( key, updown ) + min_box->checkKey ( key, updown ) ) ; } plib-1.8.5/src/puAux/puAux.dsp0000644000175000001440000001031510765364434013107 00000000000000# Microsoft Developer Studio Project File - Name="puAux" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=puAux - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "puAux.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "puAux.mak" CFG="puAux - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "puAux - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "puAux - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "puAux - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\fnt" /I "..\sg" /I "..\util" /I ".." /I "..\pui" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "PU_USE_NONE" /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy puAux.h ..\..\puAux.h # End Special Build Tool !ELSEIF "$(CFG)" == "puAux - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\fnt" /I "..\sg" /I "..\util" /I ".." /I "..\pui" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "PU_USE_NONE" /FR /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\puAux_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy puAux.h ..\..\puAux.h # End Special Build Tool !ENDIF # Begin Target # Name "puAux - Win32 Release" # Name "puAux - Win32 Debug" # Begin Source File SOURCE=.\puAux.cxx # End Source File # Begin Source File SOURCE=.\puAux.h # End Source File # Begin Source File SOURCE=.\puAuxBiSlider.cxx # End Source File # Begin Source File SOURCE=.\puAuxBiSliderWithEnds.cxx # End Source File # Begin Source File SOURCE=.\puAuxComboBox.cxx # End Source File # Begin Source File SOURCE=.\puAuxCompass.cxx # End Source File # Begin Source File SOURCE=.\puAuxFileSelector.cxx # End Source File # Begin Source File SOURCE=.\puAuxLargeInput.cxx # End Source File # Begin Source File SOURCE=.\puAuxList.cxx # End Source File # Begin Source File SOURCE=.\puAuxLocal.h # End Source File # Begin Source File SOURCE=.\puAuxScrollBar.cxx # End Source File # Begin Source File SOURCE=.\puAuxSelectBox.cxx # End Source File # Begin Source File SOURCE=.\puAuxSliderWithInput.cxx # End Source File # Begin Source File SOURCE=.\puAuxSpinBox.cxx # End Source File # Begin Source File SOURCE=.\puAuxTriSlider.cxx # End Source File # Begin Source File SOURCE=.\puAuxVerticalMenu.cxx # End Source File # End Target # End Project plib-1.8.5/src/puAux/puAuxLocal.h0000644000175000001440000000005410765364434013522 00000000000000 #define PU_USE_NONE 1 #include "puAux.h" plib-1.8.5/src/puAux/puAuxTriSlider.cxx0000644000175000001440000001513610765364434014753 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. Copyright (C) 1998,2002,2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxTriSlider.cxx 2022 2005-05-06 18:39:18Z fayjf $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaTriSlider,puaBiSlider) void puaTriSlider::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; // Draw the slider box itself if ( ( style == PUSTYLE_BEVELLED ) || ( style == PUSTYLE_SHADED ) ) abox.draw ( dx, dy, -PUSTYLE_BOXED, colour, FALSE, 2 ) ; else abox.draw ( dx, dy, -style, colour, FALSE, border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { // Draw the central slider and label it float val; if ( getMaxValue() > getMinValue() ) val = (float)(getFloatValue () - getMinValue()) / (float)(getMaxValue() - getMinValue()) ; else val = 0.5f ; char str_value[10] ; sprintf (str_value, "%g", getFloatValue () ) ; draw_slider_box ( dx, dy, abox, val, str_value ) ; if ( val < 0.0f ) val = 0.0f ; if ( val > 1.0f ) val = 1.0f ; // Draw the current_max slider and label it if ( getMaxValue() > getMinValue() ) val = (float)(getCurrentMax() - getMinValue()) / (float)(getMaxValue() - getMinValue()) ; else val = 1.0f ; sprintf (str_value, "%g", getCurrentMax() ) ; draw_slider_box ( dx, dy, abox, val, str_value ) ; // Draw the current_min slider and label it if ( getMaxValue() > getMinValue() ) val = (float)(getCurrentMin() - getMinValue()) / (float)(getMaxValue() - getMinValue()) ; else val = 0.0f ; sprintf (str_value, "%g", getCurrentMin() ) ; draw_slider_box ( dx, dy, abox, val, str_value ) ; draw_legend ( dx, dy ) ; } draw_label ( dx, dy ) ; } void puaTriSlider::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) { puMoveToLast ( this ); /* Bug Fixed: If you moved a slider while dragging the mouse (click and drag), then move */ /* the cursor outside of the widget and released the mouse button, the active_button would */ /* be locked to the last slider you moved, and unable to release. - JCJ 11 June 2002 */ setActiveButton ( 0 ) ; } if ( ( button == active_mouse_button ) && ( updown == PU_UP ) ) { setActiveButton ( 0 ) ; puDeactivateWidget () ; return ; } if ( button == active_mouse_button ) { int sd = isVertical() ; int sz = abox.max [sd] - abox.min [sd] ; int coord = isVertical() ? y : x ; float next_value ; if ( sz == 0 ) next_value = 0.5f ; else { next_value = ( (float)coord - (float)abox.min[sd] - (float)sz * slider_fraction / 2.0f ) / ( (float) sz * (1.0f - slider_fraction) ) ; } next_value = (next_value < 0.0f) ? 0.0f : (next_value > 1.0) ? 1.0f : next_value ; float new_value = getMinValue() + next_value * ( getMaxValue() - getMinValue() ) ; if ( getFreezeEnds() ) // Cannot move end sliders, must move middle one { setActiveButton ( 2 ) ; setValue ( checkStep(new_value) ) ; /* Ensure that the middle slider can't move beyond the barriers - JCJ 10 Jun 2002 */ if ( new_value < getCurrentMin() ) setValue ( getCurrentMin() ) ; if ( new_value > getCurrentMax() ) setValue ( getCurrentMax() ) ; } else { if ( getActiveButton() == 0 ) // No currently-active slider, set whichever is closest { if ( (new_value-getCurrentMin()) < (getFloatValue()-new_value) ) // Closest to current_min { setCurrentMin ( checkStep(new_value) ) ; setActiveButton ( 1 ) ; } else if ( (new_value-getFloatValue()) > (getCurrentMax()-new_value) ) // Closest to current_max { setCurrentMax ( checkStep(new_value) ) ; setActiveButton ( 3 ) ; } else // closest to the center slider -- ties go to the center slider { setValue ( checkStep(new_value) ) ; setActiveButton ( 2 ) ; } } else if ( getActiveButton() == 1 ) // Currently moving current_min { setCurrentMin ( checkStep(new_value) ) ; if ( getFloatValue() < getCurrentMin() ) setValue ( getCurrentMin() ) ; if ( getCurrentMax() < getCurrentMin() ) setCurrentMax ( getCurrentMin() ) ; } else if ( getActiveButton() == 2 ) // Currently moving central value { setValue ( checkStep(new_value) ) ; if ( getCurrentMin() > new_value ) setCurrentMin ( new_value ) ; if ( getCurrentMax() < new_value ) setCurrentMax ( new_value ) ; } else if ( getActiveButton() == 3 ) // Currently moving current_max { setCurrentMax ( checkStep(new_value) ) ; if ( getFloatValue() > getCurrentMax() ) setValue ( getCurrentMax() ) ; if ( getCurrentMax() < getCurrentMin() ) setCurrentMin ( getCurrentMax() ) ; } } switch ( cb_mode ) { case PUSLIDER_CLICK : if ( updown == active_mouse_edge ) { last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_DELTA :/* Deprecated! */ if ( fabs ( last_cb_value - next_value ) >= cb_delta ) { last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_ALWAYS : default : last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; break ; } } } plib-1.8.5/src/puAux/puAuxList.cxx0000644000175000001440000001554210765364434013766 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. Copyright (C) 1998,2002,2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxList.cxx 2088 2006-10-16 08:11:16Z bram $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaList,puGroup) // puAuxList.cxx - implementation of a scrolling list box. #include "puAux.h" /** * Static function: handle slider movements. */ static void handle_slider (puObject * slider) { puListBox * list_box = (puListBox *)slider->getUserData(); int total = list_box->getNumItems(); int visible = list_box->getNumVisible(); // negative numbers are OK -- setTopItem() clamps anyway int index = int((total - visible) * (1.0 - slider->getFloatValue())); list_box->setTopItem(index); } /** * Static function: handle list entry selection. */ static void handle_list_entry (puObject * listbox) { puaList * box = (puaList *)listbox->getUserData(); box->invokeCallback(); } /** * Static function: handle arrow clicks. */ static void handle_arrow (puObject * arrow) { puSlider * slider = (puSlider *)arrow->getUserData(); puListBox * list_box = (puListBox *)slider->getUserData(); puaList * list = (puaList *)list_box->getUserData(); int step; switch (((puArrowButton *)arrow)->getArrowType()) { case PUARROW_DOWN: step = 1; break; case PUARROW_UP: step = -1; break; default: step = 0; break; } int index = list->getTopItem(); list->setTopItem(index + step); slider->setValue(1.0f - float(list->getTopItem()) / (list->getNumItems() - list->getNumVisible())); } /* Create an empty list box. */ puaList::puaList (int x, int y, int w, int h, int sl_width) : puGroup(x, y), _sw(sl_width) { type |= PUCLASS_LIST; init(w, h, 1); } /* Create a filled list box. */ puaList::puaList (int x, int y, int w, int h, char ** contents, int sl_width) : puGroup(x, y), _sw(sl_width) { type |= PUCLASS_LIST; init(w, h, 1); newList(contents); } /* Create an empty list box. */ puaList::puaList (int x, int y, int w, int h, short transparent, int sl_width) : puGroup(x, y), _sw(sl_width) { type |= PUCLASS_LIST; init(w, h, transparent); } /* Create a filled list box. */ puaList::puaList (int x, int y, int w, int h, short transparent, char ** contents, int sl_width) : puGroup(x, y), _sw(sl_width) { type |= PUCLASS_LIST; init(w, h, transparent); newList(contents); } puaList::~puaList () { } void puaList::newList (char ** contents) { _list_box->newList(contents); _contents = contents; // new size calculation to consider slider visibility setSize(_width, _height); } void puaList::setTopItem (int item_index) { _list_box->setTopItem(item_index); item_index = _list_box->getTopItem(); // read clamped value back in, and only set slider if it doesn't match the new // index to avoid jumps int slider_index = int((1.0f - _slider->getFloatValue()) * (getNumItems() - getNumVisible())); if (slider_index != item_index) _slider->setValue(1.0f - float(getTopItem()) / (getNumItems() - getNumVisible())); } /* * Return a pointer to a character string with the * contents of the selected entry. */ char * puaList::getStringValue () { int currElem = _list_box->getIntegerValue(); if (currElem < 0) { return NULL; } else { return _contents[currElem]; } } /* * Set a pointer to a character string with the * contents of the selected entry */ void puaList::getValue(char **ps) { int currElem = _list_box->getIntegerValue(); if (currElem < 0) { *ps = NULL; } else { *ps = _contents[currElem]; } } /* * Set the integer pointed to by "i" to * the index of the currently selected entry. */ void puaList::getValue(int *i) { *i = _list_box->getIntegerValue(); } /* Return the index of the currently selected entry. */ int puaList::getIntegerValue() { return _list_box->getIntegerValue(); } void puaList::setColourScheme (float r, float g, float b, float a) { puObject::setColourScheme(r, g, b, a); _list_box->setColourScheme(r, g, b, a); } void puaList::setColour (int which, float r, float g, float b, float a) { puObject::setColour(which, r, g, b, a); _list_box->setColour(which, r, g, b, a); } void puaList::setSize (int w, int h) { _width = w; _height = h; puObject::setSize(w, h); if (_frame) _frame->setSize(w, h); int total = getNumItems(); int visible = getNumVisible(); if (total > visible) { if (!_slider->isVisible()) { _slider->setValue(1.0f); _slider->reveal(); _up_arrow->reveal(); _down_arrow->reveal(); } _list_box->setSize(w-_sw, h); _slider->setPosition(w-_sw, _sw); _slider->setSize(_sw, h-2*_sw); _slider->setSliderFraction(float(visible) / total); _down_arrow->setPosition(w-_sw, 0); _up_arrow->setPosition(w-_sw, h-_sw); } else { if (_slider->isVisible()) { _slider->hide(); _up_arrow->hide(); _down_arrow->hide(); } _list_box->setSize(w, h); } } void puaList::init (int w, int h, short transparent) { if ( transparent ) _frame = NULL ; else _frame = new puFrame(0, 0, w, h); _list_box = new puListBox(0, 0, w-_sw, h); _list_box->setStyle(-PUSTYLE_SMALL_SHADED); _list_box->setUserData(this); _list_box->setCallback(handle_list_entry); _list_box->setValue(0); _slider = new puSlider(w-_sw, _sw, h-2*_sw, true, _sw); _slider->setValue(1.0f); _slider->setUserData(_list_box); _slider->setCallback(handle_slider); _slider->setCBMode(PUSLIDER_ALWAYS); _down_arrow = new puArrowButton(w-_sw, 0, w, _sw, PUARROW_DOWN) ; _down_arrow->setUserData(_slider); _down_arrow->setCallback(handle_arrow); _up_arrow = new puArrowButton(w-_sw, h-_sw, w, h, PUARROW_UP); _up_arrow->setUserData(_slider); _up_arrow->setCallback(handle_arrow); setSize(w, h); close(); } // end of puAuxList.cxx plib-1.8.5/src/puAux/puAuxSliderWithInput.cxx0000644000175000001440000000534710765364434016153 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. Copyright (C) 1998,2002,2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxSliderWithInput.cxx 1902 2004-03-21 19:03:23Z sjbaker $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaSliderWithInput,puGroup) void puaSliderWithInput::handle_slider ( puObject *obj ) { puaSliderWithInput *sl = (puaSliderWithInput *)obj->getUserData () ; sl->setValue ( obj->getFloatValue () ) ; sl->__setInputBox ( obj->getFloatValue () ) ; sl->invokeCallback () ; } void puaSliderWithInput::handle_input ( puObject *obj ) { puaSliderWithInput *sl = (puaSliderWithInput *)obj->getUserData () ; sl->setValue ( obj->getFloatValue () ) ; sl->invokeCallback () ; } puaSliderWithInput::puaSliderWithInput ( int minx, int miny, int maxx, int maxy, int above ) : puGroup ( minx, miny ) { type |= PUCLASS_SLIDERWITHINPUT ; slider = new puSlider ( (maxx - minx)/2-10, above ? 0 : 20, maxy-miny-20, TRUE ) ; input_box = new puInput ( 0, above ? maxy - miny - 20 : 0, maxx-minx, above ? maxy - miny : 20 ) ; input_box->setValue ( 0 ) ; slider->setUserData ( this ) ; slider->setCallback ( handle_slider ) ; input_box->setUserData ( this ) ; input_box->setCallback ( handle_input ) ; close () ; input_position = above ; } void puaSliderWithInput::setSize ( int w, int h ) { slider->setSize ( 20, h-40 ) ; slider->setPosition ( w/2-10, input_position ? 0 : 20 ) ; input_box->setSize ( w, 20 ) ; input_box->setPosition ( 0, input_position ? h-20 : 0 ) ; } void puaSliderWithInput::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; draw_label ( dx, dy ) ; puGroup::draw ( dx, dy ) ; } int puaSliderWithInput::checkKey ( int key, int updown ) { if ( ! isVisible () || ! isActive () || ( window != puGetWindow () ) ) return FALSE ; return ( input_box->checkKey ( key, updown ) ) ; } plib-1.8.5/src/puAux/Makefile.in0000644000175000001440000004416610765365023013350 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/puAux DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibpuaux_a_AR = $(AR) $(ARFLAGS) libplibpuaux_a_LIBADD = am__libplibpuaux_a_SOURCES_DIST = puAux.cxx puAuxBiSlider.cxx \ puAuxBiSliderWithEnds.cxx puAuxComboBox.cxx puAuxCompass.cxx \ puAuxFileSelector.cxx puAuxLargeInput.cxx puAuxList.cxx \ puAuxScrollBar.cxx puAuxSelectBox.cxx puAuxSliderWithInput.cxx \ puAuxSpinBox.cxx puAuxTriSlider.cxx puAuxVerticalMenu.cxx \ puAuxChooser.cxx @BUILD_PUAUX_TRUE@am_libplibpuaux_a_OBJECTS = puAux.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxBiSlider.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxBiSliderWithEnds.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxComboBox.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxCompass.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxFileSelector.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxLargeInput.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxList.$(OBJEXT) puAuxScrollBar.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxSelectBox.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxSliderWithInput.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxSpinBox.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxTriSlider.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxVerticalMenu.$(OBJEXT) \ @BUILD_PUAUX_TRUE@ puAuxChooser.$(OBJEXT) libplibpuaux_a_OBJECTS = $(am_libplibpuaux_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libplibpuaux_a_SOURCES) DIST_SOURCES = $(am__libplibpuaux_a_SOURCES_DIST) am__include_HEADERS_DIST = puAux.h puAuxLocal.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_PUAUX_TRUE@lib_LIBRARIES = libplibpuaux.a @BUILD_PUAUX_TRUE@include_HEADERS = puAux.h puAuxLocal.h @BUILD_PUAUX_TRUE@libplibpuaux_a_SOURCES = puAux.cxx \ @BUILD_PUAUX_TRUE@ puAuxBiSlider.cxx \ @BUILD_PUAUX_TRUE@ puAuxBiSliderWithEnds.cxx \ @BUILD_PUAUX_TRUE@ puAuxComboBox.cxx \ @BUILD_PUAUX_TRUE@ puAuxCompass.cxx \ @BUILD_PUAUX_TRUE@ puAuxFileSelector.cxx \ @BUILD_PUAUX_TRUE@ puAuxLargeInput.cxx \ @BUILD_PUAUX_TRUE@ puAuxList.cxx \ @BUILD_PUAUX_TRUE@ puAuxScrollBar.cxx \ @BUILD_PUAUX_TRUE@ puAuxSelectBox.cxx \ @BUILD_PUAUX_TRUE@ puAuxSliderWithInput.cxx \ @BUILD_PUAUX_TRUE@ puAuxSpinBox.cxx \ @BUILD_PUAUX_TRUE@ puAuxTriSlider.cxx \ @BUILD_PUAUX_TRUE@ puAuxVerticalMenu.cxx \ @BUILD_PUAUX_TRUE@ puAuxChooser.cxx @BUILD_PUAUX_TRUE@INCLUDES = -I$(top_srcdir)/src/sg \ @BUILD_PUAUX_TRUE@ -I$(top_srcdir)/src/pui \ @BUILD_PUAUX_TRUE@ -I$(top_srcdir)/src/fnt \ @BUILD_PUAUX_TRUE@ -I$(top_srcdir)/src/util EXTRA_DIST = puAux.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/puAux/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/puAux/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibpuaux.a: $(libplibpuaux_a_OBJECTS) $(libplibpuaux_a_DEPENDENCIES) -rm -f libplibpuaux.a $(libplibpuaux_a_AR) libplibpuaux.a $(libplibpuaux_a_OBJECTS) $(libplibpuaux_a_LIBADD) $(RANLIB) libplibpuaux.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxBiSlider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxBiSliderWithEnds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxChooser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxComboBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxCompass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxFileSelector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxLargeInput.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxScrollBar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxSelectBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxSliderWithInput.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxSpinBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxTriSlider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puAuxVerticalMenu.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/puAux/puAuxSelectBox.cxx0000644000175000001440000001257010765364434014741 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxSelectBox.cxx 2084 2006-05-02 16:28:07Z bram $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaSelectBox,puGroup) void puaSelectBox::handle_arrow ( puObject *arrow ) { puaSelectBox *selbox = (puaSelectBox *) arrow -> getUserData () ; int arrow_type = ((puArrowButton*) arrow) -> getArrowType () ; if ( arrow_type == PUARROW_DOWN ) selbox -> setCurrentItem ( selbox -> getCurrentItem () - 1 ) ; else if ( arrow_type == PUARROW_UP ) selbox -> setCurrentItem ( selbox -> getCurrentItem () + 1 ) ; } void puaSelectBox::update_widgets ( void ) { if ( curr_item >= 0 ) /* There are some items */ { setValue ( list[curr_item] ) ; input->setValue( list[curr_item] ); if ( curr_item == 0 ) /* Current item is first item, deactivate 'down' button */ down_arrow -> greyOut () ; else down_arrow -> activate () ; if ( curr_item == (num_items - 1) ) /* Current item is last item, deactivate 'up' button */ up_arrow -> greyOut () ; else up_arrow -> activate () ; } else /* There aren't any items */ { setValue ( "" ) ; down_arrow -> greyOut () ; up_arrow -> greyOut () ; } } void puaSelectBox::newList ( char ** _list ) { list = _list ; if ( list == NULL ) num_items = 0 ; else { for ( num_items = 0 ; list[num_items] != NULL ; num_items++ ) /* Count number of items */ ; } curr_item = ( num_items > 0 ? 0 : - 1 ) ; update_widgets () ; } void puaSelectBox::setSize ( int w, int h ) { int arrow_size = h / 2 ; /* Resize the puInput widget */ input -> setSize ( w - arrow_size, h ) ; /* Resize and reposition the arrow buttons */ down_arrow -> setPosition ( w - arrow_size, 0 ) ; down_arrow -> setSize ( arrow_size, arrow_size ) ; up_arrow -> setPosition ( w - arrow_size, arrow_size ) ; up_arrow -> setSize ( arrow_size, arrow_size ) ; } void puaSelectBox::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; draw_label ( dx, dy ) ; puGroup::draw ( dx, dy ) ; } int puaSelectBox::checkKey ( int key, int updown ) { if ( updown == PU_UP || ! input -> isAcceptingInput () || ! isVisible () || ! isActive () || ( window != puGetWindow () ) ) return FALSE ; switch ( key ) { case PU_KEY_HOME : setCurrentItem ( 0 ) ; break ; case PU_KEY_END : setCurrentItem ( num_items - 1 ) ; break ; case PU_KEY_UP : case PU_KEY_PAGE_UP : setCurrentItem ( curr_item + 1 ) ; break ; case PU_KEY_DOWN : case PU_KEY_PAGE_DOWN : setCurrentItem ( curr_item - 1 ) ; break ; default : /* We might decide to make the input box editable on request in future - and it does not hurt ... */ return input -> checkKey ( key, updown ) ; break ; } return TRUE ; } void puaSelectBox::setColourScheme ( float r, float g, float b, float a ) { puObject::setColourScheme ( r, g, b, a ) ; setChildColourScheme( PUCLASS_INPUT, colour [ PUCOL_EDITFIELD ][0], colour [ PUCOL_EDITFIELD ][1], colour [ PUCOL_EDITFIELD ][2], colour [ PUCOL_EDITFIELD ][3] ) ; } void puaSelectBox::setColour ( int which, float r, float g, float b, float a ) { if (which == PUCOL_EDITFIELD) input->setColourScheme ( r, g, b, a ) ; else puObject::setColour ( which, r, g, b, a ) ; } puaSelectBox::puaSelectBox ( int minx, int miny, int maxx, int maxy, char **entries ) : puGroup( minx, miny ) { type |= PUCLASS_SELECTBOX ; char *stringval ; int arrow_size = (maxy - miny) / 2 ; input = new puInput ( 0, 0, maxx-minx - arrow_size, maxy-miny ) ; input -> setStyle ( PUSTYLE_SMALL_SHADED ) ; input -> disableInput () ; /* Share 'string' value with input box */ input -> getValue ( &stringval ) ; setValuator ( stringval ) ; down_arrow = new puArrowButton ( maxx-minx - arrow_size, 0, maxx-minx, arrow_size, PUARROW_DOWN ) ; down_arrow -> setStyle ( PUSTYLE_SMALL_SHADED ) ; down_arrow -> setUserData ( this ) ; down_arrow -> setCallback ( handle_arrow ) ; up_arrow = new puArrowButton ( maxx-minx - arrow_size, arrow_size, maxx-minx, maxy-miny, PUARROW_UP ) ; up_arrow -> setStyle ( PUSTYLE_SMALL_SHADED ) ; up_arrow -> setUserData ( this ) ; up_arrow -> setCallback ( handle_arrow ) ; newList ( entries ) ; close () ; } plib-1.8.5/src/puAux/puAuxSpinBox.cxx0000644000175000001440000000716010765364434014432 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. Copyright (C) 1998,2002,2004 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxSpinBox.cxx 1902 2004-03-21 19:03:23Z sjbaker $ */ #include "puAuxLocal.h" UL_RTTI_DEF2(puaSpinBox,puRange,puGroup) puaSpinBox::puaSpinBox ( int minx, int miny, int maxx, int maxy, int arrow_pos ) : puRange ( 1.0f, 10.0f, 1.0f ), puGroup ( minx, miny ) { extern void puaSpinBox_handle_input ( puObject* ob ) ; extern void puaSpinBox_handle_input_active ( puObject* ob ) ; extern void puaSpinBox_handle_arrow ( puObject* ob ) ; type |= PUCLASS_SPINBOX ; arrow_position = arrow_pos ; int arrow_size = ( maxy - miny ) / 2 ; if ( arrow_pos == 1 ) input_box = new puInput ( 0, 0, maxx - minx - arrow_size, maxy - miny ) ; else input_box = new puInput ( arrow_size, 0, maxx - minx, maxy - miny ) ; input_box->setCallback ( puaSpinBox_handle_input ) ; input_box->setActiveCallback ( puaSpinBox_handle_input_active ) ; input_box->setDownCallback ( puaSpinBox_handle_input ) ; input_box->setUserData ( this ) ; up_arrow = new puArrowButton ( arrow_position?maxx-minx-arrow_size:0, arrow_size, arrow_position?maxx-minx:arrow_size, maxy-miny, PUARROW_UP ) ; up_arrow->setCallback ( puaSpinBox_handle_arrow ) ; up_arrow->setUserData ( this ) ; down_arrow = new puArrowButton ( arrow_position?maxx-minx-arrow_size:0, 0, arrow_position?maxx-minx:arrow_size, arrow_size, PUARROW_DOWN ) ; down_arrow->setCallback ( puaSpinBox_handle_arrow ) ; down_arrow->setUserData ( this ) ; close () ; } void puaSpinBox_handle_arrow ( puObject *ob ) { puaSpinBox *master = (puaSpinBox *)(ob->getUserData ()) ; float val = master->getFloatValue () ; if ( ((puArrowButton *)ob)->getArrowType () == PUARROW_UP ) val += master->getStepSize () ; else val -= master->getStepSize () ; if ( val > master->getMaxValue () ) val = master->getMaxValue () ; if ( val < master->getMinValue () ) val = master->getMinValue () ; master->setValue ( val ) ; master->invokeCallback () ; } void puaSpinBox_handle_input ( puObject *ob ) { puaSpinBox *master = (puaSpinBox *)(ob->getUserData ()) ; float val = ob->getFloatValue () ; if ( val > master->getMaxValue () ) val = master->getMaxValue () ; if ( val < master->getMinValue () ) val = master->getMinValue () ; master->setValue ( val ) ; master->invokeCallback () ; } void puaSpinBox_handle_input_active ( puObject *ob ) { puaSpinBox *master = (puaSpinBox *)(ob->getUserData ()) ; float val = ob->getFloatValue () ; if ( val > master->getMaxValue () ) val = master->getMaxValue () ; if ( val < master->getMinValue () ) val = master->getMinValue () ; master->setValue ( val ) ; master->invokeActiveCallback () ; } plib-1.8.5/src/puAux/puAux.h0000644000175000001440000007030710765364434012557 00000000000000/* PUI Auxiliary Widget Library Derived from PLIB, the Portable Game Library by Steve Baker. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAux.h 2094 2006-10-26 20:48:04Z fayjf $ */ #ifndef _PUI_AUX_WIDGETS_H_ #define _PUI_AUX_WIDGETS_H_ 1 #include "pu.h" // Widget Class Bit Patterns // PUI classes take up 0x00000001 through 0x00020000 #define PUCLASS_FILESELECTOR 0x00040000 /* Because FilePicker is obsolete */ #define PUCLASS_BISLIDER 0x00080000 #define PUCLASS_TRISLIDER 0x00100000 #define PUCLASS_VERTMENU 0x00200000 #define PUCLASS_LARGEINPUT 0x00400000 #define PUCLASS_COMBOBOX 0x00800000 #define PUCLASS_SELECTBOX 0x01000000 #define PUCLASS_SPINBOX 0x02000000 #define PUCLASS_SCROLLBAR 0x04000000 #define PUCLASS_BISLIDERWITHENDS 0x08000000 #define PUCLASS_SLIDERWITHINPUT 0x10000000 #define PUCLASS_COMPASS 0x20000000 #define PUCLASS_CHOOSER 0x40000000 #define PUCLASS_LIST 0x80000000 // Widget Declarations class puaSpinBox ; class puaFileSelector ; class puaBiSlider ; class puaTriSlider ; class puaVerticalMenu ; class puaLargeInput ; class puaComboBox ; class puaSelectBox ; class puaScrollBar ; class puaBiSliderWithEnds ; class puaCompass ; class puaSliderWithInput ; class puaChooser ; class puaList ; // A File selector widget class puaFileSelector : public puDialogBox { UL_TYPE_DATA protected: char** files ; char* dflag ; int num_files ; int arrow_count ; char *startDir ; void find_files ( void ) ; static void handle_select ( puObject* ) ; static void input_entered ( puObject* ) ; puFrame *frame ; puListBox *list_box ; puSlider *slider ; puOneShot *cancel_button ; puOneShot *ok_button ; puInput *input ; puArrowButton *up_arrow ; puArrowButton *down_arrow ; puArrowButton *fastup_arrow ; puArrowButton *fastdown_arrow ; void puaFileSelectorInit ( int x, int y, int w, int h, int arrows, const char *dir, const char *title ) ; public: puaFileSelector ( int x, int y, int w, int h, int arrows, const char *dir, const char *title = "Pick a file" ) : puDialogBox ( x, y ) { puaFileSelectorInit ( x, y, w, h, arrows, dir, title ) ; } puaFileSelector ( int x, int y, int w, int h, const char *dir, const char *title = "Pick a file" ) : puDialogBox ( x, y ) { puaFileSelectorInit ( x, y, w, h, 1, dir, title ) ; } puaFileSelector ( int x, int y, int arrows, const char *dir, const char *title = "Pick a file" ) : puDialogBox ( x, y ) { puaFileSelectorInit ( x, y, 220, 170, arrows, dir, title ) ; } puaFileSelector ( int x, int y, const char *dir, const char *title = "Pick a file" ) : puDialogBox ( x, y ) { puaFileSelectorInit ( x, y, 220, 170, 1, dir, title ) ; } ~puaFileSelector () ; /* Not for application use!! */ puInput *__getInput ( void ) const { return input ; } char *__getStartDir ( void ) const { return (char *) startDir ; } void setInitialValue ( const char *fname ) ; void setSize ( int w, int h ) ; } ; // An input box that takes an arbitrary number of lines of input class puaLargeInput : public puInputBase, public puGroup { UL_TYPE_DATA protected: int num_lines ; // Number of lines of text in the box int lines_in_window ; // Number of lines showing in the window int top_line_in_window ; // Number of the first line in the window float max_width ; // Width of longest line of text in box, in pixels int slider_width ; puFrame *frame ; puSlider *bottom_slider ; // Horizontal slider at bottom of window puaScrollBar *right_slider ; // Vertical slider at right of window int arrow_count ; // Number of up/down arrows above and below the right slider void normalizeCursors ( void ) ; void removeSelectRegion ( void ) ; void wrapText ( void ) ; public: puaLargeInput ( int x, int y, int w, int h, int arrows, int sl_width, int wrap_text = FALSE ) ; ~puaLargeInput () { if ( puActiveWidget() == this ) puDeactivateWidget () ; } void setSize ( int w, int h ) ; int getNumLines ( void ) const { return num_lines ; } int getLinesInWindow ( void ) const { return lines_in_window ; } void setTopLineInWindow ( int val ) { top_line_in_window = (val<0) ? 0 : ( (val>num_lines-2) ? num_lines-2 : val ) ; } void draw ( int dx, int dy ) ; int checkHit ( int button, int updown, int x, int y ) ; void doHit ( int button, int updown, int x, int y ) ; int checkKey ( int key, int updown ) ; void setSelectRegion ( int s, int e ) ; void selectEntireLine ( void ) ; void invokeDownCallback ( void ) { rejectInput () ; normalizeCursors () ; if ( down_cb != NULL ) (*down_cb)(this) ; } void setValue ( const char *s ) ; void setText ( const char *l ) { setValue ( l ) ; } /* DEPRECATED */ char *getText ( void ) { return getStringValue () ; } /* DEPRECATED */ void addNewLine ( const char *l ) ; void addText ( const char *l ) ; void appendText ( const char *l ) ; void removeText ( int start, int end ) ; char *getDisplayedText ( void ) { return ( displayed_text == NULL ? getStringValue () : displayed_text ) ; } char *getWrappedText ( void ) // THIS FUNCTION IS DEPRECATED 3/21/06 { return getDisplayedText () ; } } ; // A box that contains a set of alternatives that drop down when the user clicks on the down-arrow // Defined constants telling how the callback got triggered. This is needed for // cases in which the user has deleted the entry in the input box and wants that // entry deleted from the list of items. #define PUACOMBOBOX_CALLBACK_NONE 0 #define PUACOMBOBOX_CALLBACK_INPUT 1 #define PUACOMBOBOX_CALLBACK_ARROW 2 class puaComboBox : public puGroup { UL_TYPE_DATA protected: char ** list ; int num_items ; int curr_item ; puInput *input ; puArrowButton *arrow_btn ; puPopupMenu *popup_menu ; int callback_source ; static void input_cb ( puObject *inp ) ; static void input_active_cb ( puObject *inp ) ; static void input_down_cb ( puObject *inp ) ; static void handle_arrow ( puObject *arrow ) ; static void handle_popup ( puObject *popupm ) ; void update_widgets ( void ) ; void update_current_item ( void ) ; void setCallbackSource ( int s ) { callback_source = s ; } public: /* Not for application use ! */ puPopupMenu * __getPopupMenu ( void ) const { return popup_menu ; } void newList ( char ** _list ) ; int getNumItems ( void ) const { return num_items ; } char *getNewEntry ( void ) const { return input->getStringValue () ; } int getCurrentItem ( void ) ; void setCurrentItem ( int item ) { if ( ( item >= 0 ) && ( item < num_items ) ) { curr_item = item ; update_widgets () ; callback_source = PUACOMBOBOX_CALLBACK_ARROW ; invokeCallback () ; } } void setCurrentItem ( const char *item_ptr ) ; void setPosition ( int x, int y ) { puGroup::setPosition ( x, y ) ; /* Ensure that popup menu will show up at the right place */ newList ( list ) ; } void setSize ( int w, int h ) ; void setValue ( float f ) { puValue::setValue ( f ) ; input->setValue ( f ) ; } void setValue ( int i ) { puValue::setValue ( i ) ; input->setValue ( i ) ; } void setValue ( const char *s ) { puValue::setValue ( s ) ; input->setValue ( s ) ; } void setValue ( puValue *pv ) { puValue::setValue ( pv ) ; input->setValue ( pv ) ; } void draw ( int dx, int dy ) ; int checkHit ( int button, int updown, int x, int y ) ; int checkKey ( int key, int updown ) ; int getCallbackSource ( void ) const { return callback_source ; } virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ; virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) ; puaComboBox ( int minx, int miny, int maxx, int maxy, char **list, int editable = TRUE ) ; ~puaComboBox () { int i ; for ( i = 0; i < num_items; i++ ) delete [] list[i] ; delete [] list ; } } ; // Like a menu bar, but the selections are one above the other class puaVerticalMenu : public puGroup { UL_TYPE_DATA protected: public: puaVerticalMenu ( int x = -1, int y = -1 ) : puGroup ( x < 0 ? puGetWindowWidth() - ( puGetDefaultLegendFont().getStringWidth ( " " ) + PUSTR_TGAP + PUSTR_BGAP ) : x, y < 0 ? puGetWindowHeight() - ( puGetDefaultLegendFont().getStringHeight () + PUSTR_TGAP + PUSTR_BGAP ) : y) { type |= PUCLASS_VERTMENU ; floating = TRUE ; // DEPRECATED! -- we need to replace this code. if ( y < 0 ) { setVStatus( TRUE ) ; } /* It is now supposed to stick to the top left - JCJ*/ } void add_submenu ( const char *str, char *items[], puCallback _cb[], void *_user_data[] = NULL ) ; void close ( void ) ; } ; // Not sure what this one does ... class puaSelectBox : public puGroup { UL_TYPE_DATA protected: char ** list ; int num_items ; int curr_item ; puInput *input ; puArrowButton *down_arrow ; puArrowButton *up_arrow ; static void handle_arrow ( puObject *arrow ) ; void update_widgets ( void ) ; public: void newList ( char ** _list ) ; int getNumItems ( void ) const { return num_items ; } int getCurrentItem ( void ) const { return curr_item ; } void setCurrentItem ( int item ) { if ( ( item >= 0 ) && ( item < num_items ) ) { curr_item = item ; update_widgets () ; invokeCallback () ; } } void setSize ( int w, int h ) ; void draw ( int dx, int dy ) ; int checkKey ( int key, int updown ) ; virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ; virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) ; puaSelectBox ( int minx, int miny, int maxx, int maxy, char **list ) ; } ; // A slider with up- and down-arrows on its ends class puaScrollBar : public puSlider { UL_TYPE_DATA protected: int arrow_count ; int fast_up_arrow_active, fast_down_arrow_active ; int up_arrow_active, down_arrow_active ; public: void doHit ( int button, int updown, int x, int y ) ; void draw ( int dx, int dy ) ; puaScrollBar ( int minx, int miny, int sz, int arrows, int vertical = FALSE ) : puSlider ( minx, miny, sz, vertical ) { type |= PUCLASS_SCROLLBAR ; arrow_count = arrows ; fast_up_arrow_active = fast_down_arrow_active = up_arrow_active = down_arrow_active = FALSE ; } /* Alternate constructor which lets you explicitly set width */ puaScrollBar ( int minx, int miny, int sz, int arrows, int vertical, int width ) : puSlider ( minx, miny, sz, vertical, width ) { type |= PUCLASS_SCROLLBAR ; arrow_count = arrows ; fast_up_arrow_active = fast_down_arrow_active = up_arrow_active = down_arrow_active = FALSE ; } void setMaxValue ( float f ) { maximum_value = f ; slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ; puPostRefresh () ; } void setMinValue ( float i ) { minimum_value = i ; slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ; puPostRefresh () ; } } ; // A puSlider with two slide boxes instead of one class puaBiSlider : public puSlider { UL_TYPE_DATA protected: float current_max ; float current_min ; int active_button ; // Zero for none, one for min, two for max public: void doHit ( int button, int updown, int x, int y ) ; void draw ( int dx, int dy ) ; puaBiSlider ( int minx, int miny, int sz, int vertical = FALSE ) : puSlider ( minx, miny, sz, vertical ) { type |= PUCLASS_BISLIDER ; setMaxValue ( 1.0f ) ; setMinValue ( 0.0f ) ; setStepSize ( 1.0f ) ; current_max = 1.0f ; current_min = 0.0f ; active_button = 0 ; } /* Alternate constructor which lets you explicitly set width */ puaBiSlider ( int minx, int miny, int sz, int vertical, int width ) : puSlider ( minx, miny, sz, vertical, width ) { type |= PUCLASS_BISLIDER ; setMaxValue ( 1.0f ) ; setMinValue ( 0.0f ) ; setStepSize ( 1.0f ) ; current_max = 1.0f ; current_min = 0.0f ; active_button = 0 ; } void setMaxValue ( float i ) { maximum_value = i ; slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ; puPostRefresh () ; } void setMinValue ( float i ) { minimum_value = i ; slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ; puPostRefresh () ; } void setCurrentMax ( int i ) { current_max = (float) i ; puPostRefresh () ; } /* DEPRECATED */ void setCurrentMax ( float f ) { current_max = f ; puPostRefresh () ; } float getCurrentMax ( void ) const { return current_max ; } void setCurrentMin ( int i ) { current_min = (float) i ; puPostRefresh () ; } /* DEPRECATED */ void setCurrentMin ( float f ) { current_min = f ; puPostRefresh () ; } float getCurrentMin ( void ) const { return current_min ; } void setActiveButton ( int i ) { active_button = i ; } int getActiveButton ( void ) const { return active_button ; } } ; // A puSlider with three slide boxes class puaTriSlider : public puaBiSlider { UL_TYPE_DATA protected: // "active_button" is now zero for none, one for min, two for middle, three for max int freeze_ends ; // true to make end sliders unmovable public: void doHit ( int button, int updown, int x, int y ) ; void draw ( int dx, int dy ) ; puaTriSlider ( int minx, int miny, int sz, int vertical = FALSE ) : puaBiSlider ( minx, miny, sz, vertical ) { type |= PUCLASS_TRISLIDER ; freeze_ends = TRUE ; } /* Alternate constructor which lets you explicitly set width */ puaTriSlider ( int minx, int miny, int sz, int vertical, int width ) : puaBiSlider ( minx, miny, sz, vertical, width ) { type |= PUCLASS_TRISLIDER ; freeze_ends = TRUE ; } int getFreezeEnds ( void ) const { return freeze_ends ; } void setFreezeEnds ( int val ) { freeze_ends = val ; puPostRefresh () ; } } ; // A vertical puBiSlider with a puInput box above it showing the current maximum // value and a puInput box below it showing the current minimum value class puaBiSliderWithEnds : public puGroup { UL_TYPE_DATA protected: puaBiSlider *slider ; puInput *max_box ; puInput *min_box ; static void handle_slider ( puObject *obj ) ; static void handle_max ( puObject *obj ) ; static void handle_min ( puObject *obj ) ; static void input_down_callback ( puObject *obj ) ; void update_widgets ( void ) ; public: // For internal use only: void __setMax ( float f ) { max_box->setValue ( f ) ; } void __setMin ( float f ) { min_box->setValue ( f ) ; } // For public use: void draw ( int dx, int dy ) ; int checkHit ( int button, int updown, int x, int y ) { return puGroup::checkHit ( button, updown, x, y ) ; } int checkKey ( int key, int updown ) ; puaBiSliderWithEnds ( int minx, int miny, int maxx, int maxy ) ; void setSize ( int w, int h ) ; void setMaxValue ( float f ) { slider->setMaxValue ( f ) ; } float getMaxValue ( void ) const { return slider->getMaxValue () ; } void setMinValue ( float f ) { slider->setMinValue ( f ) ; } float getMinValue ( void ) const { return slider->getMinValue () ; } void setCurrentMax ( float f ) { slider->setCurrentMax ( f ) ; max_box->setValue ( f ) ; } float getCurrentMax ( void ) const { return slider->getCurrentMax () ; } void setCurrentMin ( float f ) { slider->setCurrentMin ( f ) ; min_box->setValue ( f ) ; } float getCurrentMin ( void ) const { return slider->getCurrentMin () ; } void setActiveButton ( int i ) { slider->setActiveButton ( i ) ; } int getActiveButton ( void ) const { return slider->getActiveButton () ; } char *getValidData ( void ) const { return max_box->getValidData () ; } void setValidData ( char *data ) { max_box->setValidData ( data ) ; min_box->setValidData ( data ) ; } void addValidData ( char *data ) { max_box->addValidData ( data ) ; min_box->addValidData ( data ) ; } void setCBMode ( int m ) { slider->setCBMode ( m ) ; } int getCBMode ( void ) const { return slider->getCBMode () ; } void setDelta ( float f ) { slider->setDelta ( f ) ; } float getDelta ( void ) const { return slider->getDelta () ; } float getStepSize ( void ) const { return slider->getStepSize () ; } void setStepSize ( float f ) { slider->setStepSize ( f ) ; } } ; // A vertical puSlider with a puInput box above or below it showing its value class puaSliderWithInput : public puGroup { UL_TYPE_DATA protected: puSlider *slider ; puInput *input_box ; int input_position ; static void handle_slider ( puObject *obj ) ; static void handle_input ( puObject *obj ) ; static void input_down_callback ( puObject *obj ) ; void update_widgets ( void ) ; public: // For internal use only: void __setInputBox ( float f ) { input_box->setValue ( f ) ; } // For public use: void draw ( int dx, int dy ) ; int checkHit ( int button, int updown, int x, int y ) { return puGroup::checkHit ( button, updown, x, y ) ; } int checkKey ( int key, int updown ) ; puaSliderWithInput ( int minx, int miny, int maxx, int maxy, int above = 0 ) ; void setSize ( int w, int h ) ; void setMaxValue ( float f ) { slider->setMaxValue ( f ) ; } float getMaxValue ( void ) const { return slider->getMaxValue () ; } void setMinValue ( float f ) { slider->setMinValue ( f ) ; } float getMinValue ( void ) const { return slider->getMinValue () ; } void setValue ( int i ) { slider->setValue ( i ) ; input_box->setValue ( i ) ; } void setValue ( float f ) { slider->setValue ( f ) ; input_box->setValue ( f ) ; } virtual void setValue ( const char *s ) { slider->setValue ( s ) ; } virtual void setValue ( bool b ) { slider->setValue ( b ) ; } int getIntegerValue ( void ) { return slider->getIntegerValue () ; } float getFloatValue ( void ) { return slider->getFloatValue () ; } char getCharValue ( void ) { return slider->getCharValue () ; } char *getStringValue ( void ) { return slider->getStringValue () ; } bool getBooleanValue ( void ) { return slider->getBooleanValue () ; } char *getValidData ( void ) const { return input_box->getValidData () ; } void setValidData ( char *data ) { input_box->setValidData ( data ) ; } void addValidData ( char *data ) { input_box->addValidData ( data ) ; } void setCBMode ( int m ) { slider->setCBMode ( m ) ; } int getCBMode ( void ) const { return slider->getCBMode () ; } void setDelta ( float f ) { slider->setDelta ( f ) ; } float getDelta ( void ) const { return slider->getDelta () ; } float getStepSize ( void ) const { return slider->getStepSize () ; } void setStepSize ( float f ) { slider->setStepSize ( f ) ; } } ; class puaSpinBox : public puRange, public puGroup { UL_TYPE_DATA protected : puInput *input_box ; puArrowButton *up_arrow ; puArrowButton *down_arrow ; int arrow_position ; public : /* Whether the arrows are on the LEFT of the input box (0) or RIGHT (1 DEFAULT) */ int getArrowPosition ( void ) const { return arrow_position ; } /* Offered as a proportion of the input box height. Default = 0.5 */ void setArrowHeight ( float height ) { puBox ibox = *(input_box->getABox()) ; int size = int(height * ( ibox.max[1] - ibox.min[1] )) ; up_arrow->setSize ( size, size ) ; down_arrow->setSize ( size, size ) ; int xpos = getArrowPosition () ? ibox.max[0] : ibox.min[0] - size ; int ymid = ( ibox.max[1] + ibox.min[1] ) / 2 ; if ( getArrowPosition () == 0 ) /* Arrows are on the left, adjust the x-position of the input box */ { ibox.min[0] -= xpos ; input_box->setPosition ( ibox.min[0], ibox.min[1] ) ; abox.min[0] += xpos ; xpos = 0 ; } if ( height > 0.5f ) /* Adjust the input box to be up from the bottom */ { input_box->setPosition ( ibox.min[0], ibox.min[1] + size - ymid ) ; abox.min[1] += ymid - size ; ymid = size ; } else /* Input box is at the bottom of the group area */ { input_box->setPosition ( ibox.min[0], 0 ) ; abox.min[1] += ibox.min[1] ; } up_arrow->setPosition ( xpos, ymid ) ; down_arrow->setPosition ( xpos, ymid - size ) ; recalc_bbox() ; } float getArrowHeight ( void ) const { int awid, ahgt, iwid, ihgt ; input_box->getSize ( &iwid, &ihgt ) ; up_arrow->getSize ( &awid, &ahgt ) ; return float(ahgt) / float(ihgt) ; } puaSpinBox ( int minx, int miny, int maxx, int maxy, int arrow_pos = 1 ) ; void setValue ( float f ) { puValue::setValue ( f ) ; input_box->setValue ( f ) ; } void setValue ( int i ) { puValue::setValue ( i ) ; input_box->setValue ( i ) ; } void setValue ( const char *s ) { puValue::setValue ( s ) ; input_box->setValue ( s ) ; } void setValue ( puValue *pv ) { puValue::setValue ( pv ) ; input_box->setValue ( pv ) ; } } ; /* * Widget that looks like a 3-d coordinate system with quarter-circles in the coordinate planes. * It is used in 3-d modeling to translate and rotate the scene. The coordinates rotate with * the scene but do not translate. Defined values are: * 0 - Nothing active * 1 - Dot at origin active: reset (usually) * 2 - X-axis dot active: rotate about y- and z-axes * 3 - Y-axis dot active: rotate about z- and x-axes * 4 - Z-axis dot active: rotate about x- and y-axes * 5 - X-axis bar active: translate along x-axis * 6 - Y-axis bar active: translate along y-axis * 7 - Z-axis bar active: translate along z-axis * 8 - XY-plane arc active: rotate about z-axis * 9 - YZ-plane arc active: rotate about x-axis * 10 - ZX-plane arc active: rotate about y-axis * 11 - X-axis, Y-axis, and XY-arc active: translate in xy-plane * 12 - Y-axis, Z-axis, and YZ-arc active: translate in yz-plane * 13 - Z-axis, X-axis, and ZX-arc active: translate in zx-plane */ #define PUACOMPASS_INACTIVE 0 #define PUACOMPASS_RESET 1 #define PUACOMPASS_ROTATE_Y_Z 2 #define PUACOMPASS_ROTATE_Z_X 3 #define PUACOMPASS_ROTATE_X_Y 4 #define PUACOMPASS_TRANSLATE_X 5 #define PUACOMPASS_TRANSLATE_Y 6 #define PUACOMPASS_TRANSLATE_Z 7 #define PUACOMPASS_ROTATE_Z 8 #define PUACOMPASS_ROTATE_X 9 #define PUACOMPASS_ROTATE_Y 10 #define PUACOMPASS_TRANSLATE_X_Y 11 #define PUACOMPASS_TRANSLATE_Y_Z 12 #define PUACOMPASS_TRANSLATE_Z_X 13 class puaCompass : public puObject { UL_TYPE_DATA protected : sgQuat rotation ; sgVec3 translation ; float point_size ; int button_state ; int trigger_button ; float mouse_x, mouse_y, mouse_z ; float translation_sensitivity ; float xint, yint, zint ; float prev_angle ; sgQuat prev_rotation ; public : puaCompass ( int minx, int miny, int maxx, int maxy ) : puObject ( minx, miny, maxx, maxy ) { setValue ( PUACOMPASS_INACTIVE ) ; // sgSetQuat ( rotation, 1.0f, 0.0f, 0.0f, 0.0f ) ; // sgSetQuat ( rotation, 0.707107f, 0.707107f, 0.0f, 0.0f ) ; // sgSetQuat ( rotation, 0.5f, -0.5f, 0.5f, 0.5f ) ; // sgSetQuat ( rotation, 0.866025f, -0.166667f, 0.166667f, 0.166667f ) ; sgSetQuat ( rotation, 0.866025f, -0.408248f, 0.288675f, 0.0f ) ; sgSetVec3 ( translation, 0.0f, 0.0f, 0.0f ) ; point_size = 10.0f ; button_state = PU_UP ; trigger_button = active_mouse_button ; mouse_x = mouse_y = mouse_z = 0.0f ; translation_sensitivity = 1.0f ; xint = yint = zint = 0.0f ; prev_angle = 0.0f ; sgCopyQuat ( prev_rotation, rotation ) ; } void draw ( int dx, int dy ) ; void doHit ( int button, int updown, int x, int y ) ; // Accessors and mutators void getRotation ( sgQuat q ) const { memcpy ( q, rotation, 4 * sizeof(sgFloat) ) ; } void setRotation ( sgQuat q ) { memcpy ( rotation, q, 4 * sizeof(sgFloat) ) ; } void setRotation ( sgFloat t, sgFloat x, sgFloat y, sgFloat z ) { sgFloat sinth = sgSin ( t / 2.0f ) ; sgFloat norm = sgSqrt ( x * x + y * y + z * z ) ; if ( norm == 0.0 ) norm = 1.0 ; rotation[SG_W] = sgCos ( t / 2.0f ) ; rotation[SG_X] = sinth * x / norm ; rotation[SG_Y] = sinth * y / norm ; rotation[SG_Z] = sinth * z / norm ; } void getTranslation ( sgVec3 t ) const { memcpy ( t, translation, 3 * sizeof(sgFloat) ) ; } void setTranslation ( sgVec3 t ) { memcpy ( translation, t, 3 * sizeof(sgFloat) ) ; } void setTranslation ( sgFloat x, sgFloat y, sgFloat z ) { translation[SG_X] = x ; translation[SG_Y] = y ; translation[SG_Z] = z ; } float getPointSize () const { return point_size ; } void setPointSize ( float p ) { point_size = p ; } int getTriggerButton () const { return trigger_button ; } void setTriggerButton ( int b ) { trigger_button = b ; } float getTranslationSensitivity () const { return translation_sensitivity ; } void setTranslationSensitivity ( float t ) { translation_sensitivity = t ; } } ; class puaChooser { UL_TYPE_DATA puButton *chooser_button ; puPopupMenu *popup_menu ; int x1, y1, x2, y2 ; static void static_popup_cb ( puObject * ) ; static void static_menu_cb ( puObject * ) ; public: virtual ~puaChooser () { delete chooser_button ; delete popup_menu ; } puaChooser ( int _x1, int _y1, int _x2, int _y2, char *legend ) ; void add_item ( char *str, puCallback _cb, void *_user_data = NULL ) ; void close () ; void popup_cb () ; void menuCleanup ( const char *s ) ; void hide () { chooser_button -> hide () ; popup_menu -> hide () ; } void reveal () { chooser_button -> reveal () ; popup_menu -> hide () ; } static void menuCleanup ( puObject * ) ; } ; /** * A scrolling list for PUI. * * Believe it or not, PUI does not have one of these. * * This widget consists of a puListBox, a slider and two * arrow buttons. This makes the ListBox scrollable, * very handy if the box is too small to show all items * at once. * * (Original code taken from FlightGear 0.9.6 sources, * modified by Jan Reucker) */ class puaList : public puGroup { UL_TYPE_DATA char ** _contents; puFrame * _frame; puSlider * _slider; puArrowButton * _up_arrow; puArrowButton * _down_arrow; int _style; int _sw; // slider width int _width, _height; protected: virtual void init (int w, int h, short transparent); puListBox * _list_box; public: puaList (int x, int y, int w, int h, int sl_width = 20); puaList (int x, int y, int w, int h, char ** contents, int sl_width = 20); puaList (int x, int y, int w, int h, short transparent, int sl_width = 20); puaList (int x, int y, int w, int h, short transparent, char ** contents, int sl_width = 20); virtual ~puaList (); virtual void newList (char ** contents); virtual char * getStringValue (); virtual int getIntegerValue (); virtual void getValue (char **ps); virtual void getValue (int *i); virtual void setColourScheme (float r, float g, float b, float a); virtual void setColour (int which, float r, float g, float b, float a); virtual void setSize (int w, int h); int getNumVisible ( void ) const { return _list_box->getNumVisible(); } int getNumItems ( void ) const { return _list_box->getNumItems(); } int getTopItem ( void ) const { return _list_box->getTopItem(); } void setTopItem ( int item_index ); }; #endif plib-1.8.5/src/puAux/puAuxScrollBar.cxx0000644000175000001440000002007110765364434014727 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxScrollBar.cxx 2022 2005-05-06 18:39:18Z fayjf $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaScrollBar,puSlider) void puaScrollBar::draw ( int dx, int dy ) { extern void puDrawArrowButtonTriangle ( int pos_x, int pos_y, int size_x, int size_y, puColour colour, int arrow_type, int active ) ; if ( !visible || ( window != puGetWindow () ) ) return ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { puBox box = abox ; int width = isVertical () ? abox.max[0] - abox.min[0] : abox.max[1] - abox.min[1] ; /* Draw the arrow buttons */ if ( arrow_count == 2 ) /* Double-arrow buttons */ { if ( isVertical () ) { box.min[1] = abox.max[1] - width ; box.draw ( dx, dy, style, colour, FALSE, border_thickness ) ; puDrawArrowButtonTriangle ( dx+box.min[0]+width/2, dy+box.min[1]+width/2, width, width, colour [ PUCOL_MISC ], PUARROW_FASTUP, fast_up_arrow_active ) ; box.min[1] = abox.min[1] ; box.max[1] = box.min[1] + width ; box.draw ( dx, dy, style, colour, FALSE, border_thickness ) ; puDrawArrowButtonTriangle ( dx+box.min[0]+width/2, dy+box.min[1]+width/2, width, width, colour [ PUCOL_MISC ], PUARROW_FASTDOWN, fast_down_arrow_active ) ; } else { box.min[0] = abox.max[0] - width ; box.draw ( dx, dy, style, colour, FALSE, border_thickness ) ; puDrawArrowButtonTriangle ( dx+box.min[0]+width/2, dy+box.min[1]+width/2, width, width, colour [ PUCOL_MISC ], PUARROW_FASTRIGHT, fast_up_arrow_active ) ; box.min[0] = abox.min[0] ; box.max[0] = box.min[0] + width ; box.draw ( dx, dy, style, colour, FALSE, border_thickness ) ; puDrawArrowButtonTriangle ( dx+box.min[0]+width/2, dy+box.min[1]+width/2, width, width, colour [ PUCOL_MISC ], PUARROW_FASTLEFT, fast_down_arrow_active ) ; } } if ( arrow_count > 0 ) /* Single-arrow buttons */ { if ( isVertical () ) { box.min[1] = abox.max[1] - arrow_count * width ; box.max[1] = box.min[1] + width ; box.draw ( dx, dy, style, colour, FALSE, border_thickness ) ; puDrawArrowButtonTriangle ( dx+box.min[0]+width/2, dy+box.min[1]+width/2, width, width, colour [ PUCOL_MISC ], PUARROW_UP, up_arrow_active ) ; box.max[1] = abox.min[1] + arrow_count * width ; box.min[1] = box.max[1] - width ; box.draw ( dx, dy, style, colour, FALSE, border_thickness ) ; puDrawArrowButtonTriangle ( dx+box.min[0]+width/2, dy+box.min[1]+width/2, width, width, colour [ PUCOL_MISC ], PUARROW_DOWN, down_arrow_active ) ; } else { box.min[0] = abox.max[0] - arrow_count * width ; box.max[0] = box.min[0] + width ; box.draw ( dx, dy, style, colour, FALSE, border_thickness ) ; puDrawArrowButtonTriangle ( dx+box.min[0]+width/2, dy+box.min[1]+width/2, width, width, colour [ PUCOL_MISC ], PUARROW_RIGHT, up_arrow_active ) ; box.max[0] = abox.min[0] + arrow_count * width ; box.min[0] = box.max[0] - width ; box.draw ( dx, dy, style, colour, FALSE, border_thickness ) ; puDrawArrowButtonTriangle ( dx+box.min[0]+width/2, dy+box.min[1]+width/2, width, width, colour [ PUCOL_MISC ], PUARROW_LEFT, down_arrow_active ) ; } } /* Draw the surrounding box */ box.min[0] = abox.min[0] + ( isVertical () ? 0 : arrow_count * width ) ; box.max[0] = abox.max[0] - ( isVertical () ? 0 : arrow_count * width ) ; box.min[1] = abox.min[1] + ( isVertical () ? arrow_count * width : 0 ) ; box.max[1] = abox.max[1] - ( isVertical () ? arrow_count * width : 0 ) ; if ( ( style == PUSTYLE_BEVELLED ) || ( style == PUSTYLE_SHADED ) ) box.draw ( dx, dy, -PUSTYLE_BOXED, colour, FALSE, 2 ) ; else box.draw ( dx, dy, -style, colour, FALSE, border_thickness ) ; /* Draw the slider box */ float val = getFloatValue () ; draw_slider_box ( dx, dy, box, ( val - getMinValue () ) / ( getMaxValue () - getMinValue () ) ) ; draw_legend ( dx, dy ) ; } draw_label ( dx, dy ) ; } void puaScrollBar::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); if ( ( button == active_mouse_button ) && ( updown == PU_UP ) ) { puDeactivateWidget () ; return ; } if ( button == active_mouse_button ) { int width = isVertical () ? abox.max[0] - abox.min[0] : abox.max[1] - abox.min[1] ; float next_value = getFloatValue () ; float step = getStepSize () ; if ( step == 0.0f ) step = ( getMaxValue () - getMinValue () ) / 10.0f ; /* Check for hitting a button */ int sd = isVertical() ; int coord = ( isVertical() ? y : x ) ; if( arrow_count == 2 ) { if ( coord < abox.min[sd] + width ) /* Fast down button */ next_value -= 10.0f * step ; if ( coord > abox.max[sd] - width ) /* Fast up button */ next_value += 10.0f * step ; } if ( arrow_count > 0 ) { if ( ( coord < abox.min[sd] + arrow_count*width ) && ( coord > abox.min[sd] + (arrow_count-1)*width ) ) /* Down button */ next_value -= step ; if ( ( coord > abox.max[sd] - arrow_count*width ) && ( coord < abox.max[sd] - (arrow_count-1)*width ) ) /* Down button */ next_value += step ; } /* Check for hitting the slider bar */ if ( ( coord > abox.min[sd]+arrow_count*width ) && ( coord < abox.max[sd]-arrow_count*width ) ) { int sz = abox.max [sd] - abox.min [sd] - 2 * arrow_count * width ; if ( sz <= 0 ) next_value = 0.5f ; else { next_value = ( float(coord - arrow_count * width - abox.min[sd]) - float(sz) * slider_fraction / 2.0f ) / ( float(sz) * (1.0f - slider_fraction) ) ; } next_value = (next_value < 0.0f) ? 0.0f : (next_value > 1.0f) ? 1.0f : next_value ; next_value = getMinValue () + next_value * ( getMaxValue () - getMinValue () ) ; } if ( next_value < getMinValue () ) next_value = getMinValue () ; if ( next_value > getMaxValue () ) next_value = getMaxValue () ; setValue ( checkStep (next_value) ); switch ( cb_mode ) { case PUSLIDER_CLICK : if ( updown == active_mouse_edge ) { last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_DELTA : /* Deprecated! */ if ( fabs ( last_cb_value - next_value ) >= cb_delta ) { last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_ALWAYS : default : last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; break ; } } } plib-1.8.5/src/puAux/puAuxComboBox.cxx0000644000175000001440000002204710765364434014561 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puAuxComboBox.cxx 2050 2005-11-10 20:07:08Z fayjf $ */ #include "puAuxLocal.h" UL_RTTI_DEF1(puaComboBox,puGroup) void puaComboBox::input_cb ( puObject *inp ) { puaComboBox *cbox = (puaComboBox *) inp -> getUserData () ; if ( strcmp ( inp->getStringValue (), cbox->getStringValue () ) ) { cbox->update_current_item () ; cbox->setCallbackSource ( PUACOMBOBOX_CALLBACK_INPUT ) ; cbox -> invokeCallback () ; } } void puaComboBox::input_active_cb ( puObject *inp ) { puaComboBox *cbox = (puaComboBox *) inp -> getUserData () ; cbox->update_current_item () ; cbox->setCallbackSource ( PUACOMBOBOX_CALLBACK_INPUT ) ; cbox -> invokeActiveCallback () ; } void puaComboBox::input_down_cb ( puObject *inp ) { puaComboBox *cbox = (puaComboBox *) inp -> getUserData () ; cbox->update_current_item () ; cbox->setCallbackSource ( PUACOMBOBOX_CALLBACK_INPUT ) ; cbox -> invokeCallback () ; } void puaComboBox::handle_arrow ( puObject *arrow ) { puaComboBox *cbox = (puaComboBox *) arrow -> getUserData () ; if ( ! cbox -> __getPopupMenu () -> isVisible () ) cbox -> __getPopupMenu () -> reveal () ; else cbox -> __getPopupMenu () -> hide () ; /* arrow -> setStyle ( - arrow -> getStyle () ) ; */ } void puaComboBox::handle_popup ( puObject *popupm ) { puaComboBox *cbox = (puaComboBox *) popupm -> getUserData () ; cbox -> setCurrentItem ( popupm -> getLegend () ) ; } void puaComboBox::update_widgets ( void ) { if ( curr_item >= 0 ) /* There are some items */ { setValue ( list[curr_item] ) ; arrow_btn -> activate () ; } else /* There aren't any items */ { setValue ( "" ) ; arrow_btn -> greyOut () ; } input->setValue ( getStringValue () ) ; } void puaComboBox::update_current_item ( void ) { if ( strcmp ( getStringValue (), input->getStringValue () ) ) { /* User has typed in an arbitrary string; see if it is in the list */ int i ; for ( i = 0 ; i < num_items ; i++ ) { if ( !strcmp ( list[i], input->getStringValue () ) ) { /* ... yes, it is ! */ curr_item = i ; break ; } } if ( ( i == num_items ) || ( num_items == 0 ) ) { /* Didn't find it in the list--or the list is empty */ char **old_list = list ; list = new char * [ num_items + 2 ] ; for ( i = 0; i < num_items; i++ ) /* Copy over the old list */ list[i] = old_list[i] ; delete old_list ; num_items++ ; int len = strlen ( input->getStringValue () ) + 1 ; curr_item = num_items - 1 ; list[curr_item] = new char [ len ] ; memcpy ( list[curr_item], input->getStringValue (), len ) ; list[num_items] = NULL ; newList ( list ) ; update_widgets () ; } setValue ( input->getStringValue () ) ; } } void puaComboBox::newList ( char ** _list ) { // Delete the existing list--if it has not been passed in as the argument int i ; if ( list && ( list != _list ) ) { for ( i = 0; i < num_items; i++ ) delete list[i] ; delete list ; list = NULL ; } popup_menu -> empty () ; if ( _list == NULL ) num_items = 0 ; else { for ( num_items = 0 ; _list[num_items] != NULL ; num_items++ ) /* Count number of items */ ; if ( num_items > 0 ) { if ( list != _list ) { list = new char * [ num_items + 1 ] ; /* '+ 1' to capture the trailing NULL */ for ( i = 0; i < num_items; i++ ) { int len = strlen ( _list[i] ) + 1 ; /* "+ 1" to capture the \0 */ list[i] = new char [ len ] ; memcpy ( list[i], _list[i], len * sizeof(char) ) ; } list[num_items] = NULL ; } int dummy, h ; int old_height = abox.max[1] - abox.min[1] ; puPushGroup ( popup_menu ) ; for ( i = (num_items - 1) ; i >= 0 ; i-- ) { puObject *menu_item = popup_menu -> add_item ( list[i], handle_popup ) ; menu_item -> setUserData ( this ) ; menu_item -> getSize ( &dummy, &h ) ; menu_item -> setSize ( abox.max[0] - abox.min[0], h ) ; } popup_menu -> close() ; /* Position popup menu correctly */ popup_menu -> getSize ( &dummy, &h ) ; if ( (abox.min[1] - h) >= 0 ) { popup_menu -> setPosition ( 0, 0 - h ) ; arrow_btn -> setArrowType ( PUARROW_DOWN ) ; } else { popup_menu -> setPosition ( 0, old_height ) ; arrow_btn -> setArrowType ( PUARROW_UP ) ; } } } if ( ( curr_item >= num_items ) || ( curr_item < 0 ) ) { curr_item = ( num_items > 0 ? 0 : - 1 ) ; update_widgets () ; } } int puaComboBox::getCurrentItem ( void ) { update_current_item () ; return curr_item ; } void puaComboBox::setCurrentItem ( const char *item_ptr ) { int i ; for ( i = 0 ; i < num_items ; i++ ) { if ( list[i] == item_ptr ) { setCurrentItem ( i ) ; break ; } } } void puaComboBox::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; draw_label ( dx, dy ) ; puGroup::draw ( dx, dy ) ; } int puaComboBox::checkHit ( int button, int updown, int x, int y ) { if ( input -> checkHit ( button, updown, x-abox.min[0], y-abox.min[1] ) ) { popup_menu -> hide () ; puSetActiveWidget ( this, x, y ) ; return TRUE ; } else return puGroup::checkHit ( button, updown, x, y ) ; } int puaComboBox::checkKey ( int key, int updown ) { if ( updown == PU_UP || ! input -> isAcceptingInput () || ! isVisible () || ! isActive () || ( window != puGetWindow () ) ) return FALSE ; switch ( key ) { case PU_KEY_HOME : setCurrentItem ( 0 ) ; break ; case PU_KEY_END : setCurrentItem ( num_items - 1 ) ; break ; case PU_KEY_UP : setCurrentItem ( getCurrentItem () + 1 ) ; break ; case PU_KEY_DOWN : setCurrentItem ( getCurrentItem () - 1 ) ; break ; case PU_KEY_PAGE_UP : case PU_KEY_PAGE_DOWN : if ( ! popup_menu -> isVisible () ) popup_menu -> reveal () ; else popup_menu -> hide () ; break ; default : return input -> checkKey ( key, updown ) ; break ; } return TRUE ; } void puaComboBox::setColourScheme ( float r, float g, float b, float a ) { puObject::setColourScheme ( r, g, b, a ) ; setChildColourScheme( PUCLASS_INPUT, colour [ PUCOL_EDITFIELD ][0], colour [ PUCOL_EDITFIELD ][1], colour [ PUCOL_EDITFIELD ][2], colour [ PUCOL_EDITFIELD ][3] ) ; } void puaComboBox::setColour ( int which, float r, float g, float b, float a ) { if (which == PUCOL_EDITFIELD) input->setColourScheme ( r, g, b, a ) ; else puObject::setColour ( which, r, g, b, a ) ; } puaComboBox::puaComboBox ( int minx, int miny, int maxx, int maxy, char **entries, int editable ) : puGroup( minx, miny ) { type |= PUCLASS_COMBOBOX ; char *stringval ; int arrow_width = (int) ( (maxy-miny) / 1.5f ) ; input = new puInput ( 0, 0, maxx-minx - arrow_width, maxy-miny ) ; input -> setUserData ( this ) ; input -> setCallback ( input_cb ) ; input -> setActiveCallback ( input_active_cb ) ; input -> setDownCallback ( input_down_cb ) ; input -> setStyle ( PUSTYLE_SMALL_SHADED ) ; if ( ! editable ) input -> disableInput () ; /* Share 'string' value with input box */ input -> getValue ( &stringval ) ; // setValuator ( stringval ) ; arrow_btn = new puArrowButton ( maxx-minx - arrow_width, 0, maxx-minx, maxy-miny, PUARROW_DOWN ) ; arrow_btn -> setStyle ( PUSTYLE_SMALL_SHADED ) ; arrow_btn -> setUserData ( this ) ; arrow_btn -> setCallback ( handle_arrow ) ; popup_menu = new puPopupMenu ( 0, 0 ) ; popup_menu -> close () ; close () ; list = NULL ; curr_item = 0 ; num_items = 0 ; callback_source = PUACOMBOBOX_CALLBACK_NONE ; newList ( entries ) ; update_widgets () ; } void puaComboBox::setSize ( int w, int h ) { int arrow_width = (int) ( float(h) / 1.5f ) ; input->setSize ( w - arrow_width, h ) ; arrow_btn->setPosition ( w - arrow_width, 0 ) ; arrow_btn->setSize ( arrow_width, h ) ; } plib-1.8.5/src/Makefile.am0000644000175000001440000000007410765364440012225 00000000000000SUBDIRS = util js sl pui puAux sg ssg fnt ssgAux net psl pw plib-1.8.5/src/util/0000777000175000001440000000000010765365517011237 500000000000000plib-1.8.5/src/util/ul.cxx0000644000175000001440000003021510765364437012320 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ul.cxx 2129 2007-10-16 00:45:26Z fayjf $ */ #include "ul.h" #include #include #ifdef UL_MSVC #include #else #include #endif #ifdef UL_MSVC #define SLASH "\\" #else #define SLASH "/" #endif struct _ulDir { char dirname [ UL_NAME_MAX+1 ]; ulDirEnt curr ; #ifdef UL_MSVC WIN32_FIND_DATA data ; HANDLE hFind ; bool first ; bool done ; #else DIR *dirp ; #endif } ; void ulInit () { } ulDir* ulOpenDir ( const char* dirname ) { ulDir* dir = new ulDir; if ( dir != NULL ) { strcpy( dir->dirname, dirname ) ; #ifdef UL_MSVC char search[_MAX_PATH]; strcpy(search,dirname); //munch the directory seperator int len = strlen(search); if ( len>0 && strchr("/\\",search[len-1]) ) search[len-1] = 0; //add the wildcard strcat(search,"/*.*"); dir->first = true; dir->done = false; dir->hFind = FindFirstFile(search, &dir->data); if (dir->hFind == INVALID_HANDLE_VALUE) { delete dir; dir = NULL; } #else dir->dirp = opendir(dirname) ; if ( dir->dirp == NULL ) { delete dir ; dir = NULL ; } #endif } return dir; } ulDirEnt* ulReadDir ( ulDir* dir ) { //read the next entry from the directory #ifdef UL_MSVC //update state if ( dir->first ) dir->first = false ; else if ( !dir->done && !FindNextFile(dir->hFind,&dir->data) ) dir->done = true ; if ( dir->done ) return NULL ; strcpy( dir->curr.d_name, dir->data.cFileName ) ; #else struct dirent* direntp = readdir( dir->dirp ); if ( !direntp ) return NULL ; strcpy( dir->curr.d_name, direntp->d_name ); #endif //determine if this entry is a directory #ifdef UL_MSVC dir->curr.d_isdir = ( dir->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0; #else char path[ 1000 + UL_NAME_MAX+1 ]; sprintf( path, "%s/%s", dir->dirname, dir->curr.d_name ); struct stat buf ; if ( stat(path,&buf) == 0 ) dir->curr.d_isdir = (buf.st_mode & S_IFDIR) != 0 ; else dir->curr.d_isdir = false ; #endif return( &dir->curr ) ; } void ulCloseDir ( ulDir* dir ) { if ( dir != NULL ) { #ifdef UL_MSVC FindClose(dir->hFind); #else closedir ( dir->dirp ) ; #endif delete dir ; } } bool ulFileExists ( const char *fileName ) { #ifdef UL_MSVC struct _stat buf ; if ( _stat ( fileName, &buf ) < 0 ) return false ; return ((S_IFREG & buf.st_mode ) !=0) ; #else struct stat buf ; if ( stat ( fileName, &buf ) < 0 ) return false ; return ((S_ISREG ( buf.st_mode )) != 0) ; #endif } char* ulMakePath( char* path, const char* dir, const char* fname ) { if ( fname ) { if ( !ulIsAbsolutePathName (fname) && dir != NULL && dir[0] != '\0' ) { strcpy ( path, dir ) ; strcat ( path, SLASH ) ; strcat ( path, fname ) ; } else strcpy ( path, fname ) ; } else path [0] = 0 ; return( path ); } static int recursiveFindFileInSubDirs ( char * filenameOutput, const char * tPath, const char * tfnameInput ) { int bFound = FALSE; char tempString [ 1024 ]; ulMakePath ( filenameOutput, tPath, tfnameInput ) ; if ( ulFileExists ( filenameOutput ) ) return TRUE; ulDir* dirp = ulOpenDir(tPath); if ( dirp != NULL ) { ulDirEnt* dp; while ( ! bFound && ((dp = ulReadDir(dirp)) != NULL ) ) { // I am doing recursive ulOpenDir/ulReadDirs here. // I know this works under Windo$. if ( dp->d_isdir && strcmp( dp->d_name, ".") != 0 && strcmp( dp->d_name, "..") != 0 ) { ulMakePath ( tempString, tPath, dp->d_name) ; bFound = recursiveFindFileInSubDirs ( filenameOutput, tempString, tfnameInput ); } } ulCloseDir ( dirp ) ; } return bFound; } void ulFindFile( char *filenameOutput, const char *path, const char * tfnameInput, const char *sAPOM ) /* adds tfnameInput to the path and puts this into the buffer filenameOutput. sAPOM is used iff path contains "$(APOM)" handles special chars in path: ";;" is replaced by ";" "$$" is replaced by "$" "$(APOM)" is replaced by sAPOM If there are ";" in path, the path-variable is interpreted as several paths "segments", delimited by ";". The first file found by this function is returned. It looks from left to right. A segment may end in $(...). ulFindFile will then look in in this path and recursively in all the sub-paths Some examples: for loading *.MDl-models, it is very nice to set the texture path to $(APOM);$(APOM)/texture;$(APOM)/../texture This consits of three segments and tells ulFindFile to look in the path of the model, in a subpath texture and in a path texture "besides" the path of the model. Some *.mdl-models are shipped in a directory which conatins a "texture"-directory, a "Model"-directory and others. In this case you find the texture in $(APOM)/../texture Another example: You have all your textures in a directory-structure under /roomplan. For example brick is under /roomplan/bricks, wood is under /roomplan/wood, oak is under /roomplan/wood/oak. Then you should use the following texture path: "/roomplan/$(...)" If you dont want all of the bells and whistles, just call: _ssgMakePath ( filenameOutput, path, tfnameInput ) ; */ { char temp_texture_path[1024], *s_ptr, *s_ptr1, *current_path; strncpy(temp_texture_path, path, 1024); current_path = temp_texture_path; s_ptr = temp_texture_path; while ( *s_ptr != 0 ) { if ( *s_ptr == ';' ) { if ( s_ptr [ 1 ] == ';' ) { // replace ";;" with ";" s_ptr1 = ++s_ptr; // both pointers on second ";" while ( *s_ptr1 != 0) { s_ptr1 [ 0 ] = s_ptr1 [ 1 ]; s_ptr1++; } } else { // found a single ';'. This delimits paths *s_ptr++ = 0; ulMakePath ( filenameOutput, current_path, tfnameInput ) ; if ( ulFileExists ( filenameOutput ) ) return; // success! // this path doesnt hold the texture. Try next one current_path = s_ptr; } } else if ( *s_ptr == '$' ) { if ( s_ptr [ 1 ] == '$' ) { // replace "$$" with "$" s_ptr1 = ++s_ptr; // both pointers on second "$" while ( *s_ptr1 != 0) { s_ptr1 [ 0 ] = s_ptr1 [ 1 ]; s_ptr1++; } } else if ( 0 == strncmp( s_ptr, "$(APOM)", strlen("$(APOM)" ) ) ) { // replace "$(APOM)" by sAPOM char temp_buffer[1024]; * s_ptr = 0; s_ptr += strlen ( "$(APOM)" ); strcpy ( temp_buffer, s_ptr ); strcat ( current_path, sAPOM); s_ptr = & current_path [ strlen(current_path) ] ; // onto the 0 strcat ( current_path, temp_buffer ); } else if ( 0 == strncmp( s_ptr, "$(...)", strlen("$(...)" ) ) ) { //strcpy(temp_texture_path_for_recursion, current_path); char * nextPath=s_ptr; nextPath += strlen("$(...)" ); while (*nextPath != 0 ) { if ( *nextPath == ';' ) { if ( nextPath[1] == ';' ) nextPath++; // so its "add 2 " togehter with the ++ further down else { *nextPath = 0; break; // breaks the while } } nextPath++; } // This segment of the path ends with a 0 now // ***** char tPath [ 1024 ]; strcpy ( tPath, current_path ) ; tPath [ (long) (s_ptr - current_path) ] = 0; // So, lets recurse into the sub-dirs: // Here I just assume that the "$(...)" is the last thing in // this segment if ( recursiveFindFileInSubDirs ( filenameOutput, tPath, tfnameInput ) ) return ; // success // ***** // we handled the path-segment current_path containing the $(...) and // didnt find the file, so go on to the nect segment current_path = nextPath; // points to a 0 if this was the last segment s_ptr = current_path; } else s_ptr++; } else // neither ';' nor '$' s_ptr++; } ulMakePath ( filenameOutput, current_path, tfnameInput ) ; // pfusch? kludge? } ///////////////////// string handling /////////////////////////////// /* Strdup is *evil* - use this instead... */ char *ulStrDup ( const char *s ) { int s_sz = strlen ( s ) + 1 ; char *ret = new char [ s_sz ] ; memcpy ( ret, s, s_sz ) ; return ret ; } // string comparisons that are *not* case sensitive: /* I'm sick of half the machines on the planet supporting strncasecmp and the other half strnicmp - so here is my own offering. **** ATTENTION **** WK: If you used strnicmp, make sure you realise the completely changed meaning of the return value - 0 means not equal! */ int ulStrNEqual ( const char *s1, const char *s2, int len ) { int l1 = (s1==NULL) ? 0 : strlen ( s1 ) ; int l2 = (s2==NULL) ? 0 : strlen ( s2 ) ; if ( l1 > len ) l1 = len ; if ( l2 < l1 || l1 < len ) return FALSE ; for ( int i = 0 ; i < l1 ; i++ ) { char c1 = s1[i] ; char c2 = s2[i] ; if ( c1 == c2 ) continue ; if ( c1 >= 'a' && c1 <= 'z' ) c1 = c1 - ('a'-'A') ; if ( c2 >= 'a' && c2 <= 'z' ) c2 = c2 - ('a'-'A') ; if ( c1 != c2 ) return FALSE ; } return TRUE ; } /* I'm sick of half the machines on the planet supporting strcasecmp and the other half stricmp - so here is my own offering. **** ATTENTION **** WK: If you used stricmp, make sure you realise the completely changed meaning of the return value - 0 means not equal! */ int ulStrEqual ( const char *s1, const char *s2 ) { int l1 = (s1==NULL) ? 0 : strlen ( s1 ) ; int l2 = (s2==NULL) ? 0 : strlen ( s2 ) ; if ( l1 != l2 ) return FALSE ; for ( int i = 0 ; i < l1 ; i++ ) { char c1 = s1[i] ; char c2 = s2[i] ; if ( c1 == c2 ) continue ; if ( c1 >= 'a' && c1 <= 'z' ) c1 -= ('a'-'A') ; if ( c2 >= 'a' && c2 <= 'z' ) c2 -= ('a'-'A') ; if ( c1 != c2 ) return FALSE ; } return TRUE ; } int ulIsAbsolutePathName ( const char *pathname ) { /* Is this an absolute pathname or a relative one? */ if ( (pathname == NULL) || (pathname [0] == 0) ) return FALSE; #ifdef UL_MSVC /* Under WinDOS, it's an absolute path if it starts with a slash *or* if it starts with a drive letter, a colon and a slash. */ return ( pathname[0] == SLASH[0] || pathname[0] == '/' ) || ( ( ( pathname[0] >= 'a' && pathname[0] <= 'z' ) || ( pathname[0] >= 'A' && pathname[0] <= 'Z' ) ) && pathname[1] == ':' && ( pathname[2] == SLASH[0] || pathname[2] == '/' ) ) ; #elif defined(UL_MACINTOSH) return (pathname [0] != ':' && strchr( pathname, ':') != NULL ); #else return pathname [0] == SLASH[0] ; #endif } char *ulGetCWD ( char *result, int maxlength ) { /* Return the current working directory into 'result' - which has enough space for 'maxlength-1' characters and a '\0'. */ #ifdef UL_MSVC return _getcwd ( result, maxlength ) ; #else return getcwd ( result, maxlength ) ; #endif } plib-1.8.5/src/util/ul.h0000644000175000001440000004060510765365005011741 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ul.h 2117 2007-09-13 23:21:09Z fayjf $ */ // // UL - utility library // // Contains: // - necessary system includes // - basic types // - error message routines // - high performance clocks // - ulList // - ulLinkedList // - more to come (endian support, version ID) // #ifndef _INCLUDED_UL_H_ #define _INCLUDED_UL_H_ #include #include #include #include #include #include /**********************\ * * * Determine OS type * * * \**********************/ #if defined(__CYGWIN__) #define UL_WIN32 1 #define UL_CYGWIN 1 /* Windoze AND Cygwin. */ #elif defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) #define UL_WIN32 1 #define UL_MSVC 1 /* Windoze AND MSVC. */ #elif defined(__BEOS__) #define UL_BEOS 1 #elif defined( macintosh ) #define UL_MACINTOSH 1 #elif defined(__APPLE__) #define UL_MAC_OSX 1 #elif defined(__linux__) #define UL_LINUX 1 #elif defined(__sgi) #define UL_IRIX 1 #elif defined(_AIX) #define UL_AIX 1 #elif defined(SOLARIS) || defined(sun) #define UL_SOLARIS 1 #elif defined(hpux) #define UL_HPUX 1 #elif (defined(__unix__) || defined(unix)) && !defined(USG) #define UL_BSD 1 #endif /* Add specialised includes/defines... */ #ifdef UL_WIN32 #define WIN32_LEAN_AND_MEAN #include #include #include #define UL_WGL 1 #endif #ifdef UL_CYGWIN #include #define UL_WGL 1 #endif #ifdef UL_BEOS #include #define UL_GLX 1 #endif #ifdef UL_MACINTOSH #include #include #define UL_AGL 1 #endif #ifdef UL_MAC_OSX #include #define UL_CGL 1 #endif #if defined(UL_LINUX) || defined(UL_BSD) || defined(UL_IRIX) || defined(UL_SOLARIS) || defined(UL_AIX) #include #include #include #define UL_GLX 1 #endif #if defined(UL_BSD) #include #define UL_GLX 1 #endif #include #include #include #include #include /* PLIB version macros */ #define PLIB_MAJOR_VERSION 1 #define PLIB_MINOR_VERSION 8 #define PLIB_TINY_VERSION 5 #define PLIB_VERSION (PLIB_MAJOR_VERSION*100 \ +PLIB_MINOR_VERSION*10 \ +PLIB_TINY_VERSION) /* SGI machines seem to suffer from a lack of FLT_EPSILON so... */ #ifndef FLT_EPSILON #define FLT_EPSILON 1.19209290e-07f #endif #ifndef DBL_EPSILON #define DBL_EPSILON 1.19209290e-07f #endif #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* SUNWspro 4.2 and earlier need bool to be defined */ #if defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500 typedef int bool ; const int true = 1 ; const int false = 0 ; #endif /* Let's define our own "min" and "max" so that different operating systems * don't complain */ #define ulMax(a,b) ((a)>(b)?(a):(b)) #define ulMin(a,b) ((a)<(b)?(a):(b)) /* Basic Types */ /* High precision clocks. */ class ulClock { double start ; double now ; double delta ; double last_time ; double max_delta ; #ifdef UL_WIN32 static double res ; static int perf_timer ; void initPerformanceTimer () ; #endif double getRawTime () const ; public: ulClock () { reset () ; } void reset () { #ifdef UL_WIN32 initPerformanceTimer () ; #endif start = getRawTime () ; now = 0.0 ; max_delta = 0.2 ; delta = 0.0000001 ; /* Faked so stoopid programs won't div0 */ last_time = 0.0 ; } void setMaxDelta ( double maxDelta ) { max_delta = maxDelta ; } double getMaxDelta () const { return max_delta ; } void update () ; double getAbsTime () const { return now ; } double getDeltaTime () const { return delta ; } double getFrameRate () const { return 1.0 / delta ; } } ; inline void ulSleep ( int seconds ) { if ( seconds >= 0 ) { #ifdef UL_WIN32 Sleep ( 1000 * seconds ) ; #else sleep ( seconds ) ; #endif } } inline void ulMilliSecondSleep ( int milliseconds ) { if ( milliseconds >= 0 ) { #ifdef UL_WIN32 Sleep ( milliseconds ) ; #else usleep ( milliseconds * 1000 ) ; #endif } } /* This is extern C to enable 'configure.in' to find it with a C-coded probe. */ extern "C" void ulInit () ; /* Error handler. */ enum ulSeverity { UL_DEBUG, // Messages that can safely be ignored. UL_WARNING, // Messages that are important. UL_FATAL, // Errors that we cannot recover from. UL_MAX_SEVERITY } ; typedef void (*ulErrorCallback) ( enum ulSeverity severity, char* msg ) ; void ulSetError ( enum ulSeverity severity, const char *fmt, ... ) ; char* ulGetError ( void ) ; void ulClearError ( void ) ; ulErrorCallback ulGetErrorCallback ( void ) ; void ulSetErrorCallback ( ulErrorCallback cb ) ; /* Directory Reading */ #define UL_NAME_MAX 256 typedef struct _ulDir ulDir ; struct ulDirEnt { char d_name [ UL_NAME_MAX+1 ]; bool d_isdir ; } ; int ulIsAbsolutePathName ( const char *pathname ) ; char *ulGetCWD ( char *result, int maxlength ) ; ulDir* ulOpenDir ( const char* dirname ) ; ulDirEnt* ulReadDir ( ulDir* dir ) ; void ulCloseDir ( ulDir* dir ) ; // file handling char* ulMakePath( char* path, const char* dir, const char* fname ); bool ulFileExists ( const char *fileName ) ; void ulFindFile( char *filenameOutput, const char *path, const char * tfnameInput, const char *sAPOM ) ; /* Endian handling */ static const int _ulEndianTest = 1; #define ulIsLittleEndian (*((char *) &_ulEndianTest ) != 0) #define ulIsBigEndian (*((char *) &_ulEndianTest ) == 0) inline void ulEndianSwap(unsigned int *x) { *x = (( *x >> 24 ) & 0x000000FF ) | (( *x >> 8 ) & 0x0000FF00 ) | (( *x << 8 ) & 0x00FF0000 ) | (( *x << 24 ) & 0xFF000000 ) ; } inline void ulEndianSwap(unsigned short *x) { *x = (( *x >> 8 ) & 0x00FF ) | (( *x << 8 ) & 0xFF00 ) ; } inline void ulEndianSwap(float *x) { ulEndianSwap((unsigned int *)x); } inline void ulEndianSwap(int *x) { ulEndianSwap((unsigned int *)x); } inline void ulEndianSwap(short *x) { ulEndianSwap((unsigned short *)x); } inline unsigned short ulEndianLittle16(unsigned short x) { if (ulIsLittleEndian) { return x; } else { ulEndianSwap(&x); return x; } } inline unsigned int ulEndianLittle32(unsigned int x) { if (ulIsLittleEndian) { return x; } else { ulEndianSwap(&x); return x; } } inline float ulEndianLittleFloat(float x) { if (ulIsLittleEndian) { return x; } else { ulEndianSwap(&x); return x; } } inline void ulEndianLittleArray16(unsigned short *x, int length) { if (ulIsLittleEndian) { return; } else { for (int i = 0; i < length; i++) { ulEndianSwap(x++); } } } inline void ulEndianLittleArray32(unsigned int *x, int length) { if (ulIsLittleEndian) { return; } else { for (int i = 0; i < length; i++) { ulEndianSwap(x++); } } } inline void ulEndianLittleArrayFloat(float *x, int length) { if (ulIsLittleEndian) { return; } else { for (int i = 0; i < length; i++) { ulEndianSwap(x++); } } } inline void ulEndianBigArray16(unsigned short *x, int length) { if (ulIsBigEndian) { return; } else { for (int i = 0; i < length; i++) { ulEndianSwap(x++); } } } inline void ulEndianBigArray32(unsigned int *x, int length) { if (ulIsBigEndian) { return; } else { for (int i = 0; i < length; i++) { ulEndianSwap(x++); } } } inline void ulEndianBigArrayFloat(float *x, int length) { if (ulIsBigEndian) { return; } else { for (int i = 0; i < length; i++) { ulEndianSwap(x++); } } } inline unsigned short ulEndianBig16(unsigned short x) { if (ulIsBigEndian) { return x; } else { ulEndianSwap(&x); return x; } } inline unsigned int ulEndianBig32(unsigned int x) { if (ulIsBigEndian) { return x; } else { ulEndianSwap(&x); return x; } } inline float ulEndianBigFloat(float x) { if (ulIsBigEndian) { return x; } else { ulEndianSwap(&x); return x; } } inline unsigned short ulEndianReadLittle16(FILE *f) { unsigned short x; fread(&x, 2, 1, f); return ulEndianLittle16(x); } inline unsigned int ulEndianReadLittle32(FILE *f) { unsigned int x; fread(&x, 4, 1, f); return ulEndianLittle32(x); } inline float ulEndianReadLittleFloat(FILE *f) { float x; fread(&x, 4, 1, f); return ulEndianLittleFloat(x); } inline unsigned short ulEndianReadBig16(FILE *f) { unsigned short x; fread(&x, 2, 1, f); return ulEndianBig16(x); } inline unsigned int ulEndianReadBig32(FILE *f) { unsigned int x; fread(&x, 4, 1, f); return ulEndianBig32(x); } inline float ulEndianReadBigFloat(FILE *f) { float x; fread(&x, 4, 1, f); return ulEndianBigFloat(x); } inline size_t ulEndianWriteLittle16(FILE *f, unsigned short x) { x = ulEndianLittle16(x); return fwrite( &x, 2, 1, f ); } inline size_t ulEndianWriteLittle32(FILE *f, unsigned int x) { x = ulEndianLittle32(x); return fwrite( &x, 4, 1, f ); } inline size_t ulEndianWriteLittleFloat(FILE *f, float x) { x = ulEndianLittleFloat(x); return fwrite( &x, 4, 1, f ); } inline size_t ulEndianWriteBig16(FILE *f, unsigned short x) { x = ulEndianBig16(x); return fwrite( &x, 2, 1, f ); } inline size_t ulEndianWriteBig32(FILE *f, unsigned int x) { x = ulEndianBig32(x); return fwrite( &x, 4, 1, f ); } inline size_t ulEndianWriteBigFloat(FILE *f, float x) { x = ulEndianBigFloat(x); return fwrite( &x, 4, 1, f ); } /* Windoze/BEOS code based on contribution from Sean L. Palmer */ #ifdef UL_WIN32 class ulDynamicLibrary { HMODULE handle ; public: ulDynamicLibrary ( const char *libname ) { char dllname[1024]; strcpy ( dllname, libname ) ; strcat ( dllname, ".dll" ) ; handle = (HMODULE) LoadLibrary ( dllname ) ; } void *getFuncAddress ( const char *funcname ) { return (void *) GetProcAddress ( handle, funcname ) ; //lint !e611 } ~ulDynamicLibrary () { if ( handle != NULL ) FreeLibrary ( handle ) ; } } ; #elif defined (UL_MACINTOSH) class ulDynamicLibrary { CFragConnectionID connection; OSStatus error; public: ulDynamicLibrary ( const char *libname ) { Str63 pstr; int sz; sz = strlen (libname); if (sz < 64) { pstr[0] = sz; memcpy (pstr+1, libname, sz); error = GetSharedLibrary (pstr, kPowerPCCFragArch, kReferenceCFrag, &connection, NULL, NULL); } else error = 1; } ~ulDynamicLibrary () { if ( ! error ) CloseConnection (&connection); } void* getFuncAddress ( const char *funcname ) { if ( ! error ) { char* addr; Str255 sym; int sz; sz = strlen (funcname); if (sz < 256) { sym[0] = sz; memcpy (sym+1, funcname, sz); error = FindSymbol (connection, sym, &addr, 0); if ( ! error ) return addr; } } return NULL; } }; #elif defined (UL_MAC_OSX) class ulDynamicLibrary { public: ulDynamicLibrary ( const char *libname ) { } ~ulDynamicLibrary () { } void* getFuncAddress ( const char *funcname ) { ulSetError ( UL_WARNING, "ulDynamicLibrary unsuppored on Mac OS X" ); return NULL; } }; #elif defined (__BEOS__) class ulDynamicLibrary { image_id *handle ; public: ulDynamicLibrary ( const char *libname ) { char addonname[1024] ; strcpy ( addonname, libname ) ; strcat ( addonname, ".so" ) ; handle = new image_id ; *handle = load_add_on ( addonname ) ; if ( *handle == B_ERROR ) { delete handle ; handle = NULL ; } } void *getFuncAddress ( const char *funcname ) { void *sym = NULL ; if ( handle && get_image_symbol ( handle, "funcname", B_SYMBOL_TYPE_TEXT, &sym ) == B_NO_ERROR ) return sym ; return NULL ; } ~ulDynamicLibrary () { if ( handle != NULL ) unload_add_on ( handle ) ; delete handle ; } } ; # else /* Linux/UNIX */ class ulDynamicLibrary { void *handle ; public: ulDynamicLibrary ( const char *libname ) { char dsoname [ 1024 ] ; strcpy ( dsoname, libname ) ; strcat ( dsoname, ".so" ) ; handle = (void *) dlopen ( dsoname, RTLD_NOW | RTLD_GLOBAL ) ; if ( handle == NULL ) ulSetError ( UL_WARNING, "ulDynamicLibrary: %s\n", dlerror() ) ; } void *getFuncAddress ( const char *funcname ) { return (handle==NULL) ? NULL : dlsym ( handle, funcname ) ; } ~ulDynamicLibrary () { if ( handle != NULL ) dlclose ( handle ) ; } } ; #endif class ulList { protected: unsigned int total ; /* The total number of entities in the list */ unsigned int limit ; /* The current limit on number of entities */ unsigned int next ; /* The next entity when we are doing getNext ops */ void **entity_list ; /* The list. */ void sizeChk (void) ; public: ulList ( int init_max = 1 ) ; virtual ~ulList (void) ; void *getEntity ( unsigned int n ) { next = n + 1 ; return ( n >= total ) ? (void *) NULL : entity_list [ n ] ; } virtual void addEntity ( void *entity ) ; virtual void addEntityBefore ( int n, void *entity ) ; virtual void removeEntity ( unsigned int n ) ; void removeAllEntities () ; void removeEntity ( void *entity ) { removeEntity ( searchForEntity ( entity ) ) ; } virtual void replaceEntity ( unsigned int n, void *new_entity ) ; void replaceEntity ( void *old_entity, void *new_entity ) { replaceEntity ( searchForEntity ( old_entity ), new_entity ) ; } void *getNextEntity (void) { return getEntity ( next ) ; } int getNumEntities (void) const { return total ; } int searchForEntity ( void *entity ) const ; } ; typedef bool (*ulIterateFunc)( const void *data, void *user_data ) ; typedef int (*ulCompareFunc)( const void *data1, const void *data2 ) ; /* Linked list. */ class ulListNode ; class ulLinkedList { protected: ulListNode *head ; ulListNode *tail ; int nnodes ; bool sorted ; void unlinkNode ( ulListNode *prev, ulListNode *node ) ; bool isValidPosition ( int pos ) const { if ( ( pos < 0 ) || ( pos >= nnodes ) ) { ulSetError ( UL_WARNING, "ulLinkedList: Invalid 'pos' %u", pos ) ; return false ; } return true ; } public: ulLinkedList () { head = tail = NULL ; nnodes = 0 ; sorted = true ; } ~ulLinkedList () { empty () ; } int getNumNodes ( void ) const { return nnodes ; } bool isSorted ( void ) const { return sorted ; } int getNodePosition ( void *data ) const ; void insertNode ( void *data, int pos ) ; void prependNode ( void *data ) { insertNode ( data, 0 ) ; } void appendNode ( void *data ) ; int insertSorted ( void *data, ulCompareFunc comparefn ) ; void removeNode ( void *data ) ; void * removeNode ( int pos ) ; void * getNodeData ( int pos ) const ; void * forEach ( ulIterateFunc fn, void *user_data = NULL ) const ; void empty ( ulIterateFunc destroyfn = NULL, void *user_data = NULL ) ; } ; extern char *ulStrDup ( const char *s ) ; extern int ulStrNEqual ( const char *s1, const char *s2, int len ); extern int ulStrEqual ( const char *s1, const char *s2 ); //lint -restore #endif plib-1.8.5/src/util/ul.dsp0000644000175000001440000000672510765364437012315 00000000000000# Microsoft Developer Studio Project File - Name="ul" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=ul - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "ul.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "ul.mak" CFG="ul - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "ul - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "ul - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "ul - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy ul.h ..\..\ul.h copy ulRTTI.h ..\..\ulRTTI.h # End Special Build Tool !ELSEIF "$(CFG)" == "ul - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\ul_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy ul.h ..\..\ul.h copy ulRTTI.h ..\..\ulRTTI.h # End Special Build Tool !ENDIF # Begin Target # Name "ul - Win32 Release" # Name "ul - Win32 Debug" # Begin Source File SOURCE=.\ul.cxx # End Source File # Begin Source File SOURCE=.\ul.h # End Source File # Begin Source File SOURCE=.\ulClock.cxx # End Source File # Begin Source File SOURCE=.\ulError.cxx # End Source File # Begin Source File SOURCE=.\ulLinkedList.cxx # End Source File # Begin Source File SOURCE=.\ulList.cxx # End Source File # Begin Source File SOURCE=.\ulLocal.h # End Source File # Begin Source File SOURCE=.\ulRTTI.cxx # End Source File # Begin Source File SOURCE=.\ulRTTI.h # End Source File # End Target # End Project plib-1.8.5/src/util/ulLocal.h0000644000175000001440000000263210765364437012722 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ulLocal.h 1568 2002-09-02 06:05:49Z sjbaker $ */ #ifndef _UL_LOCAL_H_ #define _UL_LOCAL_H_ 1 #include "ul.h" class ulListNode { protected: ulListNode *next ; void *data ; public: ulListNode ( void *dt, ulListNode *next_node ) { data = dt ; next = next_node ; } void * getData ( void ) const { return data ; } void setData ( void *d ) { data = d ; } ulListNode * getNext ( void ) const { return next ; } void setNext ( ulListNode *n ) { next = n ; } } ; #endif plib-1.8.5/src/util/Makefile.am0000644000175000001440000000033010765364437013203 00000000000000if BUILD_UL lib_LIBRARIES = libplibul.a include_HEADERS = ul.h ulRTTI.h libplibul_a_SOURCES = ul.cxx ulClock.cxx ulError.cxx ulLinkedList.cxx \ ulList.cxx ulLocal.h ulRTTI.cxx endif EXTRA_DIST = ul.dsp plib-1.8.5/src/util/ulLinkedList.cxx0000644000175000001440000001216510765364437014307 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ulLinkedList.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ulLocal.h" void ulLinkedList::unlinkNode ( ulListNode *prev, ulListNode *node ) { /* Is this the first node ? */ if ( prev == NULL ) head = node -> getNext () ; else prev -> setNext ( node -> getNext () ) ; /* Is this the last node ? */ if ( node -> getNext () == NULL ) tail = prev ; } int ulLinkedList::getNodePosition ( void *data ) const { ulListNode *curr = head ; int pos = 0 ; while ( curr != NULL ) { if ( curr -> getData () == data ) return pos ; pos++ ; curr = curr -> getNext () ; } return -1 ; } void ulLinkedList::appendNode ( void *data ) { ulListNode *new_node = new ulListNode ( data, NULL ) ; if ( head == NULL ) head = new_node ; else tail -> setNext ( new_node ) ; tail = new_node ; if ( ++nnodes > 1 ) sorted = false ; } void ulLinkedList::insertNode ( void *data, int pos ) { if ( pos == 0 ) { head = new ulListNode ( data, head ) ; if ( tail == NULL ) tail = head ; } else { if ( ! isValidPosition ( pos ) ) return ; else { ulListNode *prev = head ; while ( --pos > 0 ) prev = prev -> getNext () ; prev -> setNext ( new ulListNode ( data, prev -> getNext () ) ) ; } } if ( ++nnodes > 1 ) sorted = false ; } int ulLinkedList::insertSorted ( void *data, ulCompareFunc comparefn ) { if ( comparefn != NULL ) { if ( sorted ) { int pos = 0 ; if ( head == NULL ) head = tail = new ulListNode ( data, NULL ) ; else { ulListNode *curr = head, *prev = NULL ; while ( (*comparefn)( curr -> getData (), data ) < 0 ) { prev = curr ; curr = curr -> getNext () ; pos++ ; if ( curr == NULL ) { tail = new ulListNode ( data, curr ) ; prev -> setNext ( tail ) ; nnodes++ ; return pos ; } } if ( prev == NULL ) head = new ulListNode ( data, head ) ; else prev -> setNext ( new ulListNode ( data, curr ) ) ; } nnodes++ ; return pos ; } else ulSetError ( UL_WARNING, "ulLinkedList::insertSorted: This is not a sorted list !" ) ; } return -1 ; } void ulLinkedList::removeNode ( void *data ) { ulListNode *curr = head, *prev = NULL ; while ( curr != NULL ) { if ( curr -> getData () == data ) { unlinkNode ( prev, curr ) ; delete curr ; if ( --nnodes <= 0 ) sorted = true ; return ; } prev = curr ; curr = curr -> getNext () ; } ulSetError ( UL_WARNING, "ulLinkedList::removeNode: No such node" ) ; } void * ulLinkedList::removeNode ( int pos ) { if ( ! isValidPosition ( pos ) ) return NULL ; ulListNode *curr = head, *prev = NULL ; while ( pos-- > 0 ) { prev = curr ; curr = curr -> getNext () ; } unlinkNode ( prev, curr ) ; void *datap = curr -> getData () ; delete curr ; if ( --nnodes <= 1 ) sorted = true ; return datap ; } void * ulLinkedList::getNodeData ( int pos ) const { if ( ! isValidPosition ( pos ) ) return NULL ; ulListNode *node ; if ( pos == nnodes - 1 ) node = tail ; else { node = head ; while ( pos-- > 0 ) node = node -> getNext () ; } return node -> getData () ; } void * ulLinkedList::forEach ( ulIterateFunc fn, void *user_data ) const { if ( fn != NULL ) { ulListNode *curr ; for ( curr = head ; curr != NULL ; curr = curr -> getNext () ) { if ( (*fn)( curr -> getData (), user_data ) == false ) return curr -> getData () ; } } return NULL ; } void ulLinkedList::empty ( ulIterateFunc destroyfn, void *user_data ) { ulListNode *curr = head ; if ( destroyfn != NULL ) { while ( curr != NULL ) { ulListNode *next = curr -> getNext () ; (*destroyfn) ( curr -> getData (), user_data ) ; delete curr ; curr = next ; } } else { while ( curr != NULL ) { ulListNode *next = curr -> getNext () ; delete curr ; curr = next ; } } head = tail = NULL ; nnodes = 0 ; sorted = true ; } plib-1.8.5/src/util/ulRTTI.cxx0000644000175000001440000000722710765364437013032 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "ulRTTI.h" /* Originally written by: Alexandru C. Telea */ static const ulRTTITypeinfo *RTTI_base_null_type [] = { 0 } ; const ulRTTITypeinfo* ulRTTIdyntypeid::a[] = { 0 } ; const ulRTTITypeinfo ulRTTITypeinfo::null_type ( "NULL", RTTI_base_null_type, 0, 0 ) ; ulRTTITypeinfo::ulRTTITypeinfo ( const char *name, const ulRTTITypeinfo *bb[], void* (*f1)(int,void*),void* (*f2)() ) { /* Create default ulRTTITypeinfo */ n = ulStrDup ( name ) ; b = bb ; /* ns = 0 ; subtypes = 0 ; */ cast = f1 ; /* Attach casting func */ new_obj = f2 ; /* Attach creation func */ for ( int i = 0 ; b[i] ; i++ ) /* Add this as subtype to all its basetypes */ /* REMARK: Harmless const castaway */ ((ulRTTITypeinfo**)b)[i]->add_subtype ( this ) ; } ulRTTITypeinfo::~ulRTTITypeinfo () { delete [] n ; for ( int i = 0 ; b[i] ; i++ ) /* Del this subtype from all its basetypes */ /* REMARK: Harmless const castaway */ ((ulRTTITypeinfo**)b)[i]->del_subtype ( this ) ; } void ulRTTITypeinfo::add_subtype ( const ulRTTITypeinfo *t ) /* Adds t as last ulRTTITypeinfo in the 'subtypes' list. For this, the list is realloc'd with one extra entry. */ { const ulRTTITypeinfo **ptr = new const ulRTTITypeinfo*[ns+1] ; int i ; for ( i = 0 ; i < ns ; i++ ) ptr[i] = subtypes[i] ; ptr[i] = t ; ns++ ; delete[] subtypes ; subtypes = ptr ; } void ulRTTITypeinfo::del_subtype ( const ulRTTITypeinfo* t ) /* Searches for t in the subtypes list of this and removes it, if found. */ { int i ; for ( i = 0 ; i < ns && subtypes[i] != t ; i++ ) ; if ( i < ns ) for(; i < ns-1 ; i++ ) subtypes[i] = subtypes[i+1] ; } void * ulRTTITypeinfo::create ( const ulRTTITypeinfo* bt, const char *c ) const /* Tries to create an obj of type-name given by char*. Searches for this type in the type-DAG rooted by this, creates it and returns it as cast to 'bt', where bt is either this or a direct base of this. */ { void *p = NULL ; int i ; if ( !strcmp ( c, n ) ) /* Want to create an obj of this type ? */ /* Yes, do it if this type is instantiable. */ p = (new_obj) ? new_obj () : 0 ; else /* No, try with subclasses... */ for ( i = 0 ; i < ns && !( ( p = subtypes[i]->create ( this, c ) ) ) ; i++ ) ; /* Succeeded creating on ith subclass branch ? */ if ( !p ) return 0 ; /* Couldn't create it in any way, abort. */ if ( bt == this ) i = -1 ; /* Must cast to this's own type (i==-1) */ else /* Search to which base of this we should cast */ for ( i = 0 ; b[i] && b[i] != bt ; i++ ) ; /* Found: cast to ith base of this */ return cast(i,p) ; /* Cast to ith base of to this, return as void* */ } plib-1.8.5/src/util/ulError.cxx0000644000175000001440000000405010765364437013330 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ulError.cxx 1967 2004-10-02 12:20:43Z wolfram_kuss $ */ #include "ul.h" static char _ulErrorBuffer [ 1024 ] = { '\0' } ; static ulErrorCallback _ulErrorCB = 0 ; static const char* _ulSeverityText [ UL_MAX_SEVERITY ] = { "DEBUG", "WARNING", "FATAL", }; void ulSetError ( enum ulSeverity severity, const char *fmt, ... ) { va_list argp; va_start ( argp, fmt ) ; vsprintf ( _ulErrorBuffer, fmt, argp ) ; va_end ( argp ) ; if ( _ulErrorCB ) { (*_ulErrorCB)( severity, _ulErrorBuffer ) ; } else { fprintf ( stderr, "%s: %s\n", _ulSeverityText[ severity ], _ulErrorBuffer ) ; if ( severity == UL_FATAL ) { #ifdef WIN32 // A Windows user that does not start the program from the command line // will not see output to stderr ::MessageBox(0, _ulErrorBuffer, "fatal error!:", 0); #endif exit (1) ; } } } char* ulGetError ( void ) { return _ulErrorBuffer ; } void ulClearError ( void ) { _ulErrorBuffer [0] = 0 ; } ulErrorCallback ulGetErrorCallback ( void ) { return _ulErrorCB ; } void ulSetErrorCallback ( ulErrorCallback cb ) { _ulErrorCB = cb ; } plib-1.8.5/src/util/ulRTTI.h0000644000175000001440000003051510765364437012453 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ /* Originally written by: Alexandru C. Telea */ /* This file provides support for RTTI and generalized (virtual-base to derived and separate hierarchy branches) casting. There is also support for RT obj creation from type names. In order to enable these features for a class, two things should be done: 1) insert the text UL_TYPE_DATA (without ';') in the class-decl. 2) in the .C file where the class's implementation resides, insert the following (without';'): UL_RTTI_DEF(classname) if the class has no bases with RTTI UL_RTTI_DEFn(classname,b1,...bn) if the class has bases b1,...bn with RTTI Use UL_RTTI_DEF_INST instead of UL_RTTI_DEF if you want to enable RT obj creation for classname. You should provide then a public default ctor. RTTI is used via a class called ulRTTItypeid. A typeid describes a type of a class. [..] They should provide all necessary support for any kind of RTTI/casting [..]. [..] REMARK: There are two classes related to RTTI: ulRTTItypeid and ======= ulRTTITypeinfo. A ulRTTItypeid is, as it says, an 'id for a type'. It actually wraps a ulRTTITypeinfo*, where a ulRTTITypeinfo contains the actual encoding of a class type. You can freely create/copy/destroy/manipulate ulRTTItypeid's, but you should NEVER deal directly with ulRTTITypeinfo. A ulRTTITypeinfo should actually be created ONLY by the UL_TYPE_DATA macros, as part of a class definition, since the ulRTTITypeinfo encodes a type info for an EXISTING class [..]. All type-related stuff should be therefore handled via ulRTTItypeid's. */ #ifndef _UL_RTTI_H_ #define _UL_RTTI_H_ #include #include "ul.h" class ulRTTITypeinfo /* Implementation of type-related info */ { private: char *n ; /* type name */ /* base types (NULL-ended array of ulRTTITypeinfo's for this's direct bases) */ const ulRTTITypeinfo** b ; int ns ; /* #subtypes of this type */ const ulRTTITypeinfo **subtypes ; /* types derived from this type */ /* convenience type info for a 'null' type */ static const ulRTTITypeinfo null_type ; void* (*new_obj)() ; /* func to create a new obj of this type */ void* (*cast)(int,void*) ; /* func to cast an obj of this type to ith baseclass of it or to itself */ /* adds a subtype to this's subtypes[] */ void add_subtype ( const ulRTTITypeinfo * ) ; /* dels a subtype from this's subtypes[] */ void del_subtype ( const ulRTTITypeinfo* ) ; friend class ulRTTItypeid ; /* for null_type */ public: ulRTTITypeinfo ( const char* name, const ulRTTITypeinfo* bb[], void* (*)(int,void*),void* (*)() ) ; ~ulRTTITypeinfo () ; /* Returns name of this ulRTTITypeinfo */ const char* getname () const { return n ; } /* Compares 2 ulRTTITypeinfo objs */ bool same ( const ulRTTITypeinfo *p ) const { /* First, try to see if it's the same 'physical' ulRTTITypeinfo (which should be the case, since we create them per-class and not per-obj). */ return ( this == p ) || !strcmp ( n, p->n ) ; } /* true if the arg can be cast to this, else false */ bool can_cast ( const ulRTTITypeinfo *p ) const { return same ( p ) || p->has_base ( this ) ; } /* true if this has the arg as some base, else false */ bool has_base ( const ulRTTITypeinfo *p ) const { for ( int i = 0 ; b[i] != NULL ; i++ ) /* for all bases of this... */ /* match found, return 1 or no match, search deeper */ if ( p->same ( b[i] ) || b[i]->has_base ( p ) ) return true ; return false ; /* no match at all, return false */ } /* get i-th subclass of this, if any, else NULL */ const ulRTTITypeinfo * subclass ( int i = 0 ) const { return ( i >= 0 && i < ns ) ? subtypes[i] : NULL ; } int num_subclasses () const { return ns ; } /* get # subclasses of this */ /* search for a subclass named char*, create obj of it and return it cast to the ulRTTITypeinfo* type, which is either this or a direct base of this. */ void * create ( const ulRTTITypeinfo *, const char * ) const ; /* Returns true if this type has a default ctor, else false */ bool can_create () const { return new_obj != NULL ; } } ; class ulRTTItypeid /* Main class for RTTI interface */ { protected: /* ulRTTItypeid implementation (the only data-member) */ const ulRTTITypeinfo* id ; public: /* Not for application use ! */ const ulRTTITypeinfo* get_info () const { return id ; } ulRTTItypeid ( const ulRTTITypeinfo* p ) : id ( p ) { } ulRTTItypeid () : id ( &ulRTTITypeinfo::null_type ) { } /* Compares 2 ulRTTItypeid objs */ bool isSame ( ulRTTItypeid i ) const { return id->same ( i.id ) ; } /* true if the arg can be cast to this, else false */ bool canCast ( ulRTTItypeid i ) const { return id->can_cast ( i.id ) ; } const char * getName () const { return id->getname () ; } /* Return # subclasses of this */ int getNumSubclasses () const { return id->num_subclasses () ; } /* Return ith subclass of this */ ulRTTItypeid getSubclass ( int i ) const { return id->subclass ( i ) ; } /* Return # baseclasses of this */ int getNumBaseclasses () const { int i ; for ( i = 0 ; id->b[i] != NULL ; i++ ) ; return i ; } /* Return ith baseclass of this */ ulRTTItypeid getBaseclass ( int i ) const { return id->b[i] ; } /* Tries to create an instance of a subclass of this having of type given by the ulRTTItypeid arg. If ok, it returns it casted to the class-type of this and then to void* */ void * create ( ulRTTItypeid t ) const { return id->create ( id, t.getName () ) ; } /* Returns true if this type is instantiable, else false */ bool canCreate () const { return id->can_create () ; } } ; class ulRTTIdyntypeid : public ulRTTItypeid /* Class for dynamic type creation from user strings. Useful for creating typeids at RT for comparison purposes. */ { private: static const ulRTTITypeinfo *a[] ; public: ulRTTIdyntypeid ( const char *c ) : /* create a dummy ulRTTITypeinfo */ ulRTTItypeid ( new ulRTTITypeinfo ( c, a, NULL, NULL ) ) { } ~ulRTTIdyntypeid () { delete id ; /* delete the dummy ulRTTITypeinfo */ } } ; /* Macros */ /* 'ulRTTItypeid' UL_STATIC_TYPE_INFO(T) T=RTTI-class name. Returns a ulRTTItypeid with T's type. If T hasn't RTTI, a compile-time error occurs. */ #define UL_STATIC_TYPE_INFO(T) T::RTTI_sinfo() /* 'T*' UL_PTR_CAST(T,p) T=RTTI-class, p=RTTI-class ptr. Returns p cast to the type T as a T*, if cast is possible, else returns NULL. If *p or T have no RTTI, a compile-time error occurs. Note that p can point to virtual base classes. Casting between separat branches of a class hierarchy is also supported, as long as all classes have RTTI. Therefore UL_PTR_CAST is a fully general and safe operator. If p==NULL, the operator returns NULL. */ #define UL_PTR_CAST(T,p) ((p != NULL)? (T*)((p)->RTTI_cast(UL_STATIC_TYPE_INFO(T))) : NULL) /* 'T*' UL_TYPE_NEW(T,t) T=RTTI-class, t=ulRTTItypeid Returns a new object of type t cast to the type T as a T*. t must represent a type identical to or derived from T. If t is not a type derived from T or not an instantiable type having a default constructor, NULL is returned. */ #define UL_TYPE_NEW(T,t) ((T*)t.create(T)) /* Definition of TYPE_DATA for a RTTI-class: introduces one static ulRTTITypeinfo data-member and a couple of virtuals. */ #define UL_TYPE_DATA \ protected: \ static const ulRTTITypeinfo RTTI_obj; \ static void* RTTI_scast(int,void*); \ static void* RTTI_new(); \ virtual ulRTTItypeid RTTI_vinfo() const { return &RTTI_obj; }\ public: \ static ulRTTItypeid RTTI_sinfo() { return &RTTI_obj; }\ virtual void* RTTI_cast(ulRTTItypeid); /* Definition of auxiliary data-structs supporting RTTI for a class: defines the static ulRTTITypeinfo object of that class and its associated virtuals. */ /* Auxiliary definition of the construction method: */ #define UL_RTTI_NEW(cls) void* cls::RTTI_new() { return new cls; } \ const ulRTTITypeinfo cls::RTTI_obj(#cls,RTTI_base_ ## cls,cls::RTTI_scast,cls::RTTI_new); #define UL_RTTI_NO_NEW(cls) const ulRTTITypeinfo cls::RTTI_obj(#cls,RTTI_base_ ## cls,cls::RTTI_scast,NULL); /* Top-level macros: */ #define UL_RTTI_DEF_BASE(cls) \ static const ulRTTITypeinfo* RTTI_base_ ## cls [] = { NULL }; \ void* cls::RTTI_cast(ulRTTItypeid t) \ { \ if (t.isSame(&RTTI_obj)) return this; \ return NULL; \ } \ void* cls::RTTI_scast(int i,void* p) \ { cls* ptr = (cls*)p; return ptr; } #define UL_RTTI_DEF1_BASE(cls,b1) \ static const ulRTTITypeinfo* RTTI_base_ ## cls [] = \ { UL_STATIC_TYPE_INFO(b1).get_info(), NULL }; \ void* cls::RTTI_cast(ulRTTItypeid t) \ { \ if (t.isSame(&RTTI_obj)) return this; \ void* ptr; \ if ((ptr=b1::RTTI_cast(t))) return ptr; \ return NULL; \ } \ void* cls::RTTI_scast(int i,void* p) \ { cls* ptr = (cls*)p; \ switch(i) \ { case 0: return (b1*)ptr; } \ return ptr; \ } #define UL_RTTI_DEF2_BASE(cls,b1,b2) \ static const ulRTTITypeinfo* RTTI_base_ ## cls [] = \ { UL_STATIC_TYPE_INFO(b1).get_info(), \ UL_STATIC_TYPE_INFO(b2).get_info(), NULL }; \ void* cls::RTTI_cast(ulRTTItypeid t) \ { \ if (t.isSame(&RTTI_obj)) return this; \ void* ptr; \ if ((ptr=b1::RTTI_cast(t))) return ptr; \ if ((ptr=b2::RTTI_cast(t))) return ptr; \ return NULL; \ } \ void* cls::RTTI_scast(int i,void* p) \ { cls* ptr = (cls*)p; \ switch(i) \ { case 0: return (b1*)ptr; \ case 1: return (b2*)ptr; \ } \ return ptr; \ } #define UL_RTTI_DEF3_BASE(cls,b1,b2,b3) \ static const ulRTTITypeinfo* RTTI_base_ ## cls [] = \ { UL_STATIC_TYPE_INFO(b1).get_info(), \ UL_STATIC_TYPE_INFO(b2).get_info(), \ UL_STATIC_TYPE_INFO(b3).get_info(), NULL }; \ void* cls::RTTI_cast(ulRTTItypeid t) \ { \ if (t.isSame(&RTTI_obj)) return this; \ void* ptr; \ if ((ptr=b1::RTTI_cast(t))) return ptr; \ if ((ptr=b2::RTTI_cast(t))) return ptr; \ if ((ptr=b3::RTTI_cast(t))) return ptr; \ return NULL; \ } \ void* cls::RTTI_scast(int i,void* p) \ { cls* ptr = (cls*)p; \ switch(i) \ { case 0: return (b1*)ptr; \ case 1: return (b2*)ptr; \ case 2: return (b3*)ptr; \ } \ return ptr; \ } #define UL_RTTI_DEF_INST(cls) \ UL_RTTI_DEF_BASE(cls) \ UL_RTTI_NEW(cls) #define UL_RTTI_DEF(cls) \ UL_RTTI_DEF_BASE(cls) \ UL_RTTI_NO_NEW(cls) #define UL_RTTI_DEF1_INST(cls,b1) \ UL_RTTI_DEF1_BASE(cls,b1) \ UL_RTTI_NEW(cls) #define UL_RTTI_DEF1(cls,b1) \ UL_RTTI_DEF1_BASE(cls,b1) \ UL_RTTI_NO_NEW(cls) #define UL_RTTI_DEF2_INST(cls,b1,b2) \ UL_RTTI_DEF2_BASE(cls,b1,b2) \ UL_RTTI_NEW(cls) #define UL_RTTI_DEF2(cls,b1,b2) \ UL_RTTI_DEF2_BASE(cls,b1,b2) \ UL_RTTI_NO_NEW(cls) #define UL_RTTI_DEF3_INST(cls,b1,b2,b3) \ UL_RTTI_DEF3_BASE(cls,b1,b2,b3) \ UL_RTTI_NEW(cls) #define UL_RTTI_DEF3(cls,b1,b2,b3) \ UL_RTTI_DEF3_BASE(cls,b1,b2,b3) \ UL_RTTI_NO_NEW(cls) #endif plib-1.8.5/src/util/Makefile.in0000644000175000001440000003726110765365024013222 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/util DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibul_a_AR = $(AR) $(ARFLAGS) libplibul_a_LIBADD = am__libplibul_a_SOURCES_DIST = ul.cxx ulClock.cxx ulError.cxx \ ulLinkedList.cxx ulList.cxx ulLocal.h ulRTTI.cxx @BUILD_UL_TRUE@am_libplibul_a_OBJECTS = ul.$(OBJEXT) ulClock.$(OBJEXT) \ @BUILD_UL_TRUE@ ulError.$(OBJEXT) ulLinkedList.$(OBJEXT) \ @BUILD_UL_TRUE@ ulList.$(OBJEXT) ulRTTI.$(OBJEXT) libplibul_a_OBJECTS = $(am_libplibul_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libplibul_a_SOURCES) DIST_SOURCES = $(am__libplibul_a_SOURCES_DIST) am__include_HEADERS_DIST = ul.h ulRTTI.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_UL_TRUE@lib_LIBRARIES = libplibul.a @BUILD_UL_TRUE@include_HEADERS = ul.h ulRTTI.h @BUILD_UL_TRUE@libplibul_a_SOURCES = ul.cxx ulClock.cxx ulError.cxx ulLinkedList.cxx \ @BUILD_UL_TRUE@ ulList.cxx ulLocal.h ulRTTI.cxx EXTRA_DIST = ul.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/util/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/util/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibul.a: $(libplibul_a_OBJECTS) $(libplibul_a_DEPENDENCIES) -rm -f libplibul.a $(libplibul_a_AR) libplibul.a $(libplibul_a_OBJECTS) $(libplibul_a_LIBADD) $(RANLIB) libplibul.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ul.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulClock.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulError.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulLinkedList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulRTTI.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/util/ulClock.cxx0000644000175000001440000000516410765364437013301 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ulClock.cxx 1735 2002-12-01 18:21:48Z sjbaker $ */ #include #include #include "ul.h" #ifdef UL_CYGWIN typedef long long _int64; #define LARGEINTEGER _int64 #endif #ifndef UL_WIN32 # include #endif #include #ifdef UL_WIN32 double ulClock::res ; int ulClock::perf_timer = -1; void ulClock::initPerformanceTimer () { if ( perf_timer == -1 ) { /* Use Performance Timer if it's available, mmtimer if not. */ __int64 frequency ; perf_timer = QueryPerformanceFrequency ( (LARGE_INTEGER *) & frequency ) ; if ( perf_timer ) { res = 1.0 / (double) frequency ; perf_timer = 1 ; } } } #endif double ulClock::getRawTime () const { #ifdef UL_WIN32 /* Use Performance Timer if it's available, mmtimer if not. */ if ( perf_timer ) { __int64 t ; QueryPerformanceCounter ( (LARGE_INTEGER *) &t ) ; return res * (double) t ; } return (double) timeGetTime() * 0.001 ; #else timeval tv ; gettimeofday ( & tv, NULL ) ; return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; #endif } void ulClock::update () { now = getRawTime() - start ; delta = now - last_time ; /* KLUDGE: If the frame rate drops below ~5Hz, then control will be very difficult. It's actually easier to give up and slow down the action. max_delta defaults to 200ms for that reason. KLUDGE: If update is called very rapidly, then delta can be zero which causes some programs to div0. So we'll clamp to a millionth of a second. */ if ( delta > max_delta ) delta = max_delta ; if ( delta <= 0.0 ) delta = 0.0000001 ; last_time = now ; } plib-1.8.5/src/util/ulList.cxx0000644000175000001440000000531010765364437013152 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ulList.cxx 1732 2002-11-30 00:41:50Z sjbaker $ */ #include "ul.h" ulList::ulList ( int init ) { total = 0 ; next = 0 ; entity_list = new void * [ limit = (init <= 0) ? 1 : init ] ; } ulList::~ulList (void) { removeAllEntities () ; delete [] entity_list ; } void ulList::addEntity ( void *entity ) { sizeChk () ; entity_list [ total++ ] = entity ; } void ulList::addEntityBefore ( int i, void *entity ) { sizeChk () ; memmove ( &entity_list[i+1], &entity_list[i], sizeof(void *) * (total-i) ) ; entity_list [ i ] = entity ; total++ ; } void ulList::sizeChk (void) { /* Room for one more Entity? */ if ( total >= limit ) { limit += limit ; void **nlist = new void * [ limit ] ; memmove ( nlist, entity_list, sizeof(void *) * total ) ; delete [] entity_list ; entity_list = nlist ; } } int ulList::searchForEntity ( void *entity ) const { for ( unsigned int i = 0 ; i < total ; i++ ) if ( entity_list [ i ] == entity ) return (int) i ; return -1 ; } void ulList::removeAllEntities () { while ( total > 0 ) removeEntity ( (unsigned int) 0 ) ; } void ulList::removeEntity ( unsigned int n ) { memmove ( &(entity_list[n]), &(entity_list[n+1]), sizeof(void *) * (total-n-1) ) ; total-- ; if ( next >= n ) next-- ; } void ulList::replaceEntity ( unsigned int n, void *new_entity ) { if ( n >= 0 ) entity_list [ n ] = new_entity; else addEntity ( new_entity ) ; } plib-1.8.5/src/pui/0000777000175000001440000000000010765365517011057 500000000000000plib-1.8.5/src/pui/puPW.h0000644000175000001440000000331510765364437012041 00000000000000 /* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puPW.h 1863 2004-02-17 01:43:21Z sjbaker $ */ #ifndef _PU_PW_H_ #define _PU_PW_H_ #include "pu.h" #define PUPW_WINDOW_MAGIC 0x3DEB4938 /* Random! */ inline int puGetWindowPW() { return PUPW_WINDOW_MAGIC ; } inline void puSetWindowPW ( int window ) { // Not possible because PW is a single-window library. // But we can at least check that the handle matches. assert ( window == PUPW_WINDOW_MAGIC ) ; } inline void puGetWindowSizePW ( int *width, int *height ) { pwGetSize ( width, height ) ; } inline void puSetWindowSizePW ( int width, int height ) { pwSetSize ( width, height ) ; } inline void puInitPW () { puSetWindowFuncs ( puGetWindowPW, puSetWindowPW, puGetWindowSizePW, puSetWindowSizePW ) ; puRealInit () ; } #endif plib-1.8.5/src/pui/puText.cxx0000644000175000001440000000227410765364437013015 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puText.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "puLocal.h" UL_RTTI_DEF1(puText,puObject) void puText::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; draw_label ( dx, dy ) ; } plib-1.8.5/src/pui/puObject.cxx0000644000175000001440000003356310765364437013304 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puObject.cxx 2051 2005-11-10 20:21:22Z fayjf $ */ #include "puLocal.h" UL_RTTI_DEF1(puObject,puValue) static inline float clamp01 ( float x ) { return (x >= 1.0f) ? 1.0f : x ; } static puColour _puDefaultColourTable[] = { { 0.5f, 0.5f, 0.5f, 1.0f }, /* PUCOL_FOREGROUND */ { 0.3f, 0.3f, 0.3f, 1.0f }, /* PUCOL_BACKGROUND */ { 0.7f, 0.7f, 0.7f, 1.0f }, /* PUCOL_HIGHLIGHT */ { 0.0f, 0.0f, 0.0f, 1.0f }, /* PUCOL_LABEL */ { 1.0f, 1.0f, 1.0f, 1.0f }, /* PUCOL_LEGEND */ { 0.0f, 0.0f, 0.0f, 1.0f }, /* PUCOL_MISC */ { 0.8f, 0.7f, 0.7f, 1.0f } /* PUCOL_EDITFIELD */ } ; static void load_colour_scheme ( float col[][4], float r, float g, float b, float a ) { puSetColour ( col [ PUCOL_FOREGROUND ], r, g, b, a ) ; puSetColour ( col [ PUCOL_BACKGROUND ], r/2.0f, g/2.0f, b/2.0f, a ) ; puSetColour ( col [ PUCOL_HIGHLIGHT ], clamp01(r*1.3f), clamp01(g*1.3f), clamp01(b*1.3f), a ) ; if ( 4.0f * g + 3.0f * r + b > 4.0f ) { puSetColour ( col [ PUCOL_LEGEND ], 0.0f, 0.0f, 0.0f, a ) ; puSetColour ( col [ PUCOL_MISC ], 0.0f, 0.0f, 0.0f, a ) ; } else { puSetColour ( col [ PUCOL_LEGEND ], 1.0f, 1.0f, 1.0f, a ) ; puSetColour ( col [ PUCOL_MISC ], 1.0f, 1.0f, 1.0f, a ) ; } } static int defaultStyle = PUSTYLE_DEFAULT ; static int defaultBorderThickness = 5 ; static puFont defaultLegendFont ; static puFont defaultLabelFont ; static float defaultColourScheme [ 4 ] ; void puSetDefaultStyle ( int style ) { defaultStyle = style ; switch ( abs(style) ) { case PUSTYLE_SPECIAL_UNDERLINED : defaultBorderThickness = 1 ; break ; case PUSTYLE_SMALL_BEVELLED : case PUSTYLE_SMALL_SHADED : case PUSTYLE_BOXED : defaultBorderThickness = 2 ; break ; case PUSTYLE_BEVELLED : case PUSTYLE_SHADED : case PUSTYLE_DROPSHADOW : defaultBorderThickness = 5 ; break ; } } int puGetDefaultStyle ( void ) { return defaultStyle ; } void puSetDefaultBorderThickness ( int t ) { defaultBorderThickness = t ; } int puGetDefaultBorderThickness ( void ) { return defaultBorderThickness ; } void puSetDefaultFonts ( puFont legendFont, puFont labelFont ) { defaultLegendFont = legendFont ; defaultLabelFont = labelFont ; } puFont puGetDefaultLabelFont ( void ) { return defaultLabelFont ; } puFont puGetDefaultLegendFont ( void ) { return defaultLegendFont ; } void puGetDefaultFonts ( puFont *legendFont, puFont *labelFont ) { if ( legendFont ) *legendFont = defaultLegendFont ; if ( labelFont ) *labelFont = defaultLabelFont ; } void puSetDefaultColourScheme ( float r, float g, float b, float a ) { defaultColourScheme[0] = r ; defaultColourScheme[1] = g ; defaultColourScheme[2] = b ; defaultColourScheme[3] = a ; load_colour_scheme ( _puDefaultColourTable, r, g, b, a ) ; } void puGetDefaultColourScheme ( float *r, float *g, float *b, float *a ) { if ( r ) *r = defaultColourScheme[0] ; if ( g ) *g = defaultColourScheme[1] ; if ( b ) *b = defaultColourScheme[2] ; if ( a ) *a = defaultColourScheme[3] ; } void puObject::setColourScheme ( float r, float g, float b, float a ) { load_colour_scheme ( colour, r, g, b, a ) ; puPostRefresh () ; } puObject::puObject ( int minx, int miny, int maxx, int maxy ) : puValue () { type |= PUCLASS_OBJECT ; bbox.min[0] = abox.min[0] = minx ; bbox.min[1] = abox.min[1] = miny ; bbox.max[0] = abox.max[0] = maxx ; bbox.max[1] = abox.max[1] = maxy ; active_mouse_edge = PU_UP ; active_mouse_button = PU_LEFT_BUTTON ; style = defaultStyle ; visible = active = TRUE ; highlighted = FALSE ; am_default = FALSE ; window = puGetWindow () ; v_status = 0 ; cb = NULL ; active_cb = NULL ; down_cb = NULL ; r_cb = NULL ; border_thickness = defaultBorderThickness ; render_data = NULL ; user_data = NULL ; next = prev = NULL ; label = NULL ; labelPlace = PUPLACE_LABEL_DEFAULT ; labelFont = defaultLabelFont ; legend = NULL ; legendFont = defaultLegendFont ; legendPlace = PUPLACE_LEGEND_DEFAULT ; when_to_deactivate = PUDEACTIVATE_ON_MOUSE_CLICK ; for ( int i = 0 ; i < PUCOL_MAX ; i++ ) puSetColour ( colour[i], _puDefaultColourTable[i] ) ; parent = NULL ; if ( ! puNoGroup() ) puGetCurrGroup() -> add ( this ) ; puPostRefresh () ; } puObject::~puObject () { if ( parent != this && parent != NULL ) parent -> remove ( this ) ; if ( this == puActiveWidget () ) puDeactivateWidget () ; puPostRefresh () ; } void puObject::recalc_bbox ( void ) { bbox = abox ; if ( label != NULL ) { switch ( labelPlace ) // Extend the bounding box left and right { case PUPLACE_ABOVE_LEFT : case PUPLACE_UPPER_LEFT : case PUPLACE_CENTERED_LEFT : case PUPLACE_LOWER_LEFT : case PUPLACE_BELOW_LEFT : bbox.min[0] -= labelFont.getStringWidth ( label ) + PUSTR_LGAP ; break ; case PUPLACE_ABOVE_RIGHT : case PUPLACE_UPPER_RIGHT : case PUPLACE_CENTERED_RIGHT : case PUPLACE_LOWER_RIGHT : case PUPLACE_BELOW_RIGHT : bbox.max[0] += labelFont.getStringWidth ( label ) + PUSTR_RGAP ; break ; } switch ( labelPlace ) // Extend the bounding box up and down { case PUPLACE_ABOVE_LEFT : case PUPLACE_TOP_LEFT : case PUPLACE_TOP_CENTERED : case PUPLACE_TOP_RIGHT : case PUPLACE_ABOVE_RIGHT : bbox.max[1] += labelFont.getStringHeight ( label ) + labelFont.getStringDescender () + PUSTR_TGAP ; break ; case PUPLACE_BELOW_LEFT : case PUPLACE_BOTTOM_LEFT : case PUPLACE_BOTTOM_CENTERED : case PUPLACE_BOTTOM_RIGHT : case PUPLACE_BELOW_RIGHT : bbox.min[1] -= labelFont.getStringHeight ( label ) + labelFont.getStringDescender () + PUSTR_BGAP ; break ; } } if ( parent != NULL ) parent -> recalc_bbox () ; } void puObject::getAbsolutePosition ( int *x, int *y ) const { puGroup *par ; *x = abox.min[0] ; *y = abox.min[1] ; for ( par = getParent () ; par != NULL ; par = par -> getParent () ) { int x_offset, y_offset ; par -> getPosition ( &x_offset, &y_offset ) ; *x += x_offset ; *y += y_offset ; } } void puObject::draw_legend ( int dx, int dy ) { if ( legend == NULL ) return ; int xx, yy ; int lgap = PUSTR_LGAP ; int rgap = PUSTR_RGAP ; int tgap = PUSTR_TGAP ; int bgap = PUSTR_BGAP ; if ( ( abs(style) != PUSTYLE_NONE ) && ( abs(style) != PUSTYLE_PLAIN ) && ( abs(style) != PUSTYLE_DROPSHADOW ) ) { if ( abs(style) != PUSTYLE_SPECIAL_UNDERLINED ) { lgap += getBorderThickness () ; rgap += getBorderThickness () ; tgap += getBorderThickness () ; } bgap += getBorderThickness () ; } /* If greyed out then halve the opacity when drawing the legend */ if ( active ) glColor4fv ( colour [ PUCOL_LEGEND ] ) ; else glColor4f ( colour [ PUCOL_LEGEND ][0], colour [ PUCOL_LEGEND ][1], colour [ PUCOL_LEGEND ][2], colour [ PUCOL_LEGEND ][3] / 2.0f ) ; /* 50% more transparent */ switch ( getLegendPlace() ) { case PUPLACE_TOP_LEFT : case PUPLACE_CENTERED_LEFT : case PUPLACE_BOTTOM_LEFT : case PUPLACE_LOWER_LEFT : xx = lgap ; break ; case PUPLACE_TOP_CENTERED : case PUPLACE_CENTERED_CENTERED : case PUPLACE_BOTTOM_CENTERED : xx = ( abox.max[0] - abox.min[0] - legendFont.getStringWidth (legend) ) / 2 ; break ; case PUPLACE_TOP_RIGHT : case PUPLACE_CENTERED_RIGHT : case PUPLACE_BOTTOM_RIGHT : case PUPLACE_LOWER_RIGHT : xx = abox.max[0] - abox.min[0] - legendFont.getStringWidth ( legend ) - rgap ; break ; default : ulSetError ( UL_WARNING, "PUI: Unrecognised LEGEND place %d", getLegendPlace() ) ; return ; } switch ( getLegendPlace() ) { case PUPLACE_TOP_LEFT : case PUPLACE_TOP_CENTERED : case PUPLACE_TOP_RIGHT : yy = abox.max[1] - abox.min[1] - legendFont.getStringHeight ( legend ) - legendFont.getStringDescender () - tgap ; break ; case PUPLACE_CENTERED_LEFT : case PUPLACE_CENTERED_CENTERED : case PUPLACE_CENTERED_RIGHT : case PUPLACE_LOWER_LEFT : /* Backwards compatibility to PUPLACE_LEFT */ case PUPLACE_LOWER_RIGHT : /* Backwards compatibility to PUPLACE_RIGHT */ default : yy = ( abox.max[1] - abox.min[1] - legendFont.getStringHeight ( legend ) ) / 2 + legendFont.getStringDescender () ; break ; case PUPLACE_BOTTOM_LEFT : case PUPLACE_BOTTOM_CENTERED : case PUPLACE_BOTTOM_RIGHT : yy = bgap + legendFont.getStringDescender () ; break ; } legendFont.drawString ( legend, dx + abox.min[0] + xx, dy + abox.min[1] + yy ) ; } void puObject::draw_label ( int dx, int dy ) { if ( label == NULL ) return ; int xx, yy ; /* If greyed out then halve the opacity when drawing the label */ if ( active ) glColor4fv ( colour [ PUCOL_LABEL ] ) ; else glColor4f ( colour [ PUCOL_LABEL ][0], colour [ PUCOL_LABEL ][1], colour [ PUCOL_LABEL ][2], colour [ PUCOL_LABEL ][3] / 2.0f ) ; /* 50% more transparent */ switch ( getLabelPlace() ) { case PUPLACE_ABOVE_LEFT : case PUPLACE_UPPER_LEFT : case PUPLACE_CENTERED_LEFT : case PUPLACE_LOWER_LEFT : case PUPLACE_BELOW_LEFT : xx = 0 ; break ; case PUPLACE_TOP_LEFT : case PUPLACE_BOTTOM_LEFT : xx = abox.min[0] - bbox.min[0] + PUSTR_LGAP ; break ; case PUPLACE_TOP_CENTERED : case PUPLACE_BOTTOM_CENTERED : xx = ( bbox.max[0] - bbox.min[0] - labelFont.getStringWidth ( label ) ) / 2 ; break ; case PUPLACE_TOP_RIGHT : case PUPLACE_BOTTOM_RIGHT : xx = abox.max[0] - bbox.min[0] - labelFont.getStringWidth ( label ) - PUSTR_RGAP ; break ; case PUPLACE_ABOVE_RIGHT : case PUPLACE_UPPER_RIGHT : case PUPLACE_CENTERED_RIGHT : case PUPLACE_LOWER_RIGHT : case PUPLACE_BELOW_RIGHT : xx = bbox.max[0] - bbox.min[0] - labelFont.getStringWidth ( label ) ; break ; default : ulSetError ( UL_WARNING, "PUI: Unrecognised LABEL place %d", getLegendPlace() ) ; return ; } switch ( getLabelPlace() ) { case PUPLACE_ABOVE_LEFT : case PUPLACE_TOP_LEFT : case PUPLACE_TOP_CENTERED : case PUPLACE_TOP_RIGHT : case PUPLACE_ABOVE_RIGHT : yy = bbox.max[1] - bbox.min[1] - labelFont.getStringHeight () - labelFont.getStringDescender () ; break ; case PUPLACE_UPPER_LEFT : case PUPLACE_UPPER_RIGHT : yy = abox.max[1] - bbox.min[1] - labelFont.getStringHeight ( label ) - PUSTR_TGAP ; break ; case PUPLACE_CENTERED_LEFT : case PUPLACE_CENTERED_RIGHT : default : yy = ( bbox.max[1] - bbox.min[1] - labelFont.getStringHeight ( label ) ) / 2 + labelFont.getStringDescender () ; break ; case PUPLACE_LOWER_LEFT : case PUPLACE_LOWER_RIGHT : yy = abox.min[1] - bbox.min[1] + labelFont.getStringDescender () + PUSTR_BGAP ; break ; case PUPLACE_BELOW_LEFT : case PUPLACE_BOTTOM_LEFT : case PUPLACE_BOTTOM_CENTERED : case PUPLACE_BOTTOM_RIGHT : case PUPLACE_BELOW_RIGHT : yy = labelFont.getStringDescender () ; break ; } labelFont.drawString ( label, dx + bbox.min[0] + xx, dy + bbox.min[1] + yy ) ; } int puObject::checkKey ( int key, int updown ) { if ( updown == PU_UP ) return FALSE ; if ( isReturnDefault() && ( key == '\r' || key == '\n' ) && ( window == puGetWindow () ) ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } checkHit ( active_mouse_button, PU_DOWN, (abox.min[0]+abox.max[0])/2, (abox.min[1]+abox.max[1])/2 ) ; checkHit ( active_mouse_button, PU_UP , (abox.min[0]+abox.max[0])/2, (abox.min[1]+abox.max[1])/2 ) ; return TRUE ; } return FALSE ; } void puObject::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); if ( button == active_mouse_button ) { if ( ( updown == active_mouse_edge ) || ( active_mouse_edge == PU_UP_AND_DOWN ) ) { lowlight () ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } else highlight () ; } else lowlight () ; } int puObject::checkHit ( int button, int updown, int x, int y ) { if ( ( puGetPressedButton () || ( updown == PU_UP ) ) && isHit( x, y ) || puGetPressedButton () && ( isHit( x, y ) || ( puActiveWidget () == this ) ) ) { doHit ( button, updown, x, y ) ; return TRUE ; } return FALSE ; } plib-1.8.5/src/pui/puInput.cxx0000644000175000001440000003064710765364437013175 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puInput.cxx 2093 2006-10-26 20:39:14Z fayjf $ */ #include "puLocal.h" UL_RTTI_DEF2(puInput,puInputBase,puObject) static char *chop_to_width ( puFont fnt, const char *s, int width, int cursor_position, int *display_starting_point ) { int new_len = strlen ( s ) ; char *res = new char [ new_len + 1 ] ; int n = 0 ; int w ; if ( new_len == 0 ) { *res = '\0' ; if ( display_starting_point != NULL ) *display_starting_point = 0 ; } else { do { memcpy ( res, s + n, new_len + 1 ) ; n++ ; new_len -- ; w = fnt.getStringWidth ( res ) + 2 * PUSTR_RGAP + PUSTR_LGAP ; } while ( ( w >= width ) && ( n < cursor_position - 1 ) ) ; if ( display_starting_point != NULL ) *display_starting_point = n - 1 ; n = 0 ; while ( w >= width ) { res[new_len] = '\0' ; n++ ; new_len -- ; w = fnt.getStringWidth ( res ) + 2 * PUSTR_RGAP + PUSTR_LGAP ; } } return res ; } void puInput::draw ( int dx, int dy ) { normalizeCursors () ; if ( !visible || ( window != puGetWindow () ) ) return ; /* 3D Input boxes look nicest if they are always in inverse style. */ abox.draw ( dx, dy, ( (style==PUSTYLE_SMALL_BEVELLED || style==PUSTYLE_SMALL_SHADED) ) ? -style : (accepting ? -style : style ), colour, FALSE, border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { int xx = legendFont.getStringWidth ( " " ) ; int yy = ( ( abox.max[1] - abox.min[1] - legendFont.getStringHeight () ) / 2 + legendFont.getStringDescender () ) ; if ( !displayed_text ) displayed_text = chop_to_width ( legendFont, getStringValue(), abox.max[0]-abox.min[0], getCursor (), &display_starting_point ) ; if ( accepting ) { /* Highlight the select area */ if ( select_end_position > 0 && select_end_position != select_start_position ) { int sep = select_end_position - display_starting_point ; int ssp = select_start_position - display_starting_point ; if ( sep < 0 ) sep = 0 ; if ( ssp < 0 ) ssp = 0 ; if ( ssp < sep ) { char save_char = displayed_text [ sep ] ; displayed_text [ sep ] = '\0' ; int cpos2 = legendFont.getStringWidth ( displayed_text ) + xx + dx + abox.min[0] ; displayed_text [ sep ] = save_char ; save_char = displayed_text [ ssp ] ; displayed_text [ ssp ] = '\0' ; int cpos1 = legendFont.getStringWidth ( displayed_text ) + xx + dx + abox.min[0] ; displayed_text [ ssp ] = save_char ; glColor3f ( 1.0f, 1.0f, 0.7f ) ; glRecti ( cpos1, dy + abox.min[1] + 2 , cpos2, dy + abox.max[1] - 2 ) ; } } } /* Draw the text */ /* If greyed out then halve the opacity when drawing the text */ if ( active ) glColor4fv ( colour [ PUCOL_LEGEND ] ) ; else glColor4f ( colour [ PUCOL_LEGEND ][0], colour [ PUCOL_LEGEND ][1], colour [ PUCOL_LEGEND ][2], colour [ PUCOL_LEGEND ][3] / 2.0f ) ; /* 50% more transp */ legendFont.drawString ( displayed_text, dx + abox.min[0] + xx, dy + abox.min[1] + yy ) ; if ( accepting ) { /* Draw the 'I' bar cursor. */ if ( cursor_position - display_starting_point >= 0 ) { char save_char = displayed_text [ cursor_position-display_starting_point ] ; displayed_text [ cursor_position-display_starting_point ] = '\0' ; float cpos = 0.5f + legendFont.getStringWidth ( displayed_text ) + xx + dx + abox.min[0] ; displayed_text [ cursor_position-display_starting_point ] = save_char ; float top = 0.5f + dy + abox.min[1] + yy + legendFont.getPointSize () ; float bot = 0.5f + dy + abox.min[1] + yy - legendFont.getStringDescender() ; glColor4fv ( colour [ PUCOL_MISC ] ) ; glBegin ( GL_LINES ) ; glVertex2f ( cpos , bot ) ; glVertex2f ( cpos , top ) ; glVertex2f ( cpos - 1, bot ) ; glVertex2f ( cpos - 1, top ) ; glVertex2f ( cpos - 3, bot ) ; glVertex2f ( cpos + 3, bot ) ; glVertex2f ( cpos - 3, top ) ; glVertex2f ( cpos + 3, top ) ; glEnd () ; } } } draw_label ( dx, dy ) ; } void puInput::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { /* Active widget exists and is not this one; call its down callback if it exists */ puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); if ( button == active_mouse_button ) { /* Most GUI's activate a button on button-UP not button-DOWN. */ /* Find the position of the mouse on the line of text */ if ( !displayed_text ) displayed_text = chop_to_width ( legendFont, getStringValue(), abox.max[0]-abox.min[0], getCursor (), &display_starting_point ) ; int i = strlen ( displayed_text ) ; int length, prev_length ; length = legendFont.getStringWidth ( displayed_text ) + abox.min[0] ; prev_length = length ; while ( ( x <= prev_length ) && ( i > 0 ) ) { prev_length = length ; displayed_text[--i] = '\0' ; length = legendFont.getStringWidth ( displayed_text ) + abox.min[0] ; } if ( ( x - length ) > ( prev_length - x ) ) i++ ; /* Mouse is closer to next character than previous character */ i += display_starting_point ; /* Process the mouse click. */ if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN ) { lowlight () ; accepting = TRUE ; cursor_position = i ; normalizeCursors () ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } else if ( updown == PU_DOWN ) { /* * We get here if the active edge is not down but the mouse button has * been pressed. Start a selection if this isn't the initial activation * of the widget. */ if ( this == puActiveWidget() ) { select_start_position = i ; select_end_position = i ; } } else if ( updown == PU_DRAG ) { if ( (select_end_position - i) > (i - select_start_position) ) select_start_position = i ; /* Cursor closer to start than to end */ else select_end_position = i ; /* Cursor closer to end than to start */ if (select_start_position > select_end_position) { i = select_end_position ; select_end_position = select_start_position ; select_start_position = i ; } } else highlight () ; /* Required because we have pretty much destroyed "displayed_text" */ delete [] displayed_text ; displayed_text = chop_to_width ( legendFont, getStringValue(), abox.max[0]-abox.min[0], getCursor (), &display_starting_point ) ; } else lowlight () ; } int puInput::checkKey ( int key, int updown ) { if ( updown == PU_UP || ! isAcceptingInput() || ! isActive () || ! isVisible () || ( window != puGetWindow () ) ) return FALSE ; if ( puActiveWidget() && ( this != puActiveWidget() ) ) { /* Active widget exists and is not this one; call its down callback if it exists */ puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } normalizeCursors () ; char *p = NULL ; int char_used = TRUE ; switch ( key ) { case PU_KEY_PAGE_UP : case PU_KEY_PAGE_DOWN : case PU_KEY_INSERT : return FALSE ; case PU_KEY_UP : case PU_KEY_DOWN : case 0x1B /* ESC */ : case '\t' : case '\r' : case '\n' : /* Carriage return/Line Feed/TAB -- End of input */ rejectInput () ; normalizeCursors () ; invokeCallback () ; puDeactivateWidget () ; break ; case PU_KEY_HOME : cursor_position = 0 ; break ; case PU_KEY_END : cursor_position = strlen ( getStringValue () ) ; break ; case PU_KEY_LEFT : cursor_position-- ; break ; case PU_KEY_RIGHT : cursor_position++ ; break ; default : char_used = FALSE ; } if ( ! input_disabled && ! char_used ) { switch ( key ) { case '\b' : /* Backspace */ if ( select_start_position != select_end_position ) removeSelectRegion () ; else if ( cursor_position > 0 ) { p = new char [ strlen ( getStringValue () ) ] ; strncpy ( p, getStringValue (), cursor_position - 1 ) ; strcpy ( p + cursor_position - 1, getStringValue () + cursor_position ) ; cursor_position-- ; } break ; case 0x7F : /* DEL */ if ( select_start_position != select_end_position ) removeSelectRegion () ; else if ( cursor_position != (int)strlen ( getStringValue() ) ) { p = new char [ strlen ( getStringValue () ) ] ; strncpy ( p, getStringValue (), cursor_position ) ; strcpy ( p + cursor_position, getStringValue () + cursor_position + 1 ) ; } break ; case 0x15 /* ^U */ : setValue ( "\0" ) ; break ; case 0x03 /* ^C */ : case 0x18 /* ^X */ : /* Cut or copy selected text */ if ( select_start_position != select_end_position ) { p = getStringValue () ; char ch = p[select_end_position] ; p[select_end_position] = '\0' ; puSetPasteBuffer ( p + select_start_position ) ; p[select_end_position] = ch ; if ( key == 0x18 ) /* Cut, remove text from string */ removeSelectRegion () ; /* So we don't set the widget to its value at the end of the function */ p = NULL ; } break ; case 0x16 /* ^V */ : /* Paste buffer into text */ { if ( select_start_position != select_end_position ) removeSelectRegion () ; int str_val_len = strlen ( getStringValue () ) ; int paste_len = strlen ( puGetPasteBuffer () ) ; p = new char [ str_val_len + paste_len + 1 ] ; memcpy ( p, getStringValue (), cursor_position ) ; memcpy ( p + cursor_position, puGetPasteBuffer (), paste_len ) ; memcpy ( p + cursor_position + paste_len, getStringValue () + cursor_position, str_val_len - cursor_position + 1 ) ; cursor_position += paste_len ; } break ; default: if ( key < ' ' || key > 127 ) return FALSE ; if ( valid_data ) { if ( !strchr ( valid_data, key ) ) return TRUE ; } if ( select_start_position != select_end_position ) // remove selected text removeSelectRegion () ; p = new char [ strlen ( getStringValue () ) + 2 ] ; strncpy ( p, getStringValue (), cursor_position ) ; p[cursor_position] = key ; strcpy ( p + cursor_position + 1, getStringValue () + cursor_position ) ; cursor_position++ ; break ; } if ( p != NULL ) setValue ( p ) ; /* Set the widget value to the new string */ delete [] p ; } /* Since the keystroke has changed the text value, we need to change the displayed text as well. */ delete [] displayed_text ; displayed_text = NULL ; normalizeCursors () ; return TRUE ; } plib-1.8.5/src/pui/pui.dsp0000644000175000001440000001240210765364437012277 00000000000000# Microsoft Developer Studio Project File - Name="pui" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=pui - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "pui.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "pui.mak" CFG="pui - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "pui - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "pui - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "pui - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\fnt" /I "..\sg" /I "..\util" /I ".." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "PU_USE_NONE" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy pu.h ..\..\pu.h copy puGLUT.h "..\..\" copy puFLTK.h "..\..\" copy puSDL.h "..\..\" copy puNative.h "..\..\" copy puPW.h ..\..\ # End Special Build Tool !ELSEIF "$(CFG)" == "pui - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\fnt" /I "..\sg" /I "..\util" /I ".." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "PU_USE_NONE" /FR /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\pui_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy pu.h ..\..\pu.h copy puGLUT.h "..\..\" copy puFLTK.h "..\..\" copy puSDL.h "..\..\" copy puNative.h "..\..\" copy puPW.h ..\..\ # End Special Build Tool !ENDIF # Begin Target # Name "pui - Win32 Release" # Name "pui - Win32 Debug" # Begin Source File SOURCE=.\pu.cxx # End Source File # Begin Source File SOURCE=.\pu.h # End Source File # Begin Source File SOURCE=.\puArrowButton.cxx # End Source File # Begin Source File SOURCE=.\puBox.cxx # End Source File # Begin Source File SOURCE=.\puButton.cxx # End Source File # Begin Source File SOURCE=.\puButtonBox.cxx # End Source File # Begin Source File SOURCE=.\puDial.cxx # End Source File # Begin Source File SOURCE=.\puDialogBox.cxx # End Source File # Begin Source File SOURCE=.\puFLTK.h # End Source File # Begin Source File SOURCE=.\puFont.cxx # End Source File # Begin Source File SOURCE=.\puFrame.cxx # End Source File # Begin Source File SOURCE=.\puGLUT.h # End Source File # Begin Source File SOURCE=.\puGroup.cxx # End Source File # Begin Source File SOURCE=.\puInput.cxx # End Source File # Begin Source File SOURCE=.\puInputBase.cxx # End Source File # Begin Source File SOURCE=.\puInterface.cxx # End Source File # Begin Source File SOURCE=.\puListBox.cxx # End Source File # Begin Source File SOURCE=.\puLocal.h # End Source File # Begin Source File SOURCE=.\puMenuBar.cxx # End Source File # Begin Source File SOURCE=.\puNative.h # End Source File # Begin Source File SOURCE=.\puObject.cxx # End Source File # Begin Source File SOURCE=.\puOneShot.cxx # End Source File # Begin Source File SOURCE=.\puPopup.cxx # End Source File # Begin Source File SOURCE=.\puPopupMenu.cxx # End Source File # Begin Source File SOURCE=.\puPW.h # End Source File # Begin Source File SOURCE=.\puRange.cxx # End Source File # Begin Source File SOURCE=.\puSDL.h # End Source File # Begin Source File SOURCE=.\puSlider.cxx # End Source File # Begin Source File SOURCE=.\puText.cxx # End Source File # Begin Source File SOURCE=.\puValue.cxx # End Source File # End Target # End Project plib-1.8.5/src/pui/puSDL.h0000644000175000001440000000267210765364437012142 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puSDL.h 2130 2007-11-18 21:46:37Z fayjf $ */ #ifndef _PU_SDL_H_ #define _PU_SDL_H_ #ifndef PU_USE_SDL # define PU_USE_SDL #endif #include "pu.h" #include "SDL.h" inline int puGetWindowSDL () { return 0; } inline void puGetWindowSizeSDL ( int *width, int *height ) { SDL_Surface *display = SDL_GetVideoSurface () ; *width = display->w ; *height = display->h ; } inline void puInitSDL () { puSetWindowFuncs ( puGetWindowSDL, NULL, puGetWindowSizeSDL, NULL ) ; puRealInit () ; } #endif plib-1.8.5/src/pui/puFont.cxx0000644000175000001440000000732210765364437012776 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puFont.cxx 1943 2004-08-05 01:05:48Z puggles $ */ #include "puLocal.h" puFont PUFONT_8_BY_13 ( fntGetBitmapFont( FNT_BITMAP_8_BY_13 ) ) ; puFont PUFONT_9_BY_15 ( fntGetBitmapFont( FNT_BITMAP_9_BY_15 ) ) ; puFont PUFONT_TIMES_ROMAN_10 ( fntGetBitmapFont( FNT_BITMAP_TIMES_ROMAN_10 ) ) ; puFont PUFONT_TIMES_ROMAN_24 ( fntGetBitmapFont( FNT_BITMAP_TIMES_ROMAN_24 ) ) ; puFont PUFONT_HELVETICA_10 ( fntGetBitmapFont( FNT_BITMAP_HELVETICA_10 ) ) ; puFont PUFONT_HELVETICA_12 ( fntGetBitmapFont( FNT_BITMAP_HELVETICA_12 ) ) ; puFont PUFONT_HELVETICA_18 ( fntGetBitmapFont( FNT_BITMAP_HELVETICA_18 ) ) ; puFont::puFont () { fnt_font_handle = fntGetBitmapFont( FNT_BITMAP_8_BY_13 ); pointsize = 13 ; slant = 0 ; } float puFont::getFloatStringWidth ( const char *str ) const { if ( str == NULL ) return 0.0f ; if ( fnt_font_handle != NULL ) { float r, l ; fnt_font_handle -> getBBox ( str, pointsize, slant, &l, &r, NULL, NULL ) ; return ( r - l ) ; } return 0.0f ; } static int count_lines ( const char *str ) { int k = 0 ; if ( str != NULL ) { for ( k = 1 ; *str != '\0' ; str++ ) if ( *str == '\n' ) k++ ; } return k ; } int puFont::getStringHeight ( const char *s ) const { if (!s || !fnt_font_handle) return 0 ; // The height of a single line is the ascender plus descender, not // including whitespace above and below. Each additional line // adds one point size, of course. Remember to round up to avoid // overlapping artifacts. The bbox string is just a sample of // "likely to be tall" glyphs. float ascend; fnt_font_handle -> getBBox ( "$lfKL", pointsize, slant, NULL, NULL, NULL, &ascend ) ; float height = ascend + getStringDescender() ; int lines = count_lines ( s ) ; if ( lines > 1 ) height += ( lines - 1 ) * pointsize ; return int ( height + 0.999 ) ; // return int ( pointsize * count_lines ( s ) + 0.999 ) - getStringDescender(); } int puFont::getStringDescender ( void ) const { if ( fnt_font_handle != NULL ) { float b ; fnt_font_handle -> getBBox ( "y", pointsize, slant, NULL, NULL, &b, NULL ) ; return (int) -b ; } return 0 ; } void puFont::drawString ( const char *str, int x, int y ) { if ( str == NULL ) return ; if ( fnt_font_handle != NULL ) { sgVec3 curpos ; sgSetVec3 ( curpos, (float)x, (float)y, 0.0f ) ; glPushAttrib( GL_COLOR_BUFFER_BIT ); // NHV glEnable ( GL_ALPHA_TEST ) ; glEnable ( GL_BLEND ) ; glAlphaFunc ( GL_GREATER, 0.1f ) ; glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; fnt_font_handle -> begin () ; fnt_font_handle -> puts ( curpos, pointsize, slant, str ) ; fnt_font_handle -> end () ; glPopAttrib () ; glDisable ( GL_TEXTURE_2D ) ; return ; } } plib-1.8.5/src/pui/puGLUT.h0000644000175000001440000000352210765364437012266 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puGLUT.h 2122 2007-09-15 12:34:36Z fayjf $ */ #ifndef _PU_GLUT_H_ #define _PU_GLUT_H_ #ifndef PU_USE_GLUT # define PU_USE_GLUT #endif #include "pu.h" #ifdef UL_MAC_OSX # include #else # ifdef FREEGLUT_IS_PRESENT /* for FreeGLUT like PLIB 1.6.1*/ # include # else # include # endif #endif inline int puGetWindowGLUT() { return glutGetWindow () ; } inline void puSetWindowGLUT ( int window ) { glutSetWindow ( window ) ; } inline void puGetWindowSizeGLUT ( int *width, int *height ) { *width = glutGet ( (GLenum) GLUT_WINDOW_WIDTH ) ; *height = glutGet ( (GLenum) GLUT_WINDOW_HEIGHT ) ; } inline void puSetWindowSizeGLUT ( int width, int height ) { glutReshapeWindow ( width, height ) ; } inline void puInitGLUT () { puSetWindowFuncs ( puGetWindowGLUT, puSetWindowGLUT, puGetWindowSizeGLUT, puSetWindowSizeGLUT ) ; puRealInit () ; } #endif plib-1.8.5/src/pui/puDialogBox.cxx0000644000175000001440000000201410765364437013731 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puDialogBox.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "puLocal.h" UL_RTTI_DEF1(puDialogBox,puPopup) plib-1.8.5/src/pui/puLocal.h0000644000175000001440000000210210765364437012536 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puLocal.h 1902 2004-03-21 19:03:23Z sjbaker $ */ #define PU_USE_NONE 1 #include "pu.h" void puSetPasteBuffer ( const char *ch ) ; char *puGetPasteBuffer () ; plib-1.8.5/src/pui/puArrowButton.cxx0000644000175000001440000001227510765364437014361 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puArrowButton.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "puLocal.h" UL_RTTI_DEF1(puArrowButton,puButton) void puDrawArrowButtonTriangle ( int pos_x, int pos_y, int size_x, int size_y, puColour colour, int arrow_type, int active ) { /* If greyed out then halve the opacity when drawing the widget */ if ( active ) glColor4fv ( colour ) ; else glColor4f ( colour [0], colour [1], colour [2], colour [3] / 2.0f ) ; // 50% more transparent switch ( arrow_type ) { case PUARROW_UP : glBegin ( GL_TRIANGLES ) ; glVertex2i ( pos_x - size_x/4, pos_y - size_y/4 ) ; glVertex2i ( pos_x , pos_y + size_y/4 ) ; glVertex2i ( pos_x + size_x/4, pos_y - size_y/4 ) ; glEnd () ; break; case PUARROW_DOWN : glBegin ( GL_TRIANGLES ) ; glVertex2i ( pos_x - size_x/4, pos_y + size_y/4 ) ; glVertex2i ( pos_x , pos_y - size_y/4 ) ; glVertex2i ( pos_x + size_x/4, pos_y + size_y/4 ) ; glEnd () ; break; case PUARROW_FASTUP : glBegin ( GL_TRIANGLES ) ; glVertex2i ( pos_x - size_x/4, pos_y - size_y/4 ) ; glVertex2i ( pos_x , pos_y ) ; glVertex2i ( pos_x + size_x/4, pos_y - size_y/4 ) ; glVertex2i ( pos_x - size_x/4, pos_y ) ; glVertex2i ( pos_x , pos_y + size_y/4 ) ; glVertex2i ( pos_x + size_x/4, pos_y ) ; glEnd () ; break; case PUARROW_FASTDOWN : glBegin ( GL_TRIANGLES ) ; glVertex2i ( pos_x - size_x/4, pos_y + size_y/4 ) ; glVertex2i ( pos_x , pos_y ) ; glVertex2i ( pos_x + size_x/4, pos_y + size_y/4 ) ; glVertex2i ( pos_x - size_x/4, pos_y ) ; glVertex2i ( pos_x , pos_y - size_y/4 ) ; glVertex2i ( pos_x + size_x/4, pos_y ) ; glEnd () ; break; case PUARROW_LEFT : glBegin ( GL_TRIANGLES ) ; glVertex2i ( pos_x + size_x/4, pos_y - size_y/4 ) ; glVertex2i ( pos_x - size_x/4, pos_y ) ; glVertex2i ( pos_x + size_x/4, pos_y + size_y/4 ) ; glEnd () ; break; case PUARROW_RIGHT : glBegin ( GL_TRIANGLES ) ; glVertex2i ( pos_x - size_x/4, pos_y - size_y/4 ) ; glVertex2i ( pos_x + size_x/4, pos_y ) ; glVertex2i ( pos_x - size_x/4, pos_y + size_y/4 ) ; glEnd () ; break; case PUARROW_FASTLEFT : glBegin ( GL_TRIANGLES ) ; glVertex2i ( pos_x + size_x/4, pos_y - size_y/4 ) ; glVertex2i ( pos_x , pos_y ) ; glVertex2i ( pos_x + size_x/4, pos_y + size_y/4 ) ; glVertex2i ( pos_x , pos_y - size_y/4 ) ; glVertex2i ( pos_x - size_x/4, pos_y ) ; glVertex2i ( pos_x , pos_y + size_y/4 ) ; glEnd () ; break; case PUARROW_FASTRIGHT : glBegin ( GL_TRIANGLES ) ; glVertex2i ( pos_x - size_x/4, pos_y - size_y/4 ) ; glVertex2i ( pos_x , pos_y ) ; glVertex2i ( pos_x - size_x/4, pos_y + size_y/4 ) ; glVertex2i ( pos_x , pos_y - size_y/4 ) ; glVertex2i ( pos_x + size_x/4, pos_y ) ; glVertex2i ( pos_x , pos_y + size_y/4 ) ; glEnd () ; break; default : ulSetError ( UL_WARNING, "PUI: Unrecognised 'arrow_type' %d", arrow_type ) ; break; } } void puArrowButton::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; /* If arrow button is pushed or highlighted - use inverse style for button itself */ if ( getIntegerValue() ^ highlighted ) { if ( parent && ( ( parent->getType() & PUCLASS_POPUPMENU ) || ( parent->getType() & PUCLASS_MENUBAR ) ) ) abox.draw ( dx, dy, PUSTYLE_SMALL_SHADED, colour, isReturnDefault(), 2 ) ; else abox.draw ( dx, dy, -style, colour, isReturnDefault(), border_thickness ) ; } else abox.draw ( dx, dy, style, colour, isReturnDefault(), border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { int size_x = abox.max[0] - abox.min[0] ; int size_y = abox.max[1] - abox.min[1] ; int pos_x = dx + ( abox.max[0] + abox.min[0] ) / 2 ; int pos_y = dy + ( abox.max[1] + abox.min[1] ) / 2 ; puDrawArrowButtonTriangle ( pos_x, pos_y, size_x, size_y, colour [ PUCOL_MISC ], arrow_type, active ) ; } draw_label ( dx, dy ) ; } plib-1.8.5/src/pui/puGroup.cxx0000644000175000001440000002667410765364437013177 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puGroup.cxx 2076 2006-04-13 16:20:23Z bram $ */ #include "puLocal.h" UL_RTTI_DEF1(puGroup,puObject) #define PUSTACK_MAX 100 /* This is a stack of groups that are currently being filled with other widgets. A group is pushed onto the stack when it is created and it is popped off the stack when its "close" function is called. */ static int currGroup = -1 ; static puGroup *groupStack [ PUSTACK_MAX ] ; void puPushGroup ( puGroup *in ) { if ( currGroup < PUSTACK_MAX ) groupStack [ ++currGroup ] = in ; else ulSetError ( UL_WARNING, "PUI: Too many puGroups open at once!" ) ; } void puPopGroup ( void ) { if ( currGroup > 0 ) --currGroup ; else ulSetError ( UL_WARNING, "PUI: puGroup stack is empty!" ) ; } int puNoGroup ( void ) { return currGroup < 0 ; } puGroup *puGetCurrGroup ( void ) { if ( currGroup < 0 ) { ulSetError ( UL_WARNING, "PUI: No Group!" ) ; return NULL ; } return groupStack [ currGroup ] ; } void puGroup::remove ( puObject *obj ) { if ( obj -> getParent () != this ) return ; /* Are we the first object in the list */ if ( obj -> getPrevObject() == NULL ) dlist = obj -> getNextObject() ; else obj -> getPrevObject() -> setNextObject( obj -> getNextObject() ) ; /* Are we the last object in the list */ if ( obj -> getNextObject() != NULL ) obj -> getNextObject() -> setPrevObject( obj -> getPrevObject() ) ; obj -> setNextObject ( NULL ) ; obj -> setPrevObject ( NULL ) ; obj -> setParent ( NULL ) ; num_children-- ; recalc_bbox () ; } void puGroup::empty ( void ) { puObject *obj = getLastChild () ; while ( obj != NULL ) { if ( obj->getType () & PUCLASS_GROUP ) { puGroup *group = (puGroup *)obj ; group->empty () ; } puObject *temp = obj->getPrevObject () ; delete obj ; obj = temp ; } dlist = NULL ; } void puGroup::add ( puObject *new_obj ) { if ( new_obj -> getParent () != NULL ) new_obj -> getParent () -> remove ( new_obj ) ; new_obj -> setParent ( this ) ; if ( dlist == NULL ) { dlist = new_obj ; new_obj -> setNextObject ( NULL ) ; new_obj -> setPrevObject ( NULL ) ; } else { puObject *last ; for ( last = dlist ; last -> getNextObject() != NULL ; last = last -> getNextObject() ) /* Search for end of list. */ ; last -> setNextObject ( new_obj ) ; new_obj -> setPrevObject ( last ) ; new_obj -> setNextObject ( NULL ) ; } num_children++ ; recalc_bbox () ; } int puGroup::checkKey ( int key, int updown ) { if ( updown == PU_UP || dlist == NULL || ! isVisible () || ! isActive () ) return FALSE ; puObject *bo ; /* We have to walk the list backwards to ensure that the click order is the same as the DRAW order. */ bo = getLastChild () ; for ( ; bo != NULL ; bo = bo -> getPrevObject() ) if ( bo -> checkKey ( key, updown ) ) return TRUE ; return FALSE ; } int puGroup::checkHit ( int button, int updown, int x, int y ) { if ( dlist == NULL || ! isVisible () || ! isActive () ) return FALSE ; /* This might be a bit redundant - but it's too hard to keep track of changing abox sizes when daughter objects are changing sizes. */ recalc_bbox () ; puObject *bo ; x -= abox.min[0] ; y -= abox.min[1] ; /* We have to walk the list backwards to ensure that the click order is the same as the DRAW order. */ if ( !mouse_active ) { bo = getLastChild () ; for ( ; bo != NULL ; bo = bo -> getPrevObject() ) { /* If this is a menu bar and the mouse is over the button, highlight the button, if it's in the right window - JCJ 6 Jun 2002 */ if ( ( getType () & PUCLASS_MENUBAR ) && ( bo->getType () & PUCLASS_ONESHOT ) && ( window == puGetWindow () ) ) /* Changing this statement to something like this: if ( bo->getType () & PUCLASS_ONESHOT ) Breaks a lot of stuff... like pressing buttons actually working in filepicker. Need to just define everything that can be pressed passively above, and things should be fröhlich. */ { puBox *box = bo->getABox () ; if ( ( x >= box->min[0] ) && ( x <= box->max[0] ) && ( y >= box->min[1] ) && ( y <= box->max[1] ) ) bo->highlight () ; else bo->lowlight () ; } if ( bo -> checkHit ( button, updown, x, y ) ) return TRUE ; } } /* If right mouse button is pressed, save mouse coordinates for dragging and dropping. Do this only if the "floating" flag is set. */ if ( mouse_active || ( isHit ( x+abox.min[0], y+abox.min[1]) && floating && ( button == PU_RIGHT_BUTTON ) ) ) // DEPRECATED! -- we need to replace this code. { puMoveToLast ( this ); /* Return (x, y) to coordinates of parent interface to avoid "jumping" of present interface as mouse drags */ x += abox.min[0] ; y += abox.min[1] ; if ( updown == PU_DOWN ) { mouse_x = x; /* Save mouse coordinates for dragging */ mouse_y = y; mouse_active = TRUE ; return TRUE ; } else if ( updown == PU_DRAG ) { int curr_x, curr_y; getPosition ( &curr_x, &curr_y ); setPosition ( curr_x+x-mouse_x, curr_y+y-mouse_y ); /* Move to new position */ mouse_x = x; /* Save new coordinates */ mouse_y = y; return TRUE ; } else if ( updown == PU_UP ) { mouse_active = FALSE ; return TRUE ; } } return FALSE ; } void puGroup::draw ( int dx, int dy ) { if ( ! isVisible () ) return ; for ( puObject *bo = dlist ; bo != NULL ; bo = bo -> getNextObject() ) { /* June 16th, 98, Shammi : * The next if statement checks if the object is * a menu bar and makes sure it is repositioned * correctly. */ int x, y ; int xdraw = dx + abox.min[0] ; int ydraw = dy + abox.min[1] ; bo -> getPosition (&x, &y) ; /* If the object is a menubar or a vertmenu and supposed to be locked to the top, */ /* then move it there. - JCJ 6 June 2002 */ if ( ( bo -> getType () & PUCLASS_MENUBAR ) && ( bo -> getWindow () == puGetWindow () ) ) { int obWidth, obHeight ; bo -> getSize ( &obWidth, &obHeight ) ; bo -> setPosition ( 0, puGetWindowHeight() - obHeight ) ; } else { if ( ( y < 0 ) && ( bo->getType () & PUCLASS_POPUPMENU ) ) { /* IF the object's bottom left corner lies outside the window, THEN */ /* move the object to the top left - JCJ and Fay 5 Jun 2002 */ int absx, absy ; bo -> getAbsolutePosition (&absx, &absy) ; if ( absy < 0 ) ydraw -= absy ; } } bo -> draw ( xdraw, ydraw ) ; } if ( getWindow () == puGetWindow () ) draw_label ( dx, dy ) ; } void puGroup::recalc_bbox ( void ) { puBox contents ; contents . empty () ; for ( puObject *bo = dlist ; bo != NULL ; bo = bo -> getNextObject() ) contents . extend ( bo -> getBBox() ) ; if ( contents . isEmpty () ) { abox . max[0] = abox . min[0] ; abox . max[1] = abox . min[1] ; } else { abox . max[0] = abox . min[0] + contents . max[0] ; abox . max[1] = abox . min[1] + contents . max[1] ; } puObject::recalc_bbox () ; } void puGroup::doHit ( int, int, int, int ) { } puGroup::~puGroup () { void puCleanUpJunk ( void ) ; puObject *bo = getLastChild () ; while ( bo != NULL ) { dlist = bo ; bo = bo -> getPrevObject() ; puDeleteObject ( dlist ) ; } // Since this is an object destructor, it should be okay to delete the child objects as well. puCleanUpJunk () ; } void puGroup::setChildStyle ( int childs, int which, int recursive ) { puObject *curr_obj ; for ( curr_obj = getFirstChild () ; curr_obj != NULL ; curr_obj = curr_obj->getNextObject () ) { if ( ( recursive == TRUE ) && ( curr_obj->getType () & PUCLASS_GROUP ) ) ((puGroup*)curr_obj)->setChildStyle ( childs, style, TRUE ) ; else { if ( curr_obj->getType () & childs ) curr_obj->setStyle ( style ) ; } } } void puGroup::setChildBorderThickness ( int childs, int t, int recursive ) { puObject *curr_obj ; for ( curr_obj = getFirstChild () ; curr_obj != NULL ; curr_obj = curr_obj->getNextObject () ) { if ( ( recursive == TRUE ) && ( curr_obj->getType () & PUCLASS_GROUP ) ) ((puGroup*)curr_obj)->setChildBorderThickness ( childs, t, TRUE ) ; else { if ( curr_obj->getType () & childs ) curr_obj->setBorderThickness ( t ) ; } } } void puGroup::setChildColour ( int childs, int which, float r, float g, float b, float a, int recursive ) { puObject *curr_obj ; for ( curr_obj = getFirstChild () ; curr_obj != NULL ; curr_obj = curr_obj->getNextObject () ) { if ( ( recursive == TRUE ) && ( curr_obj->getType () & PUCLASS_GROUP ) ) ((puGroup*)curr_obj)->setChildColour ( childs, which, r, g, b, a, TRUE ) ; else { if ( curr_obj->getType () & childs ) curr_obj->setColour ( which, r, g, b, a ) ; } } } void puGroup::setChildColourScheme ( int childs, float r, float g, float b, float a, int recursive ) { puObject *curr_obj ; for ( curr_obj = getFirstChild () ; curr_obj != NULL ; curr_obj = curr_obj->getNextObject () ) { if ( ( recursive == TRUE ) && ( curr_obj->getType () & PUCLASS_GROUP ) ) ((puGroup*)curr_obj)->setChildColourScheme ( childs, r, g, b, a, TRUE ) ; else { if ( curr_obj->getType () & childs ) curr_obj->setColourScheme ( r, g, b, a ) ; } } } void puGroup::setChildLegendFont ( int childs, puFont f, int recursive ) { puObject *curr_obj ; for ( curr_obj = getFirstChild () ; curr_obj != NULL ; curr_obj = curr_obj->getNextObject () ) { if ( ( recursive == TRUE ) && ( curr_obj->getType () & PUCLASS_GROUP ) ) ((puGroup*)curr_obj)->setChildLegendFont ( childs, f, TRUE ) ; else { if ( curr_obj->getType () & childs ) curr_obj->setLegendFont ( f ) ; } } } void puGroup::setChildLabelFont ( int childs, puFont f, int recursive ) { puObject *curr_obj ; for ( curr_obj = getFirstChild () ; curr_obj != NULL ; curr_obj = curr_obj->getNextObject () ) { if ( ( recursive == TRUE ) && ( curr_obj->getType () & PUCLASS_GROUP ) ) ((puGroup*)curr_obj)->setChildLabelFont ( childs, f, TRUE ) ; else { if ( curr_obj->getType () & childs ) curr_obj->setLabelFont ( f ) ; } } } plib-1.8.5/src/pui/puFLTK.h0000644000175000001440000000344210765364437012254 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puFLTK.h 1857 2004-02-16 13:49:03Z stromberg $ */ #ifndef _PU_FLTK_H_ #define _PU_FLTK_H_ #ifndef PU_USE_FLTK # define PU_USE_FLTK #endif #include "pu.h" #include inline int puGetWindowFLTK () { return (int) Fl_Window::current () ; } inline void puSetWindowFLTK ( int window ) { ((Fl_Gl_Window *) window) -> make_current () ; } inline void puGetWindowSizeFLTK ( int *width, int *height ) { Fl_Window * window = Fl_Window::current () ; *width = window->w() ; *height = window->h() ; } inline void puSetWindowSizeFLTK ( int width, int height ) { Fl_Window * window = Fl_Window::current () ; window -> resize ( window->x(), window->y(), width, height ) ; } inline void puInitFLTK () { puSetWindowFuncs ( puGetWindowFLTK, puSetWindowFLTK, puGetWindowSizeFLTK, puSetWindowSizeFLTK ) ; puRealInit () ; } #endif plib-1.8.5/src/pui/puInputBase.cxx0000644000175000001440000000551510765364437013764 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puInputBase.cxx 1709 2002-09-27 23:57:33Z ude $ */ #include "puLocal.h" UL_RTTI_DEF(puInputBase) void puInputBase::normalizeCursors ( void ) { int sl = strlen ( widget -> getStringValue () ) ; /* Clamp the positions to the limits of the text. */ if ( cursor_position < 0 ) cursor_position = 0 ; if ( select_start_position < 0 ) select_start_position = 0 ; if ( select_end_position < 0 ) select_end_position = 0 ; if ( cursor_position > sl ) cursor_position = sl ; if ( select_start_position > sl ) select_start_position = sl ; if ( select_end_position > sl ) select_end_position = sl ; /* Swap the ends of the select window if they get crossed over */ if ( select_end_position < select_start_position ) { int tmp = select_end_position ; select_end_position = select_start_position ; select_start_position = tmp ; } } void puInputBase::removeSelectRegion ( void ) { char *text = widget -> getStringValue () ; int text_len = strlen ( text ) ; char *p = new char [ text_len + 1 - ( select_end_position - select_start_position ) ] ; memcpy ( p, text, select_start_position ) ; memcpy ( p + select_start_position, text + select_end_position, text_len - select_end_position + 1 ) ; widget -> setValue ( p ) ; delete [] p ; cursor_position = select_end_position = select_start_position ; } void puInputBase::addValidData ( const char *data ) { int valid_len = valid_data != NULL ? strlen ( valid_data ) : 0 ; int data_len = data != NULL ? strlen ( data ) : 0 ; int new_data_len = valid_len + data_len ; char *new_data = new char [ new_data_len + 1 ] ; if ( valid_len != 0 ) memcpy ( new_data, valid_data, valid_len ) ; if ( data_len != 0 ) memcpy ( new_data + valid_len, data, data_len ) ; new_data [ new_data_len ] = '\0' ; delete [] valid_data ; valid_data = new_data ; } plib-1.8.5/src/pui/pu.cxx0000644000175000001440000002615410765364437012153 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pu.cxx 2030 2005-05-23 21:24:26Z fayjf $ */ #include "puLocal.h" #if defined(UL_AGL) # include #elif defined(UL_CGL) # include #elif defined(UL_GLX) # include #endif int puRefresh = TRUE ; static puGetWindowCallback cbGetWindow; static puSetWindowCallback cbSetWindow; static puGetWindowSizeCallback cbGetWindowSize; static puSetWindowSizeCallback cbSetWindowSize; void puSetWindowFuncs ( puGetWindowCallback getWindow, puSetWindowCallback setWindow, puGetWindowSizeCallback getWindowSize, puSetWindowSizeCallback setWindowSize ) { cbGetWindow = getWindow; cbSetWindow = setWindow; cbGetWindowSize = getWindowSize; cbSetWindowSize = setWindowSize; } int puGetWindow () { if ( !cbGetWindow ) ulSetError ( UL_FATAL, "puGetWindow: Callbacks not initialized." ) ; return ( *cbGetWindow ) () ; } void puSetWindow ( int window ) { if ( !cbSetWindow ) ulSetError ( UL_WARNING, "puSetWindow: Cannot set window (null callback)." ) ; else ( *cbSetWindow ) ( window ) ; } void puGetWindowSize ( int *width, int *height ) { if ( !cbGetWindowSize ) ulSetError ( UL_FATAL, "puGetWindowSize: Callbacks not initialized." ) ; ( *cbGetWindowSize ) ( width, height ) ; } void puSetWindowSize ( int width, int height ) { if ( !cbSetWindowSize ) ulSetError ( UL_WARNING, "puSetWindowSize: Cannot change size (null callback)." ) ; else ( *cbSetWindowSize ) ( width, height ) ; } int puGetWindowWidth () { int w, h ; puGetWindowSize ( &w, &h ) ; return w ; } int puGetWindowHeight () { int w, h ; puGetWindowSize ( &w, &h ) ; return h ; } static bool glIsValidContext ( void ) { #if defined(UL_WGL) return ( wglGetCurrentContext () != NULL ) ; #elif defined(UL_AGL) return ( aglGetCurrentContext () != NULL ) ; #elif defined(UL_CGL) return ( CGLGetCurrentContext () != NULL ) ; #elif defined(UL_GLX) return ( glXGetCurrentContext () != NULL ) ; #else return true ; #endif } static int _puCursor_enable = FALSE ; static int _puCursor_x = 0 ; static int _puCursor_y = 0 ; static float _puCursor_bgcolour [4] = { 1.0f, 1.0f, 1.0f, 1.0f } ; static float _puCursor_fgcolour [4] = { 0.0f, 0.0f, 0.0f, 1.0f } ; void puHideCursor ( void ) { _puCursor_enable = FALSE ; } void puShowCursor ( void ) { _puCursor_enable = TRUE ; } int puCursorIsHidden ( void ) { return ! _puCursor_enable ; } void puCursor ( int x, int y ) { _puCursor_x = x ; _puCursor_y = y ; } static void puDrawCursor ( int x, int y ) { glColor4fv ( _puCursor_bgcolour ) ; glBegin ( GL_TRIANGLES ) ; glVertex2i ( x, y ) ; glVertex2i ( x + 13, y - 4 ) ; glVertex2i ( x + 4, y - 13 ) ; glVertex2i ( x + 8, y - 3 ) ; glVertex2i ( x + 17, y - 12 ) ; glVertex2i ( x + 12, y - 17 ) ; glVertex2i ( x + 12, y - 17 ) ; glVertex2i ( x + 3, y - 8 ) ; glVertex2i ( x + 8, y - 3 ) ; glEnd () ; glColor4fv ( _puCursor_fgcolour ) ; glBegin ( GL_TRIANGLES ) ; glVertex2i ( x+1, y-1 ) ; glVertex2i ( x + 11, y - 4 ) ; glVertex2i ( x + 4, y - 11 ) ; glVertex2i ( x + 8, y - 5 ) ; glVertex2i ( x + 15, y - 12 ) ; glVertex2i ( x + 12, y - 15 ) ; glVertex2i ( x + 12, y - 15 ) ; glVertex2i ( x + 5, y - 8 ) ; glVertex2i ( x + 8, y - 5 ) ; glEnd () ; } // Pointer to linked list of objects to delete // as a result of keyboarding or mouse clicking static puObject *objects_to_delete = NULL; void puDeleteObject ( puObject *ob ) { if ( ob == NULL ) return ; puGroup *parent = ob->getParent () ; /* Add object to linked list to be deleted */ if ( objects_to_delete == NULL ) objects_to_delete = ob ; else { /* Ensure that objects are deleted in the order of puDeleteObject calls */ puObject *last ; for ( last = objects_to_delete ; last -> getNextObject() != NULL ; last = last -> getNextObject() ) /* Find last object. */ ; last -> setNextObject ( ob ) ; } /* Remove from parent interface */ if ( parent != ob && parent != NULL ) parent -> remove ( ob ) ; /* Sets object's next and previous pointers to null as well */ } void puCleanUpJunk ( void ) { puObject * local_objects_to_delete = objects_to_delete ; objects_to_delete = NULL ; /* Step through the linked list of objects to delete, removing them. */ while ( local_objects_to_delete != NULL ) { puObject *next_ob = local_objects_to_delete -> getNextObject() ; delete local_objects_to_delete ; local_objects_to_delete = next_ob ; /* If we've reached the end of the list, start over (in case we've deleted a group and * it has put new widgets on the delete list) */ if ( local_objects_to_delete == NULL ) { local_objects_to_delete = objects_to_delete ; objects_to_delete = NULL ; } } } static puObject *active_widget ; /* Widget which is currently receiving user input */ static char *input_paste_buffer ; /* Cut/Copy/Paste buffer for input widgets */ static int firsttime = TRUE ; void puRealInit ( void ) { if ( firsttime ) { if ( ! glIsValidContext () ) { ulSetError ( UL_FATAL, "puInit called without a valid OpenGL context."); } new puInterface ( 0, 0 ) ; active_widget = NULL ; input_paste_buffer = NULL ; firsttime = FALSE ; } } void puExit ( void ) { if ( firsttime ) ulSetError ( UL_FATAL, "puExit called without a previous call to puInit." ) ; delete puGetBaseLiveInterface () ; firsttime = TRUE ; } static void puSetOpenGLState ( void ) { int w, h ; puGetWindowSize ( &w, &h ) ; glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_TRANSFORM_BIT | GL_LIGHTING_BIT ) ; glDisable ( GL_LIGHTING ) ; glDisable ( GL_FOG ) ; glDisable ( GL_TEXTURE_2D ) ; glDisable ( GL_DEPTH_TEST ) ; glDisable ( GL_CULL_FACE ) ; glViewport ( 0, 0, w, h ) ; glMatrixMode ( GL_PROJECTION ) ; glPushMatrix () ; glLoadIdentity () ; glOrtho ( 0, w, 0, h, -1, 1 ) ; glMatrixMode ( GL_MODELVIEW ) ; glPushMatrix () ; glLoadIdentity () ; } static void puRestoreOpenGLState ( void ) { glMatrixMode ( GL_PROJECTION ) ; glPopMatrix () ; glMatrixMode ( GL_MODELVIEW ) ; glPopMatrix () ; glPopAttrib () ; } void puDisplay ( void ) { puCleanUpJunk () ; puSetOpenGLState () ; puGetUltimateLiveInterface () -> draw ( 0, 0 ) ; int h = puGetWindowHeight () ; if ( _puCursor_enable ) puDrawCursor ( _puCursor_x, h - _puCursor_y ) ; puRestoreOpenGLState () ; puRefresh = FALSE ; } void puDisplay ( int window_number ) /* Deprecated */ { if ( window_number == puGetWindow () ) puDisplay () ; } int puKeyboard ( int key, int updown, int, int ) { return puKeyboard ( key, updown ) ; } int puKeyboard ( int key, int updown ) { int return_value = puGetBaseLiveInterface () -> checkKey ( key, updown ) ; puCleanUpJunk () ; return return_value ; } static int last_buttons = 0 ; static int pu_mouse_x = 0 ; static int pu_mouse_y = 0 ; static int pu_mouse_offset_x = 0 ; static int pu_mouse_offset_y = 0 ; int puGetPressedButton () { return last_buttons ; } int puMouse ( int button, int updown, int x, int y ) { puCursor ( x, y ) ; int h = puGetWindowHeight () ; if ( updown == PU_DOWN ) last_buttons |= ( 1 << button ) ; else last_buttons &= ~( 1 << button ) ; pu_mouse_x = x ; pu_mouse_y = h - y ; puObject *active = puActiveWidget () ; if ( ( last_buttons != 0 ) && ( active != NULL ) ) { int x_offset, y_offset ; active -> getAbsolutePosition ( &x_offset, &y_offset ) ; x_offset -= active -> getABox () -> min [0] ; y_offset -= active -> getABox () -> min [1] ; if ( ( ! active -> isHit ( pu_mouse_x - x_offset, pu_mouse_y - y_offset ) ) && ( active -> getWhenToDeactivate () == PUDEACTIVATE_ON_MOUSE_CLICK ) ) { active -> invokeDownCallback () ; puDeactivateWidget () ; } } int return_value = puGetBaseLiveInterface () -> checkHit ( button, updown, pu_mouse_x, pu_mouse_y ) ; puCleanUpJunk () ; return return_value ; } int puMouse ( int x, int y ) { puCursor ( x, y ) ; // Pick buttons in order of descending priority: Left, Right, Middle int button = (last_buttons & (1<checkHit(button, PU_DRAG, pu_mouse_x - pu_mouse_offset_x, pu_mouse_y - pu_mouse_offset_y) ) return TRUE ; else return FALSE ; } int return_value = puGetBaseLiveInterface () -> checkHit ( button, PU_DRAG, pu_mouse_x, pu_mouse_y ) ; puCleanUpJunk () ; return return_value ; } void puMoveToLast (puObject *ob) { puGroup *parent = ob -> getParent () ; /* If no parent interface, return. */ if ( ! parent ) return; /* Remove "ob" from present place in the "dlist" list */ parent -> remove (ob) ; /* Place at the end of the list */ parent -> add (ob) ; /* Now repeat the process for the parent interface so that the interface will be drawn last of all interfaces. */ puMoveToLast ( parent ); } void puDeactivateWidget ( void ) { active_widget = NULL ; } void puSetActiveWidget ( puObject *w, int x, int y ) { active_widget = w ; pu_mouse_offset_x = pu_mouse_x - x ; pu_mouse_offset_y = pu_mouse_y - y ; } puObject *puActiveWidget ( void ) { return active_widget ; } void puSetPasteBuffer ( const char *ch ) { delete [] input_paste_buffer ; input_paste_buffer = ulStrDup ( ch ) ; } char *puGetPasteBuffer ( void ) { return input_paste_buffer ; } int puNeedRefresh ( void ) { return puRefresh ; } void puPostRefresh ( void ) { puRefresh = TRUE ; } void puSetResizeMode ( int mode ) { static int last = 0; if ( last == 0 && mode != 0 ) ulSetError ( UL_WARNING, "puSetResizeMode is deprecated!" ) ; last = mode ; } plib-1.8.5/src/pui/puRange.cxx0000644000175000001440000000170110765364437013117 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "puLocal.h" UL_RTTI_DEF(puRange) plib-1.8.5/src/pui/puValue.cxx0000644000175000001440000001247210765364437013146 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puValue.cxx 2076 2006-04-13 16:20:23Z bram $ */ #include "puLocal.h" UL_RTTI_DEF(puValue) static inline void skip_whitespace ( const char **str ) { while ( isspace ( **str ) != 0 ) (*str)++ ; } static int strtoint ( const char *str ) { skip_whitespace ( &str ) ; if ( *str == '\0') return 0 ; int result ; if ( *str == '-' ) { result = -1 ; skip_whitespace ( &(++str) ) ; } else { result = 1 ; if ( *str == '+' ) skip_whitespace ( &(++str) ) ; } if ( ulStrNEqual ( str, "0x", 2 ) == TRUE ) result *= (int) strtol ( str + 2, NULL, 16 ) ; /* try hexadecimal */ else if ( ulStrNEqual ( str, "0o", 2 ) == TRUE ) result *= (int) strtol ( str + 2, NULL, 8 ) ; /* try octal */ else if ( ulStrNEqual ( str, "0b", 2 ) == TRUE ) result *= (int) strtol ( str + 2, NULL, 2 ) ; /* try binary */ else result *= (int) strtol ( str, NULL, 10 ) ; /* try decimal */ return result ; } void puValue::re_eval ( void ) { if ( convert == FALSE ) return ; if ( res_integer != NULL ) { floater = (float) *res_integer ; /* Needed for puInput / puLargeInput: Do not modify the string value unless necessary */ if ( *res_integer != strtoint ( string ) ) sprintf ( string, "%d", *res_integer ) ; boolean = ( *res_integer != 0 ) ; puPostRefresh () ; } else if ( res_floater != NULL ) { integer = (int) *res_floater ; /* Needed for puInput / puLargeInput: Do not modify the string value unless necessary */ if ( *res_floater != strtod ( string, NULL ) ) sprintf ( string, "%g", *res_floater ) ; boolean = ( *res_floater != 0.0f ) ; puPostRefresh () ; } else if ( res_string != NULL ) { integer = strtoint ( res_string ) ; floater = (float) strtod ( res_string, NULL ) ; boolean = ( strcmp ( res_string, "0" ) != 0 ) ; puPostRefresh () ; } else if ( res_bool != NULL ) { integer = *res_bool ? 1 : 0 ; floater = *res_bool ? 1.0f : 0.0f ; /* Needed for puInput / puLargeInput: Do not modify the string value unless necessary */ if ( *res_bool != ( strcmp ( string, "0" ) != 0 ) ) sprintf ( string, "%d", *res_bool ? 1 : 0 ) ; puPostRefresh () ; } } void puValue::copy_stringval ( const char *str ) { if ( res_string != NULL ) { /* Work around ANSI strncpy's null-fill behaviour */ res_string[0] = '\0' ; strncat ( res_string, str, res_string_sz-1 ) ; } else { int str_len = strlen ( str ) ; int new_size = string_size ; while ( new_size < str_len + 1 ) /* While our array is too small, double it. */ new_size += new_size ; while ( ( new_size > 4 * str_len + 1 ) && ( new_size > PUSTRING_INITIAL ) ) /* While our array is too big, halve it */ new_size /= 2 ; if ( new_size != string_size ) /* If the array size has changed, allocate a new array */ { delete [] string ; string = new char [ new_size ] ; string_size = new_size ; } memcpy ( string, str, str_len + 1 ) ; } } void puValue::setValue ( const char *s ) { if ( s == NULL ) s = "" ; copy_stringval ( s ) ; if ( convert == TRUE ) { *getIntegerp () = strtoint ( s ) ; *getFloaterp () = (float) strtod ( s, NULL ) ; *getBooleanp () = ( strcmp ( s, "0" ) != 0 ) ; } puPostRefresh () ; } const char *puValue::getTypeString ( void ) const { int i = getType () ; if ( i & PUCLASS_DIAL ) return "puDial" ; if ( i & PUCLASS_LISTBOX ) return "puListBox" ; if ( i & PUCLASS_ARROW ) return "puArrowButton" ; if ( i & PUCLASS_DIALOGBOX ) return "puDialogBox" ; if ( i & PUCLASS_SLIDER ) return "puSlider" ; if ( i & PUCLASS_BUTTONBOX ) return "puButtonBox" ; if ( i & PUCLASS_INPUT ) return "puInput" ; if ( i & PUCLASS_MENUBAR ) return "puMenuBar" ; if ( i & PUCLASS_POPUPMENU ) return "puPopupMenu" ; if ( i & PUCLASS_POPUP ) return "puPopup" ; if ( i & PUCLASS_ONESHOT ) return "puOneShot" ; if ( i & PUCLASS_BUTTON ) return "puButton" ; if ( i & PUCLASS_TEXT ) return "puText" ; if ( i & PUCLASS_FRAME ) return "puFrame" ; if ( i & PUCLASS_INTERFACE ) return "puInterface" ; if ( i & PUCLASS_GROUP ) return "puGroup" ; if ( i & PUCLASS_OBJECT ) return "puObject" ; if ( i & PUCLASS_VALUE ) return "puValue" ; return "Unknown Object type." ; } plib-1.8.5/src/pui/Makefile.am0000644000175000001440000000135410765364437013032 00000000000000if BUILD_PUI lib_LIBRARIES = libplibpu.a include_HEADERS = pu.h puGLUT.h puFLTK.h puSDL.h puNative.h puPW.h libplibpu_a_SOURCES = \ pu.cxx puBox.cxx puButton.cxx puButtonBox.cxx \ puArrowButton.cxx puDialogBox.cxx puFrame.cxx puGroup.cxx \ puInput.cxx puInterface.cxx puLocal.h puMenuBar.cxx \ puObject.cxx puOneShot.cxx puPopup.cxx puPopupMenu.cxx \ puListBox.cxx puSlider.cxx puText.cxx \ puValue.cxx puFont.cxx \ puDial.cxx \ puRange.cxx \ puInputBase.cxx AM_CPPFLAGS = -I$(top_srcdir)/src/sg -I$(top_srcdir)/src/fnt AM_CPPFLAGS += -I$(top_srcdir)/src/util endif EXTRA_DIST = pui.dsp plib-1.8.5/src/pui/puSlider.cxx0000644000175000001440000001202610765364437013307 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puSlider.cxx 2088 2006-10-16 08:11:16Z bram $ */ #include "puLocal.h" UL_RTTI_DEF2(puSlider,puRange,puObject) void puSlider::draw_slider_box ( int dx, int dy, const puBox &box, float val, const char *box_label ) { int sd, od ; if ( isVertical() ) { sd = 1 ; od = 0 ; } else { sd = 0 ; od = 1 ; } int sz = box.max [sd] - box.min [sd] ; // Size of slider box, in pixels if ( val < 0.0f ) val = 0.0f ; if ( val > 1.0f ) val = 1.0f ; val *= (float) sz * (1.0f - slider_fraction) ; puBox bx ; bx.min [ sd ] = box.min [ sd ] + (int) val ; bx.max [ sd ] = (int) ( (float) bx.min [ sd ] + (float) sz * slider_fraction ) ; bx.min [ od ] = box.min [ od ] + 2 ; bx.max [ od ] = box.max [ od ] - 2 ; bx.draw ( dx, dy, PUSTYLE_SMALL_SHADED, colour, FALSE, 2 ) ; if ( box_label ) { int xx ; int yy ; if ( isVertical () ) // Vertical slider, text goes to the right of it { xx = bx.max[0] + PUSTR_LGAP ; yy = ( bx.max[1] + bx.min[1] - legendFont.getStringHeight ( box_label ) ) / 2 ; } else // Horizontal slider, text goes above it { xx = ( bx.max[0] + bx.min[0] - legendFont.getStringWidth ( box_label ) ) / 2 ; yy = bx.max[1] + PUSTR_BGAP ; } /* If greyed out then halve the opacity when drawing the label */ if ( active ) glColor4fv ( colour [ PUCOL_LABEL ] ) ; else glColor4f ( colour [ PUCOL_LABEL ][0], colour [ PUCOL_LABEL ][1], colour [ PUCOL_LABEL ][2], colour [ PUCOL_LABEL ][3] / 2.0f ) ; /* 50% more transparent */ legendFont.drawString ( box_label, dx + xx, dy + yy ) ; } } void puSlider::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; if ( ( style == PUSTYLE_BEVELLED ) || ( style == PUSTYLE_SHADED ) ) abox.draw ( dx, dy, -PUSTYLE_BOXED, colour, FALSE, 2 ) ; else abox.draw ( dx, dy, -style, colour, FALSE, border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { float val = getFloatValue () ; draw_slider_box ( dx, dy, abox, ( val - minimum_value ) / ( maximum_value - minimum_value ) ) ; draw_legend ( dx, dy ) ; } draw_label ( dx, dy ) ; } void puSlider::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); if ( ( button == active_mouse_button ) && ( updown == PU_UP ) ) { puDeactivateWidget () ; return ; } if ( button == active_mouse_button ) { int sd = isVertical() ; int sz = abox.max [sd] - abox.min [sd] ; int coord = isVertical() ? y : x ; float next_value ; if ( sz == 0 ) next_value = 0.5f ; else { next_value = ( (float)coord - (float)abox.min[sd] - (float)sz * slider_fraction / 2.0f ) / ( (float) sz * (1.0f - slider_fraction) ) ; } next_value = (next_value < 0.0f) ? 0.0f : (next_value > 1.0f) ? 1.0f : next_value ; next_value = next_value * ( maximum_value - minimum_value ) + minimum_value ; setValue ( checkStep (next_value) ); switch ( cb_mode ) { case PUSLIDER_CLICK : if ( updown == active_mouse_edge ) { last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_DELTA : /* Deprecated! */ if ( fabs ( last_cb_value - next_value ) >= cb_delta ) { last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_ALWAYS : default : last_cb_value = next_value ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; break ; } } } void puSlider::setSliderFraction ( float f ) { int i = isVertical() ? 1 : 0 ; int sz = abox.max [i] - abox.min [i] ; // Size of slider box, in pixels float minf = 10.0f / sz ; // fraction that makes a 10px handle slider_fraction = (f=1.0f) ? 0.9f : f ; puPostRefresh () ; } plib-1.8.5/src/pui/puNative.h0000644000175000001440000000457010765364437012745 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puNative.h 1857 2004-02-16 13:49:03Z stromberg $ */ #ifndef _PU_NATIVE_H_ #define _PU_NATIVE_H_ #ifndef PU_USE_NATIVE # define PU_USE_NATIVE #endif #include "pu.h" #if defined(UL_GLX) # include #elif defined(UL_WGL) // nothing #elif defined(UL_AGL) # include #elif defined(UL_CGL) # include #endif inline int puGetWindowNative () { #if defined(UL_GLX) return (int) glXGetCurrentDrawable () ; #elif defined(UL_WGL) return (int) wglGetCurrentDC () ; #elif defined(UL_AGL) return (int) aglGetCurrentDrawable () ; #elif defined(UL_CGL) return (int) CGLGetCurrentContext () ; #else return 0 ; #endif } inline void puGetWindowSizeNative ( int *width, int *height ) { #if defined(UL_GLX) Window root ; int x, y ; unsigned int w, h, b, d ; XGetGeometry ( glXGetCurrentDisplay (), glXGetCurrentDrawable (), &root, &x, &y, &w, &h, &b, &d ) ; *width = w ; *height = h ; #elif defined(UL_WGL) RECT r ; GetClientRect( WindowFromDC( wglGetCurrentDC() ), &r ); *width = r.right ; *height = r.bottom ; #else // Help! Need implementations for more systems. GLint vp[4] ; glGetIntegerv ( GL_VIEWPORT, vp ) ; *width = vp[0] + vp[2] ; *height = vp[1] + vp[3] ; // Note: puSetOpenGLState calls glViewport(0, 0, w, h). #endif } inline void puInitNative () { puSetWindowFuncs ( puGetWindowNative, NULL, puGetWindowSizeNative, NULL ) ; puRealInit () ; } #endif plib-1.8.5/src/pui/puListBox.cxx0000644000175000001440000001167010765364437013455 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puListBox.cxx 2088 2006-10-16 08:11:16Z bram $ */ /**** * NAME * puListBox * * DESCRIPTION * list of strings * * AUTHOR * Dave McClurg * * CREATION DATE * August 2000 * * MODIFICATION HISTORY * John Fay - many improvements ****/ #include "puLocal.h" UL_RTTI_DEF1(puListBox,puButton) puListBox::puListBox ( int minx, int miny, int maxx, int maxy, char** _list ) : puButton ( minx, miny, maxx, maxy ) { type |= PUCLASS_LISTBOX ; newList ( _list ) ; } void puListBox::newList ( char ** _list ) { list = _list ; if ( list == NULL ) num = 0 ; else for ( num = 0 ; list [ num ] != NULL ; num++ ) /* Count number of items */ ; top = 0 ; /* Set index of selected item */ setValue ( -1 ) ; puPostRefresh () ; } void puListBox::setTopItem( int item_index ) { top = item_index ; int visible = getNumVisible(); if ( top < 0 || num <= visible ) top = 0 ; else if ( num > 0 && top > num-visible ) top = num-visible; puPostRefresh () ; } void puListBox::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) || list == NULL ) return ; abox.draw ( dx, dy, style, colour, isReturnDefault(), border_thickness ) ; /* If greyed out then halve the opacity when drawing the text */ if ( active ) glColor4fv ( colour [ PUCOL_LEGEND ] ) ; else glColor4f ( colour [ PUCOL_LEGEND ][0], colour [ PUCOL_LEGEND ][1], colour [ PUCOL_LEGEND ][2], colour [ PUCOL_LEGEND ][3] / 2.0f ) ; /* 50% more transparent */ int xsize = abox.max[0] - abox.min[0] + 1 ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { int yinc = legendFont.getStringHeight () + PUSTR_BGAP ; int num_vis = getNumVisible () ; int selected ; getValue ( &selected ) ; for ( int i = top ; i < num && i < top + num_vis ; i++ ) { if ( i == selected ) glColor4f ( (colour [ PUCOL_BACKGROUND ][0] + colour [ PUCOL_LABEL ][0]) / 2.0f, (colour [ PUCOL_BACKGROUND ][1] + colour [ PUCOL_LABEL ][1]) / 2.0f, (colour [ PUCOL_BACKGROUND ][2] + colour [ PUCOL_LABEL ][2]) / 2.0f, (colour [ PUCOL_BACKGROUND ][3] + colour [ PUCOL_LABEL ][3]) / 2.0f ); else glColor4f ( colour [ PUCOL_LABEL ][0], colour [ PUCOL_LABEL ][1], colour [ PUCOL_LABEL ][2], colour [ PUCOL_LABEL ][3] ) ; int x = PUSTR_LGAP ; int y = yinc * ((i-top)+1) ; int xx = dx + abox.min[0] + x ; int yy = dy + abox.max[1] - y ; int width ; char str [ PUSTRING_MAX ] ; strcpy ( str, list [ i ] ) ; /* Does the string fit into the box? If not, chop it down one character at a time until it does fit. */ while ( 1 ) { width = legendFont.getStringWidth ( (char *)str ) + PUSTR_LGAP ; if ( width < xsize ) break ; /* Nibble off one character and try again (Do that sneakily by replacing the last 4 characters with 3 dots) */ strcpy ( & str [ strlen(str) - 4 ], "..." ) ; } legendFont.drawString ( (char*)str, xx, yy ) ; } } draw_label ( dx, dy ) ; } void puListBox::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( button == active_mouse_button ) { if ( ( updown == active_mouse_edge ) || ( active_mouse_edge == PU_UP_AND_DOWN ) ) { lowlight () ; int yinc = legendFont.getStringHeight () + PUSTR_BGAP ; int idx = top + ( abox.max[1] - PUSTR_BGAP - y ) / yinc; if ( idx < 0 ) idx = 0; else if ( idx >= num ) idx = num-1; setValue ( idx ) ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } else highlight () ; } else lowlight () ; } plib-1.8.5/src/pui/pu.h0000644000175000001440000012750410765364437011601 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pu.h 2091 2006-10-19 14:39:35Z fayjf $ */ #ifndef _PU_H_ #define _PU_H_ 1 #include #include "fnt.h" #include "ulRTTI.h" /* Configuration */ #define PU_NOBUTTON -1 #define PU_LEFT_BUTTON 0 #define PU_MIDDLE_BUTTON 1 #define PU_RIGHT_BUTTON 2 #define PU_DOWN 0 #define PU_UP 1 class puFont { protected: fntFont * fnt_font_handle ; float pointsize ; float slant ; public: puFont () ; puFont ( fntFont *tfh, float ps = 13, float sl = 0 ) { initialize ( tfh, ps, sl ) ; } void initialize ( fntFont *tfh, float ps, float sl = 0 ) { fnt_font_handle = tfh ; pointsize = ps ; slant = sl ; } float getPointSize ( ) const { return pointsize; } int getStringDescender ( void ) const ; int getStringHeight ( const char *str ) const ; int getStringHeight ( void ) const { return getStringHeight ( "" ) ; } float getFloatStringWidth ( const char *str ) const ; int getStringWidth ( const char *str ) const /* Deprecated ? */ { return (int) getFloatStringWidth ( str ) ; } void drawString ( const char *str, int x, int y ) ; } ; extern puFont PUFONT_8_BY_13 ; extern puFont PUFONT_9_BY_15 ; extern puFont PUFONT_TIMES_ROMAN_10 ; extern puFont PUFONT_TIMES_ROMAN_24 ; extern puFont PUFONT_HELVETICA_10 ; extern puFont PUFONT_HELVETICA_12 ; extern puFont PUFONT_HELVETICA_18 ; #define PU_UP_AND_DOWN 254 #define PU_DRAG 255 #define PU_CONTINUAL PU_DRAG /* WARNING: These have to be the same as PW_KEY_whatever and also the same as (GLUT_KEY_whatever+256) */ #define PU_KEY_GLUT_SPECIAL_OFFSET 256 #define PU_KEY_F1 (1 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F2 (2 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F3 (3 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F4 (4 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F5 (5 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F6 (6 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F7 (7 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F8 (8 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F9 (9 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F10 (10 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F11 (11 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_F12 (12 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_LEFT (100 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_UP (101 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_RIGHT (102 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_DOWN (103 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_PAGE_UP (104 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_PAGE_DOWN (105 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_HOME (106 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_END (107 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PU_KEY_INSERT (108 + PU_KEY_GLUT_SPECIAL_OFFSET) #define PUARROW_UP 0 #define PUARROW_DOWN 1 #define PUARROW_FASTUP 2 #define PUARROW_FASTDOWN 3 #define PUARROW_LEFT 4 #define PUARROW_RIGHT 5 #define PUARROW_FASTLEFT 6 #define PUARROW_FASTRIGHT 7 #define PUBUTTON_NORMAL 0 #define PUBUTTON_RADIO 1 #define PUBUTTON_CIRCLE 2 #define PUBUTTON_VCHECK 3 /* v-shaped checkmark */ #define PUBUTTON_XCHECK 4 /* X checkmark */ /* Rational Definitions of PUI Legend and Label Places */ #define PUPLACE_TOP_LEFT 0 #define PUPLACE_TOP_CENTERED 1 #define PUPLACE_TOP_RIGHT 2 #define PUPLACE_CENTERED_LEFT 3 #define PUPLACE_CENTERED_RIGHT 4 #define PUPLACE_BOTTOM_LEFT 5 #define PUPLACE_BOTTOM_CENTERED 6 #define PUPLACE_BOTTOM_RIGHT 7 /* Additional definitions for PUI Legend places */ #define PUPLACE_CENTERED_CENTERED 8 /* Additional definitions for PUI Label places */ #define PUPLACE_ABOVE_LEFT 9 #define PUPLACE_ABOVE_RIGHT 10 #define PUPLACE_BELOW_LEFT 11 #define PUPLACE_BELOW_RIGHT 12 #define PUPLACE_UPPER_LEFT 13 #define PUPLACE_UPPER_RIGHT 14 #define PUPLACE_LOWER_LEFT 15 #define PUPLACE_LOWER_RIGHT 16 /* Default places */ #define PUPLACE_LABEL_DEFAULT PUPLACE_LOWER_RIGHT #define PUPLACE_LEGEND_DEFAULT PUPLACE_CENTERED_CENTERED /* Keep these for backwards compatibility but deprecate them */ #define PUPLACE_ABOVE PUPLACE_TOP_LEFT #define PUPLACE_BELOW PUPLACE_BOTTOM_LEFT #define PUPLACE_LEFT PUPLACE_LOWER_LEFT #define PUPLACE_RIGHT PUPLACE_LOWER_RIGHT #define PUPLACE_CENTERED PUPLACE_CENTERED_CENTERED #define PUPLACE_TOP_CENTER PUPLACE_TOP_CENTERED #define PUPLACE_BOTTOM_CENTER PUPLACE_BOTTOM_CENTERED #define PUPLACE_LEFT_CENTER PUPLACE_CENTERED_LEFT #define PUPLACE_RIGHT_CENTER PUPLACE_CENTERED_RIGHT #define PUPLACE_DEFAULT PUPLACE_LABEL_DEFAULT #define PUCOL_FOREGROUND 0 #define PUCOL_BACKGROUND 1 #define PUCOL_HIGHLIGHT 2 #define PUCOL_LABEL 3 #define PUCOL_LEGEND 4 #define PUCOL_MISC 5 #define PUCOL_EDITFIELD 6 #define PUCOL_MAX 7 #define PUSLIDER_CLICK 0 #define PUSLIDER_ALWAYS 1 #define PUSLIDER_DELTA 2 /* These styles may be negated to get 'highlighted' graphics */ #define PUSTYLE_DEFAULT PUSTYLE_SHADED #define PUSTYLE_NONE 0 #define PUSTYLE_PLAIN 1 #define PUSTYLE_BEVELLED 2 #define PUSTYLE_BOXED 3 #define PUSTYLE_DROPSHADOW 4 #define PUSTYLE_SPECIAL_UNDERLINED 5 #define PUSTYLE_SMALL_BEVELLED 6 #define PUSTYLE_RADIO 7 /* deprecated ! */ #define PUSTYLE_SHADED 8 #define PUSTYLE_SMALL_SHADED 9 #define PUSTYLE_MAX 10 /* These are the gaps that we try to leave around text objects */ #define PUSTR_TGAP 5 #define PUSTR_BGAP 5 #define PUSTR_LGAP 5 #define PUSTR_RGAP 5 #define PU_RADIO_BUTTON_SIZE 16 /* When to deactivate a widget and call its down callback */ #define PUDEACTIVATE_ON_MOUSE_CLICK 0 #define PUDEACTIVATE_ON_NEXT_WIDGET_ACTIVATION 1 extern int puRefresh ; /* Should not be used directly by applications any longer. Instead, use puPostRefresh () and puNeedRefresh (). */ #define PUCLASS_VALUE 0x00000001 #define PUCLASS_OBJECT 0x00000002 #define PUCLASS_GROUP 0x00000004 #define PUCLASS_INTERFACE 0x00000008 #define PUCLASS_FRAME 0x00000010 #define PUCLASS_TEXT 0x00000020 #define PUCLASS_BUTTON 0x00000040 #define PUCLASS_ONESHOT 0x00000080 #define PUCLASS_POPUP 0x00000100 #define PUCLASS_POPUPMENU 0x00000200 #define PUCLASS_MENUBAR 0x00000400 #define PUCLASS_INPUT 0x00000800 #define PUCLASS_BUTTONBOX 0x00001000 #define PUCLASS_SLIDER 0x00002000 #define PUCLASS_DIALOGBOX 0x00004000 #define PUCLASS_ARROW 0x00008000 #define PUCLASS_LISTBOX 0x00010000 #define PUCLASS_DIAL 0x00020000 class puValue ; class puObject ; class puGroup ; class puInterface ; class puButtonBox ; class puFrame ; class puText ; class puButton ; class puOneShot ; class puPopup ; class puPopupMenu ; class puMenuBar ; class puInput ; class puSlider ; class puListBox ; class puArrowButton ; class puDial ; // Global function to move active object to the end of the "dlist" // so it is displayed in front of everything else void puMoveToLast ( puObject *ob ) ; typedef float puColour [ 4 ] ; /* RGBA */ typedef puColour puColor ; struct puBox { int min [ 2 ] ; int max [ 2 ] ; void draw ( int dx, int dy, int style, puColour colour[], int am_default, int border ) ; void extend ( puBox *bx ) ; void empty ( void ) { min[0]=min[1]=1000000 ; max[0]=max[1]=-1000000 ; } int isEmpty ( void ) const { return min[0]>max[0] || min[1]>max[1] ; } } ; #define PUSTRING_MAX 256 /* With many memory managers, allocating powers of two is more efficient */ #define PUSTRING_INITIAL 64 inline void puSetColour ( puColour dst, const puColour src ) { dst[0] = src[0] ; dst[1] = src[1] ; dst[2] = src[2] ; dst[3] = src[3] ; } inline void puSetColor ( puColour dst, const puColour src ) { dst[0] = src[0] ; dst[1] = src[1] ; dst[2] = src[2] ; dst[3] = src[3] ; } inline void puSetColour ( puColour c, float r, float g, float b, float a = 1.0f ) { c [ 0 ] = r ; c [ 1 ] = g ; c [ 2 ] = b ; c [ 3 ] = a ; } inline void puSetColor ( puColour c, float r, float g, float b, float a = 1.0f ) { c [ 0 ] = r ; c [ 1 ] = g ; c [ 2 ] = b ; c [ 3 ] = a ; } // puInit () -- is a macro, see below void puRealInit ( void ) ; void puExit ( void ) ; void puDisplay ( void ) ; void puDisplay ( int window_number ) ; /* Deprecated */ int puMouse ( int button, int updown, int x, int y ) ; int puMouse ( int x, int y ) ; int puKeyboard ( int key, int updown, int x, int y ) ; /* For PW */ int puKeyboard ( int key, int updown ) ; void puHideCursor ( void ) ; void puShowCursor ( void ) ; int puCursorIsHidden ( void ) ; void puDeleteObject ( puObject *ob ) ; int puNeedRefresh ( void ) ; void puPostRefresh ( void ) ; int puGetWindow ( void ) ; void puGetWindowSize ( int *width, int *height ) ; int puGetWindowWidth ( void ) ; int puGetWindowHeight ( void ) ; void puSetWindow ( int w ) ; // don't use it! void puSetWindowSize ( int width, int height ) ; // don't use it! void puSetResizeMode ( int mode ) ; // DEPRECATED // Active widget functions void puDeactivateWidget ( void ) ; void puSetActiveWidget ( puObject *w, int x, int y ) ; puObject *puActiveWidget ( void ) ; // Return the currently active mouse button extern int puGetPressedButton () ; class puValue { UL_TYPE_DATA protected: int type ; int integer ; float floater ; char *string ; bool boolean ; int *res_integer ; float *res_floater ; char *res_string ; bool *res_bool ; int string_size ; int res_string_sz ; int convert ; void re_eval ( void ) ; void update_res ( void ) const { } /* Obsolete ! */ ; void copy_stringval ( const char *str ) ; int * getIntegerp ( void ) { return res_integer != NULL ? res_integer : &integer ; } float * getFloaterp ( void ) { return res_floater != NULL ? res_floater : &floater ; } char * getStringp ( void ) { return res_string != NULL ? res_string : string ; } bool * getBooleanp ( void ) { return res_bool != NULL ? res_bool : &boolean ; } void enableConversion ( void ) { convert = TRUE ; } void disableConversion ( void ) { convert = FALSE ; } int conversionEnabled ( void ) const { return convert ; } public: puValue () { convert = TRUE ; string_size = PUSTRING_INITIAL ; string = new char [ string_size ] ; type = PUCLASS_VALUE ; res_integer = NULL ; res_floater = NULL ; res_string = NULL ; res_bool = NULL ; clrValue () ; } virtual ~puValue () { delete [] string ; } int getType ( void ) const { return type ; } const char *getTypeString ( void ) const ; void clrValue ( void ) { setValue ( "" ) ; } virtual void setValue ( puValue *pv ) { *getIntegerp () = pv -> getIntegerValue () ; *getFloaterp () = pv -> getFloatValue () ; copy_stringval ( pv -> getStringValue () ) ; *getBooleanp () = pv -> getBooleanValue () ; puPostRefresh () ; } void setValuator ( int *i ) { res_integer = i ; if ( convert == TRUE ) { res_floater = NULL ; res_string = NULL ; res_bool = NULL ; re_eval () ; } } void setValuator ( float *f ) { res_floater = f ; if ( convert == TRUE ) { res_integer = NULL ; res_string = NULL ; res_bool = NULL ; re_eval () ; } } void setValuator ( char *s, int size ) { res_string = s ; res_string_sz = size ; if ( convert == TRUE ) { res_integer = NULL ; res_floater = NULL ; res_bool = NULL ; re_eval () ; } } void setValuator ( bool *b ) { res_bool = b ; if ( convert == TRUE ) { res_integer = NULL ; res_floater = NULL ; res_string = NULL ; re_eval () ; } } /* Obsolete ! */ void setValuator ( char *s ) { setValuator ( s, PUSTRING_MAX ) ; } virtual void setValue ( int i ) { *getIntegerp () = i ; if ( convert == TRUE ) { *getFloaterp () = (float) i ; sprintf ( getStringp (), "%d", i ) ; *getBooleanp () = ( i != 0 ) ; } puPostRefresh () ; } virtual void setValue ( float f ) { *getFloaterp () = f ; if ( convert == TRUE ) { *getIntegerp () = (int) f ; sprintf ( getStringp (), "%g", f ) ; *getBooleanp () = ( f != 0.0 ) ; } puPostRefresh () ; } virtual void setValue ( const char *s ) ; virtual void setValue ( bool b ) { *getBooleanp () = b ; if ( convert == TRUE ) { *getIntegerp () = b ? 1 : 0 ; *getFloaterp () = b ? 1.0f : 0.0f ; sprintf ( getStringp (), "%s", b ? "1" : "0" ) ; } puPostRefresh () ; } void getValue ( int *i ) { re_eval () ; *i = *getIntegerp () ; } void getValue ( float *f ) { re_eval () ; *f = *getFloaterp () ; } void getValue ( char **s ) { re_eval () ; *s = getStringp () ; } void getValue ( char *s, int size ) { re_eval () ; /* Work around ANSI strncpy's null-fill behaviour */ s[0] = '\0' ; strncat ( s, getStringp (), size-1 ) ; } void getValue ( char *s ) { getValue ( s, PUSTRING_MAX ) ; } /* Obsolete ! */ void getValue ( bool *b ) { re_eval () ; *b = *getBooleanp () ; } int getValue ( void ) { return getIntegerValue () ; } /* Obsolete ! */ virtual int getIntegerValue ( void ) { re_eval () ; return *getIntegerp () ; } virtual float getFloatValue ( void ) { re_eval () ; return *getFloaterp () ; } virtual char getCharValue ( void ) { re_eval () ; return getStringp ()[0]; } virtual char *getStringValue ( void ) { re_eval () ; return getStringp () ; } virtual bool getBooleanValue ( void ) { re_eval () ; return *getBooleanp () ; } /* RTTI */ ulRTTItypeid getTypeInfo ( void ) const { return RTTI_vinfo () ; } } ; typedef void (*puCallback)(class puObject *) ; typedef void (*puRenderCallback)(class puObject *, int dx, int dy, void *) ; void puSetDefaultStyle ( int style ) ; int puGetDefaultStyle ( void ) ; void puSetDefaultBorderThickness ( int t ) ; int puGetDefaultBorderThickness ( void ) ; void puSetDefaultFonts ( puFont legendFont, puFont labelFont ) ; void puGetDefaultFonts ( puFont *legendFont, puFont *labelFont ) ; puFont puGetDefaultLabelFont ( void ) ; puFont puGetDefaultLegendFont ( void ) ; void puSetDefaultColourScheme ( float r, float g, float b, float a = 1.0f ) ; inline void puSetDefaultColorScheme ( float r, float g, float b, float a = 1.0f ) { puSetDefaultColourScheme ( r, g, b, a ) ; } void puGetDefaultColourScheme ( float *r, float *g, float *b, float *a = NULL ); inline void puGetDefaultColorScheme ( float *r, float *g, float *b, float *a = NULL ) { puGetDefaultColourScheme ( r, g, b, a ) ; } class puObject : public puValue { UL_TYPE_DATA protected: puValue default_value ; puBox bbox ; /* Bounding box of entire Object */ puBox abox ; /* Active (clickable) area */ puColour colour [ PUCOL_MAX ] ; puGroup *parent ; int active_mouse_edge ; /* is it PU_UP or PU_DOWN (or both) that activates this? */ int active_mouse_button ; /* which mouse button or buttons activate this */ int style ; int visible ; int active ; int highlighted ; int am_default ; int window ; /* Which window does the object appear in? */ int v_status ; /* 1 if the Object should lock in the top left corner, 0 if not */ const char *label ; puFont labelFont ; int labelPlace ; const char *legend ; puFont legendFont ; int legendPlace ; void *user_data ; puCallback cb ; puCallback active_cb ; puCallback down_cb ; puRenderCallback r_cb ; void *render_data ; int border_thickness ; short when_to_deactivate ; /* On next mouseclick or on next widget activation */ virtual void draw_legend ( int dx, int dy ) ; virtual void draw_label ( int dx, int dy ) ; public: virtual int isHit ( int x, int y ) const { return isVisible() && isActive() && x > abox.min[0] && x < abox.max[0] && y > abox.min[1] && y < abox.max[1] && window == puGetWindow () ; } virtual void doHit ( int button, int updown, int x, int y ) ; puObject ( int minx, int miny, int maxx, int maxy ) ; ~puObject () ; puObject *next ; /* Should not be used directly by applications any longer. */ puObject *prev ; /* Instead, use the setNextObject and setPrevObject methods. */ puBox *getBBox ( void ) const { return (puBox *) &bbox ; } puBox *getABox ( void ) const { return (puBox *) &abox ; } void getAbsolutePosition ( int *x, int *y ) const ; virtual void setPosition ( int x, int y ) { if ( abox.isEmpty() ) { abox.max[0] = abox.min[0] = x ; abox.max[1] = abox.min[1] = y ; } else { abox.max[0] += x - abox.min[0] ; abox.max[1] += y - abox.min[1] ; abox.min[0] = x ; abox.min[1] = y ; } recalc_bbox() ; puPostRefresh () ; } virtual void setSize ( int w, int h ) { abox.max[0] = abox.min[0] + w ; abox.max[1] = abox.min[1] + h ; recalc_bbox() ; puPostRefresh () ; } void getPosition ( int *x, int *y ) const { if ( abox.isEmpty () ) { if ( x ) *x = 0 ; if ( y ) *y = 0 ; } else { if ( x ) *x = abox.min[0] ; if ( y ) *y = abox.min[1] ; } } void getSize ( int *w, int *h ) const { if ( abox.isEmpty () ) { if ( w ) *w = 0 ; if ( h ) *h = 0 ; } else { if ( w ) *w = abox.max[0] - abox.min[0] ; if ( h ) *h = abox.max[1] - abox.min[1] ; } } virtual void recalc_bbox ( void ) ; virtual int checkHit ( int button, int updown, int x, int y ) ; virtual int checkKey ( int key , int updown ) ; virtual void draw ( int dx, int dy ) = 0 ; puGroup *getParent ( void ) const { return parent ; } void setParent ( puGroup* p ) { parent = p ; } void setNextObject ( puObject *obj ) { next = obj ; } puObject *getNextObject ( void ) const { return next ; } void setPrevObject ( puObject *obj ) { prev = obj ; } puObject *getPrevObject ( void ) const { return prev ; } void setCallback ( puCallback c ) { cb = c ; } puCallback getCallback ( void ) const { return cb ; } void invokeCallback ( void ) { if ( cb != NULL ) (*cb)(this) ; } void setActiveCallback ( puCallback c ) { active_cb = c ; } puCallback getActiveCallback ( void ) const { return active_cb ; } void invokeActiveCallback ( void ) { if ( active_cb != NULL ) (*active_cb)(this) ; } void setDownCallback ( puCallback c ) { down_cb = c ; } puCallback getDownCallback ( void ) const { return down_cb ; } virtual void invokeDownCallback ( void ) { if ( down_cb != NULL ) (*down_cb)(this) ; } void setRenderCallback ( puRenderCallback c, void *d = NULL ) { r_cb = c ; render_data = d ; } puRenderCallback getRenderCallback ( void ) const { return r_cb ; } void *getRenderCallbackData ( void ) const { return render_data ; } void invokeRenderCallback ( int dx, int dy ) { if ( r_cb != NULL ) (*r_cb)(this, dx, dy, render_data) ; } void setBorderThickness ( int t ) { border_thickness = t ; puPostRefresh () ; } int getBorderThickness ( void ) const { return border_thickness ; } void makeReturnDefault ( int def ) { am_default = def ; puPostRefresh () ; } int isReturnDefault ( void ) const { return am_default ; } int getWindow ( void ) const { return window ; } void setWindow ( int w ) { window = w ; puPostRefresh () ; } void setActiveDirn ( int e ) { active_mouse_edge = e ; } int getActiveDirn ( void ) const { return active_mouse_edge ; } void setActiveButton ( int b ) { active_mouse_button = b ; } int getActiveButton ( void ) const { return active_mouse_button ; } void setWhenToDeactivate ( short d ) { when_to_deactivate = d ; } short getWhenToDeactivate ( void ) const { return when_to_deactivate ; } void setLegend ( const char *l ) { legend = l ; recalc_bbox() ; puPostRefresh () ; } const char *getLegend ( void ) const { return legend ; } void setLegendFont ( puFont f ) { legendFont = f ; recalc_bbox() ; puPostRefresh () ; } puFont getLegendFont ( void ) const { return legendFont ; } void setLegendPlace ( int lp ) { legendPlace = lp ; recalc_bbox() ; puPostRefresh () ; } int getLegendPlace ( void ) const { return legendPlace ; } void setLabel ( const char *l ) { label = l ; recalc_bbox() ; puPostRefresh () ; } const char *getLabel ( void ) const { return label ; } void setLabelFont ( puFont f ) { labelFont = f ; recalc_bbox() ; puPostRefresh () ; } puFont getLabelFont ( void ) const { return labelFont ; } void setLabelPlace ( int lp ) { labelPlace = lp ; recalc_bbox() ; puPostRefresh () ; } int getLabelPlace ( void ) const { return labelPlace ; } void activate ( void ) { if ( ! active ) { active = TRUE ; puPostRefresh () ; } } void greyOut ( void ) { if ( active ) { active = FALSE ; puPostRefresh () ; } } int isActive ( void ) const { return active ; } void highlight ( void ) { if ( ! highlighted ) { highlighted = TRUE ; puPostRefresh () ; } } void lowlight ( void ) { if ( highlighted ) { highlighted = FALSE ; puPostRefresh () ; } } int isHighlighted( void ) const { return highlighted ; } void reveal ( void ) { if ( ! visible ) { visible = TRUE ; puPostRefresh () ; } } void hide ( void ) { if ( visible ) { visible = FALSE ; puPostRefresh () ; } } int isVisible ( void ) const { return visible ; } void setStyle ( int which ) { style = which ; switch ( abs(style) ) { case PUSTYLE_SPECIAL_UNDERLINED : border_thickness = 1 ; break ; case PUSTYLE_SMALL_BEVELLED : case PUSTYLE_SMALL_SHADED : case PUSTYLE_BOXED : border_thickness = 2 ; break ; case PUSTYLE_BEVELLED : case PUSTYLE_SHADED : case PUSTYLE_DROPSHADOW : border_thickness = 5 ; break ; } recalc_bbox () ; puPostRefresh () ; } int getStyle ( void ) const { return style ; } virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ; void setColorScheme ( float r, float g, float b, float a = 1.0f ) { setColourScheme ( r, g, b, a ) ; } virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) { puSetColour ( colour [ which ], r, g, b, a ) ; puPostRefresh () ; } void setColor ( int which, float r, float g, float b, float a = 1.0f ) { setColour ( which, r, g, b, a ) ; } void getColour ( int which, float *r, float *g, float *b, float *a = NULL ) const { if ( r ) *r = colour[which][0] ; if ( g ) *g = colour[which][1] ; if ( b ) *b = colour[which][2] ; if ( a ) *a = colour[which][3] ; } void getColor ( int which, float *r, float *g, float *b, float *a = NULL ) const { getColour ( which, r, g, b, a ); } void setUserData ( void *data ) { user_data = data ; } void *getUserData ( void ) const { return user_data ; } void defaultValue ( void ) { setValue ( & default_value ) ; } void setDefaultValue ( int i ) { default_value.setValue ( i ) ; } void setDefaultValue ( float f ) { default_value.setValue ( f ) ; } void setDefaultValue ( const char *s ) { default_value.setValue ( s ) ; } void getDefaultValue ( int *i ) { default_value.getValue ( i ) ; } void getDefaultValue ( float *f ) { default_value.getValue ( f ) ; } void getDefaultValue ( char **s ) { default_value.getValue ( s ) ; } void getDefaultValue ( char *s ) { default_value.getValue ( s ) ; } int getDefaultValue ( void ) { return default_value.getValue () ; } /* Obsolete ! */ int getDefaultIntegerValue ( void ) { return default_value.getIntegerValue () ; } float getDefaultFloatValue ( void ) { return default_value.getFloatValue () ; } char *getDefaultStringValue ( void ) { return default_value.getStringValue () ; } int getVStatus ( void ) const { return v_status ; } /* JCJ 6 Jun 2002 */ void setVStatus ( int vstat ) { v_status = vstat ; } } ; /* The 'live' interface stack is used for clicking and rendering. */ void puPushLiveInterface ( puInterface *in ) ; void puPopLiveInterface ( puInterface *in = 0 ) ; int puNoLiveInterface ( void ) ; puInterface *puGetBaseLiveInterface ( void ) ; puInterface *puGetUltimateLiveInterface ( void ) ; /* The regular group stack is used for adding widgets */ void puPushGroup ( puGroup *in ) ; void puPopGroup ( void ) ; int puNoGroup ( void ) ; puGroup *puGetCurrGroup ( void ) ; class puGroup : public puObject { UL_TYPE_DATA protected: int num_children ; puObject *dlist ; int mouse_x ; // Coordinates of mouse when right button pressed for int mouse_y ; // drag and drop int mouse_active; // Flag telling whether interface is presently being dragged void doHit ( int button, int updown, int x, int y ) ; int floating; // DEPRECATED! -- Flag telling whether the interface floats in the window or stays put public: puGroup ( int x, int y ) : puObject ( x, y, x, y ) { type |= PUCLASS_GROUP ; dlist = NULL ; num_children = 0 ; mouse_x = 0 ; mouse_y = 0 ; mouse_active = FALSE ; floating = FALSE ; // DEPRECATED! puPushGroup ( this ) ; } ~puGroup () ; void recalc_bbox ( void ) ; virtual void add ( puObject *new_object ) ; virtual void remove ( puObject *old_object ) ; virtual void empty ( void ) ; void draw ( int dx, int dy ) ; int checkHit ( int button, int updown, int x, int y ) ; int checkKey ( int key , int updown ) ; puObject *getFirstChild ( void ) const { return dlist ; } puObject *getLastChild ( void ) const { puObject *bo = dlist ; if ( bo != NULL ) { while ( bo -> getNextObject() != NULL ) bo = bo -> getNextObject() ; } return bo ; } int getNumChildren ( void ) const { return num_children ; } virtual void close ( void ) { if ( puGetCurrGroup () != this ) ulSetError ( UL_WARNING, "PUI: puGroup::close() is mismatched!" ) ; else puPopGroup () ; } void setFloating ( int value ) { floating = value ; } // DEPRECATED! int getFloating ( void ) const { return floating ; } // DEPRECATED! void setChildStyle ( int childs, int which, int recursive = FALSE ) ; void setChildBorderThickness ( int childs, int t, int recursive = FALSE ) ; void setChildColour ( int childs, int which, float r, float g, float b, float a = 1.0f, int recursive = FALSE ) ; void setChildColor ( int childs, int which, float r, float g, float b, float a = 1.0f, int recursive = FALSE ) { setChildColour ( childs, which, r, g, b, a, recursive ) ; } void setChildColourScheme ( int childs, float r, float g, float b, float a = 1.0f, int recursive = FALSE ) ; void setChildColorScheme ( int childs, float r, float g, float b, float a = 1.0f, int recursive = FALSE ) { setChildColourScheme ( childs, r, g, b, a, recursive ) ; } void setChildLegendFont ( int childs, puFont f, int recursive = FALSE ) ; void setChildLabelFont ( int childs, puFont f, int recursive = FALSE ) ; } ; class puInterface : public puGroup { UL_TYPE_DATA public: puInterface ( int x, int y ) : puGroup ( x, y ) { type |= PUCLASS_INTERFACE ; puPushLiveInterface ( this ) ; } ~puInterface () ; } ; class puFrame : public puObject { UL_TYPE_DATA public: void draw ( int dx, int dy ) ; puFrame ( int minx, int miny, int maxx, int maxy ) : puObject ( minx, miny, maxx, maxy ) { type |= PUCLASS_FRAME ; } void doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { // Active widget exists and is not this one; call its down callback if it exists puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( isHit ( x, y ) && ( updown != PU_DRAG ) ) puMoveToLast ( this -> parent ); } } ; class puText : public puObject { UL_TYPE_DATA public: virtual int isHit ( int /* x */, int /* y */ ) const { return FALSE ; } void draw ( int dx, int dy ) ; puText ( int x, int y ) : puObject ( x, y, x, y ) { type |= PUCLASS_TEXT ; } } ; class puButton : public puObject { UL_TYPE_DATA protected: int button_type ; public: void doHit ( int button, int updown, int x, int y ) ; void draw ( int dx, int dy ) ; int getButtonType ( void ) const { return button_type ; } void setButtonType ( int btype ) { button_type = btype ; puPostRefresh () ; } puButton ( int minx, int miny, const char *l ) : puObject ( minx, miny, minx + puGetDefaultLegendFont().getStringWidth ( l ) + PUSTR_LGAP + PUSTR_RGAP, miny + puGetDefaultLegendFont().getStringHeight ( l ) + puGetDefaultLegendFont().getStringDescender () + PUSTR_TGAP + PUSTR_BGAP ) { type |= PUCLASS_BUTTON ; button_type = PUBUTTON_NORMAL ; setLegend ( l ) ; } puButton ( int minx, int miny, int maxx, int maxy, int btype = PUBUTTON_NORMAL ) : puObject ( minx, miny, maxx, maxy ) { type |= PUCLASS_BUTTON ; button_type = btype ; } } ; class puOneShot : public puButton { UL_TYPE_DATA protected: public: void doHit ( int button, int updown, int x, int y ) ; puOneShot ( int minx, int miny, const char *l ) : puButton ( minx, miny, l ) { type |= PUCLASS_ONESHOT ; } puOneShot ( int minx, int miny, int maxx, int maxy ) : puButton ( minx, miny, maxx, maxy ) { type |= PUCLASS_ONESHOT ; } } ; class puArrowButton : public puOneShot { UL_TYPE_DATA protected: int arrow_type ; public: void draw ( int dx, int dy ) ; int getArrowType ( void ) const { return arrow_type ; } void setArrowType ( int i ) { arrow_type = i ; puPostRefresh () ; } puArrowButton ( int minx, int miny, int maxx, int maxy, int ptype ) : puOneShot ( minx, miny, maxx, maxy ) { type |= PUCLASS_ARROW ; arrow_type = ptype ; } } ; class puRange { UL_TYPE_DATA protected: float minimum_value ; float maximum_value ; float step_size ; float last_cb_value ; float cb_delta ; int cb_mode ; void puRange_init ( float minval, float maxval, float step ) { if ( maxval == minval ) { maxval = 1.0f ; minval = 0.0f ; } minimum_value = minval ; maximum_value = maxval ; step_size = step ; last_cb_value = -1.0f ; cb_delta = 0.1f ; cb_mode = PUSLIDER_ALWAYS ; } public: puRange () { puRange_init ( 0.0f, 1.0f, 0.0f ) ; } puRange ( float minval, float maxval, float step = 0.0f ) { puRange_init ( minval, maxval, step ) ; } virtual ~puRange() { } float getMaxValue ( void ) const { return maximum_value ; } virtual void setMaxValue ( float f ) { maximum_value = f ; } float getMinValue ( void ) const { return minimum_value ; } virtual void setMinValue ( float f ) { minimum_value = f ; } float getStepSize ( void ) const { return step_size ; } void setStepSize ( float f ) { step_size = f ; } float checkStep ( float val_to_check ) const { float step = val_to_check ; if ( getStepSize () > 0.0f ) { step = val_to_check - (float) fmod ( val_to_check, getStepSize () ) ; if ( ( val_to_check - step ) > ( step + getStepSize() - val_to_check ) ) step += getStepSize () ; } return step ; } void setCBMode ( int m ) { cb_mode = m ; } int getCBMode ( void ) const { return cb_mode ; } void setDelta ( float f ) { cb_delta = (f<=0.0f) ? 0.1f : (f>=1.0f) ? 0.9f : f ; } float getDelta ( void ) const { return cb_delta ; } } ; class puSlider : public puRange, public puObject { UL_TYPE_DATA protected: int vert ; float slider_fraction ; void draw_slider_box ( int dx, int dy, const puBox &box, float val, const char *box_label = NULL ) ; void puSlider_init ( int vertical ) { type |= PUCLASS_SLIDER ; slider_fraction = 0.1f ; vert = vertical ; } public: void doHit ( int button, int updown, int x, int y ) ; void draw ( int dx, int dy ) ; puSlider ( int minx, int miny, int sz, int vertical = FALSE ) : puRange (), puObject ( minx, miny, vertical ? ( minx + puGetDefaultLegendFont().getStringWidth ( "W" ) + PUSTR_LGAP + PUSTR_RGAP ) : ( minx + sz ), vertical ? ( miny + sz ) : ( miny + puGetDefaultLegendFont().getStringHeight () + puGetDefaultLegendFont().getStringDescender () + PUSTR_TGAP + PUSTR_BGAP ) ) { puSlider_init ( vertical ) ; } /* Blake Friesen - alternate constructor which lets you explicitly set width */ puSlider ( int minx, int miny, int sz, int vertical, int width ) : puRange (), puObject ( minx, miny, vertical ? ( minx + width ) : ( minx + sz ), vertical ? ( miny + sz ) : ( miny + width ) ) { puSlider_init ( vertical ) ; } int isVertical ( void ) const { return vert ; } void setSliderFraction ( float f ) ; float getSliderFraction ( void ) const { return slider_fraction ; } } ; class puListBox : public puButton { UL_TYPE_DATA protected: char ** list ; int num ; int top ; public: void doHit ( int button, int updown, int x, int y ) ; void draw ( int dx, int dy ) ; puListBox ( int minx, int miny, int maxx, int maxy, char** list = NULL ) ; void newList ( char ** _list ) ; int getNumItems ( void ) const { return num ; } int getNumVisible ( void ) const { int ysize = abox.max[1] - abox.min[1] + 1 ; int yinc = legendFont.getStringHeight () + PUSTR_BGAP ; return (ysize - PUSTR_BGAP) / yinc ; } int getTopItem ( void ) const { return top ; } void setTopItem ( int item_index ) ; } ; class puDial : public puRange, public puObject { UL_TYPE_DATA protected: int wrap ; // Flag telling whether you can wrap around the bottom of the dial public: void doHit ( int button, int updown, int x, int y ) ; void draw ( int dx, int dy ) ; puDial ( int minx, int miny, int sz ) : puRange (), puObject ( minx, miny, minx+sz, miny+sz ) { type |= PUCLASS_DIAL ; setValue ( 0.0f ) ; wrap = TRUE ; } puDial ( int minx, int miny, int sz, float minval, float maxval, float step = 0.0f ) : puRange ( minval, maxval, step ), puObject ( minx, miny, minx+sz, miny+sz ) { type |= PUCLASS_DIAL ; setValue ( 0.0f ) ; wrap = TRUE ; } void setWrap ( int in ) { wrap = in ; } int getWrap ( void ) const { return wrap ; } } ; class puPopup : public puInterface { UL_TYPE_DATA protected: public: puPopup ( int x, int y ) : puInterface ( x, y ) { type |= PUCLASS_POPUP ; hide () ; } } ; class puPopupMenu : public puPopup { UL_TYPE_DATA protected: public: puPopupMenu ( int x, int y ) : puPopup ( x, y ) { type |= PUCLASS_POPUPMENU ; } puObject *add_item ( const char *str, puCallback _cb, void *_user_data = NULL ) ; int checkHit ( int button, int updown, int x, int y ) ; int checkKey ( int key , int updown ) ; void close ( void ) ; } ; class puMenuBar : public puInterface { UL_TYPE_DATA protected: int bar_height ; public: puMenuBar ( int h = -1 ) : puInterface ( 0, 0 ) { type |= PUCLASS_MENUBAR ; bar_height = h ; } void add_submenu ( const char *str, char *items[], puCallback _cb[], void *_user_data[] = NULL ) ; void close ( void ) ; } ; class puInputBase { UL_TYPE_DATA protected: int accepting ; int cursor_position ; int select_start_position ; int select_end_position ; char *valid_data ; int input_disabled ; char *displayed_text ; // Pointer to text as it is displayed in the box (chopped or word-wrapped) puObject *widget ; /* Pointer to associated input box widget */ virtual void normalizeCursors ( void ) ; virtual void removeSelectRegion ( void ) ; public: int isAcceptingInput ( void ) const { return accepting ; } void rejectInput ( void ) { accepting = FALSE ; puPostRefresh () ; } void acceptInput ( void ) { accepting = TRUE ; cursor_position = strlen ( widget -> getStringValue () ) ; select_start_position = select_end_position = -1 ; puPostRefresh () ; } int getCursor ( void ) const { return cursor_position ; } void setCursor ( int c ) { cursor_position = c ; puPostRefresh () ; } virtual void setSelectRegion ( int s, int e ) { select_start_position = s ; select_end_position = e ; puPostRefresh () ; } void getSelectRegion ( int *s, int *e ) const { if ( s ) *s = select_start_position ; if ( e ) *e = select_end_position ; } char *getValidData ( void ) const { return valid_data ; } void setValidData ( const char *data ) { delete [] valid_data ; valid_data = ( data != NULL ) ? ulStrDup ( data ) : NULL ; } void addValidData ( const char *data ) ; int isValidCharacter ( char c ) const { if ( valid_data != NULL ) return ( strchr ( valid_data, c ) != NULL ) ? 1 : 0 ; else return 1 ; } void enableInput ( void ) { input_disabled = FALSE ; } void disableInput ( void ) { input_disabled = TRUE ; } int inputDisabled ( void ) const { return input_disabled ; } puInputBase ( void ) { accepting = FALSE ; cursor_position = 0 ; select_start_position = -1 ; select_end_position = -1 ; valid_data = NULL; displayed_text = NULL ; widget = (puObject *)NULL ; input_disabled = FALSE ; } virtual ~puInputBase () { delete [] valid_data ; delete [] displayed_text ; } } ; class puInput : public puInputBase, public puObject { UL_TYPE_DATA int display_starting_point ; char *getDisplayedText ( void ) { return ( displayed_text == NULL ? getStringValue () : displayed_text ) ; } public: void draw ( int dx, int dy ) ; void doHit ( int button, int updown, int x, int y ) ; int checkKey ( int key, int updown ) ; void invokeDownCallback ( void ) { rejectInput () ; normalizeCursors () ; if ( down_cb != NULL ) (*down_cb)(this) ; } puInput ( int minx, int miny, int maxx, int maxy ) : puInputBase (), puObject ( minx, miny, maxx, maxy ) { type |= PUCLASS_INPUT ; display_starting_point = 0 ; setColourScheme ( colour [ PUCOL_EDITFIELD ][0], colour [ PUCOL_EDITFIELD ][1], colour [ PUCOL_EDITFIELD ][2], colour [ PUCOL_EDITFIELD ][3] ) ; setColour ( PUCOL_MISC, 0.1f, 0.1f, 1.0f ) ; /* Colour of 'I' bar cursor */ widget = this ; } virtual void setValue ( puValue *pv ) { puValue::setValue ( pv ) ; delete displayed_text ; displayed_text = NULL ; } virtual void setValue ( int i ) { puValue::setValue ( i ) ; delete displayed_text ; displayed_text = NULL ; } virtual void setValue ( float f ) { puValue::setValue ( f ) ; delete displayed_text ; displayed_text = NULL ; } virtual void setValue ( const char *s ) { puValue::setValue ( s ) ; delete displayed_text ; displayed_text = NULL ; } virtual void setValue ( bool b ) { puValue::setValue ( b ) ; delete displayed_text ; displayed_text = NULL ; } } ; class puButtonBox : public puObject { UL_TYPE_DATA protected: int one_only ; int num_kids ; char **button_labels ; public: puButtonBox ( int minx, int miny, int maxx, int maxy, char **labels, int one_button ) ; int isOneButton ( void ) const { return one_only ; } void newList ( char ** _list ) ; int getNumItems ( void ) const { return num_kids ; } int checkKey ( int key , int updown ) ; int checkHit ( int button, int updown, int x, int y ) ; void draw ( int dx, int dy ) ; } ; class puDialogBox : public puPopup { UL_TYPE_DATA protected: public: puDialogBox ( int x, int y ) : puPopup ( x, y ) { type |= PUCLASS_DIALOGBOX ; } } ; /* * Window System Integration * ------------------------- * * PUI has direct support for GLUT, PW, FLTK, SDL and GTK. All code is provided * inline, making PUI itself independent. There are several ways to choose * implementation, for instance: * * #include * #include * * or simply: * * #include * * Note that both cases may fail if pu.h has been included earlier. * A safer option is therefore to compile with -DPU_USE_FLTK. * * The default system is GLUT for backwards compability. * * To use PUI with an unsupported system, define PU_USE_NONE and * provide your own callbacks (if needed, the defaults will work * in many cases). * * When compiling the PUI library itself, PU_USE_NONE must be defined. * */ typedef int (*puGetWindowCallback) ( ) ; typedef void (*puSetWindowCallback) ( int window ) ; typedef void (*puGetWindowSizeCallback) ( int *width, int *height ) ; typedef void (*puSetWindowSizeCallback) ( int width, int height ) ; void puSetWindowFuncs ( puGetWindowCallback, puSetWindowCallback, puGetWindowSizeCallback, puSetWindowSizeCallback ) ; // Choose implementation #if !defined(PU_USE_GLUT) && \ !defined(PU_USE_PW) && \ !defined(PU_USE_FLTK) && \ !defined(PU_USE_SDL) && \ !defined(PU_USE_NATIVE) && \ !defined(PU_USE_NONE) // Nothing selected. Try to figure out which one to use. #if defined(PW_IS_PRESENT) # define PU_USE_PW #elif defined(FL_MAJOR_VERSION) # define PU_USE_FLTK #elif defined(SDL_MAJOR_VERSION) # define PU_USE_SDL #else # define PU_USE_GLUT #endif #endif // Roll out the code and define puInit #if defined(PU_USE_GLUT) # include "puGLUT.h" # define puInit puInitGLUT #elif defined(PU_USE_PW) # include "puPW.h" # define puInit puInitPW #elif defined(PU_USE_FLTK) # include "puFLTK.h" # define puInit puInitFLTK #elif defined(PU_USE_SDL) # include "puSDL.h" # define puInit puInitSDL #elif defined(PU_USE_NATIVE) # include "puNative.h" # define puInit puInitNative #else # define puInit #endif #endif plib-1.8.5/src/pui/puInterface.cxx0000644000175000001440000000614310765364437013770 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puInterface.cxx 1834 2003-12-16 23:16:04Z puggles $ */ #include "puLocal.h" UL_RTTI_DEF1(puInterface,puGroup) #define PUSTACK_MAX 100 static int currLiveInterface = -1 ; static puInterface *liveInterfaceStack [ PUSTACK_MAX ] ; void puPushLiveInterface ( puInterface *in ) { if ( currLiveInterface < PUSTACK_MAX - 1 ) liveInterfaceStack [ ++currLiveInterface ] = in ; else ulSetError ( UL_WARNING, "PUI: Too many live puInterfaces open at once!\n" ) ; } void puPopLiveInterface ( puInterface *in ) { if ( currLiveInterface < 0 ) { ulSetError ( UL_WARNING, "PUI: Live puInterface stack is empty!\n" ) ; return; } if ( in == NULL ) --currLiveInterface ; else { for ( int i = currLiveInterface ; i >= 0 ; i-- ) { if ( in == liveInterfaceStack [ i ] ) { /* Handle interfaces that are buried in the stack */ while ( i < currLiveInterface ) { liveInterfaceStack [ i ] = liveInterfaceStack [ i+1 ] ; i++ ; } --currLiveInterface ; break ; } } } } int puNoLiveInterface ( void ) { return currLiveInterface < 0 ; } puInterface *puGetUltimateLiveInterface ( void ) { if ( currLiveInterface < 0 ) ulSetError ( UL_FATAL, "PUI: No Live Interface! Forgot to call puInit ?\n" ) ; return liveInterfaceStack [ 0 ] ; } puInterface *puGetBaseLiveInterface ( void ) { if ( currLiveInterface < 0 ) ulSetError ( UL_FATAL, "PUI: No Live Interface! Forgot to call puInit ?\n" ) ; /* Work down the interface stack until you either get to the bottom or find a block in the form of a puDialogBox. */ for ( int i = currLiveInterface ; i > 0 ; i-- ) if ( liveInterfaceStack [ i ] -> getType () & PUCLASS_DIALOGBOX ) return liveInterfaceStack [ i ] ; return liveInterfaceStack [ 0 ] ; } puInterface::~puInterface () { void puCleanUpJunk ( void ) ; puObject *bo = getLastChild () ; while ( bo != NULL ) { dlist = bo ; bo = bo -> getPrevObject() ; puDeleteObject ( dlist ) ; } // Since this is an object destructor, it should be okay to delete the child objects as well. puCleanUpJunk () ; dlist = NULL ; puPopLiveInterface ( this ) ; } plib-1.8.5/src/pui/puDial.cxx0000644000175000001440000001163310765364437012741 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puDial.cxx 2021 2005-05-06 18:31:27Z fayjf $ */ #include "puLocal.h" UL_RTTI_DEF2(puDial,puRange,puObject) void puDial::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; // Draw the active box. if ( ( style == PUSTYLE_BEVELLED ) || ( style == PUSTYLE_SHADED ) ) abox.draw ( dx, dy, -PUSTYLE_BOXED, colour, FALSE, 2 ) ; else abox.draw ( dx, dy, -style, colour, FALSE, border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { // If greyed out then halve the opacity when drawing the widget if ( active ) glColor4fv ( colour [ PUCOL_MISC ] ) ; else glColor4f ( colour [ PUCOL_MISC ][0], colour [ PUCOL_MISC ][1], colour [ PUCOL_MISC ][2], colour [ PUCOL_MISC ][3] / 2.0f ) ; // 50% more transparent // Draw the surrounding circle. float rad = (float)( abox.max [0] - abox.min [0] ) / 2.0f - 3.0f ; int x_cen = dx + ( abox.max [0] + abox.min [0] ) / 2 ; int y_cen = dy + ( abox.max [1] + abox.min [1] ) / 2 ; float dtheta = 3.0f / rad ; // three pixels per segment glPushAttrib ( GL_LINE_BIT ) ; glLineWidth ( 2.0f ) ; // set line width to two pixels glBegin ( GL_LINE_STRIP ) ; float theta ; for ( theta = -SG_PI; theta < SG_PI+dtheta; theta+= dtheta ) { float x = (float)x_cen + rad * (float)cos ( (double)theta ) ; float y = (float)y_cen + rad * (float)sin ( (double)theta ) ; glVertex2f ( x, y ) ; } glEnd () ; // Draw the line from the center. glLineWidth ( 4.0f ) ; // four pixels wide float val ; getValue ( &val ) ; val = ( val - minimum_value) / (maximum_value - minimum_value) ; if ( val < 0.0f ) val = 0.0f ; if ( val > 1.0f ) val = 1.0f ; val = ( 2.0f * val - 1.0f ) * SG_PI ; glBegin ( GL_LINES ) ; glVertex2f ( (float)x_cen, (float)y_cen ) ; glVertex2f ( (float)x_cen + rad * (float)sin ( (double)val ), (float)y_cen + rad * (float)cos ( (double)val ) ) ; glEnd () ; glPopAttrib () ; draw_legend ( dx, dy ) ; } draw_label ( dx, dy ) ; } void puDial::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); if ( ( button == active_mouse_button ) && ( updown == PU_UP ) ) { puDeactivateWidget () ; return ; } if ( button == active_mouse_button ) { int x_cen = ( abox.max [0] + abox.min [0] ) / 2 ; int y_cen = ( abox.max [1] + abox.min [1] ) / 2 ; float angle = (float)atan2 ( (double)(x-x_cen), (double)(y-y_cen) ) / SG_PI ; // Move to within the (0,1) interval if ( angle < -1.0f ) angle += 2.0f ; else if (angle > 1.0f ) angle -= 2.0f ; angle = ( angle + 1.0f ) / 2.0f ; // Check for hitting the limits (user has dragged the mouse around the bottom // of the widget) if ( !wrap ) { if ( ( angle > 0.75f ) && ( getFloatValue () < 0.25f ) ) angle = 0.0f ; else if ( ( angle < 0.25f ) && ( getFloatValue () > 0.75f ) ) angle = 1.0f ; } angle = angle * (maximum_value - minimum_value) + minimum_value ; setValue( checkStep(angle) ) ; switch ( cb_mode ) { case PUSLIDER_CLICK : if ( updown == active_mouse_edge ) { last_cb_value = angle ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_DELTA :/* Deprecated! */ if ( fabs ( last_cb_value - angle ) >= cb_delta ) { last_cb_value = angle ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } break ; case PUSLIDER_ALWAYS : default : last_cb_value = angle ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; break ; } } } plib-1.8.5/src/pui/Makefile.in0000644000175000001440000004452210765365023013037 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/pui DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibpu_a_AR = $(AR) $(ARFLAGS) libplibpu_a_LIBADD = am__libplibpu_a_SOURCES_DIST = pu.cxx puBox.cxx puButton.cxx \ puButtonBox.cxx puArrowButton.cxx puDialogBox.cxx puFrame.cxx \ puGroup.cxx puInput.cxx puInterface.cxx puLocal.h \ puMenuBar.cxx puObject.cxx puOneShot.cxx puPopup.cxx \ puPopupMenu.cxx puListBox.cxx puSlider.cxx puText.cxx \ puValue.cxx puFont.cxx puDial.cxx puRange.cxx puInputBase.cxx @BUILD_PUI_TRUE@am_libplibpu_a_OBJECTS = pu.$(OBJEXT) puBox.$(OBJEXT) \ @BUILD_PUI_TRUE@ puButton.$(OBJEXT) puButtonBox.$(OBJEXT) \ @BUILD_PUI_TRUE@ puArrowButton.$(OBJEXT) puDialogBox.$(OBJEXT) \ @BUILD_PUI_TRUE@ puFrame.$(OBJEXT) puGroup.$(OBJEXT) \ @BUILD_PUI_TRUE@ puInput.$(OBJEXT) puInterface.$(OBJEXT) \ @BUILD_PUI_TRUE@ puMenuBar.$(OBJEXT) puObject.$(OBJEXT) \ @BUILD_PUI_TRUE@ puOneShot.$(OBJEXT) puPopup.$(OBJEXT) \ @BUILD_PUI_TRUE@ puPopupMenu.$(OBJEXT) puListBox.$(OBJEXT) \ @BUILD_PUI_TRUE@ puSlider.$(OBJEXT) puText.$(OBJEXT) \ @BUILD_PUI_TRUE@ puValue.$(OBJEXT) puFont.$(OBJEXT) \ @BUILD_PUI_TRUE@ puDial.$(OBJEXT) puRange.$(OBJEXT) \ @BUILD_PUI_TRUE@ puInputBase.$(OBJEXT) libplibpu_a_OBJECTS = $(am_libplibpu_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libplibpu_a_SOURCES) DIST_SOURCES = $(am__libplibpu_a_SOURCES_DIST) am__include_HEADERS_DIST = pu.h puGLUT.h puFLTK.h puSDL.h puNative.h \ puPW.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_PUI_TRUE@lib_LIBRARIES = libplibpu.a @BUILD_PUI_TRUE@include_HEADERS = pu.h puGLUT.h puFLTK.h puSDL.h puNative.h puPW.h @BUILD_PUI_TRUE@libplibpu_a_SOURCES = \ @BUILD_PUI_TRUE@ pu.cxx puBox.cxx puButton.cxx puButtonBox.cxx \ @BUILD_PUI_TRUE@ puArrowButton.cxx puDialogBox.cxx puFrame.cxx puGroup.cxx \ @BUILD_PUI_TRUE@ puInput.cxx puInterface.cxx puLocal.h puMenuBar.cxx \ @BUILD_PUI_TRUE@ puObject.cxx puOneShot.cxx puPopup.cxx puPopupMenu.cxx \ @BUILD_PUI_TRUE@ puListBox.cxx puSlider.cxx puText.cxx \ @BUILD_PUI_TRUE@ puValue.cxx puFont.cxx \ @BUILD_PUI_TRUE@ puDial.cxx \ @BUILD_PUI_TRUE@ puRange.cxx \ @BUILD_PUI_TRUE@ puInputBase.cxx @BUILD_PUI_TRUE@AM_CPPFLAGS = -I$(top_srcdir)/src/sg \ @BUILD_PUI_TRUE@ -I$(top_srcdir)/src/fnt \ @BUILD_PUI_TRUE@ -I$(top_srcdir)/src/util EXTRA_DIST = pui.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/pui/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/pui/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibpu.a: $(libplibpu_a_OBJECTS) $(libplibpu_a_DEPENDENCIES) -rm -f libplibpu.a $(libplibpu_a_AR) libplibpu.a $(libplibpu_a_OBJECTS) $(libplibpu_a_LIBADD) $(RANLIB) libplibpu.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puArrowButton.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puButton.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puButtonBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puDial.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puDialogBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puFont.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puFrame.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puGroup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puInput.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puInputBase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puInterface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puListBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puMenuBar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puObject.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puOneShot.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puPopup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puPopupMenu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puRange.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puSlider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puText.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/puValue.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/pui/puButtonBox.cxx0000644000175000001440000001066510765364437014020 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puButtonBox.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "puLocal.h" UL_RTTI_DEF1(puButtonBox,puObject) puButtonBox::puButtonBox ( int minx, int miny, int maxx, int maxy, char **labels, int one_button ) : puObject ( minx, miny, maxx, maxy ) { type |= PUCLASS_BUTTONBOX ; one_only = one_button ; button_labels = labels ; newList ( labels ) ; } void puButtonBox::newList ( char ** _list ) { button_labels = _list ; if ( button_labels == NULL ) num_kids = 0 ; else for ( num_kids = 0 ; button_labels [ num_kids ] != NULL ; num_kids++ ) /* Count number of items */ ; puPostRefresh() ; } int puButtonBox::checkKey ( int key, int updown ) { if ( updown == PU_UP || ! isReturnDefault() || ( key != '\r' && key != '\n' ) || ( window != puGetWindow () ) ) return FALSE ; if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } int v = getIntegerValue () ; if ( ! one_only ) v = ~v ; else if ( ++v > num_kids ) v = 0 ; setValue ( v ) ; // puSetActiveWidget ( this, x, y ) ; invokeCallback() ; return TRUE ; } int puButtonBox::checkHit ( int /*button*/, int updown, int x, int y ) { if ( ! isHit ( x, y ) || ( updown != active_mouse_edge && active_mouse_edge != PU_UP_AND_DOWN ) ) return FALSE ; if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); int i = num_kids - 1 - (( y - abox.min[1] - PUSTR_BGAP ) * num_kids ) / ( abox.max[1] - abox.min[1] - PUSTR_BGAP - PUSTR_TGAP ) ; if ( i < 0 ) i = 0 ; if ( i >= num_kids ) i = num_kids - 1 ; if ( one_only ) setValue ( i ) ; else setValue ( getIntegerValue () ^ ( 1 << i ) ) ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; return TRUE ; } void puButtonBox::draw ( int dx, int dy ) { if ( !visible || ( window != puGetWindow () ) ) return ; abox.draw ( dx, dy, style, colour, isReturnDefault(), border_thickness ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { for ( int i = 0 ; i < num_kids ; i++ ) { puBox tbox ; tbox.min [ 0 ] = abox.min [ 0 ] + PUSTR_LGAP + PUSTR_LGAP ; tbox.min [ 1 ] = abox.min [ 1 ] + ((abox.max[1]-abox.min[1]-PUSTR_TGAP-PUSTR_BGAP)/num_kids) * (num_kids-1-i) ; tbox.max [ 0 ] = tbox.min [ 0 ] ; tbox.max [ 1 ] = tbox.min [ 1 ] ; if (( one_only && i == getIntegerValue() ) || ( !one_only && ((1<getType() & PUCLASS_POPUPMENU ) || ( parent->getType() & PUCLASS_MENUBAR ) ) ) abox.draw ( dx, dy, active ? PUSTYLE_SMALL_SHADED : PUSTYLE_PLAIN, colour, isReturnDefault(), active ? 2 : 0 ) ; else abox.draw ( dx, dy, -style, colour, isReturnDefault(), border_thickness ) ; } else abox.draw ( dx, dy, style, colour, isReturnDefault(), border_thickness ) ; } else if ( ( button_type == PUBUTTON_VCHECK ) || ( button_type == PUBUTTON_XCHECK ) ) abox.draw ( dx, dy, PUSTYLE_BOXED, colour, isReturnDefault(), 1 ) ; if ( r_cb ) r_cb ( this, dx, dy, render_data ) ; else { switch ( button_type ) { case PUBUTTON_NORMAL : draw_legend ( dx, dy ) ; break ; case PUBUTTON_RADIO : { int btn_width = abox.max[0] - abox.min[0], btn_height = abox.max[1] - abox.min[1] ; glColor4fv ( ( getIntegerValue () ^ highlighted ) ? colour [ PUCOL_BACKGROUND ] : colour [ PUCOL_LEGEND ] ) ; glBegin ( GL_LINE_LOOP ) ; glVertex2i ( dx+abox.min[0] + btn_width/2, dy+abox.min[1] ) ; glVertex2i ( dx+abox.min[0] + btn_width, dy+abox.min[1] + btn_height/2 ) ; glVertex2i ( dx+abox.min[0] + btn_width/2, dy+abox.min[1] + btn_height ) ; glVertex2i ( dx+abox.min[0], dy+abox.min[1] + btn_height/2 ) ; glEnd () ; if ( getIntegerValue () ^ highlighted ) { /* If greyed out then halve the opacity when drawing the widget */ if ( active ) glColor4fv ( colour [ PUCOL_HIGHLIGHT ] ) ; else glColor4f ( colour [ PUCOL_HIGHLIGHT ][0], colour [ PUCOL_HIGHLIGHT ][1], colour [ PUCOL_HIGHLIGHT ][2], colour [ PUCOL_HIGHLIGHT ][3] / 2.0f ) ; /* 50% more transparent */ glBegin ( GL_QUADS ) ; glVertex2i ( dx+abox.min[0] + btn_width/2, dy+abox.min[1] + 2 ) ; glVertex2i ( dx+abox.min[0] + btn_width - 2, dy+abox.min[1] + btn_height/2 ) ; glVertex2i ( dx+abox.min[0] + btn_width/2, dy+abox.min[1] + btn_height - 2 ) ; glVertex2i ( dx+abox.min[0] + 2, dy+abox.min[1] + btn_height/2 ) ; glEnd () ; } break ; } case PUBUTTON_CIRCLE : { float rad = ( (abox.max[0]-abox.min[0]) < (abox.max[1]-abox.min[1]) ) ? (abox.max[0]-abox.min[0])/2.0f : (abox.max[1]-abox.min[1])/2.0f ; float dtheta = 2.0f / rad ; float theta ; /* Draw the outer circle */ glColor4fv ( colour [ PUCOL_FOREGROUND ] ) ; glBegin ( GL_POLYGON ) ; for ( theta = -SG_PI ; theta <= SG_PI ; theta += dtheta ) glVertex2f ( dx + abox.min[0] + rad + (rad * float(cos ( theta ))), dy + abox.min[1] + rad + (rad * float(sin ( theta ))) ) ; glEnd () ; if ( getIntegerValue () ^ highlighted ) /* If clicked, draw the inner circle with half the radius */ { rad /= 2 ; dtheta = 2.0f / rad ; /* If greyed out then halve the opacity when drawing the widget */ if ( active ) glColor4fv ( colour [ PUCOL_MISC ] ) ; else glColor4f ( colour [ PUCOL_MISC ][0], colour [ PUCOL_MISC ][1], colour [ PUCOL_MISC ][2], colour [ PUCOL_MISC ][3] / 2.0f ) ; /* 50% more transparent */ glBegin ( GL_POLYGON ) ; for ( theta = -SG_PI ; theta <= SG_PI ; theta += dtheta ) glVertex2f ( dx + abox.min[0] + rad*2 + (rad * float(cos ( theta ))), dy + abox.min[1] + rad*2 + (rad * float(sin ( theta ))) ) ; glEnd () ; } break ; } case PUBUTTON_VCHECK : case PUBUTTON_XCHECK : if ( getIntegerValue () ^ highlighted ) { /* If greyed out then halve the opacity when drawing the widget */ if ( active ) glColor4fv ( colour [ PUCOL_MISC ] ) ; else glColor4f ( colour [ PUCOL_MISC ][0], colour [ PUCOL_MISC ][1], colour [ PUCOL_MISC ][2], colour [ PUCOL_MISC ][3] / 2.0f ) ; /* 50% more transparent */ glPushAttrib ( GL_LINE_BIT ) ; glLineWidth ( 2.0f ) ; if ( button_type == PUBUTTON_VCHECK ) { glBegin ( GL_LINE_STRIP ) ; glVertex2i ( dx + abox.min[0], dy + abox.min[1] + (abox.max[1] - abox.min[1])/2 ) ; glVertex2i ( dx + abox.min[0] + (abox.max[0] - abox.min[0])/3, dy + abox.min[1] ) ; glVertex2i ( dx + abox.max[0], dy + abox.max[1] ) ; glEnd () ; } else if ( button_type == PUBUTTON_XCHECK ) { glBegin ( GL_LINES ) ; glVertex2i ( dx + abox.min[0] + 1, dy + abox.min[1] + 1 ) ; glVertex2i ( dx + abox.max[0] - 1, dy + abox.max[1] - 1 ) ; glVertex2i ( dx + abox.max[0] - 1, dy + abox.min[1] + 1 ) ; glVertex2i ( dx + abox.min[0] + 1, dy + abox.max[1] - 1 ) ; glEnd () ; } glPopAttrib () ; } break ; default : ulSetError ( UL_WARNING, "PUI: Unrecognised 'button_type' %d", button_type ) ; break; } } draw_label ( dx, dy ) ; } void puButton::doHit ( int button, int updown, int x, int y ) { if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown != PU_DRAG ) puMoveToLast ( this ); if ( button == active_mouse_button ) { if ( ( updown == active_mouse_edge ) || ( active_mouse_edge == PU_UP_AND_DOWN ) ) { lowlight () ; setValue ( (int) ! getIntegerValue () ) ; puSetActiveWidget ( this, x, y ) ; invokeCallback () ; } else { /* If the mouse is over the widget, highlight it; otherwise lowlight it */ if ( ( abox.min[0] <= x ) && ( abox.max[0] >= x ) && ( abox.min[1] <= y ) && ( abox.max[1] >= y ) ) highlight () ; else lowlight () ; } } else lowlight () ; } plib-1.8.5/src/pui/puOneShot.cxx0000644000175000001440000000221610765364437013444 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puOneShot.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "puLocal.h" UL_RTTI_DEF1(puOneShot,puButton) void puOneShot::doHit ( int button, int updown, int x, int y ) { puButton::doHit ( button, updown, x, y ) ; setValue ( 0 ) ; } plib-1.8.5/src/pui/puBox.cxx0000644000175000001440000002234410765364437012621 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puBox.cxx 1943 2004-08-05 01:05:48Z puggles $ */ #include "puLocal.h" #define PU_DFLT_OFFSET 5 void puBox::extend ( puBox *bx ) { if ( bx -> isEmpty () ) return ; if ( min[0]>bx->min[0] ) min[0] = bx->min[0] ; if ( min[1]>bx->min[1] ) min[1] = bx->min[1] ; if ( max[0]max[0] ) max[0] = bx->max[0] ; if ( max[1]max[1] ) max[1] = bx->max[1] ; } void puBox::draw ( int dx, int dy, int style, puColour colour[], int am_default, int border ) { int mid = PUCOL_FOREGROUND ; int hi = PUCOL_HIGHLIGHT ; int lo = PUCOL_BACKGROUND ; /* Colour assignments */ switch ( style ) { case PUSTYLE_NONE : return ; case PUSTYLE_PLAIN : case PUSTYLE_DROPSHADOW : mid = PUCOL_FOREGROUND ; lo = PUCOL_BACKGROUND ; break ; case PUSTYLE_SMALL_SHADED : case PUSTYLE_SHADED : case PUSTYLE_SMALL_BEVELLED : case PUSTYLE_BEVELLED : case PUSTYLE_BOXED : case PUSTYLE_SPECIAL_UNDERLINED : mid = PUCOL_FOREGROUND ; hi = PUCOL_HIGHLIGHT ; lo = PUCOL_BACKGROUND ; break ; case PUSTYLE_RADIO : hi = PUCOL_HIGHLIGHT ; lo = PUCOL_LEGEND ; break ; case -PUSTYLE_RADIO : hi = PUCOL_HIGHLIGHT ; lo = PUCOL_BACKGROUND ; break ; case -PUSTYLE_PLAIN : case -PUSTYLE_DROPSHADOW : mid = PUCOL_HIGHLIGHT ; lo = PUCOL_BACKGROUND ; break ; case -PUSTYLE_SMALL_BEVELLED : case -PUSTYLE_BEVELLED : case -PUSTYLE_SMALL_SHADED : case -PUSTYLE_SHADED : case -PUSTYLE_BOXED : case -PUSTYLE_SPECIAL_UNDERLINED : mid = PUCOL_FOREGROUND ; hi = PUCOL_BACKGROUND ; lo = PUCOL_HIGHLIGHT ; break ; default : ulSetError ( UL_WARNING, "PUI: Unrecognised 'style' %d", style ) ; return ; } switch ( abs(style) ) { case PUSTYLE_PLAIN : glColor4fv ( colour [ mid ] ) ; glRecti ( dx + min[0], dy + min[1], dx + max[0], dy + max[1] ) ; break ; case PUSTYLE_SMALL_BEVELLED : case PUSTYLE_SMALL_SHADED : case PUSTYLE_BEVELLED : case PUSTYLE_SHADED : glColor4fv ( colour [ hi ] ) ; glBegin ( GL_QUAD_STRIP ) ; glVertex2i ( dx + min[0] + border, dy + min[1] + border ) ; glVertex2i ( dx + min[0], dy + min[1] ) ; glVertex2i ( dx + min[0] + border, dy + max[1] - border ) ; glVertex2i ( dx + min[0], dy + max[1] ) ; glVertex2i ( dx + max[0] - border, dy + max[1] - border ) ; glVertex2i ( dx + max[0], dy + max[1] ) ; glEnd () ; glColor4fv ( colour [ lo ] ) ; glBegin ( GL_QUAD_STRIP ) ; glVertex2i ( dx + min[0], dy + min[1] ) ; glVertex2i ( dx + min[0] + border, dy + min[1] + border ) ; glVertex2i ( dx + max[0], dy + min[1] ) ; glVertex2i ( dx + max[0] - border, dy + min[1] + border ) ; glVertex2i ( dx + max[0], dy + max[1] ) ; glVertex2i ( dx + max[0] - border, dy + max[1] - border ) ; glEnd () ; if ( ( abs(style) == PUSTYLE_SMALL_BEVELLED ) || ( abs(style) == PUSTYLE_BEVELLED ) ) { glColor4fv ( colour [ mid ] ) ; glRecti ( dx + min[0] + border, dy + min[1] + border, dx + max[0] - border, dy + max[1] - border ) ; } else { glShadeModel ( GL_SMOOTH ) ; glBegin ( GL_POLYGON ) ; glColor4fv ( colour [ mid ] ) ; glVertex2i ( dx + min[0] + border, dy + min[1] + border ) ; if ( ( style == PUSTYLE_SMALL_SHADED ) || ( style == PUSTYLE_SHADED ) ) glColor4f ( colour [mid][0] + (colour[lo][0] - colour[mid][0])/2.0f, colour [mid][1] + (colour[lo][1] - colour[mid][1])/2.0f, colour [mid][2] + (colour[lo][2] - colour[mid][2])/2.0f, colour [lo][3] ) ; else glColor4f ( colour [mid][0] + (colour[hi][0] - colour[mid][0])/2.0f, colour [mid][1] + (colour[hi][1] - colour[mid][1])/2.0f, colour [mid][2] + (colour[hi][2] - colour[mid][2])/2.0f, colour [hi][3] ) ; glVertex2i ( dx + min[0] + border, dy + max[1] - border ) ; glColor4fv ( colour [ mid ] ) ; glVertex2i ( dx + max[0] - border, dy + max[1] - border ) ; if ( ( style == -PUSTYLE_SMALL_SHADED ) || ( style == -PUSTYLE_SHADED ) ) glColor4f ( colour [mid][0] + (colour[lo][0] - colour[mid][0])/2.0f, colour [mid][1] + (colour[lo][1] - colour[mid][1])/2.0f, colour [mid][2] + (colour[lo][2] - colour[mid][2])/2.0f, colour [lo][3] ) ; else glColor4f ( colour [mid][0] + (colour[hi][0] - colour[mid][0])/2.0f, colour [mid][1] + (colour[hi][1] - colour[mid][1])/2.0f, colour [mid][2] + (colour[hi][2] - colour[mid][2])/2.0f, colour [hi][3] ) ; glVertex2i ( dx + max[0] - border, dy + min[1] + border ) ; glEnd () ; glShadeModel (GL_FLAT) ; if ( ( style == -PUSTYLE_SMALL_SHADED ) || ( style == -PUSTYLE_SHADED ) ) { glColor4fv ( colour [ lo ] ) ; glBegin ( GL_QUAD_STRIP ) ; glVertex2i ( dx + min[0] + border , dy + min[1] + border ) ; glVertex2i ( dx + min[0] + border/2 , dy + min[1] + border/2 ) ; glVertex2i ( dx + min[0] + border , dy + max[1] - border ) ; glVertex2i ( dx + min[0] + border/2 , dy + max[1] - border/2 ) ; glVertex2i ( dx + max[0] - border , dy + max[1] - border ) ; glVertex2i ( dx + max[0] - border/2 , dy + max[1] - border/2 ) ; glEnd () ; glColor4fv ( colour [ hi ] ) ; glBegin ( GL_QUAD_STRIP ) ; glVertex2i ( dx + min[0] + border/2 , dy + min[1] + border/2 ) ; glVertex2i ( dx + min[0] + border , dy + min[1] + border ) ; glVertex2i ( dx + max[0] - border/2 , dy + min[1] + border/2 ) ; glVertex2i ( dx + max[0] - border , dy + min[1] + border ) ; glVertex2i ( dx + max[0] - border/2 , dy + max[1] - border/2 ) ; glVertex2i ( dx + max[0] - border , dy + max[1] - border ) ; glEnd () ; } } break ; case PUSTYLE_BOXED : glColor4fv ( colour [ hi ] ) ; glRecti ( dx + min[0], dy + min[1], dx + max[0], dy + max[1] ) ; glColor4fv ( colour [ mid ] ) ; glRecti ( dx + min[0]+border, dy + min[1]+border, dx + max[0]-border, dy + max[1]-border ) ; break ; case PUSTYLE_RADIO : glColor4fv ( colour [ lo ] ) ; glBegin ( GL_LINE_LOOP ) ; glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] ) ; glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ; glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + PU_RADIO_BUTTON_SIZE ) ; glVertex2i ( dx + min[0] , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ; glEnd () ; if ( style < 0 ) { glColor4fv ( colour [ hi ] ) ; glBegin ( GL_QUADS ) ; glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + 2 ) ; glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE-2, dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ; glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + PU_RADIO_BUTTON_SIZE-2 ) ; glVertex2i ( dx + min[0] + 2 , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ; glEnd () ; } break ; case PUSTYLE_SPECIAL_UNDERLINED : glColor4fv ( colour [ hi ] ) ; glRecti ( dx + min[0], dy + min[1], dx + max[0], dy + min[1]+border ) ; glColor4fv ( colour [ mid ] ) ; glRecti ( dx + min[0], dy + min[1]+border, dx + max[0], dy + max[1] ) ; break ; case PUSTYLE_DROPSHADOW : glColor4fv ( colour [ lo ] ) ; glRecti ( dx + min[0] + border, dy + min[1] - border, dx + max[0] + border, dy + max[1] - border ) ; glColor4fv ( colour [ mid ] ) ; glRecti ( dx + min[0], dy + min[1], dx + max[0], dy + max[1] ) ; break ; } if ( am_default ) { glColor4fv ( colour [ PUCOL_BACKGROUND ] ) ; glLineStipple ( 1, 0xF0F0 ) ; glEnable ( GL_LINE_STIPPLE ) ; glBegin ( GL_LINE_LOOP ) ; glVertex2f ( dx + min[0] + PU_DFLT_OFFSET + 0.5f, dy + min[1] + PU_DFLT_OFFSET + 0.5f ) ; glVertex2f ( dx + min[0] + PU_DFLT_OFFSET + 0.5f, dy + max[1] - PU_DFLT_OFFSET - 0.5f ) ; glVertex2f ( dx + max[0] - PU_DFLT_OFFSET - 0.5f, dy + max[1] - PU_DFLT_OFFSET - 0.5f ) ; glVertex2f ( dx + max[0] - PU_DFLT_OFFSET - 0.5f, dy + min[1] + PU_DFLT_OFFSET + 0.5f ) ; glEnd () ; glDisable ( GL_LINE_STIPPLE ) ; } } plib-1.8.5/src/pui/puMenuBar.cxx0000644000175000001440000001250710765364437013422 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puMenuBar.cxx 2021 2005-05-06 18:31:27Z fayjf $ */ #include "puLocal.h" UL_RTTI_DEF1(puMenuBar,puInterface) void puMenuBar_drop_down_the_menu ( puObject *b ) { // Inputs: b = pointer to the button on the menu which has been pushed // p = pointer to the popup menu which is b's submenu puPopupMenu *p = (puPopupMenu *) b -> getUserData () ; if ( b -> getIntegerValue () ) { /* SJBL Test hack. */ puDeactivateWidget () ; p->reveal () ; // Reveal the submenu // If the parent floats in its own window, and the submenu drops off the window, // expand the window to fit. #if 1 puGroup *parent = p -> getParent () ; if ( ( parent != parent -> getParent () ) && parent -> getFloating () ) // DEPRECATED! -- we need to replace this code. { int temp_window = puGetWindow () ; puSetWindow ( parent -> getWindow () ) ; puBox *par_box = parent -> getBBox () ; puBox *cur_box = p -> getBBox () ; int x_min = (cur_box->min[0] < 0) ? par_box->min[0] + cur_box->min[0] : par_box->min[0] ; int x_max = (par_box->max[0] > par_box->min[0] + cur_box->max[0]) ? par_box->max[0] : par_box->min[0] + cur_box->max[0] ; int y_min = (cur_box->min[1] < 0) ? par_box->min[1] + cur_box->min[1] : par_box->min[1] ; int y_max = (par_box->max[1] > par_box->min[1] + cur_box->max[1]) ? par_box->max[1] : par_box->min[1] + cur_box->max[1] ; int x_siz, y_siz; puGetWindowSize ( &x_siz, &y_siz ) ; if ( x_siz < (x_max - x_min) ) x_siz = x_max - x_min ; // Adjust the present size if ( y_siz < (y_max - y_min) ) y_siz = y_max - y_min ; puSetWindowSize ( x_siz, y_siz ) ; x_min = par_box->min[0] - x_min ; y_min = y_siz - ( par_box->max[1] - par_box->min[1] ) ; /* If the parent window is SUPPOSED to be stuck at the top of the screen, move it. - JCJ 6 June 2002 */ if (parent -> getVStatus () == 1) parent -> setPosition ( x_min, y_min ) ; puSetWindow ( temp_window ) ; } #endif } else p->hide () ; for ( puObject *child = b -> getParent () -> getFirstChild () ; child != NULL ; child = child -> getNextObject() ) { if (( child -> getType() & PUCLASS_BUTTON ) != 0 && child != b ) child -> clrValue () ; if (( child -> getType() & PUCLASS_POPUPMENU ) != 0 && child != p ) child -> hide () ; } // Move the popup menu to the last item in the "dlist" so it is drawn last // (in front of everything else). puMoveToLast ( p ); } void puMenuBar::add_submenu ( const char *str, char *items[], puCallback _cb[], void *_user_data[] ) { int w, h ; getSize ( &w, &h ) ; puOneShot *b ; if ( bar_height > 0 ) { b = new puOneShot ( w+10, 0, w+10 + PUSTR_LGAP + puGetDefaultLegendFont().getStringWidth ( str ) + PUSTR_RGAP, bar_height ) ; b -> setLegend ( str ) ; } else b = new puOneShot ( w+10, 0, str ) ; b -> setStyle ( PUSTYLE_SPECIAL_UNDERLINED ) ; b -> setColourScheme ( colour[PUCOL_FOREGROUND][0], colour[PUCOL_FOREGROUND][1], colour[PUCOL_FOREGROUND][2], colour[PUCOL_FOREGROUND][3] ) ; b -> setCallback ( puMenuBar_drop_down_the_menu ) ; b -> setActiveDirn ( PU_UP_AND_DOWN ) ; puPopupMenu *p = new puPopupMenu ( w+10, 0 ) ; p->setActiveButton ( active_mouse_button ) ; b -> setUserData ( p ) ; if ( _user_data != NULL ) for ( int i = 0 ; items[i] != NULL ; i++ ) p -> add_item ( items[i], _cb[i], _user_data[i] ) ; else for ( int i = 0 ; items[i] != NULL ; i++ ) p -> add_item ( items[i], _cb[i] ) ; p->close () ; recalc_bbox () ; } void puMenuBar::close (void) { puInterface::close () ; if ( dlist == NULL ) return ; int width = 0 ; puObject *ob ; /* Use alternate objects - which gets the puOneShot/puPopupMenu pairs */ for ( ob = dlist ; ob != NULL ; ob = ob -> getNextObject() ) { int w, h ; /* Reposition the button so it looks nice */ ob -> getSize ( &w, &h ) ; ob -> setPosition ( width, 0 ) ; ob = ob -> getNextObject() ; /* Reposition the submenu so it sits under the button */ int w2, h2 ; ob -> getSize ( &w2, &h2 ) ; ob -> setPosition ( width, -h2 ) ; /* Next please! */ width += w ; } recalc_bbox () ; } plib-1.8.5/src/pui/puPopupMenu.cxx0000644000175000001440000001466610765364437014031 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: puPopupMenu.cxx 2021 2005-05-06 18:31:27Z fayjf $ */ #include "puLocal.h" UL_RTTI_DEF1(puPopupMenu,puPopup) puObject *puPopupMenu::add_item ( const char *str, puCallback _cb, void *_user_data ) { int w, h ; getSize ( &w, &h ) ; puOneShot *b = new puOneShot ( 0, h, str ) ; b->setStyle ( PUSTYLE_PLAIN ) ; b->setColourScheme ( colour[PUCOL_FOREGROUND][0], colour[PUCOL_FOREGROUND][1], colour[PUCOL_FOREGROUND][2], colour[PUCOL_FOREGROUND][3] ) ; b->setCallback ( _cb ) ; b->setLegendPlace ( PUPLACE_LOWER_LEFT ) ; b->setUserData ( _user_data ) ; b->setActiveButton ( active_mouse_button ) ; b->setWindow ( getWindow () ) ; recalc_bbox () ; return b ; } void puPopupMenu::close ( void ) { puPopup::close () ; int widest = 0 ; puObject *ob = dlist ; /* * June 17th, 1998, Shammi * There seems to be some mismatch with the * #define pumenusize and the actual size * There seems to be some overlap resulting * in more than one option being highlighted. * By setting the size to the actual values, * the overlap area seems to be less now. */ int w, h ; for ( ob = dlist ; ob != NULL ; ob = ob -> getNextObject() ) { ob -> getSize ( &w, &h ) ; if ( w > widest ) widest = w ; } for ( ob = dlist ; ob != NULL ; ob = ob -> getNextObject() ) { ob -> getSize ( &w, &h ) ; ob -> setSize ( widest, h ) ; } recalc_bbox () ; } int puPopupMenu::checkKey ( int key, int updown ) { if ( dlist == NULL || ! isVisible () || ! isActive () || ( window != puGetWindow () ) ) return FALSE ; if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } if ( updown == PU_DOWN ) { hide () ; /* Turn everything off ready for next time. */ for ( puObject *bo = dlist ; bo != NULL ; bo = bo -> getNextObject() ) bo -> clrValue () ; } puObject *bo ; /* We have to walk the list backwards to ensure that the click order is the same as the DRAW order. */ for ( bo = dlist ; bo -> getNextObject() != NULL ; bo = bo -> getNextObject() ) /* Find the last object in our list. */ ; for ( ; bo != NULL ; bo = bo -> getPrevObject() ) if ( bo -> checkKey ( key, updown ) ) return TRUE ; return FALSE ; } int puPopupMenu::checkHit ( int button, int updown, int x, int y ) { if ( dlist == NULL || ! isVisible () || ! isActive () || ( window != puGetWindow () ) ) return FALSE ; /* If an item is going to fall out the bottom of the window and puGroup will */ /* move it upward (around line 303 of puGroup.cxx), then make sure checkhit */ /* realizes the thing has moved -- JCJ and Fay 5 June 2002 */ int absx, absy ; getAbsolutePosition (&absx, &absy) ; if ( absy < 0 ) y += absy ; /* Must test 'isHit' before making the menu invisible! */ /* * June 17th, 1998, Shammi : * There seemed to be a miscalculation with the menus initially * Therefore I moved the recalculation stuff before the clearing. */ /* This might be a bit redundant - but it's too hard to keep track of changing abox sizes when daughter objects are changing sizes. */ int hit = isHit ( x, y ) ; /* If the mouse is clicked on another widget, hide the window - JCJ 18 Jun 2002 */ if ( updown != PU_DRAG && !hit ) hide () ; recalc_bbox(); x -= abox.min[0] ; y -= abox.min[1] ; /* * June 17th, 1998, Shammi : * Also clear the menu when the dragging the mouse and not hit. */ if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN || ( updown == PU_DRAG && !hit ) ) { /* June 17th, 1998, Shammi : * Do not hide the menu if mouse is dragged out */ if ( updown != PU_DRAG ) hide () ; /* Turn everything off ready for next time. */ /* June 17th, 1998, Shammi: * Make sure we check for a hit, if the mouse is moved * out of the menu. */ for ( puObject *bo = dlist ; bo != NULL ; bo = bo -> getNextObject() ) { if ( ! hit ) bo -> checkHit ( button, updown, x , y ) ; bo -> clrValue () ; } } if ( ! hit ) return FALSE ; puObject *bo ; int objecthit = FALSE ; /* We have to walk the list backwards to ensure that the click order is the same as the DRAW order. */ /* June 17th, 1998, Shammi : * If the mouse is dragged and the menuItem is not hit, * clear it */ for ( bo = dlist ; bo -> getNextObject() != NULL ; bo = bo -> getNextObject() ) if ( updown == PU_DRAG && ! bo -> checkHit ( button, updown, x, y ) ) bo -> clrValue () ; /* Find the last object in our list. */ ; /* Following code permits highlighting and lowlighting */ /* of oneshots underneath a PopupMenu. */ /* - JCJ and Fay 31 May 2002 */ for ( ; bo != NULL ; bo = bo -> getPrevObject() ) { puBox *box = bo->getABox () ; if ( ( x > box->min[0] ) && ( x < box->max[0] ) && ( y > box->min[1] ) && ( y < box->max[1] ) ) bo->highlight () ; else bo->lowlight () ; /* Since actually RETURNing here would break the for loop early and kill the */ /* correct lowlighting, just set a var to check later. - JCJ 3 Jun 2002 */ if ( bo -> checkHit ( button, updown, x, y ) ) objecthit = TRUE ; } /* If the object was hit in the above for loop, then it.. was hit.*/ if (objecthit) return TRUE ; return FALSE ; } plib-1.8.5/src/Makefile.in0000644000175000001440000003424210765365022012237 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ SUBDIRS = util js sl pui puAux sg ssg fnt ssgAux net psl pw all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh uninstall-info-am: # 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -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-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ clean clean-generic clean-recursive ctags ctags-recursive \ distclean distclean-generic distclean-recursive distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-info-am # 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: plib-1.8.5/src/ssgAux/0000777000175000001440000000000010765365521011527 500000000000000plib-1.8.5/src/ssgAux/ssgAux.dsp0000644000175000001440000001267610765364435013444 00000000000000# Microsoft Developer Studio Project File - Name="ssgAux" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=ssgAux - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "ssgAux.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "ssgAux.mak" CFG="ssgAux - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "ssgAux - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "ssgAux - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "ssgAux - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\sg" /I "..\util" /I "..\ssg" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy ssgAux.h ..\..\ssgAux.h copy ssgaFire.h ..\..\ssgaFire.h copy ssgaLensFlare.h ..\..\ssgaLensFlare.h copy ssgaParticleSystem.h ..\..\ssgaParticleSystem.h copy ssgaShapes.h ..\..\ssgaShapes.h copy ssgaWaveSystem.h ..\..\ssgaWaveSystem.h copy ssgaSky.h ..\..\ssgaSky.h copy ssgaScreenDump.h ..\..\ssgaScreenDump.h # End Special Build Tool !ELSEIF "$(CFG)" == "ssgAux - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\sg" /I "..\util" /I "..\ssg" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\ssgAux_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy ssgAux.h ..\..\ssgAux.h copy ssgaFire.h ..\..\ssgaFire.h copy ssgaLensFlare.h ..\..\ssgaLensFlare.h copy ssgaParticleSystem.h ..\..\ssgaParticleSystem.h copy ssgaShapes.h ..\..\ssgaShapes.h copy ssgaWaveSystem.h ..\..\ssgaWaveSystem.h copy ssgaSky.h ..\..\ssgaSky.h copy ssgaScreenDump.h ..\..\ssgaScreenDump.h # End Special Build Tool !ENDIF # Begin Target # Name "ssgAux - Win32 Release" # Name "ssgAux - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\ssgaCelestialBody.cxx # End Source File # Begin Source File SOURCE=.\ssgaCloudLayer.cxx # End Source File # Begin Source File SOURCE=.\ssgaFire.cxx # End Source File # Begin Source File SOURCE=.\ssgaLensFlare.cxx # End Source File # Begin Source File SOURCE=.\ssgaLensFlareTexture.cxx # End Source File # Begin Source File SOURCE=.\ssgaParticleSystem.cxx # End Source File # Begin Source File SOURCE=.\ssgaPatch.cxx # End Source File # Begin Source File SOURCE=.\ssgaScreenDump.cxx # End Source File # Begin Source File SOURCE=.\ssgaShapes.cxx # End Source File # Begin Source File SOURCE=.\ssgaSky.cxx # End Source File # Begin Source File SOURCE=.\ssgaSkyDome.cxx # End Source File # Begin Source File SOURCE=.\ssgaSphere.cxx # End Source File # Begin Source File SOURCE=.\ssgaStars.cxx # End Source File # Begin Source File SOURCE=.\ssgaTeapot.cxx # End Source File # Begin Source File SOURCE=.\ssgAux.cxx # End Source File # Begin Source File SOURCE=.\ssgaWaveSystem.cxx # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\ssgaFire.h # End Source File # Begin Source File SOURCE=.\ssgaLensFlare.h # End Source File # Begin Source File SOURCE=.\ssgaParticleSystem.h # End Source File # Begin Source File SOURCE=.\ssgaScreenDump.h # End Source File # Begin Source File SOURCE=.\ssgaShapes.h # End Source File # Begin Source File SOURCE=.\ssgaSky.h # End Source File # Begin Source File SOURCE=.\ssgaSphere.h # End Source File # Begin Source File SOURCE=.\ssgAux.h # End Source File # Begin Source File SOURCE=.\ssgaWaveSystem.h # End Source File # End Group # End Target # End Project plib-1.8.5/src/ssgAux/ssgaSkyDome.cxx0000644000175000001440000003404210765364435014426 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaSkyDome.cxx 1798 2003-09-26 14:54:20Z sjbaker $ */ // Written by Curtis Olson, started December 1997. // SSG-ified by Curtis Olson, February 2000. // // Moved into ssgAux, July 2003. #include #include "ssgaSky.h" // proportions of max dimensions fed to the build() routine static const float center_elev = 1.0f; static const float upper_radius = 0.6f; static const float upper_elev = 0.15f; static const float middle_radius = 0.9f; static const float middle_elev = 0.08f; static const float lower_radius = 1.0f; static const float lower_elev = 0.0f; static const float bottom_radius = 0.8f; static const float bottom_elev = -0.1f; static int ssgaSkyDomePreDraw( ssgEntity *e ) { ssgLeaf *f = (ssgLeaf *)e; if ( f -> hasState () ) f->getState()->apply() ; glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); glDisable( GL_DEPTH_TEST ); glDisable( GL_FOG ); return true; } static int ssgaSkyDomePostDraw( ssgEntity *e ) { glPopAttrib(); return true; } ssgaSkyDome::ssgaSkyDome( void ) { dome_transform = 0; } ssgaSkyDome::~ssgaSkyDome( void ) { ssgDeRefDelete( dome_transform ); } // initialize the sky object and connect it into our scene graph ssgBranch * ssgaSkyDome::build( double hscale, double vscale ) { sgVec4 color; double theta; int i; // clean-up previous ssgDeRefDelete( dome_transform ); // create new dome_transform = new ssgTransform; dome_transform->ref(); // set up the state dome_state = new ssgSimpleState(); dome_state->setShadeModel( GL_SMOOTH ); dome_state->disable( GL_LIGHTING ); dome_state->disable( GL_CULL_FACE ); dome_state->disable( GL_TEXTURE_2D ); dome_state->enable( GL_COLOR_MATERIAL ); dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); dome_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); dome_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); dome_state->disable( GL_BLEND ); dome_state->disable( GL_ALPHA_TEST ); // initialize arrays center_disk_vl = new ssgVertexArray( 14 ); center_disk_cl = new ssgColourArray( 14 ); upper_ring_vl = new ssgVertexArray( 26 ); upper_ring_cl = new ssgColourArray( 26 ); middle_ring_vl = new ssgVertexArray( 26 ); middle_ring_cl = new ssgColourArray( 26 ); lower_ring_vl = new ssgVertexArray( 26 ); lower_ring_cl = new ssgColourArray( 26 ); // initially seed to all blue sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 ); // generate the raw vertex data sgVec3 center_vertex; sgVec3 upper_vertex[12]; sgVec3 middle_vertex[12]; sgVec3 lower_vertex[12]; sgVec3 bottom_vertex[12]; sgSetVec3( center_vertex, 0.0, 0.0, (float)(center_elev * vscale) ); for ( i = 0; i < 12; i++ ) { theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS; sgSetVec3( upper_vertex[i], (float)(cos(theta) * upper_radius * hscale), (float)(sin(theta) * upper_radius * hscale), (float)(upper_elev * vscale)); sgSetVec3( middle_vertex[i], (float)(cos(theta) * middle_radius * hscale), (float)(sin(theta) * middle_radius * hscale), (float)(middle_elev * vscale)); sgSetVec3( lower_vertex[i], (float)(cos(theta) * lower_radius * hscale), (float)(sin(theta) * lower_radius * hscale), (float)(lower_elev * vscale)); sgSetVec3( bottom_vertex[i], (float)(cos(theta) * bottom_radius * hscale), (float)(sin(theta) * bottom_radius * hscale), (float)(bottom_elev * vscale)); } // generate the center disk vertex/color arrays center_disk_vl->add( center_vertex ); center_disk_cl->add( color ); for ( i = 11; i >= 0; i-- ) { center_disk_vl->add( upper_vertex[i] ); center_disk_cl->add( color ); } center_disk_vl->add( upper_vertex[11] ); center_disk_cl->add( color ); // generate the upper ring for ( i = 0; i < 12; i++ ) { upper_ring_vl->add( middle_vertex[i] ); upper_ring_cl->add( color ); upper_ring_vl->add( upper_vertex[i] ); upper_ring_cl->add( color ); } upper_ring_vl->add( middle_vertex[0] ); upper_ring_cl->add( color ); upper_ring_vl->add( upper_vertex[0] ); upper_ring_cl->add( color ); // generate middle ring for ( i = 0; i < 12; i++ ) { middle_ring_vl->add( lower_vertex[i] ); middle_ring_cl->add( color ); middle_ring_vl->add( middle_vertex[i] ); middle_ring_cl->add( color ); } middle_ring_vl->add( lower_vertex[0] ); middle_ring_cl->add( color ); middle_ring_vl->add( middle_vertex[0] ); middle_ring_cl->add( color ); // generate lower ring for ( i = 0; i < 12; i++ ) { lower_ring_vl->add( bottom_vertex[i] ); lower_ring_cl->add( color ); lower_ring_vl->add( lower_vertex[i] ); lower_ring_cl->add( color ); } lower_ring_vl->add( bottom_vertex[0] ); lower_ring_cl->add( color ); lower_ring_vl->add( lower_vertex[0] ); lower_ring_cl->add( color ); // force a repaint of the sky colors with ugly defaults sgVec3 fog_color; sgSetVec3( fog_color, 1.0, 1.0, 1.0 ); repaint( color, fog_color, 0.0, 5000.0 ); // build the ssg scene graph sub tree for the sky and connected // into the provide scene graph branch ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring; center_disk = new ssgVtxTable( GL_TRIANGLE_FAN, center_disk_vl, NULL, NULL, center_disk_cl ); upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, upper_ring_vl, NULL, NULL, upper_ring_cl ); middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, middle_ring_vl, NULL, NULL, middle_ring_cl ); lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, lower_ring_vl, NULL, NULL, lower_ring_cl ); center_disk->setState( dome_state ); upper_ring->setState( dome_state ); middle_ring->setState( dome_state ); lower_ring->setState( dome_state ); dome_transform->addKid( center_disk ); dome_transform->addKid( upper_ring ); dome_transform->addKid( middle_ring ); dome_transform->addKid( lower_ring ); // not entirely satisfying. We are depending here that the first // thing we add to a parent is the first drawn center_disk->setCallback( SSG_CALLBACK_PREDRAW, ssgaSkyDomePreDraw ); center_disk->setCallback( SSG_CALLBACK_POSTDRAW, ssgaSkyDomePostDraw ); upper_ring->setCallback( SSG_CALLBACK_PREDRAW, ssgaSkyDomePreDraw ); upper_ring->setCallback( SSG_CALLBACK_POSTDRAW, ssgaSkyDomePostDraw ); middle_ring->setCallback( SSG_CALLBACK_PREDRAW, ssgaSkyDomePreDraw ); middle_ring->setCallback( SSG_CALLBACK_POSTDRAW, ssgaSkyDomePostDraw ); lower_ring->setCallback( SSG_CALLBACK_PREDRAW, ssgaSkyDomePreDraw ); lower_ring->setCallback( SSG_CALLBACK_POSTDRAW, ssgaSkyDomePostDraw ); return dome_transform; } bool ssgaSkyDome::repositionFlat( sgVec3 p, double spin ) { sgMat4 T, SPIN; sgVec3 axis; // Translate to view position sgMakeTransMat4( T, p ); // Rotate to proper orientation sgSetVec3( axis, 0.0, 0.0, 1.0 ); sgMakeRotMat4( SPIN, (float)(spin * SGD_RADIANS_TO_DEGREES), axis ); sgMat4 TRANSFORM; sgCopyMat4( TRANSFORM, T ); sgPreMultMat4( TRANSFORM, SPIN ); sgCoord skypos; sgSetCoord( &skypos, TRANSFORM ); dome_transform->setTransform( &skypos ); return true; } bool ssgaSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) { sgMat4 T, LON, LAT, SPIN; sgVec3 axis; // Translate to view position sgMakeTransMat4( T, p ); // Rotate to proper orientation sgSetVec3( axis, 0.0, 0.0, 1.0 ); sgMakeRotMat4( LON, (float)(lon * SGD_RADIANS_TO_DEGREES), axis ); sgSetVec3( axis, 0.0, 1.0, 0.0 ); sgMakeRotMat4( LAT, (float)(90.0 - lat * SGD_RADIANS_TO_DEGREES), axis ); sgSetVec3( axis, 0.0, 0.0, 1.0 ); sgMakeRotMat4( SPIN, (float)(spin * SGD_RADIANS_TO_DEGREES), axis ); sgMat4 TRANSFORM; sgCopyMat4( TRANSFORM, T ); sgPreMultMat4( TRANSFORM, LON ); sgPreMultMat4( TRANSFORM, LAT ); sgPreMultMat4( TRANSFORM, SPIN ); sgCoord skypos; sgSetCoord( &skypos, TRANSFORM ); dome_transform->setTransform( &skypos ); return true; } bool ssgaSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sol_angle, double vis ) { double diff; sgVec3 outer_param, outer_amt, outer_diff; sgVec3 middle_param, middle_amt, middle_diff; int i, j; sol_angle *= SGD_RADIANS_TO_DEGREES; // Check for sunrise/sunset condition if ( (sol_angle > 80.0) ) { // && (sol_angle < 100.0) ) // 0.0 - 0.4 sgSetVec3( outer_param, (float)((10.0 - fabs(90.0 - sol_angle)) / 20.0), (float)((10.0 - fabs(90.0 - sol_angle)) / 40.0), (float)(-(10.0 - fabs(90.0 - sol_angle)) / 30.0)); sgSetVec3( middle_param, (float)((10.0 - fabs(90.0 - sol_angle)) / 40.0), (float)((10.0 - fabs(90.0 - sol_angle)) / 80.0), 0.0 ); sgScaleVec3( outer_diff, outer_param, 1.0f / 6.0f ); sgScaleVec3( middle_diff, middle_param, 1.0f / 6.0f ); } else { sgSetVec3( outer_param, 0.0, 0.0, 0.0 ); sgSetVec3( middle_param, 0.0, 0.0, 0.0 ); sgSetVec3( outer_diff, 0.0, 0.0, 0.0 ); sgSetVec3( middle_diff, 0.0, 0.0, 0.0 ); } // calculate transition colors between sky and fog sgCopyVec3( outer_amt, outer_param ); sgCopyVec3( middle_amt, middle_param ); // // First, recalulate the basic colors // sgVec4 center_color; sgVec4 upper_color[12]; sgVec4 middle_color[12]; sgVec4 lower_color[12]; sgVec4 bottom_color[12]; double vis_factor; if ( vis < 3000.0 ) { vis_factor = (vis - 1000.0) / 2000.0; if ( vis_factor < 0.0 ) { vis_factor = 0.0; } } else { vis_factor = 1.0; } for ( j = 0; j < 3; j++ ) { diff = sky_color[j] - fog_color[j]; center_color[j] = sky_color[j] - (float)(diff * ( 1.0 - vis_factor )); } for ( i = 0; i < 6; i++ ) { for ( j = 0; j < 3; j++ ) { diff = sky_color[j] - fog_color[j]; upper_color[i][j] = sky_color[j] - (float)(diff * ( 1.0 - vis_factor * 0.7)); middle_color[i][j] = sky_color[j] - (float)(diff * ( 1.0 - vis_factor * 0.1)) + middle_amt[j]; lower_color[i][j] = fog_color[j] + outer_amt[j]; if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; } if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; } if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; } if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; } if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; } if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; } } upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0; for ( j = 0; j < 3; j++ ) { outer_amt[j] -= outer_diff[j]; middle_amt[j] -= middle_diff[j]; } } sgSetVec3( outer_amt, 0.0, 0.0, 0.0 ); sgSetVec3( middle_amt, 0.0, 0.0, 0.0 ); for ( i = 6; i < 12; i++ ) { for ( j = 0; j < 3; j++ ) { diff = sky_color[j] - fog_color[j]; upper_color[i][j] = sky_color[j] - (float)(diff * ( 1.0 - vis_factor * 0.7)); middle_color[i][j] = sky_color[j] - (float)(diff * ( 1.0 - vis_factor * 0.1)) + middle_amt[j]; lower_color[i][j] = fog_color[j] + outer_amt[j]; if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; } if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; } if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; } if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; } if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; } if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; } } upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0; for ( j = 0; j < 3; j++ ) { outer_amt[j] += outer_diff[j]; middle_amt[j] += middle_diff[j]; } } for ( i = 0; i < 12; i++ ) { sgCopyVec4( bottom_color[i], fog_color ); } // // Second, assign the basic colors to the object color arrays // float *slot; int counter; // update the center disk color arrays counter = 0; slot = center_disk_cl->get( counter++ ); // sgVec4 red; // sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 ); sgCopyVec4( slot, center_color ); for ( i = 11; i >= 0; i-- ) { slot = center_disk_cl->get( counter++ ); sgCopyVec4( slot, upper_color[i] ); } slot = center_disk_cl->get( counter++ ); sgCopyVec4( slot, upper_color[11] ); // generate the upper ring counter = 0; for ( i = 0; i < 12; i++ ) { slot = upper_ring_cl->get( counter++ ); sgCopyVec4( slot, middle_color[i] ); slot = upper_ring_cl->get( counter++ ); sgCopyVec4( slot, upper_color[i] ); } slot = upper_ring_cl->get( counter++ ); sgCopyVec4( slot, middle_color[0] ); slot = upper_ring_cl->get( counter++ ); sgCopyVec4( slot, upper_color[0] ); // generate middle ring counter = 0; for ( i = 0; i < 12; i++ ) { slot = middle_ring_cl->get( counter++ ); sgCopyVec4( slot, lower_color[i] ); slot = middle_ring_cl->get( counter++ ); sgCopyVec4( slot, middle_color[i] ); } slot = middle_ring_cl->get( counter++ ); sgCopyVec4( slot, lower_color[0] ); slot = middle_ring_cl->get( counter++ ); sgCopyVec4( slot, middle_color[0] ); // generate lower ring counter = 0; for ( i = 0; i < 12; i++ ) { slot = lower_ring_cl->get( counter++ ); sgCopyVec4( slot, bottom_color[i] ); slot = lower_ring_cl->get( counter++ ); sgCopyVec4( slot, lower_color[i] ); } slot = lower_ring_cl->get( counter++ ); sgCopyVec4( slot, bottom_color[0] ); slot = lower_ring_cl->get( counter++ ); sgCopyVec4( slot, lower_color[0] ); return true; } plib-1.8.5/src/ssgAux/ssgaStars.cxx0000644000175000001440000001450310765364435014147 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaStars.cxx 1798 2003-09-26 14:54:20Z sjbaker $ */ // Written by Durk Talsma. Originally started October 1997, for distribution // with the FlightGear project. Version 2 was written in August and // September 1998. This code is based upon algorithms and data kindly // provided by Mr. Paul Schlyter. (pausch@saaf.se). // // Separated out rendering pieces and converted to ssg by Curt Olson, // March 2000 // // Moved into ssgAux, July 2003. #include "ssgaSky.h" static int ssgaStarPreDraw( ssgEntity *e ) { ssgLeaf *f = (ssgLeaf *)e; if ( f -> hasState () ) f->getState()->apply() ; glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); //glDisable( GL_DEPTH_TEST ); glDisable( GL_FOG ); // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; return true; } static int ssgaStarPostDraw( ssgEntity *e ) { glPopAttrib(); return true; } ssgaStars::ssgaStars( void ) : stars_transform(0), old_phase(-1) { } ssgaStars::~ssgaStars( void ) { ssgDeRefDelete( stars_transform ); } ssgBranch * ssgaStars::build( int num, sgdVec3 *star_data, double star_dist ) { sgVec4 color; // clean-up previous ssgDeRefDelete( stars_transform ); // create new stars_transform = new ssgTransform; stars_transform->ref(); if ( star_data == NULL ) ulSetError(UL_WARNING, "null star data passed to ssgaStars::build()"); // set up the orb state state = new ssgSimpleState(); state->disable( GL_LIGHTING ); state->disable( GL_CULL_FACE ); state->disable( GL_TEXTURE_2D ); state->enable( GL_COLOR_MATERIAL ); state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); state->enable( GL_BLEND ); state->disable( GL_ALPHA_TEST ); vl = new ssgVertexArray( num ); cl = new ssgColourArray( num ); // cl = new ssgColourArray( 1 ); // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); // cl->add( color ); // Build ssg structure sgVec3 p; for ( int i = 0; i < num; ++i ) { // position seeded to arbitrary values sgSetVec3( p, (float)( star_dist * cos( star_data[i][0] ) * cos( star_data[i][1] )), (float)( star_dist * sin( star_data[i][0] ) * cos( star_data[i][1] )), (float)( star_dist * sin( star_data[i][1] ))); vl->add( p ); // color (magnitude) sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); cl->add( color ); } ssgLeaf *stars_obj = new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl ); stars_obj->setState( state ); stars_obj->setCallback( SSG_CALLBACK_PREDRAW, ssgaStarPreDraw ); stars_obj->setCallback( SSG_CALLBACK_POSTDRAW, ssgaStarPostDraw ); stars_transform->addKid( stars_obj ); return stars_transform; } bool ssgaStars::reposition( sgVec3 p, double angle ) { sgMat4 T1, GST; sgVec3 axis; sgMakeTransMat4( T1, p ); sgSetVec3( axis, 0.0, 0.0, -1.0 ); sgMakeRotMat4( GST, (float)angle, axis ); sgMat4 TRANSFORM; sgCopyMat4( TRANSFORM, T1 ); sgPreMultMat4( TRANSFORM, GST ); sgCoord skypos; sgSetCoord( &skypos, TRANSFORM ); stars_transform->setTransform( &skypos ); return true; } bool ssgaStars::repaint( double sol_angle, int num, sgdVec3 *star_data ) { double mag, nmag, alpha, factor, cutoff; float *color; int phase; // determine which star structure to draw if ( sol_angle > (0.5 * SGD_PI + 10.0 * SGD_DEGREES_TO_RADIANS ) ) { // deep night factor = 1.0; cutoff = 4.5; phase = 0; } else if ( sol_angle > (0.5 * SGD_PI + 8.8 * SGD_DEGREES_TO_RADIANS ) ) { factor = 1.0; cutoff = 3.8; phase = 1; } else if ( sol_angle > (0.5 * SGD_PI + 7.5 * SGD_DEGREES_TO_RADIANS ) ) { factor = 0.95; cutoff = 3.1; phase = 2; } else if ( sol_angle > (0.5 * SGD_PI + 7.0 * SGD_DEGREES_TO_RADIANS ) ) { factor = 0.9; cutoff = 2.4; phase = 3; } else if ( sol_angle > (0.5 * SGD_PI + 6.5 * SGD_DEGREES_TO_RADIANS ) ) { factor = 0.85; cutoff = 1.8; phase = 4; } else if ( sol_angle > (0.5 * SGD_PI + 6.0 * SGD_DEGREES_TO_RADIANS ) ) { factor = 0.8; cutoff = 1.2; phase = 5; } else if ( sol_angle > (0.5 * SGD_PI + 5.5 * SGD_DEGREES_TO_RADIANS ) ) { factor = 0.75; cutoff = 0.6; phase = 6; } else { // early dusk or late dawn factor = 0.7; cutoff = 0.0; phase = 7; } if( phase != old_phase ) { old_phase = phase; for ( int i = 0; i < num; ++i ) { // if ( star_data[i][2] < min ) { min = star_data[i][2]; } // if ( star_data[i][2] > max ) { max = star_data[i][2]; } // magnitude ranges from -1 (bright) to 4 (dim). The // range of star and planet magnitudes can actually go // outside of this, but for our purpose, if it is brighter // that -1, we'll color it full white/alpha anyway and 4 // is a convenient cutoff point which keeps the number of // stars drawn at about 500. // color (magnitude) mag = star_data[i][2]; if ( mag < cutoff ) { nmag = ( 4.5 - mag ) / 5.5; // translate to 0 ... 1.0 scale // alpha = nmag * 0.7 + 0.3; // translate to a 0.3 ... 1.0 scale alpha = nmag * 0.85 + 0.15; // translate to a 0.15 ... 1.0 scale alpha *= factor; // dim when the sun is brighter } else { alpha = 0.0; } if (alpha > 1.0) { alpha = 1.0; } if (alpha < 0.0) { alpha = 0.0; } color = cl->get( i ); sgSetVec4( color, 1.0, 1.0, 1.0, (float)alpha ); } } return true; } plib-1.8.5/src/ssgAux/ssgaScreenDump.cxx0000644000175000001440000001222610765364435015120 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaScreenDump.cxx 1996 2004-12-29 07:19:40Z sjbaker $ */ #include "ssgAux.h" #include #include "ul.h" static void writeByte ( FILE *fd, unsigned char x ) { fwrite ( & x, sizeof(unsigned char), 1, fd ) ; } static void writeShort ( FILE *fd, unsigned short x ) { x = ulEndianBig16 ( x ) ; fwrite ( & x, sizeof(unsigned short), 1, fd ) ; } static void writeInt ( FILE *fd, unsigned int x ) { x = ulEndianBig32 ( x ) ; fwrite ( & x, sizeof(unsigned int), 1, fd ) ; } void ssgaScreenDepthDump ( char *filename, int xsize, int ysize, int frontBuffer ) { FILE *fd = fopen ( filename, "wb" ) ; if ( fd == NULL ) { fprintf ( stderr, "Failed to open '%s' for writing screendepthdump.\n", filename ) ; return ; } unsigned char *row = new unsigned char [ xsize ] ; unsigned int *buffer = ssgaScreenDepthDump ( xsize, ysize, frontBuffer ) ; char type = 0 /* RGB_IMG_VERBATIM */ ; short dim = 3 ; short zsize = 3 ; char bpp = 1 ; int min = 0 ; int max = 255 ; short magic = 0x01DA /* RGB_IMG_MAGIC */ ; int colormap = 0 ; int i ; writeShort ( fd, magic ) ; writeByte ( fd, type ) ; writeByte ( fd, bpp ) ; writeShort ( fd, dim ) ; writeShort ( fd, xsize ) ; writeShort ( fd, ysize ) ; writeShort ( fd, zsize ) ; writeInt ( fd, min ) ; writeInt ( fd, max ) ; writeInt ( fd, 0 ) ; /* Dummy field */ for ( i = 0 ; i < 80 ; i++ ) writeByte ( fd, '\0' ) ; /* Name field */ writeInt ( fd, colormap ) ; for ( i = 0 ; i < 404 ; i++ ) writeByte ( fd, 0 ) ; /* Dummy field */ for ( int z = 0 ; z < 3 ; z++ ) for ( int y = 0 ; y < ysize ; y++ ) { for ( i = 0 ; i < xsize ; i++ ) row [ i ] = ((buffer [ y * xsize + i ] >> (8*z)) & 0xFF) ; fseek ( fd, ( z * ysize + y ) * xsize + 512, SEEK_SET ) ; fwrite ( row, 1, xsize, fd ) ; } fclose ( fd ) ; delete row ; delete buffer ; } void ssgaScreenDump ( char *filename, int xsize, int ysize, int frontBuffer ) { FILE *fd = fopen ( filename, "wb" ) ; if ( fd == NULL ) { fprintf ( stderr, "Failed to open '%s' for writing screendump.\n", filename ) ; return ; } unsigned char *row = new unsigned char [ xsize ] ; unsigned char *buffer = ssgaScreenDump ( xsize, ysize, frontBuffer ) ; char type = 0 /* RGB_IMG_VERBATIM */ ; short dim = 3 ; short zsize = 3 ; char bpp = 1 ; int min = 0 ; int max = 255 ; short magic = 0x01DA /* RGB_IMG_MAGIC */ ; int colormap = 0 ; int i ; writeShort ( fd, magic ) ; writeByte ( fd, type ) ; writeByte ( fd, bpp ) ; writeShort ( fd, dim ) ; writeShort ( fd, xsize ) ; writeShort ( fd, ysize ) ; writeShort ( fd, zsize ) ; writeInt ( fd, min ) ; writeInt ( fd, max ) ; writeInt ( fd, 0 ) ; /* Dummy field */ for ( i = 0 ; i < 80 ; i++ ) writeByte ( fd, '\0' ) ; /* Name field */ writeInt ( fd, colormap ) ; for ( i = 0 ; i < 404 ; i++ ) writeByte ( fd, 0 ) ; /* Dummy field */ for ( int z = 0 ; z < 3 ; z++ ) for ( int y = 0 ; y < ysize ; y++ ) { for ( i = 0 ; i < xsize ; i++ ) row [ i ] = buffer [ ( y * xsize + i ) * 3 + z ] ; fseek ( fd, ( z * ysize + y ) * xsize + 512, SEEK_SET ) ; fwrite ( row, 1, xsize, fd ) ; } fclose ( fd ) ; delete row ; delete buffer ; } unsigned char *ssgaScreenDump ( int xsize, int ysize, int frontBuffer ) { unsigned char *buffer = new unsigned char [ xsize * ysize * 3 ] ; if ( frontBuffer ) glReadBuffer ( GL_FRONT ) ; glReadPixels( 0, 0, xsize, ysize, GL_RGB, GL_UNSIGNED_BYTE, (void *) buffer ) ; if ( frontBuffer ) glReadBuffer ( GL_BACK ) ; return buffer ; } unsigned int *ssgaScreenDepthDump ( int xsize, int ysize, int frontBuffer ) { unsigned int *buffer = new unsigned int [ xsize * ysize ] ; if ( frontBuffer ) glReadBuffer ( GL_FRONT ) ; glReadPixels( 0, 0, xsize, ysize, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (void *) buffer ) ; if ( frontBuffer ) glReadBuffer ( GL_BACK ) ; return buffer ; } plib-1.8.5/src/ssgAux/ssgaParticleSystem.cxx0000644000175000001440000001345210765364435016025 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "ssgAux.h" ssgaParticleSystem::ssgaParticleSystem ( int num, int initial_num, float _create_rate, int _ttf, float sz, float bsphere_size, ssgaParticleCreateFunc _particle_create, ssgaParticleUpdateFunc _particle_update, ssgaParticleDeleteFunc _particle_delete ) : ssgVtxTable ( GL_QUADS, new ssgVertexArray ( num * 4, new sgVec3 [ num * 4 ] ), new ssgNormalArray ( num * 4, new sgVec3 [ num * 4 ] ), new ssgTexCoordArray ( num * 4, new sgVec2 [ num * 4 ] ), new ssgColourArray ( num * 4, new sgVec4 [ num * 4 ] ) ) { turn_to_face = _ttf ; create_error = 0 ; create_rate = _create_rate ; particle_create = _particle_create ; particle_update = _particle_update ; particle_delete = _particle_delete ; size = sz ; num_particles = num ; num_verts = num * 4 ; getBSphere () -> setRadius ( bsphere_size ) ; getBSphere () -> setCenter ( 0, 0, 0 ) ; particle = new ssgaParticle [ num ] ; int i ; for ( i = 0 ; i < num_verts ; i++ ) { sgSetVec3 ( getNormal ( i ), 0, -1, 0 ) ; sgSetVec4 ( getColour ( i ), 1, 1, 1, 1 ) ; sgZeroVec3 ( getVertex ( i ) ) ; } for ( i = 0 ; i < num_particles ; i++ ) { sgSetVec2 ( getTexCoord ( i*4+0 ), 0, 0 ) ; sgSetVec2 ( getTexCoord ( i*4+1 ), 1, 0 ) ; sgSetVec2 ( getTexCoord ( i*4+2 ), 1, 1 ) ; sgSetVec2 ( getTexCoord ( i*4+3 ), 0, 1 ) ; } num_active = 0 ; if ( particle_create ) for ( i = 0 ; i < initial_num ; i++ ) (*particle_create) ( this, i, & particle [ i ] ) ; } void ssgaParticleSystem::draw_geometry () { sgVec3 nxny, xxny, xxyy, nxyy ; float sz = size / 2.0f ; if ( turn_to_face ) { sgMat4 mat ; glGetFloatv ( GL_MODELVIEW_MATRIX, (float *) mat ) ; sgVec3 xx, yy ; sgSetVec3 ( xx, mat[0][0] * sz, mat[1][0] * sz, mat[2][0] * sz ) ; sgSetVec3 ( yy, mat[0][1] * sz, mat[1][1] * sz, mat[2][1] * sz ) ; sgSetVec3 ( nxny, -xx[0]-yy[0], -xx[1]-yy[1], -xx[2]-yy[2] ) ; sgSetVec3 ( nxyy, -xx[0]+yy[0], -xx[1]+yy[1], -xx[2]+yy[2] ) ; sgSetVec3 ( xxny, xx[0]-yy[0], xx[1]-yy[1], xx[2]-yy[2] ) ; sgSetVec3 ( xxyy, xx[0]+yy[0], xx[1]+yy[1], xx[2]+yy[2] ) ; } else { sgSetVec3 ( xxny , sz, 0, -sz ) ; sgSetVec3 ( nxny , -sz, 0, -sz ) ; sgSetVec3 ( nxyy , -sz, 0, sz ) ; sgSetVec3 ( xxyy, sz, 0, sz ) ; } int j = 0 ; for ( int i = 0 ; i < num_particles ; i++ ) { /* Make them disappear if not needed */ if ( particle[i].time_to_live <= 0.0f ) continue ; sgCopyVec4 ( getColour ( j + 0 ), particle[i].col ) ; sgCopyVec4 ( getColour ( j + 1 ), particle[i].col ) ; sgCopyVec4 ( getColour ( j + 2 ), particle[i].col ) ; sgCopyVec4 ( getColour ( j + 3 ), particle[i].col ) ; sgAddScaledVec3 ( getVertex ( j + 0 ), particle[i].pos, nxny, particle[i].size ) ; sgAddScaledVec3 ( getVertex ( j + 1 ), particle[i].pos, xxny, particle[i].size ) ; sgAddScaledVec3 ( getVertex ( j + 2 ), particle[i].pos, xxyy, particle[i].size ) ; sgAddScaledVec3 ( getVertex ( j + 3 ), particle[i].pos, nxyy, particle[i].size ) ; j += 4 ; } rawSetNumVertices ( j ) ; /* Avoid drawing more than 'j' vertices. */ if ( j > 0 ) { glDisable ( GL_CULL_FACE ) ; glDepthMask ( 0 ) ; ssgVtxTable::draw_geometry () ; glDepthMask ( 1 ) ; glEnable ( GL_CULL_FACE ) ; } } ssgaParticleSystem::~ssgaParticleSystem () { if ( particle_delete ) for ( int i = 0 ; i < num_particles ; i++ ) if ( particle [ i ] . time_to_live >= 0.0 ) (*particle_delete) ( this, i, & particle [ i ] ) ; delete [] particle ; } void ssgaParticleSystem::update ( float t ) { int i ; create_error += create_rate * t ; num_active = 0 ; /* Call the update routine for all the particles */ if ( particle_update ) { for ( i = 0 ; i < num_particles ; i++ ) if ( particle [ i ] . time_to_live > 0.0f ) { particle [ i ] . update ( t ) ; (*particle_update) ( t, this, i, & particle [ i ] ) ; } } else for ( i = 0 ; i < num_particles ; i++ ) if ( particle [ i ] . time_to_live > 0.0f ) particle [ i ] . update ( t ) ; /* Check for death of particles */ for ( i = 0 ; i < num_particles ; i++ ) if ( particle [ i ] . time_to_live <= 0.0 ) { if ( particle_delete ) (*particle_delete) ( this, i, & particle [ i ] ) ; particle [ i ] . pos [ 2 ] = -1000000.0f ; if ( create_error >= 1.0f && particle_create ) { (*particle_create) ( this, i, & particle [ i ] ) ; create_error -= 1.0f ; } } else num_active++ ; } plib-1.8.5/src/ssgAux/ssgaLensFlare.cxx0000644000175000001440000002336510765364435014734 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "ssgAux.h" #undef _SSG_PUBLIC #include "../ssg/ssgLocal.h" /* Lens flares are an effect that happens in the lens - your eye or a camera lens. As such, they are completely invisible if the light itself is not visible - which should mean that if the light is culled then so is the lens flare. This suggests that the bsphere center should be at the light point and the radius should be tiny. However, if you have a multi-facetted display, pretending to be a single display rather than a lot of separate 'cameras' then you may want to set the SSGA_CONTINUOUS_DISPLAY_SURFACE flag. This should probably be realtime settable - but to do it 'right', you'd need to know which edges of the screen were 'shared' with other screens and only allow the lens flare to cross those. */ // #define CONTINUOUS_DISPLAY_SURFACE 1 sgMat4 _ssgaIdentity = { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f } } ; /* This is based on code written by Stephen Coy - subsequently re-written by Mark Kilgard - and now re-re-written by me. Actually, only the original numbers for the dimensions of the flare planes are from the original code. All the rest is a complete rewrite because it has to work within a scene graph API. */ struct _ssgaFlarePlane { int type ; /* flare texture index, 0..5 */ float loc ; /* postion on flare_axis */ float scale ; sgVec4 color ; } ; static _ssgaFlarePlane flare [] = { { -1, 0.00f, 0.20f, { 0 , 0, 1, 1 }}, { -1, 0.00f, 0.10f, { 0 , 1, 0, 1 }}, { -1, 0.00f, 0.12f, { 1.0f, 0, 0, 1 }}, { 1, 0.50f, 0.20f, { 0.3f, 0, 0, 1 }}, { 2, -0.20f, 0.04f, { 0.6f, 0, 0, 1 }}, { 3, 0.00f, 0.10f, { 0.4f, 0, 0, 1 }}, { 3, 0.30f, 0.03f, { 0.3f, 0, 0, 1 }}, { 3, 0.80f, 0.05f, { 0.3f, 0, 0, 1 }}, { 0, 1.00f, 0.04f, { 0.3f, 0, 0, 1 }}, { 4, 1.25f, 0.07f, { 0.5f, 0, 0, 1 }}, { 5, 1.40f, 0.02f, { 0.6f, 0, 0, 1 }}, { 5, 1.60f, 0.04f, { 0.4f, 0, 0, 1 }}, { 5, 2.00f, 0.03f, { 0.2f, 0, 0, 1 }}, { -999, 0, 0, { 0, 0, 0, 0 } } /* End marker */ } ; static float shineTexCoords [ 12 ][ 4 ][ 2 ] = { { { 0.00, 0.00 }, { 0.25, 0.00 }, { 0.25, 0.50 }, { 0.00, 0.50 } }, { { 0.25, 0.00 }, { 0.50, 0.00 }, { 0.50, 0.50 }, { 0.25, 0.50 } }, { { 0.50, 0.00 }, { 0.75, 0.00 }, { 0.75, 0.50 }, { 0.50, 0.50 } }, { { 0.00, 0.50 }, { 0.25, 0.50 }, { 0.25, 0.00 }, { 0.00, 0.00 } }, { { 0.25, 0.50 }, { 0.50, 0.50 }, { 0.50, 0.00 }, { 0.25, 0.00 } }, { { 0.50, 0.50 }, { 0.75, 0.50 }, { 0.75, 0.00 }, { 0.50, 0.00 } }, { { 0.25, 0.00 }, { 0.00, 0.00 }, { 0.00, 0.50 }, { 0.25, 0.50 } }, { { 0.50, 0.00 }, { 0.25, 0.00 }, { 0.25, 0.50 }, { 0.50, 0.50 } }, { { 0.75, 0.00 }, { 0.50, 0.00 }, { 0.50, 0.50 }, { 0.75, 0.50 } }, { { 0.25, 0.50 }, { 0.00, 0.50 }, { 0.00, 0.00 }, { 0.25, 0.00 } }, { { 0.50, 0.50 }, { 0.25, 0.50 }, { 0.25, 0.00 }, { 0.50, 0.00 } }, { { 0.75, 0.50 }, { 0.50, 0.50 }, { 0.50, 0.00 }, { 0.75, 0.00 } } } ; static float flareTexCoords [ 6 ][ 4 ][ 2 ] = { { { 0.00f, 0.50f }, { 0.25f, 0.50f }, { 0.25f, 1.00f }, { 0.00f, 1.00f } }, { { 0.25f, 0.50f }, { 0.50f, 0.50f }, { 0.50f, 1.00f }, { 0.25f, 1.00f } }, { { 0.27f, 0.70f }, { 0.48f, 0.70f }, { 0.48f, 0.80f }, { 0.27f, 0.80f } }, { { 0.50f, 0.50f }, { 0.75f, 0.50f }, { 0.75f, 1.00f }, { 0.50f, 1.00f } }, { { 0.75f, 0.50f }, { 1.00f, 0.50f }, { 1.00f, 1.00f }, { 0.75f, 1.00f } }, { { 0.75f, 0.00f }, { 1.00f, 0.00f }, { 1.00f, 0.50f }, { 0.75f, 0.50f } } } ; void ssgaLensFlare::copy_from ( ssgaLensFlare *src, int clone_flags ) { ssgaShape::copy_from ( src, clone_flags ) ; } ssgBase *ssgaLensFlare::clone ( int clone_flags ) { ssgaLensFlare *b = new ssgaLensFlare ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgaLensFlare::ssgaLensFlare (void):ssgaShape () { type = ssgaTypeLensFlare () ; regenerate () ; } ssgaLensFlare::ssgaLensFlare (int nt):ssgaShape (nt) { type = ssgaTypeLensFlare () ; regenerate () ; } ssgaLensFlare::~ssgaLensFlare (void) {} static ssgSimpleState *flareState = NULL ; static ssgTexture *flareTexture = NULL ; const char *ssgaLensFlare::getTypeName(void) { return "ssgaLensFlare" ; } static int preDraw ( ssgEntity * ) { glDisable ( GL_DEPTH_TEST ) ; glBlendFunc ( GL_ONE, GL_ONE ) ; return TRUE ; } static int postDraw ( ssgEntity * ) { glEnable ( GL_DEPTH_TEST ) ; glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; return TRUE ; } void ssgaLensFlare::regenerate () { if ( kidState != NULL ) kidState -> ref () ; removeAllKids () ; if ( kidState != NULL ) kidState -> deRef () ; for ( ntriangles = 0 ; flare[ntriangles/2].type >= -1 ; ntriangles += 2 ) /* Count the number of triangles */ ; vt = new ssgVtxTable () ; v0 = new ssgVertexArray ( 2 * ntriangles ) ; n0 = new ssgNormalArray ( 2 * ntriangles ) ; c0 = new ssgColourArray ( 2 * ntriangles ) ; t0 = new ssgTexCoordArray ( 2 * ntriangles ) ; vt -> setPrimitiveType ( GL_QUADS ) ; addKid ( vt ) ; if ( flareState == NULL ) { /* The texture constructor deletes the texture from main memory after it's finished with it!! YIKES!! */ unsigned char *t = new unsigned char [ 256 * 128 ] ; memcpy ( t, _ssgaGetLensFlareTexture(), 256 * 128 ) ; flareTexture = new ssgTexture ( "NONE", t, 256, 128, 1 ) ; flareState = new ssgSimpleState () ; flareState -> setTexture ( flareTexture ) ; flareState -> setTranslucent () ; flareState -> enable ( GL_TEXTURE_2D ) ; flareState -> enable ( GL_BLEND ) ; flareState -> disable ( GL_LIGHTING ) ; flareState -> ref () ; setKidState ( flareState ) ; } vt -> setState ( getKidState () ) ; vt -> setCallback ( SSG_CALLBACK_PREDRAW , preDraw /* getKidPreDrawCB */ ); vt -> setCallback ( SSG_CALLBACK_POSTDRAW, postDraw /* getKidPostDrawCB*/ ); sgVec3 v ; sgVec3 n ; sgVec2 t ; sgVec4 c ; for ( int i = 0 ; i < ntriangles * 2 ; i++ ) { sgSetVec3 ( v, 0, 0, 0 ) ; v0->add ( v ) ; sgSetVec3 ( n, 0, -1, 0 ) ; n0->add ( n ) ; sgSetVec4 ( c, 1,1,1,1 ) ; c0->add ( c ) ; sgSetVec2 ( t, 0, 0 ) ; t0->add ( t ) ; } vt -> setVertices ( v0 ) ; vt -> setNormals ( n0 ) ; vt -> setColours ( c0 ) ; vt -> setTexCoords ( t0 ) ; #ifndef CONTINUOUS_DISPLAY_SURFACE vt -> getBSphere () -> setCenter ( 0, 0, 0 ) ; vt -> getBSphere () -> setRadius ( 0.1f ) ; getBSphere () -> setCenter ( 0, 0, 0 ) ; getBSphere () -> setRadius ( 0.1f ) ; #else vt -> recalcBSphere () ; recalcBSphere () ; #endif } void ssgaLensFlare::update ( sgMat4 mat ) { static int shine_tic = 0 ; sgVec3 flare_axis ; float *texCoords ; sgVec3 light_pos ; float znear ; ssgGetNearFar ( & znear, NULL ) ; sgNormalizeVec3 ( light_pos, mat[3] ) ; sgScaleVec3 ( light_pos, znear * 2.0f ) ; /* To avoid being near-clipped */ sgSetVec3 ( flare_axis, -light_pos[0], -light_pos[1], 0.0 ) ; int vv = 0 ; for ( int i = 0 ; flare[ i ].type >= -1 ; i++ ) { sgVec3 position ; float sz ; sz = flare[i].scale * znear * 2.0f ; sgAddScaledVec3 ( position, light_pos, flare_axis, flare[i].loc ) ; if ( flare[i].type < 0 ) { shine_tic = (shine_tic + 1) % 12 ; texCoords = & ( shineTexCoords [ shine_tic ][ 0 ][ 0 ] ) ; } else texCoords = & ( flareTexCoords [ flare[i].type ][ 0 ][ 0 ] ) ; sgVec3 vx ; sgSetVec3 ( vx, position[0]+sz, position[1]-sz, position[2] ) ; c0 -> set ( flare[i].color, vv ) ; t0 -> set ( & texCoords[0], vv ) ; v0 -> set ( vx, vv++ ) ; sgSetVec3 ( vx, position[0]+sz, position[1]+sz, position[2] ) ; c0 -> set ( flare[i].color, vv ) ; t0 -> set ( & texCoords[2], vv ) ; v0 -> set ( vx, vv++ ) ; sgSetVec3 ( vx, position[0]-sz, position[1]+sz, position[2] ) ; c0 -> set ( flare[i].color, vv ) ; t0 -> set ( & texCoords[4], vv ) ; v0 -> set ( vx, vv++ ) ; sgSetVec3 ( vx, position[0]-sz, position[1]-sz, position[2] ) ; c0 -> set ( flare[i].color, vv ) ; t0 -> set ( & texCoords[6], vv ) ; v0 -> set ( vx, vv++ ) ; } } void ssgaLensFlare::cull ( sgFrustum *f, sgMat4 m, int /* test_needed */ ) { /* Lens flares are best generated in eye-space (because they actually occur inside the lens of your eye). Hence we call 'update' with the current modelview matrix - it generates the geometry in eye-space - which means that we have to render it with the identity matrix on the stack. */ update ( m ) ; _ssgPushMatrix ( _ssgaIdentity ) ; glPushMatrix () ; glLoadMatrixf ( (float *) _ssgaIdentity ) ; ssgBranch::cull ( f, _ssgaIdentity, FALSE ) ; glPopMatrix () ; _ssgPopMatrix () ; } plib-1.8.5/src/ssgAux/ssgaWaveSystem.cxx0000644000175000001440000002422310765364435015162 00000000000000 /* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaWaveSystem.cxx 1772 2003-06-27 08:15:15Z sjbaker $ */ #include "ssgAux.h" #include #define G 9.8f void ssgaWaveSystem::updateAnimation ( float tim ) { if ( ntriangles <= 0 || normals == NULL || colours == NULL || texcoords == NULL || vertices == NULL || orig_vertices == NULL ) return ; int i ; float adjSpeed [ SSGA_MAX_WAVETRAIN ] ; float sinHeading [ SSGA_MAX_WAVETRAIN ] ; float cosHeading [ SSGA_MAX_WAVETRAIN ] ; float length [ SSGA_MAX_WAVETRAIN ] ; float lambda [ SSGA_MAX_WAVETRAIN ] ; float height [ SSGA_MAX_WAVETRAIN ] ; /* Pre-adjust speed's to allow for wind speed. */ int num_trains = 0 ; for ( i = 0 ; i < SSGA_MAX_WAVETRAIN ; i++ ) if ( train [ i ] != NULL ) { adjSpeed [num_trains] = train [ i ] -> getSpeed () * G * tim / windSpeed ; sinHeading [num_trains] = (float) -sin ( train[i]->getHeading () * SG_DEGREES_TO_RADIANS ) ; cosHeading [num_trains] = (float) cos ( train[i]->getHeading () * SG_DEGREES_TO_RADIANS ) ; length [num_trains] = train [ i ] -> getLength () ; lambda [num_trains] = train [ i ] -> getLambda () ; height [num_trains] = train [ i ] -> getWaveHeight () ; num_trains++ ; } for ( i = 0 ; i <= nstrips ; i++ ) { float fade_i = (i<2) ? 0.0f : (i<7) ? (float)(i-2)/5.0f : (i>nstrips-2) ? 0.0f : (i>nstrips-7) ? (float)(nstrips-i-2)/5.0f : 1.0f ; for ( int j = 0 ; j <= nstacks ; j++ ) { float fade_j = (j<2) ? 0.0f : (j<7) ? (float)(j-2)/5.0f : (j>nstacks-2) ? 0.0f : (j>nstacks-7) ? (float)(nstacks-j-2)/5.0f : 1.0f ; float edge_fade = fade_i * fade_j ; int idx = i * (nstrips+1) + j ; float xx = orig_vertices [idx][0] + center[0] ; float yy = orig_vertices [idx][1] + center[1] ; float zz = center[2] ; float x0 = xx + offset[0] ; float y0 = yy + offset[1] ; float z0 = vertices [idx][2] ; float depth = (gridGetter==NULL) ? 1000000.0f : gridGetter ( x0, y0 ) ; for ( int t = 0 ; t < num_trains ; t++ ) { float adjHeight = height [ t ] * edge_fade ; float adjLength = ( depth < 0.2f ) ? 0.2f : ( depth > length[t] ) ? length[t] : depth ; float phase = ( x0 * sinHeading[t] + y0 * cosHeading[t] ) / adjLength - adjSpeed[t] - lambda[t] * z0 ; float delta = adjHeight * (float) sin ( phase ) ; xx += delta * sinHeading [ t ] ; yy += delta * cosHeading [ t ] ; zz += adjHeight * (float) -cos ( phase ) ; } sgSetVec3 ( vertices [idx], xx, yy, zz ) ; sgSetVec2 ( texcoords [idx], tu * x0 / size[0], tv * y0 /size[1] ) ; } } for ( i = 0 ; i < nstrips ; i++ ) { int i1 = i * (nstrips+1) ; int i2 = (i+1) * (nstrips+1) ; for ( int j = 0 ; j < nstacks ; j++ ) { int idx1 = i1 + j ; int idx2 = i2 + j ; int idx3 = i1 + (j+1) ; sgVec3 ab ; sgSubVec3 ( ab, vertices[idx3], vertices[idx1] ) ; sgVec3 ac ; sgSubVec3 ( ac, vertices[idx2], vertices[idx1] ) ; float nx = ab[1] * ac[2] - ab[2] * ac[1] ; float ny = ab[2] * ac[0] - ab[0] * ac[2] ; float nz = ab[0] * ac[1] - ab[1] * ac[0] ; /* About 10% of execution time is in this instruction! */ float rlen = 1.0f / (float) sqrt ( nx * nx + ny * ny + nz * nz ) ; normals[idx1][0] = nx * rlen ; normals[idx1][1] = ny * rlen ; normals[idx1][2] = nz * rlen ; } } for ( i = 0 ; i < nstrips ; i++ ) { ssgVtxTable *vt = (ssgVtxTable *) getKid ( i ) ; ssgVertexArray *vv = vt -> getVertices () ; ssgNormalArray *nn = vt -> getNormals () ; ssgColourArray *cc = vt -> getColours () ; ssgTexCoordArray *tt = vt -> getTexCoords () ; int i1 = (i+1) * (nstrips+1) ; int i2 = i * (nstrips+1) ; for ( int j = 0, jj = 0 ; j < nstacks + 1 ; j++, jj += 2, i1++, i2++ ) { vv -> set ( vertices [i1], jj ) ; vv -> set ( vertices [i2], jj+1 ) ; nn -> set ( normals [i1], jj ) ; nn -> set ( normals [i2], jj+1 ) ; cc -> set ( colours [i1], jj ) ; cc -> set ( colours [i2], jj+1 ) ; tt -> set ( texcoords[i1], jj ) ; tt -> set ( texcoords[i2], jj+1 ) ; } } } void ssgaWaveSystem::copy_from ( ssgaWaveSystem *src, int clone_flags ) { ssgaShape::copy_from ( src, clone_flags ) ; setDepthCallback ( src -> getDepthCallback () ) ; setWindSpeed ( src -> getWindSpeed () ) ; setWindDirn ( src -> getWindDirn () ) ; setEdgeFlatten ( src -> getEdgeFlatten () ) ; } ssgBase *ssgaWaveSystem::clone ( int clone_flags ) { ssgaWaveSystem *b = new ssgaWaveSystem ( getNumTris() ) ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgaWaveSystem::ssgaWaveSystem ( int np ) : ssgaShape ( np ) { type=ssgaTypeWaveSystem (); setDepthCallback ( NULL ) ; setWindSpeed ( 1.0f ) ; setWindDirn ( 0.0f ) ; setEdgeFlatten ( 0.0f ) ; nstrips = nstacks = 0 ; offset [ 0 ] = offset [ 1 ] = 0.0f ; normals = NULL ; colours = NULL ; texcoords = NULL ; vertices = NULL ; orig_vertices = NULL ; tu = tv = 1.0f ; for ( int i = 0 ; i < SSGA_MAX_WAVETRAIN ; i++ ) train [ i ] = NULL ; regenerate(); } ssgaWaveSystem::~ssgaWaveSystem (void) {} const char *ssgaWaveSystem::getTypeName(void) { return "ssgaWaveSystem" ; } void ssgaWaveSystem::regenerate () { delete[] normals ; delete[] colours ; delete[] texcoords ; delete[] vertices ; delete[] orig_vertices ; normals = NULL ; colours = NULL ; texcoords = NULL ; vertices = NULL ; orig_vertices = NULL ; nstrips = nstacks = 0 ; if ( kidState != NULL ) kidState -> ref () ; removeAllKids () ; if ( kidState != NULL ) kidState -> deRef () ; if ( ntriangles <= 0 ) return ; int gridSize = (int) sqrt ( (float) ntriangles / 2.0f ) ; nstacks = gridSize ; nstrips = gridSize ; if ( nstacks < 1 ) nstacks = 1 ; if ( nstrips < 1 ) nstrips = 1 ; normals = new sgVec3 [ (nstacks+1) * (nstrips+1) ] ; colours = new sgVec4 [ (nstacks+1) * (nstrips+1) ] ; texcoords = new sgVec2 [ (nstacks+1) * (nstrips+1) ] ; vertices = new sgVec3 [ (nstacks+1) * (nstrips+1) ] ; orig_vertices = new sgVec3 [ (nstacks+1) * (nstrips+1) ] ; int i; for ( i = 0 ; i <= nstrips ; i++ ) for ( int j = 0 ; j <= nstacks ; j++ ) { int idx = i * (nstrips+1) + j ; float x = (float) j / (float) nstacks ; float y = (float) i / (float) nstrips ; // if ( j == 0 ) x = -500.0f ; // if ( j == nstacks ) x = 500.0f ; // if ( i == 0 ) y = -500.0f ; // if ( i == nstacks ) y = 500.0f ; sgSetVec3 ( vertices [idx], (x-0.5f) * size[0], (y-0.5f) * size[1], 0.0f ) ; sgSetVec3 ( normals [idx], 0.0f, 0.0f, 1.0f ) ; sgSetVec2 ( texcoords[idx], x * tu, y * tv ) ; sgCopyVec4 ( colours [idx], colour ) ; sgCopyVec3 ( orig_vertices [ idx ], vertices [idx] ) ; } for ( i = 0 ; i < nstrips ; i++ ) { ssgVtxTable *vt = new ssgVtxTable ; ssgVertexArray *vv = new ssgVertexArray ( nstacks * 2 + 2 ) ; ssgNormalArray *nn = new ssgNormalArray ( nstacks * 2 + 2 ) ; ssgColourArray *cc = new ssgColourArray ( nstacks * 2 + 2 ) ; ssgTexCoordArray *tt = new ssgTexCoordArray ( nstacks * 2 + 2 ) ; addKid ( vt ) ; vt -> setState ( getKidState () ) ; vt -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; vt -> setPrimitiveType ( GL_TRIANGLE_STRIP ) ; for ( int j = 0 ; j < nstacks + 1 ; j++ ) { int idx = (i+1) * (nstrips+1) + j ; vv -> add ( vertices [ idx ] ) ; nn -> add ( normals [ idx ] ) ; cc -> add ( colours [ idx ] ) ; tt -> add ( texcoords[ idx ] ) ; idx = i * (nstrips+1) + j ; vv -> add ( vertices [ idx ] ) ; nn -> add ( normals [ idx ] ) ; cc -> add ( colours [ idx ] ) ; tt -> add ( texcoords[ idx ] ) ; } vt -> setVertices ( vv ) ; vt -> setNormals ( nn ) ; vt -> setColours ( cc ) ; vt -> setTexCoords ( tt ) ; vt -> recalcBSphere () ; } recalcBSphere () ; } // XXX really need these (and ssgLocal.h is not accessible): extern int _ssgLoadObject ( FILE *, ssgBase **, int ) ; extern int _ssgSaveObject ( FILE *, ssgBase * ) ; #define load_field(fp, name) (fread(&(name), 1, sizeof(name), fp) == sizeof(name)) #define save_field(fp, name) (fwrite(&(name), 1, sizeof(name), fp) == sizeof(name)) int ssgaWaveSystem::load ( FILE *fp ) { return ( load_field ( fp, windSpeed ) && load_field ( fp, windHeading ) && load_field ( fp, edgeFlatten ) && load_field ( fp, tu ) && load_field ( fp, tv ) && ssgaShape::load ( fp ) ) ; } int ssgaWaveSystem::save ( FILE *fp ) { return ( save_field ( fp, windSpeed ) && save_field ( fp, windHeading ) && save_field ( fp, edgeFlatten ) && save_field ( fp, tu ) && save_field ( fp, tv ) && ssgaShape::save ( fp ) ) ; } plib-1.8.5/src/ssgAux/ssgaTeapot.cxx0000644000175000001440000002456010765364435014313 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaTeapot.cxx 2015 2005-02-02 15:48:09Z sjbaker $ */ #include "ssgAux.h" #include static int patch [][ 17 ] = { /* Rim: */ { 2, 102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* Body: */ { 2, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }, { 2, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 }, /* Lid: */ { 2, 96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3 }, { 2, 0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117 }, /* Handle: */ { 1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 }, { 1, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67 }, /* Spout: */ { 1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 }, { 1, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 }, /* Bottom: */ { 2, 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37 }, /* End Marker: */ { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 } } ; static sgVec3 vertex [] = { { 0.2000f, 0.0000f, 2.70000f }, /* 00 */ { 0.2000f, -0.1120f, 2.70000f }, { 0.1120f, -0.2000f, 2.70000f }, { 0.0000f, -0.2000f, 2.70000f }, { 1.3375f, 0.0000f, 2.53125f }, { 1.3375f, -0.7490f, 2.53125f }, { 0.7490f, -1.3375f, 2.53125f }, { 0.0000f, -1.3375f, 2.53125f }, { 1.4375f, 0.0000f, 2.53125f }, { 1.4375f, -0.8050f, 2.53125f }, { 0.8050f, -1.4375f, 2.53125f }, /* 10 */ { 0.0000f, -1.4375f, 2.53125f }, { 1.5000f, 0.0000f, 2.40000f }, { 1.5000f, -0.8400f, 2.40000f }, { 0.8400f, -1.5000f, 2.40000f }, { 0.0000f, -1.5000f, 2.40000f }, { 1.7500f, 0.0000f, 1.87500f }, { 1.7500f, -0.9800f, 1.87500f }, { 0.9800f, -1.7500f, 1.87500f }, { 0.0000f, -1.7500f, 1.87500f }, { 2.0000f, 0.0000f, 1.35000f }, /* 20 */ { 2.0000f, -1.1200f, 1.35000f }, { 1.1200f, -2.0000f, 1.35000f }, { 0.0000f, -2.0000f, 1.35000f }, { 2.0000f, 0.0000f, 0.90000f }, { 2.0000f, -1.1200f, 0.90000f }, { 1.1200f, -2.0000f, 0.90000f }, { 0.0000f, -2.0000f, 0.90000f }, { -2.0000f, 0.0000f, 0.90000f }, { 2.0000f, 0.0000f, 0.45000f }, { 2.0000f, -1.1200f, 0.45000f }, /* 30 */ { 1.1200f, -2.0000f, 0.45000f }, { 0.0000f, -2.0000f, 0.45000f }, { 1.5000f, 0.0000f, 0.22500f }, { 1.5000f, -0.8400f, 0.22500f }, { 0.8400f, -1.5000f, 0.22500f }, { 0.0000f, -1.5000f, 0.22500f }, { 1.5000f, 0.0000f, 0.15000f }, { 1.5000f, -0.8400f, 0.15000f }, { 0.8400f, -1.5000f, 0.15000f }, { 0.0000f, -1.5000f, 0.15000f }, /* 40 */ { -1.6000f, 0.0000f, 2.02500f }, { -1.6000f, -0.3000f, 2.02500f }, { -1.5000f, -0.3000f, 2.25000f }, { -1.5000f, 0.0000f, 2.25000f }, { -2.3000f, 0.0000f, 2.02500f }, { -2.3000f, -0.3000f, 2.02500f }, { -2.5000f, -0.3000f, 2.25000f }, { -2.5000f, 0.0000f, 2.25000f }, { -2.7000f, 0.0000f, 2.02500f }, { -2.7000f, -0.3000f, 2.02500f }, /* 50 */ { -3.0000f, -0.3000f, 2.25000f }, { -3.0000f, 0.0000f, 2.25000f }, { -2.7000f, 0.0000f, 1.80000f }, { -2.7000f, -0.3000f, 1.80000f }, { -3.0000f, -0.3000f, 1.80000f }, { -3.0000f, 0.0000f, 1.80000f }, { -2.7000f, 0.0000f, 1.57500f }, { -2.7000f, -0.3000f, 1.57500f }, { -3.0000f, -0.3000f, 1.35000f }, { -3.0000f, 0.0000f, 1.35000f }, /* 60 */ { -2.5000f, 0.0000f, 1.12500f }, { -2.5000f, -0.3000f, 1.12500f }, { -2.6500f, -0.3000f, 0.93750f }, { -2.6500f, 0.0000f, 0.93750f }, { -2.0000f, -0.3000f, 0.90000f }, { -1.9000f, -0.3000f, 0.60000f }, { -1.9000f, 0.0000f, 0.60000f }, { 1.7000f, 0.0000f, 1.42500f }, { 1.7000f, -0.6600f, 1.42500f }, { 1.7000f, -0.6600f, 0.60000f }, /* 70 */ { 1.7000f, 0.0000f, 0.60000f }, { 2.6000f, 0.0000f, 1.42500f }, { 2.6000f, -0.6600f, 1.42500f }, { 3.1000f, -0.6600f, 0.82500f }, { 3.1000f, 0.0000f, 0.82500f }, { 2.3000f, 0.0000f, 2.10000f }, { 2.3000f, -0.2500f, 2.10000f }, { 2.4000f, -0.2500f, 2.02500f }, { 2.4000f, 0.0000f, 2.02500f }, { 2.7000f, 0.0000f, 2.40000f }, /* 80 */ { 2.7000f, -0.2500f, 2.40000f }, { 3.3000f, -0.2500f, 2.40000f }, { 3.3000f, 0.0000f, 2.40000f }, { 2.8000f, 0.0000f, 2.47500f }, { 2.8000f, -0.2500f, 2.47500f }, { 3.5250f, -0.2500f, 2.49375f }, { 3.5250f, 0.0000f, 2.49375f }, { 2.9000f, 0.0000f, 2.47500f }, { 2.9000f, -0.1500f, 2.47500f }, { 3.4500f, -0.1500f, 2.51250f }, /* 90 */ { 3.4500f, 0.0000f, 2.51250f }, { 2.8000f, 0.0000f, 2.40000f }, { 2.8000f, -0.1500f, 2.40000f }, { 3.2000f, -0.1500f, 2.40000f }, { 3.2000f, 0.0000f, 2.40000f }, { 0.0000f, 0.0000f, 3.15000f }, { 0.8000f, 0.0000f, 3.15000f }, { 0.8000f, -0.4500f, 3.15000f }, { 0.4500f, -0.8000f, 3.15000f }, { 0.0000f, -0.8000f, 3.15000f }, /* 100 */ { 0.0000f, 0.0000f, 2.85000f }, { 1.4000f, 0.0000f, 2.40000f }, { 1.4000f, -0.7840f, 2.40000f }, { 0.7840f, -1.4000f, 2.40000f }, { 0.0000f, -1.4000f, 2.40000f }, { 0.4000f, 0.0000f, 2.55000f }, { 0.4000f, -0.2240f, 2.55000f }, { 0.2240f, -0.4000f, 2.55000f }, { 0.0000f, -0.4000f, 2.55000f }, { 1.3000f, 0.0000f, 2.55000f }, /* 110 */ { 1.3000f, -0.7280f, 2.55000f }, { 0.7280f, -1.3000f, 2.55000f }, { 0.0000f, -1.3000f, 2.55000f }, /* Next four verts kludged to make lid fit */ { 1.4000f, 0.0000f, 2.40000f }, /* { 1.3000, 0.0000, 2.40000 }, */ { 1.4000f, -0.7840f, 2.40000f }, /* { 1.3000, -0.7280, 2.40000 }, */ { 0.7840f, -1.4000f, 2.40000f }, /* { 0.7280, -1.3000, 2.40000 }, */ { 0.0000f, -1.4000f, 2.40000f }, /* { 0.0000, -1.3000, 2.40000 }, */ { 0.0000f, 0.0000f, 0.00000f }, { 1.4250f, -0.7980f, 0.00000f }, { 1.5000f, 0.0000f, 0.07500f }, /* 120 */ { 1.4250f, 0.0000f, 0.00000f }, { 0.7980f, -1.4250f, 0.00000f }, { 0.0000f, -1.5000f, 0.07500f }, { 0.0000f, -1.4250f, 0.00000f }, { 1.5000f, -0.8400f, 0.07500f }, { 0.8400f, -1.5000f, 0.07500f } } ; void ssgaTeapot::regenerate () { if ( kidState != NULL ) kidState -> ref () ; removeAllKids () ; if ( kidState != NULL ) kidState -> deRef () ; for ( int i = 0 ; patch[i][0] >= 0 ; i++ ) { ssgaPatch *p = new ssgaPatch ( ntriangles / 32 ) ; int j ; for ( j = 0 ; j < 16 ; j++ ) { sgVec3 xyz ; sgVec2 uv ; uv [ 0 ] = (float)(j&3)/3.0f ; uv [ 1 ] = (float)(j>>2)/3.0f ; sgScaleVec3 ( xyz, vertex[patch[i][j+1]], 1.0f/2.5f ) ; xyz [ 0 ] *= -1.0f ; p -> setControlPoint ( j>>2, j&3, xyz, uv, colour ) ; } p -> setKidState ( getKidState () ) ; p -> setKidCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; p -> setKidCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; p -> setColour ( colour ) ; p -> setCenter ( getCenter () ) ; p -> setSize ( getSize () ) ; p -> regenerate () ; /* Make a mirror image in the Y axis */ sgVec3 xyz ; sgVec2 uv ; sgVec4 rgba ; ssgaPatch *p2 = new ssgaPatch ( ntriangles / 32 ) ; for ( j = 0 ; j < 16 ; j++ ) { p -> getControlPoint ( j>>2, 3-(j&3), xyz, uv, rgba ) ; xyz [ 1 ] *= -1.0f ; p2 -> setControlPoint ( j>>2, j&3, xyz, uv, rgba ) ; } p2 -> setKidState ( getKidState () ) ; p2 -> setKidCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; p2 -> setKidCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; p2 -> setColour ( colour ) ; p2 -> setCenter ( getCenter () ) ; p2 -> setSize ( getSize () ) ; p2 -> regenerate () ; if ( patch[i][0] == 2 ) { /* Make a mirror images in the X axis */ ssgaPatch *p3 = new ssgaPatch ( ntriangles / 32 ) ; ssgaPatch *p4 = new ssgaPatch ( ntriangles / 32 ) ; for ( j = 0 ; j < 16 ; j++ ) { p -> getControlPoint ( j>>2, 3-(j&3), xyz, uv, rgba ) ; xyz [ 0 ] *= -1.0f ; p3 -> setControlPoint ( j>>2, j&3, xyz, uv, rgba ) ; p2 -> getControlPoint ( j>>2, 3-(j&3), xyz, uv, rgba ) ; xyz [ 0 ] *= -1.0f ; p4 -> setControlPoint ( j>>2, j&3, xyz, uv, rgba ) ; } p3 -> setKidState ( getKidState () ) ; p3 -> setKidCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; p3 -> setKidCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; p3 -> setColour ( colour ) ; p3 -> setCenter ( getCenter () ) ; p3 -> setSize ( getSize () ) ; p3 -> regenerate () ; p4 -> setKidState ( getKidState () ) ; p4 -> setKidCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; p4 -> setKidCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; p4 -> setColour ( colour ) ; p4 -> setCenter ( getCenter () ) ; p4 -> setSize ( getSize () ) ; p4 -> regenerate () ; for ( j = 0 ; j < p3 -> getNumKids () ; j++ ) { addKid ( p3->getKid(j) ) ; addKid ( p4->getKid(j) ) ; } p3 -> removeAllKids () ; p4 -> removeAllKids () ; delete p3 ; delete p4 ; } for ( j = 0 ; j < p -> getNumKids () ; j++ ) { addKid ( p->getKid(j) ) ; addKid ( p2->getKid(j) ) ; } p -> removeAllKids () ; p2 -> removeAllKids () ; delete p ; delete p2 ; } recalcBSphere () ; } plib-1.8.5/src/ssgAux/ssgaShapes.cxx0000644000175000001440000007075010765364435014304 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaShapes.cxx 2015 2005-02-02 15:48:09Z sjbaker $ */ #include "ssgAux.h" #include #define SIN(x) ((float)(sin(x))) #define COS(x) ((float)(cos(x))) #define ATAN2(x, y) ((float)(atan2(x, y))) void ssgaShape::copy_from ( ssgaShape *src, int clone_flags ) { ssgBranch::copy_from ( src, clone_flags ) ; if ( src -> isCorrupt () ) makeCorrupt () ; sgCopyVec4 ( colour, src->colour ) ; sgCopyVec3 ( center, src->center ) ; sgCopyVec3 ( size , src->size ) ; ntriangles = src -> ntriangles ; kidState = src -> getKidState () ; kidPreDrawCB = src -> getKidPreDrawCB () ; kidPostDrawCB = src -> getKidPostDrawCB () ; } void ssgaCube ::copy_from ( ssgaCube *src, int clone_flags ) { ssgaShape::copy_from ( src, clone_flags ) ;} void ssgaSphere ::copy_from ( ssgaSphere *src, int clone_flags ) { ssgaShape::copy_from ( src, clone_flags ) ;} void ssgaCylinder::copy_from ( ssgaCylinder *src, int clone_flags ) { ssgaShape::copy_from ( src, clone_flags ) ;} void ssgaPatch ::copy_from ( ssgaPatch *src, int clone_flags ) { ssgaShape::copy_from ( src, clone_flags ) ;} void ssgaTeapot ::copy_from ( ssgaTeapot *src, int clone_flags ) { ssgaShape::copy_from ( src, clone_flags ) ;} ssgBase *ssgaShape ::clone ( int clone_flags ) { /* ssgaShape *b = new ssgaShape ; b -> copy_from ( this, clone_flags ) ; return b ; */ return NULL ; } ssgBase *ssgaCube ::clone ( int clone_flags ) { ssgaCube *b = new ssgaCube ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgaSphere ::clone ( int clone_flags ) { ssgaSphere *b = new ssgaSphere ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgaTeapot::clone ( int clone_flags ) { ssgaTeapot *b = new ssgaTeapot ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgaPatch::clone ( int clone_flags ) { ssgaPatch *b = new ssgaPatch ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgBase *ssgaCylinder::clone ( int clone_flags ) { ssgaCylinder *b = new ssgaCylinder ; b -> copy_from ( this, clone_flags ) ; return b ; } ssgaShape::ssgaShape (void) { ntriangles = 50 ; init () ; } ssgaShape::ssgaShape ( int np ) { ntriangles = np ; init () ; } void ssgaShape::init () { type = ssgaTypeShape () ; corrupted = FALSE ; sgZeroVec3 ( center ) ; sgSetVec4 ( colour, 1.0f, 1.0f, 1.0f, 1.0f ) ; sgSetVec3 ( size, 1.0f, 1.0f, 1.0f ) ; kidState = NULL ; kidPreDrawCB = NULL ; kidPostDrawCB = NULL ; } ssgaCube ::ssgaCube ( void ):ssgaShape () {type=ssgaTypeCube ();regenerate();} ssgaCube ::ssgaCube (int nt):ssgaShape (nt){type=ssgaTypeCube ();regenerate();} ssgaPatch::ssgaPatch( void ):ssgaShape () {type=ssgaTypePatch();regenerate();} ssgaPatch::ssgaPatch(int nt):ssgaShape (nt){type=ssgaTypePatch();regenerate();} ssgaTeapot::ssgaTeapot( void ):ssgaShape () {type=ssgaTypeTeapot();regenerate();} ssgaTeapot::ssgaTeapot(int nt):ssgaShape (nt){type=ssgaTypeTeapot();regenerate();} ssgaSphere ::ssgaSphere ( void ) : ssgaShape () { type = ssgaTypeSphere () ; latlong_style = TRUE ; regenerate () ; } ssgaSphere ::ssgaSphere (int nt) : ssgaShape ( nt ) { type = ssgaTypeSphere () ; latlong_style = TRUE ; regenerate () ; } ssgaCylinder::ssgaCylinder ( void ) : ssgaShape () { type = ssgaTypeCylinder () ; capped = TRUE ; regenerate () ; } ssgaCylinder::ssgaCylinder (int nt) : ssgaShape ( nt ) { type = ssgaTypeCylinder () ; capped = TRUE ; regenerate () ; } ssgaShape ::~ssgaShape (void) {} ssgaCube ::~ssgaCube (void) {} ssgaPatch ::~ssgaPatch (void) {} ssgaTeapot ::~ssgaTeapot (void) {} ssgaSphere ::~ssgaSphere (void) {} ssgaCylinder::~ssgaCylinder (void) {} const char *ssgaShape ::getTypeName(void) { return "ssgaShape" ; } const char *ssgaCube ::getTypeName(void) { return "ssgaCube" ; } const char *ssgaSphere ::getTypeName(void) { return "ssgaSphere" ; } const char *ssgaCylinder::getTypeName(void) { return "ssgaCylinder" ; } const char *ssgaPatch ::getTypeName(void) { return "ssgaPatch" ; } const char *ssgaTeapot ::getTypeName(void) { return "ssgaTeapot" ; } void ssgaCube ::regenerate () { if ( kidState != NULL ) kidState -> ref () ; removeAllKids () ; if ( kidState != NULL ) kidState -> deRef () ; if ( ntriangles == 0 ) return ; ssgVtxTable *vt0 = new ssgVtxTable () ; ssgVtxTable *vt1 = new ssgVtxTable () ; ssgVertexArray *v0 = new ssgVertexArray ( 8 ) ; ssgVertexArray *v1 = new ssgVertexArray ( 8 ) ; ssgNormalArray *n0 = new ssgNormalArray ( 8 ) ; ssgNormalArray *n1 = new ssgNormalArray ( 8 ) ; ssgColourArray *c0 = new ssgColourArray ( 8 ) ; ssgColourArray *c1 = new ssgColourArray ( 8 ) ; ssgTexCoordArray *t0 = new ssgTexCoordArray ( 8 ) ; ssgTexCoordArray *t1 = new ssgTexCoordArray ( 8 ) ; vt0 -> setPrimitiveType ( GL_TRIANGLE_STRIP ) ; vt1 -> setPrimitiveType ( GL_TRIANGLE_STRIP ) ; addKid ( vt0 ) ; addKid ( vt1 ) ; vt0 -> setState ( getKidState () ) ; vt1 -> setState ( getKidState () ) ; vt0 -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt1 -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt0 -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; vt1 -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; sgVec3 v ; sgVec3 n ; sgVec2 t ; sgSetVec3 ( v, center[0]+size[0]/2.0f, center[1]-size[1]/2.0f, center[2]+size[2]/2.0f ) ; v0->add ( v ) ; sgSetVec3 ( n, 1 , 0 , 0 ) ; n0->add ( n ) ; c0->add ( colour ) ; sgSetVec2 ( t, 0 , 1 ) ; t0->add ( t ) ; sgSetVec3 ( v, center[0]+size[0]/2.0f, center[1]-size[1]/2.0f, center[2]-size[2]/2.0f ) ; v0->add ( v ) ; sgSetVec3 ( n, 1 , 0 , 0 ) ; n0->add ( n ) ; c0->add ( colour ) ; sgSetVec2 ( t, 0 , 0 ) ; t0->add ( t ) ; sgSetVec3 ( v, center[0]+size[0]/2.0f, center[1]+size[1]/2.0f, center[2]+size[2]/2.0f ) ; v0->add ( v ) ; sgSetVec3 ( n, 1 , 0 , 0 ) ; n0->add ( n ) ; c0->add ( colour ) ; sgSetVec2 ( t, 1 , 1 ) ; t0->add ( t ) ; sgSetVec3 ( v, center[0]+size[0]/2.0f, center[1]+size[1]/2.0f, center[2]-size[2]/2.0f ) ; v0->add ( v ) ; sgSetVec3 ( n, 1 , 0 , 0 ) ; n0->add ( n ) ; c0->add ( colour ) ; sgSetVec2 ( t, 1 , 0 ) ; t0->add ( t ) ; sgSetVec3 ( v, center[0]-size[0]/2.0f, center[1]+size[1]/2.0f, center[2]+size[2]/2.0f ) ; v0->add ( v ) ; sgSetVec3 ( n, 0 , 1 , 0 ) ; n0->add ( n ) ; c0->add ( colour ) ; sgSetVec2 ( t, 2 , 1 ) ; t0->add ( t ) ; sgSetVec3 ( v, center[0]-size[0]/2.0f, center[1]+size[1]/2.0f, center[2]-size[2]/2.0f ) ; v0->add ( v ) ; sgSetVec3 ( n, 0 , 1 , 0 ) ; n0->add ( n ) ; c0->add ( colour ) ; sgSetVec2 ( t, 2 , 0 ) ; t0->add ( t ) ; sgSetVec3 ( v, center[0]-size[0]/2.0f, center[1]-size[1]/2.0f, center[2]+size[2]/2.0f ) ; v0->add ( v ) ; sgSetVec3 ( n, -1 , 0 , 0 ) ; n0->add ( n ) ; c0->add ( colour ) ; sgSetVec2 ( t, 3 , 1 ) ; t0->add ( t ) ; sgSetVec3 ( v, center[0]-size[0]/2.0f, center[1]-size[1]/2.0f, center[2]-size[2]/2.0f ) ; v0->add ( v ) ; sgSetVec3 ( n, -1 , 0 , 0 ) ; n0->add ( n ) ; c0->add ( colour ) ; sgSetVec2 ( t, 3 , 0 ) ; t0->add ( t ) ; vt0 -> setVertices ( v0 ) ; vt0 -> setNormals ( n0 ) ; vt0 -> setColours ( c0 ) ; vt0 -> setTexCoords ( t0 ) ; vt0 -> recalcBSphere () ; sgSetVec3 ( v, center[0]-size[0]/2.0f, center[1]+size[1]/2.0f, center[2]-size[2]/2.0f ) ; v1->add ( v ) ; sgSetVec3 ( n, 0 , 0 , -1 ) ; n1->add ( n ) ; c1->add ( colour ) ; sgSetVec2 ( t, 0 , 0 ) ; t1->add ( t ) ; sgSetVec3 ( v, center[0]+size[0]/2.0f, center[1]+size[1]/2.0f, center[2]-size[2]/2.0f ) ; v1->add ( v ) ; sgSetVec3 ( n, 0 , 0 , -1 ) ; n1->add ( n ) ; c1->add ( colour ) ; sgSetVec2 ( t, 1 , 0 ) ; t1->add ( t ) ; sgSetVec3 ( v, center[0]-size[0]/2.0f, center[1]-size[1]/2.0f, center[2]-size[2]/2.0f ) ; v1->add ( v ) ; sgSetVec3 ( n, 0 , 0 , -1 ) ; n1->add ( n ) ; c1->add ( colour ) ; sgSetVec2 ( t, 0 , 1 ) ; t1->add ( t ) ; sgSetVec3 ( v, center[0]+size[0]/2.0f, center[1]-size[1]/2.0f, center[2]-size[2]/2.0f ) ; v1->add ( v ) ; sgSetVec3 ( n, 0 , 0 , -1 ) ; n1->add ( n ) ; c1->add ( colour ) ; sgSetVec2 ( t, 1 , 1 ) ; t1->add ( t ) ; sgSetVec3 ( v, center[0]-size[0]/2.0f, center[1]-size[1]/2.0f, center[2]+size[2]/2.0f ) ; v1->add ( v ) ; sgSetVec3 ( n, 0 , -1 , 0 ) ; n1->add ( n ) ; c1->add ( colour ) ; sgSetVec2 ( t, 0 , 2 ) ; t1->add ( t ) ; sgSetVec3 ( v, center[0]+size[0]/2.0f, center[1]-size[1]/2.0f, center[2]+size[2]/2.0f ) ; v1->add ( v ) ; sgSetVec3 ( n, 0 , -1 , 0 ) ; n1->add ( n ) ; c1->add ( colour ) ; sgSetVec2 ( t, 1 , 2 ) ; t1->add ( t ) ; sgSetVec3 ( v, center[0]-size[0]/2.0f, center[1]+size[1]/2.0f, center[2]+size[2]/2.0f ) ; v1->add ( v ) ; sgSetVec3 ( n, 0 , 0 , 1 ) ; n1->add ( n ) ; c1->add ( colour ) ; sgSetVec2 ( t, 0 , 3 ) ; t1->add ( t ) ; sgSetVec3 ( v, center[0]+size[0]/2.0f, center[1]+size[1]/2.0f, center[2]+size[2]/2.0f ) ; v1->add ( v ) ; sgSetVec3 ( n, 0 , 0 , 1 ) ; n1->add ( n ) ; c1->add ( colour ) ; sgSetVec2 ( t, 1 , 3 ) ; t1->add ( t ) ; vt1 -> setVertices ( v1 ) ; vt1 -> setNormals ( n1 ) ; vt1 -> setColours ( c1 ) ; vt1 -> setTexCoords ( t1 ) ; vt1 -> recalcBSphere () ; recalcBSphere () ; } /* This code is 'inspired' by the function 'sphere' written by David Blythe for GLUT 3.5 and uses his values for the coordinates of the initial Icosahedron. */ #define CZ 0.89442719099991f /* 2/sqrt(5) */ #define SZ 0.44721359549995f /* 1/sqrt(5) */ #define C1 0.951056516f /* cos(18) */ #define S1 0.309016994f /* sin(18) */ #define C2 0.587785252f /* cos(54) */ #define S2 0.809016994f /* sin(54) */ #define X1 (C1*CZ) #define Y1 (S1*CZ) #define X2 (C2*CZ) #define Y2 (S2*CZ) #define P0 { 0, 0, 1 } #define P1 { -X2, -Y2, SZ } #define P2 { X2, -Y2, SZ } #define P3 { X1, Y1, SZ } #define P4 { 0, CZ, SZ } #define P5 { -X1, Y1, SZ } #define P6 { -X1, -Y1, -SZ } #define P7 { 0, -CZ, -SZ } #define P8 { X1, -Y1, -SZ } #define P9 { X2, Y2, -SZ } #define PA { -X2, Y2, -SZ } #define PB { 0, 0, -1 } struct Triangle { sgVec3 v0, v1, v2 ; } ; static Triangle icosahedron [ 20 ] = { { P0, P1, P2 }, { P0, P5, P1 }, { P0, P4, P5 }, { P0, P3, P4 }, { P0, P2, P3 }, { P1, P6, P7 }, { P6, P1, P5 }, { P5, PA, P6 }, { PA, P5, P4 }, { P4, P9, PA }, { P9, P4, P3 }, { P3, P8, P9 }, { P8, P3, P2 }, { P2, P7, P8 }, { P7, P2, P1 }, { P9, P8, PB }, { PA, P9, PB }, { P6, PA, PB }, { P7, P6, PB }, { P8, P7, PB } } ; void ssgaSphere::regenerateTessellatedIcosahedron () { int tris_per_strip = 1 ; int nstrips = 1 ; int nt = 20 ; while ( nt < ntriangles ) { nstrips++ ; tris_per_strip += 2 ; nt += tris_per_strip * 20 ; } /* 20 sides of an Icosahedron */ for ( int s = 0 ; s < 20 ; s++ ) { Triangle *tri = & icosahedron [ s ] ; for ( int i = 0 ; i < nstrips ; i++ ) { /* Create a tri-strip for each row The number of triangles in each strip is two greater than the last one. */ sgVec3 v0, v1, v2, v3, va, vb ; /* t->v[0] /\ / \ /____\v1 /\ /\ / \ / \ /____\/vb__\v0 /\ /\ /\ / \ / \ / \ /____\/____\/va__\ /\ /\ /\ /\ / \ / \ / \ / \ t->v[2] /____\/____\/____\/____\ t->v[1] v3 v2 */ /* This should be a spherical interpolation - but that's slow and nobody can tell the difference anyway */ ssgVtxTable *vt = new ssgVtxTable ; ssgVertexArray *vv = new ssgVertexArray ( i + 3 ) ; ssgNormalArray *nn = new ssgNormalArray ( i + 3 ) ; ssgColourArray *cc = new ssgColourArray ( i + 3 ) ; ssgTexCoordArray *tt = new ssgTexCoordArray ( i + 3 ) ; addKid ( vt ) ; vt -> setState ( getKidState () ) ; vt -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; sgVec3 v ; sgVec3 n ; sgVec2 t ; vt -> setPrimitiveType ( GL_TRIANGLE_STRIP ) ; sgLerpVec3 ( v0, tri->v1, tri->v0, (float)(i+1) / (float) nstrips ) ; sgLerpVec3 ( v1, tri->v1, tri->v0, (float) i / (float) nstrips ) ; sgLerpVec3 ( v2, tri->v1, tri->v2, (float)(i+1) / (float) nstrips ) ; sgLerpVec3 ( v3, tri->v1, tri->v2, (float) i / (float) nstrips ) ; sgNormalizeVec3 ( v0 ) ; sgNormalizeVec3 ( v1 ) ; sgNormalizeVec3 ( v2 ) ; sgNormalizeVec3 ( v3 ) ; sgSetVec3 ( v, center[0]+size[0]*v0[0]/2.0f, center[1]+size[1]*v0[1]/2.0f, center[2]+size[2]*v0[2]/2.0f ) ; sgSetVec3 ( n, size[0]*v0[0], size[1]*v0[1], size[2]*v0[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, ATAN2(n[0],n[1])/(SG_PI*2.0f)+0.5f, 0.5f+v0[2]/2.0f ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; sgSetVec3 ( v, center[0]+size[0]*v1[0]/2.0f, center[1]+size[1]*v1[1]/2.0f, center[2]+size[2]*v1[2]/2.0f ) ; sgSetVec3 ( n, size[0]*v1[0], size[1]*v1[1], size[2]*v1[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, ATAN2(n[0],n[1])/(SG_PI*2.0f)+0.5f, 0.5f+v1[2]/2.0f ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; for ( int j = 0 ; j < i ; j++ ) { sgLerpVec3 ( va, v0, v2, (float)(j+1) / (float) (i+1) ) ; sgLerpVec3 ( vb, v1, v3, (float)(j+1) / (float) i ) ; sgNormalizeVec3 ( va ) ; sgNormalizeVec3 ( vb ) ; sgSetVec3 ( v, center[0]+size[0]*va[0]/2.0f, center[1]+size[1]*va[1]/2.0f, center[2]+size[2]*va[2]/2.0f ) ; sgSetVec3 ( n, size[0]*va[0], size[1]*va[1], size[2]*va[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, ATAN2(n[0],n[1])/(SG_PI*2.0f)+0.5f, 0.5f+va[2]/2.0f ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; sgSetVec3 ( v, center[0]+size[0]*vb[0]/2.0f, center[1]+size[1]*vb[1]/2.0f, center[2]+size[2]*vb[2]/2.0f ) ; sgSetVec3 ( n, size[0]*vb[0], size[1]*vb[1], size[2]*vb[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, ATAN2(n[0],n[1])/(SG_PI*2.0f)+0.5f, 0.5f+vb[2]/2.0f ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; } sgSetVec3 ( v, center[0]+size[0]*v2[0]/2.0f, center[1]+size[1]*v2[1]/2.0f, center[2]+size[2]*v2[2]/2.0f ) ; sgSetVec3 ( n, size[0]*v2[0], size[1]*v2[1], size[2]*v2[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, ATAN2(n[0],n[1])/(SG_PI*2.0f)+0.5f, 0.5f+v2[2]/2.0f ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; vt -> setVertices ( vv ) ; vt -> setNormals ( nn ) ; vt -> setColours ( cc ) ; vt -> setTexCoords ( tt ) ; vt -> recalcBSphere () ; } } recalcBSphere () ; } void ssgaSphere::regenerateLatLong () { int stacks = (int) sqrt ( (double) ntriangles / 2.0f ) ; if ( stacks < 2 ) stacks = 2 ; int slices = ntriangles / stacks ; if ( slices < 3 ) slices = 3 ; for ( int i = 0 ; i < stacks ; i++ ) { ssgVtxTable *vt = new ssgVtxTable ; ssgVertexArray *vv = new ssgVertexArray ( (slices+1)*2 ) ; ssgNormalArray *nn = new ssgNormalArray ( (slices+1)*2 ) ; ssgColourArray *cc = new ssgColourArray ( (slices+1)*2 ) ; ssgTexCoordArray *tt = new ssgTexCoordArray ( (slices+1)*2 ) ; addKid ( vt ) ; vt -> setState ( getKidState () ) ; vt -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; sgVec3 v ; sgVec3 n ; sgVec2 t ; if ( i == stacks-1 ) /* North Pole */ { vt -> setPrimitiveType ( GL_TRIANGLE_FAN ) ; sgSetVec3 ( v, center[0], center[1], center[2]+size[2]/2.0f ) ; sgSetVec3 ( n, 0, 0, 1 ) ; sgSetVec2 ( t, 0.5f, 1 ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; for ( int j = slices ; j >= 0 ; j-- ) { float a = (j==0 || j==slices) ? 0.0f : (float) j * SG_PI * 2.0f / (float) slices ; float b = (float) i * SG_PI / (float) stacks ; sgSetVec3 ( v, center[0] + size[0]*SIN(a)*SIN(b)/2.0f, center[1] + size[1]*COS(a)*SIN(b)/2.0f, center[2] - size[2]* COS(b)/2.0f ) ; sgSetVec3 ( n, SIN(a)*SIN(b)*size[0], COS(a)*SIN(b)*size[1], -COS(b)*size[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, (float)j/(float)slices, (float) i /(float)stacks ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; } } else if ( i == 0 ) /* South Pole */ { vt -> setPrimitiveType ( GL_TRIANGLE_FAN ) ; sgSetVec3 ( v, center[0], center[1], center[2]-size[2]/2.0f ) ; sgSetVec3 ( n, 0, 0, -1 ) ; sgSetVec2 ( t, 0.5, 0 ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; for ( int j = 0 ; j < slices+1 ; j++ ) { float a = (j==0 || j==slices) ? 0.0f : (float) j * SG_PI * 2.0f / (float) slices ; float b = (float)(i+1) * SG_PI / (float) stacks ; sgSetVec3 ( v, center[0] + size[0]*SIN(a)*SIN(b)/2.0f, center[1] + size[1]*COS(a)*SIN(b)/2.0f, center[2] - size[2]* COS(b)/2.0f ) ; sgSetVec3 ( n, SIN(a)*SIN(b)*size[0], COS(a)*SIN(b)*size[1], -COS(b)*size[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, (float)j/(float)slices, (float)(i+1)/(float)stacks ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; } } else { vt -> setPrimitiveType ( GL_TRIANGLE_STRIP ) ; for ( int j = 0 ; j < slices+1 ; j++ ) { float a = (j==0 || j==slices) ? 0.0f : (float) j * SG_PI * 2.0f / (float) slices ; float b0 = (float) i * SG_PI / (float) stacks ; float b1 = (float)(i+1) * SG_PI / (float) stacks ; sgSetVec3 ( v, center[0] + size[0]*SIN(a)*SIN(b0)/2.0f, center[1] + size[1]*COS(a)*SIN(b0)/2.0f, center[2] - size[2]* COS(b0)/2.0f ) ; sgSetVec3 ( n, SIN(a)*SIN(b0)*size[0], COS(a)*SIN(b0)*size[1], -COS(b0)*size[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, (float)j/(float)slices, (float)i/(float)stacks ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; sgSetVec3 ( v, center[0] + size[0]*SIN(a)*SIN(b1)/2.0f, center[1] + size[1]*COS(a)*SIN(b1)/2.0f, center[2] - size[2]* COS(b1)/2.0f ) ; sgSetVec3 ( n, SIN(a)*SIN(b1)*size[0], COS(a)*SIN(b1)*size[1], -COS(b1)*size[2] ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, (float)j/(float)slices, (float)(i+1)/(float)stacks ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; } } vt -> setVertices ( vv ) ; vt -> setNormals ( nn ) ; vt -> setColours ( cc ) ; vt -> setTexCoords ( tt ) ; vt -> recalcBSphere () ; } recalcBSphere () ; } void ssgaSphere::regenerate () { if ( kidState != NULL ) kidState -> ref () ; removeAllKids () ; if ( kidState != NULL ) kidState -> deRef () ; if ( ntriangles == 0 ) return ; if ( latlong_style ) regenerateLatLong () ; else regenerateTessellatedIcosahedron () ; } void ssgaCylinder::regenerate () { if ( kidState != NULL ) kidState -> ref () ; removeAllKids () ; if ( kidState != NULL ) kidState -> deRef () ; if ( ntriangles == 0 ) return ; int slices = 1 + ntriangles / 4 ; if ( slices < 3 ) slices = 3 ; ssgVtxTable *vt = new ssgVtxTable ; ssgVertexArray *vv = new ssgVertexArray ( (slices+1)*2 ) ; ssgNormalArray *nn = new ssgNormalArray ( (slices+1)*2 ) ; ssgColourArray *cc = new ssgColourArray ( (slices+1)*2 ) ; ssgTexCoordArray *tt = new ssgTexCoordArray ( (slices+1)*2 ) ; addKid ( vt ) ; vt -> setState ( getKidState () ) ; vt -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; sgVec3 v ; sgVec3 n ; sgVec2 t ; vt -> setPrimitiveType ( GL_TRIANGLE_STRIP ) ; for ( int j = 0 ; j < slices+1 ; j++ ) { float a = (j==0 || j==slices) ? 0.0f : (float) j * SG_PI * 2.0f / (float) slices ; sgSetVec3 ( v, center[0] + size[0]*SIN(a)/2.0f, center[1] + size[1]*COS(a)/2.0f, center[2] - size[2] / 2.0f ) ; sgSetVec3 ( n, -SIN(a) * size[0], -COS(a) * size[1], 0 ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, (float)j/(float)slices, 0 ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; sgSetVec3 ( v, center[0] + size[0]*SIN(a)/2.0f, center[1] + size[1]*COS(a)/2.0f, center[2] + size[2] / 2.0f ) ; sgSetVec3 ( n, -SIN(a) * size[0], -COS(a) * size[1], 0 ) ; sgNormalizeVec3 ( n ) ; sgSetVec2 ( t, (float)j/(float)slices, 1 ) ; vv->add(v) ; nn->add(n) ; cc->add(colour) ; tt->add(t) ; } vt -> setVertices ( vv ) ; vt -> setNormals ( nn ) ; vt -> setColours ( cc ) ; vt -> setTexCoords ( tt ) ; vt -> recalcBSphere () ; if ( capped ) { ssgVtxTable *vt0 = new ssgVtxTable ; ssgVtxTable *vt1 = new ssgVtxTable ; ssgVertexArray *vv0 = new ssgVertexArray ( slices ) ; ssgNormalArray *nn0 = new ssgNormalArray ( slices ) ; ssgColourArray *cc0 = new ssgColourArray ( slices ) ; ssgTexCoordArray *tt0 = new ssgTexCoordArray ( slices ) ; ssgVertexArray *vv1 = new ssgVertexArray ( slices ) ; ssgNormalArray *nn1 = new ssgNormalArray ( slices ) ; ssgColourArray *cc1 = new ssgColourArray ( slices ) ; ssgTexCoordArray *tt1 = new ssgTexCoordArray ( slices ) ; addKid ( vt0 ) ; addKid ( vt1 ) ; vt0 -> setState ( getKidState () ) ; vt0 -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt0 -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; vt1 -> setState ( getKidState () ) ; vt1 -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt1 -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; sgVec3 v ; sgVec3 n ; sgVec2 t ; vt0 -> setPrimitiveType ( GL_TRIANGLE_FAN ) ; vt1 -> setPrimitiveType ( GL_TRIANGLE_FAN ) ; for ( int j = 0 ; j < slices ; j++ ) { float a0 = (float)(1+slices-j) * SG_PI * 2.0f / (float) slices ; float a1 = (float) j * SG_PI * 2.0f / (float) slices ; /* Top */ sgSetVec3 ( v, center[0] + size[0]*SIN(a0)/2.0f, center[1] + size[1]*COS(a0)/2.0f, center[2] + size[2] / 2.0f ) ; sgSetVec3 ( n, 0, 0, 1 ) ; sgSetVec2 ( t, 0.5f + SIN(a0)/2.0f, 0.5f + COS(a0)/2.0f ) ; vv0->add(v) ; nn0->add(n) ; cc0->add(colour) ; tt0->add(t) ; /* Bottom */ sgSetVec3 ( v, center[0] + size[0]*SIN(a1)/2.0f, center[1] + size[1]*COS(a1)/2.0f, center[2] - size[2] / 2.0f ) ; sgSetVec3 ( n, 0, 0, -1 ) ; sgSetVec2 ( t, 0.5f + SIN(a1)/2.0f, 0.5f + COS(a1)/2.0f ) ; vv1->add(v) ; nn1->add(n) ; cc1->add(colour) ; tt1->add(t) ; } vt0 -> setVertices ( vv0 ) ; vt1 -> setVertices ( vv1 ) ; vt0 -> setNormals ( nn0 ) ; vt1 -> setNormals ( nn1 ) ; vt0 -> setColours ( cc0 ) ; vt1 -> setColours ( cc1 ) ; vt0 -> setTexCoords ( tt0 ) ; vt1 -> setTexCoords ( tt1 ) ; vt0 -> recalcBSphere () ; vt1 -> recalcBSphere () ; } recalcBSphere () ; } // XXX really need these (and ssgLocal.h is not accessible): extern int _ssgLoadObject ( FILE *, ssgBase **, int ) ; extern int _ssgSaveObject ( FILE *, ssgBase * ) ; #define load_field(fp, name) (fread(&(name), 1, sizeof(name), fp) == sizeof(name)) #define save_field(fp, name) (fwrite(&(name), 1, sizeof(name), fp) == sizeof(name)) int ssgaShape::load ( FILE *fp ) { return ( load_field ( fp, corrupted ) && load_field ( fp, colour ) && load_field ( fp, center ) && load_field ( fp, size ) && load_field ( fp, ntriangles ) && _ssgLoadObject ( fp, (ssgBase **) &kidState, ssgTypeState () ) && ssgBranch::load ( fp ) ) ; } int ssgaShape::save ( FILE *fp ) { return ( save_field ( fp, corrupted ) && save_field ( fp, colour ) && save_field ( fp, center ) && save_field ( fp, size ) && save_field ( fp, ntriangles ) && _ssgSaveObject ( fp, kidState ) && ssgBranch::save ( fp ) ) ; } int ssgaSphere::load ( FILE *fp ) { return ( load_field ( fp, latlong_style ) && ssgaShape::load ( fp ) ) ; } int ssgaSphere::save ( FILE *fp ) { return ( save_field ( fp, latlong_style ) && ssgaShape::save ( fp ) ) ; } int ssgaTeapot::load ( FILE *fp ) { return ssgaShape::load ( fp ) ; } int ssgaTeapot::save ( FILE *fp ) { return ssgaShape::save ( fp ) ; } int ssgaPatch::load ( FILE *fp ) { return ( load_field ( fp, levels ) && fread(control_points, 1, 16*9*sizeof(float), fp) == 16*9*sizeof(float) && ssgaShape::load ( fp ) ) ; } int ssgaPatch::save ( FILE *fp ) { return ( save_field ( fp, levels ) && fwrite(control_points, 1, 16*9*sizeof(float), fp) == 16*9*sizeof(float) && ssgaShape::save ( fp ) ) ; } int ssgaCylinder::load ( FILE *fp ) { return ( load_field ( fp, capped ) && ssgaShape::load ( fp ) ) ; } int ssgaCylinder::save ( FILE *fp ) { return ( save_field ( fp, capped ) && ssgaShape::save ( fp ) ) ; } plib-1.8.5/src/ssgAux/ssgaBillboards.cxx0000644000175000001440000002103510765364435015126 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaBillboards.cxx 1878 2004-02-25 15:39:34Z sjbaker $ */ #include #include "ssgaBillboards.h" int ssgaBillboards::total_drawn = 0; inline float max3f(const float v[3]) { float tmp = v[0] >= v[1] ? v[0] : v[1]; return tmp >= v[2] ? tmp : v[2]; } inline double random_value() { #ifdef UL_WIN32 return (double) rand() / RAND_MAX; #else return drand48(); #endif } ssgaBillboards::ssgaBillboards() : array(16) { sgSetVec3(up, 0, 0, 1); width = 1; height = 1; clip_dist = -1; fade_dist = -1; near_dist = -1; draw_num = -1; fade_num = -1; alpha_ref = 0.1f; ssgSimpleState *ss = new ssgSimpleState; ss->disable(GL_LIGHTING); ss->disable(GL_BLEND); ss->enable(GL_ALPHA_TEST); ss->enable(GL_TEXTURE_2D); setState(ss); } ssgaBillboards::~ssgaBillboards() { } void ssgaBillboards::recalcBSphere() { int i; sgBox box; box.empty(); for (i = 0; i < getNum(); i++) box.extend(get(i)); sgAddVec3(bsphere.center, box.min, box.max); sgScaleVec3(bsphere.center, 0.5f); sgSubVec3(box.max, box.min); bsphere.radius = 0.5f * max3f(box.max); for (i = 0; i < getNum(); i++) { sgSphere sph; sgCopyVec3(sph.center, get(i)); float s = get(i)[3]; sph.radius = 0.5f * s * width; bsphere.extend(&sph); sgAddScaledVec3(sph.center, up, s * height); bsphere.extend(&sph); } bsphere_is_invalid = 0; } // static void ssgaBillboards::initTexAlpha(GLuint texture, float athres) { const GLenum format[] = { GL_NONE, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA }; glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBindTexture(GL_TEXTURE_2D, texture); for (int level = 0;; level++) { GLint width = 0, height = 0, red = 0, alpha = 0; int icomp, ocomp; glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width ); glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, &height); glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_RED_SIZE, &red ); glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_ALPHA_SIZE, &alpha ); if (width <= 0 || height <= 0) break; if (red > 0) { icomp = 3 + (alpha > 0); ocomp = 4; } else { icomp = 1 + (alpha > 0); ocomp = 2; } GLubyte *pixels = new GLubyte [ width * height * ocomp ]; glGetTexImage(GL_TEXTURE_2D, level, format[icomp], GL_UNSIGNED_BYTE, pixels); for (int y = height; y--;) { for (int x = width; x--;) { float af = icomp % 2 ? 1.0f : (1.0f / 256.0f) * pixels[(y * width + x + 1) * icomp - 1]; // default alpha_ref is 0.1, so match that: af = af > athres ? 0.1f + 0.9f * random_value() : 0; int a = (int) (256.0f * af); pixels[(y * width + x + 1) * ocomp - 1] = a >= 255 ? 255 : a; if (ocomp > icomp) for (int k = 0; k < icomp; k++) pixels[(y * width + x) * ocomp + k] = pixels[(y * width + x) * icomp + k]; } } glTexImage2D(GL_TEXTURE_2D, level, format[ocomp], width, height, 0, format[ocomp], GL_UNSIGNED_BYTE, pixels); delete [] pixels; if (width == 1 && height == 1) break; } } void ssgaBillboards::cull(sgFrustum *f, sgMat4 m, int test_needed) { int cull_result = cull_test(f, m, test_needed); if (cull_result == SSG_OUTSIDE) return; draw(m); } void ssgaBillboards::draw() { sgMat4 m; glGetFloatv(GL_MODELVIEW_MATRIX, &m[0][0]); draw(m); } void ssgaBillboards::draw(const sgMat4 m) { if (!draw_num) return; sgVec4 z_axis = { m[0][2], m[1][2], m[2][2], m[3][2] }; float dist = -1; if (clip_dist >= 0) { const sgSphere *s = getBSphere(); float z = sgScalarProductVec3(s->getCenter(), z_axis) + z_axis[3]; dist = -z - s->getRadius(); if (dist >= clip_dist) return; } if (preDrawCB != NULL && !(*preDrawCB)(this)) return; float aref = alpha_ref; if (fade_dist >= 0 && fade_dist < clip_dist && dist > fade_dist) aref += (1.0f - alpha_ref) * (dist - fade_dist) / (clip_dist - fade_dist); _ssgCurrentContext->setCullface(0); getState()->apply(); glPushAttrib(GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glAlphaFunc(GL_GEQUAL, aref); glBegin(GL_QUADS); int n = getNum(); const float *p = get(0); if (draw_num > 0 && draw_num < n) n = draw_num; if (fade_num >= 0 && fade_num < n && clip_dist > near_dist && near_dist > 1e-6f) { float far_dist = fade_dist >= 0 && fade_dist < clip_dist ? fade_dist : clip_dist; if (dist > near_dist) { if (dist < far_dist) { float fn = 1.0f / near_dist; float ff = 1.0f / far_dist; float fd = 1.0f / dist; float s = (fd - fn) / (ff - fn); n -= (int) ((n - fade_num) * s + 0.5f); } else { n = fade_num; } } } if (up[2] == 1) { // fast path when Z is up float wx, wy, heightz, len; wx = z_axis[1]; wy = -z_axis[0]; len = sgHypot(wx, wy); if (len > 1e-6f) { wx *= 0.5f * width / len; wy *= 0.5f * width / len; heightz = height; for (int i = 0; i < n; i++) { float x, y, z, s, dx, dy; x = *p++; y = *p++; z = *p++; s = *p++; dx = s * wx; dy = s * wy; glTexCoord2f(0, 0); glVertex3f(x - dx, y - dy, z); glTexCoord2f(1, 0); glVertex3f(x + dx, y + dy, z); z += s * heightz; glTexCoord2f(1, 1); glVertex3f(x + dx, y + dy, z); glTexCoord2f(0, 1); glVertex3f(x - dx, y - dy, z); } total_drawn += n; } } else { sgVec3 xy; sgVectorProductVec3(xy, z_axis, up); float len = sgLengthVec3(xy); if (len > 1e-6f) { float wx, wy, wz, heightx, heighty, heightz; wx = 0.5f * width * xy[0] / len; wy = 0.5f * width * xy[1] / len; wz = 0.5f * width * xy[2] / len; heightx = height * up[0]; heighty = height * up[1]; heightz = height * up[2]; for (int i = 0; i < n; i++) { float x, y, z, s, dx, dy, dz; x = *p++; y = *p++; z = *p++; s = *p++; dx = s * wx; dy = s * wy; dz = s * wz; glTexCoord2f(0, 0); glVertex3f(x - dx, y - dy, z - dz); glTexCoord2f(1, 0); glVertex3f(x + dx, y + dy, z + dz); x += s * heightx; y += s * heighty; z += s * heightz; glTexCoord2f(1, 1); glVertex3f(x + dx, y + dy, z + dz); glTexCoord2f(0, 1); glVertex3f(x - dx, y - dy, z - dz); } total_drawn += n; } } glEnd(); glPopAttrib(); if (postDrawCB != NULL) (*postDrawCB)(this); } float *ssgaBillboards::getVertex(int i) { if (i < 0 || i >= 4 * getNum()) return _ssgVertex000; // pick any orientation sgVec3 xy, axis = { 0, 0, 0 }; axis[ sgAbs(up[0]) > sgAbs(up[1]) ] = 1; sgVectorProductVec3(xy, up, axis); sgNormaliseVec3(xy); const sgVec3 tab[4] = { {-0.5f,0.0f}, {0.5f,0.0f}, {0.5f,1.0f}, {-0.5f,1.0f} }; const float *p = array.get(i / 4); const float *d = tab[i % 4]; static sgVec3 v; for (i = 0; i < 3; i++) v[0] = p[i] + p[3] * (width * xy[i] * d[0] + height * up[i] * d[1]); return v; } float *ssgaBillboards::getTexCoord(int i) { static sgVec2 t[4] = { {0,0}, {1,0}, {1,1}, {0,1} }; return t[i & 3]; } void ssgaBillboards::getTriangle(int n, short *v1, short *v2, short *v3) { *v1 = 2*n + 0; *v2 = 2*n + 1; *v3 = 2*n + 2 - 4*(n&1); } void ssgaBillboards::transform(const sgMat4 m) { float scale = sgLengthVec3(m[0]); for (int i = 0; i < getNum(); i++) sgXformPnt3(array.get(i), array.get(i), m); sgXformVec3(up, up, m); sgNormaliseVec3(up); width *= scale; height *= scale; } /* Local Variables: mode: C++ c-basic-offset: 4 c-file-offsets: ((substatement-open 0) (case-label 0)) End: */ plib-1.8.5/src/ssgAux/ssgaLensFlareTexture.cxx0000644000175000001440000025005610765364435016314 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ static unsigned char lens_flare_texture [] = { 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, 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, 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, 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,2,12,19,24,30,36,36, 35,26,20,12,3,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,10,29,54,77,96,112,123,131,135,137, 132,126,113,99,81,60,35,14,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,4,24,60,92,124,149,173,191,207,222,228,231,231, 229,224,214,199,177,155,131,100,68,32,7,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,4,30,73,114,151,187,219,233,242,239,235,231,227,227,227, 227,229,234,238,242,235,225,195,162,123,84,39,7,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, 20,68,116,162,204,233,241,233,225,218,212,207,204,202,201,201, 201,203,206,211,217,223,231,240,237,214,172,128,81,30,3,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,5,46, 101,154,203,238,238,227,216,207,199,193,187,182,179,177,175,175, 176,178,182,186,191,197,205,214,224,235,239,215,166,115,60,11, 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,2,2, 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,12,66,128, 183,229,239,226,214,202,192,183,176,169,164,159,157,153,152,152, 153,156,159,163,168,174,181,189,199,210,222,236,239,197,141,82, 24,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,12,8, 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,4,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,21,81,143,207, 240,231,216,202,190,180,170,161,154,148,143,139,135,134,133,133, 134,135,136,142,147,152,160,168,177,187,199,212,227,241,220,159, 97,33,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,12,15, 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,16,3,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,24,89,156,221,241, 225,209,194,180,170,158,149,142,134,128,124,120,119,114,113,112, 114,118,120,123,128,133,140,147,156,166,178,190,203,219,236,231, 173,107,36,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,10,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,4,0,0, 0,7,0,0,0,12,0,0,0,0,0,0,9,2,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,12,10,2,3,6,0,12, 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,21,89,159,224,237,219, 203,187,172,162,149,139,131,124,118,112,106,104,102,96,96,96, 96,99,104,105,112,116,122,129,138,147,157,171,185,197,214,234, 236,178,107,34,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,18,3, 0,0,0,0,5,21,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,10,0,0, 3,0,0,0,7,10,0,0,0,0,0,11,10,0,0,2, 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,8,21,5,8,12,2,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,12,81,156,224,236,218,199, 182,170,155,142,131,124,114,108,102,96,90,88,86,82,80,80, 82,84,88,90,96,99,106,112,122,130,139,153,163,179,195,211, 231,237,174,102,27,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,30,33, 0,0,0,0,14,20,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,5,0,2, 0,0,0,0,0,0,0,0,0,0,0,0,0,16,11,19, 26,12,0,0,17,10,0,0,0,0,5,22,2,0,0,10, 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,4,0,0,0,0,0,0,21,10,21,15,7,36, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,8, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,5,66,143,221,237,218,197,179, 163,150,139,126,116,108,100,93,87,81,79,73,72,71,70,70, 70,72,72,76,80,86,91,98,106,115,124,133,147,163,179,195, 211,233,231,165,88,14,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,4,10,0,0,0,0,0,18,40, 0,0,0,0,32,17,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,3,13,5, 8,0,0,0,0,0,0,0,0,0,0,0,0,17,11,23, 50,58,0,0,20,3,0,0,0,0,25,9,0,5,13,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,7,7,0,0,0,0,0,23,18,26,19,9,48, 0,0,0,0,0,3,12,0,0,0,0,0,0,8,8,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,46,128,207,241,219,199,179,163, 147,134,124,113,102,93,86,79,73,68,64,63,58,57,56,56, 56,58,62,64,68,72,79,85,91,100,109,122,131,147,163,179, 195,213,235,223,145,66,5,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,2,0,0,19,8,0,0,0,0,34,55, 0,0,0,10,49,10,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,4,0, 13,16,0,0,0,0,0,0,0,0,0,0,0,14,14,30, 39,24,0,11,28,0,12,2,0,17,24,0,3,25,5,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,18,7,0,0,0,0,16,32,36,38,17,20, 0,0,0,0,0,14,11,0,0,11,6,0,13,26,3,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,20,101,183,240,225,203,182,163,147, 133,123,109,99,89,81,73,68,63,57,55,50,48,48,46,46, 47,48,49,53,56,60,65,72,79,87,97,107,117,131,147,163, 179,197,219,241,204,123,36,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,6,6,0,10,21,0,0,3,3,25,62, 0,0,0,27,56,3,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,2,8,3,0,0, 23,28,19,2,0,0,0,14,2,0,0,0,0,16,23,9, 53,30,0,21,21,4,11,0,6,36,5,4,23,7,0,0, 0,0,2,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,4,27,5,0,0,0,3,42,39,55,26,52, 0,0,0,0,0,27,4,0,3,12,0,9,32,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,4,68,154,229,231,209,187,170,150,134, 123,108,98,87,78,70,63,57,52,47,43,41,39,38,37,36, 38,39,40,43,47,51,55,62,68,76,85,94,107,117,131,147, 163,181,203,225,241,174,90,12,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 8,0,0,0,0,0,13,3,0,30,10,0,8,12,18,70, 0,0,6,61,47,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,3,15,11,0, 6,32,37,24,8,0,0,12,15,0,0,0,0,19,41,24, 78,50,0,38,15,21,10,0,35,18,3,33,17,0,0,0, 3,11,3,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,16,28,2,0,0,0,35,41,68,40,62, 0,0,0,0,13,27,0,3,17,2,6,38,10,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,30,116,203,239,216,194,172,155,139,124, 109,98,85,77,68,60,54,47,43,39,35,33,31,30,28,28, 29,30,32,35,37,41,47,52,58,66,74,83,93,107,120,133, 149,170,188,210,233,223,138,51,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 10,13,3,0,0,0,3,26,3,18,28,0,9,29,22,118, 6,3,35,93,24,0,0,6,0,0,3,16,9,22,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,3,16,23, 3,7,37,32,46,15,0,7,34,5,0,0,0,10,44,55, 82,42,5,44,7,29,0,25,36,3,34,23,0,0,0,13, 15,3,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,29,23,0,0,0,22,53,87,62,62, 5,0,10,0,29,15,0,21,16,5,39,18,0,0,0,0, 0,0,3,15,6,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,4,73,162,238,226,202,180,162,142,126,113, 99,87,77,67,58,51,45,39,35,31,28,26,23,22,22,22, 22,23,25,28,30,35,38,43,50,56,64,74,85,96,108,124, 139,155,175,196,220,241,184,95,14,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,13,27,5,0,0,0,17,25,3,38,9,2,50,34,130, 19,11,90,101,6,0,10,13,0,0,14,20,38,9,0,0, 0,0,0,0,3,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,17, 33,10,6,43,58,62,15,3,44,39,0,6,7,3,50,65, 92,44,23,39,24,21,8,49,7,30,33,0,0,6,21,22, 3,2,5,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,11,6,0,0, 0,4,17,3,0,0,4,42,14,0,0,5,55,94,84,72, 30,14,18,7,43,3,10,34,6,40,26,0,4,5,0,0, 3,25,24,8,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,24,114,204,238,214,190,170,149,131,116,102, 89,78,68,58,50,43,37,32,28,25,21,20,18,18,16,16, 17,18,20,21,24,27,31,37,42,48,56,65,75,87,99,114, 129,146,164,186,208,232,225,136,45,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,12,35,12,0,0,2,35,27,30,33,0,59,53,149, 21,24,132,82,0,4,24,5,16,26,26,37,11,0,0,0, 0,0,6,0,6,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, 10,37,23,8,49,78,72,12,22,76,21,11,18,6,52,86, 104,45,39,32,43,5,44,26,29,43,3,4,14,38,19,3, 13,9,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,12,21,7, 0,0,7,26,9,0,0,12,44,6,0,0,48,101,113,84, 48,19,14,30,28,3,39,13,38,36,0,8,16,3,0,20, 47,30,3,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,60,151,233,227,202,180,158,139,124,108,93, 81,70,60,51,43,37,32,27,21,20,17,14,12,12,12,12, 12,12,13,16,19,21,26,29,35,42,49,58,67,79,91,104, 120,135,154,174,196,220,241,175,83,5,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,7,38,22,0,0,9,53,31,51,7,53,72,149, 68,54,161,51,0,27,16,19,54,77,67,11,0,0,0,0, 10,21,12,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,4,33,41,12,52,96,82,11,65,79,12,32,19,50,102, 119,48,57,40,32,29,48,26,50,6,13,42,43,15,14,24, 10,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,8,25, 20,5,0,5,32,17,3,3,30,43,0,0,30,101,133,86, 77,44,21,58,13,28,34,34,48,3,20,28,3,14,52,58, 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,10,92,187,241,216,192,170,149,131,114,100,86, 73,63,54,45,37,32,27,21,19,13,12,11,10,5,4,4, 4,10,11,12,13,16,20,24,29,35,43,51,60,71,83,96, 111,128,144,164,186,210,235,211,116,22,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,5,40,31,3,0,28,72,53,36,38,93,138, 58,88,166,20,18,35,28,77,101,78,9,0,0,0,11,28, 24,7,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,25,50,27,55,117,88,24,118,53,37,46,49,130, 161,61,61,51,22,60,34,58,12,27,56,44,18,30,24,3, 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,2, 17,33,21,3,5,38,41,27,6,48,31,0,12,96,147,98, 104,66,54,60,13,51,35,56,10,32,30,23,53,75,42,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,29,124,219,233,207,183,161,142,124,108,93,79, 68,57,47,39,32,27,21,19,13,12,8,4,0,0,0,0, 0,0,2,6,11,12,16,20,25,31,37,45,55,65,76,89, 104,120,136,156,177,201,226,233,147,52,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,5,43,46,6,2,59,78,70,32,99,137, 91,135,124,5,44,38,97,128,80,9,0,0,11,33,33,10, 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,14,52,44,66,131,90,66,134,63,70,62,154, 195,80,71,51,55,52,63,31,56,80,50,42,40,13,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,2,0,0,0, 0,5,31,42,16,4,37,59,40,14,61,16,0,72,171,127, 125,83,94,41,51,47,63,19,44,46,64,91,69,17,0,0, 0,0,7,7,12,2,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,54,149,233,225,199,176,154,134,118,102,87,73, 63,52,43,35,28,21,19,13,11,5,0,0,0,0,0,0, 0,0,0,0,4,11,12,16,21,27,33,41,49,60,71,83, 97,112,129,150,170,193,218,242,173,78,3,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,5,56,66,18,36,98,100,66,103,163, 131,166,67,34,56,115,153,84,7,0,12,38,42,21,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,2,2,0,0,0,0,0,0,0, 0,0,0,0,8,26,52,62,77,176,109,121,119,103,83,171, 205,114,85,58,73,70,51,96,100,73,73,32,3,0,0,0, 0,0,4,6,13,14,2,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,2,8,13,12, 5,0,0,15,45,40,14,32,75,55,36,63,7,41,176,166, 149,104,99,43,67,72,36,64,80,116,107,38,3,0,0,7, 18,26,22,6,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,2,77,173,242,218,193,169,148,128,112,96,81,68, 57,47,39,31,25,20,13,12,5,0,0,0,0,0,0,0, 0,0,0,0,0,4,11,13,19,23,29,37,45,55,65,79, 92,106,125,143,163,187,212,238,197,102,13,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,9,63,88,45,75,135,120,110,210, 165,161,45,75,138,189,84,6,7,38,53,27,3,0,0,0, 0,0,0,0,3,13,10,9,12,4,0,0,0,0,0,0, 0,0,0,0,0,0,0,2,10,19,19,12,9,0,0,0, 4,14,11,3,0,14,38,66,81,110,188,133,155,137,118,178, 212,135,85,84,85,80,125,118,94,66,14,0,0,0,0,14, 22,30,19,6,3,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,3,15, 27,30,18,5,3,28,54,39,35,92,78,60,52,20,163,213, 181,125,82,80,89,84,103,139,144,75,13,0,16,34,45,41, 26,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,12,96,191,239,212,187,164,143,124,106,90,79,64, 55,43,35,28,21,17,12,8,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,5,12,14,20,27,33,41,51,63,73, 88,104,120,136,158,181,205,233,216,120,24,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,8,7,3,0,0,0,0,5,58,116,83,122,169,145,227, 189,133,75,150,202,80,12,39,60,35,6,0,0,0,0,0, 11,22,26,36,36,27,10,5,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,11,23,34,41,49,42, 25,10,12,26,30,22,12,37,88,115,141,189,179,188,166,193, 224,145,109,114,113,160,139,92,35,2,0,5,21,33,44,34, 18,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,5,6,2,0,0,0, 0,13,29,43,35,20,10,44,64,52,101,107,87,37,130,246, 205,144,97,118,137,181,178,125,35,19,51,87,96,71,36,6, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,19,112,207,235,207,182,159,139,120,104,88,73,63, 50,41,33,26,20,14,11,4,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,2,10,12,19,24,31,39,48,58,72, 84,98,116,134,154,176,202,227,228,135,39,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,5,8,24,32,22,15,2,0,2,48,133,145,195,200,223, 213,126,157,189,77,49,76,48,9,0,0,5,22,28,44,48, 46,33,21,12,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,6,12,36,61, 85,95,78,56,48,49,65,57,47,78,135,181,226,235,224,217, 239,172,151,151,185,142,62,9,12,28,48,53,42,23,6,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,5,10,20,24,20,16, 16,12,0,4,21,43,56,40,39,64,78,126,141,102,92,235, 242,159,151,185,227,180,93,67,107,137,121,72,26,9,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,24,123,222,231,204,179,157,135,119,102,86,72,58, 48,39,31,23,18,12,10,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,6,12,17,22,29,37,46,56,68, 80,96,112,131,151,174,197,224,232,147,49,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,2,3,10,6,9,2, 0,0,0,0,10,22,40,53,56,44,22,28,130,225,243,241, 221,187,188,108,110,117,58,42,48,58,68,67,65,45,36,16, 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,5,16,35,25,50,36,57, 54,61,75,93,107,100,92,95,102,90,90,146,225,251,251,247, 247,224,211,203,122,48,40,69,93,86,68,40,27,16,10,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,3,11,13, 26,46,50,56,46,32,34,41,60,67,81,116,154,177,137,213, 246,219,233,222,171,147,160,151,105,44,13,3,9,10,0,2, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,30,131,228,227,202,177,153,134,114,96,82,71,57, 48,38,30,22,18,12,5,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,4,12,14,20,28,36,45,56,66, 80,96,112,128,149,171,195,220,236,155,57,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,2,3,16,16,44,34, 59,72,64,66,61,50,42,39,54,83,107,107,85,149,237,251, 246,227,183,204,187,153,157,154,143,117,89,51,38,23,16,6, 3,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,5,13,10,38,24,70, 94,105,122,129,139,140,154,158,158,163,173,171,190,235,251,251, 251,246,201,136,133,151,141,135,109,79,50,26,13,2,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,3,10,38,58,88,119,123,107,105,108,144,191,223,231,236, 251,251,245,216,192,153,89,47,38,43,36,32,22,13,0,2, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,36,135,231,227,201,175,152,133,113,96,80,70,56, 46,37,28,22,16,12,4,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,4,12,14,20,28,34,44,54,64, 80,96,112,128,148,169,194,219,239,161,61,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,31,44,59,76,88,102,114,124,129,147,204,230,221,242,251, 251,245,249,232,194,169,141,98,70,63,44,21,18,16,3,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,3,15,27,38,50,75,93,105,130,164,184,205,229,249,251, 251,242,200,189,179,118,61,27,3,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,10,18, 18,18,18,24,30,30,47,70,97,121,135,169,237,251,251,251, 251,251,251,249,212,160,142,127,124,114,98,79,74,39,19,24, 33,26,16,3,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,36,137,231,227,201,175,152,133,112,96,80,70,56, 46,36,28,22,16,12,4,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,4,12,14,20,27,34,44,54,64, 80,96,112,128,148,169,193,219,239,162,61,0,0,0,0,0, 0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,6, 35,35,40,63,73,68,84,116,127,139,170,214,243,251,251,251, 251,247,212,157,129,129,142,150,138,125,106,57,47,59,43,24, 10,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,3,17,29,60,89,120,144,174,203,215,239,245, 251,247,214,165,113,64,42,27,8,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,10,18, 18,18,20,37,53,56,64,88,120,139,180,219,248,251,251,251, 251,251,242,243,243,208,181,166,151,130,117,102,83,68,57,48, 47,24,16,3,0,0,4,0,0,0,0,0,0,0,0,0, 0,0,0,35,132,229,227,201,176,153,134,114,96,82,70,56, 47,38,29,22,17,12,4,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,4,12,14,20,28,35,44,55,65, 80,96,112,128,149,170,195,220,238,156,59,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,0,3,27,41,56,76,106,158,193,193,183,210,248,251,251, 251,235,240,208,159,96,46,23,18,25,28,26,25,30,33,29, 36,18,16,24,0,2,3,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5, 23,42,67,88,112,154,163,202,237,247,232,189,150,177,163,218, 251,250,231,175,125,103,96,94,87,82,62,45,30,11,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,4,6,7,22, 31,36,42,44,51,50,57,85,132,167,212,211,215,213,232,251, 251,251,229,170,155,147,143,134,135,129,124,104,82,65,37,25, 9,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,26,126,224,229,203,178,156,135,118,99,84,72,58, 48,39,30,23,18,12,10,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,4,12,17,22,28,36,46,56,68, 80,96,112,129,151,172,196,223,233,150,51,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6, 18,26,29,48,62,75,96,107,109,106,113,137,214,245,239,251, 251,206,153,179,174,145,122,102,64,32,12,0,0,0,0,0, 0,0,0,6,0,2,3,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,2,8,10,25,42,68,80, 99,114,117,122,122,140,150,170,158,127,76,91,162,107,109,191, 247,244,194,148,124,78,49,42,40,42,47,58,76,79,55,30, 14,8,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,4,6,7,12, 11,3,0,0,6,31,60,102,128,126,128,147,137,171,245,251, 245,239,243,175,104,58,58,61,52,53,56,47,45,52,42,36, 23,16,3,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,20,113,214,234,206,182,159,136,120,104,88,72,62, 49,40,32,25,20,13,11,2,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,12,18,23,30,39,48,57,71, 82,98,114,134,152,176,200,227,231,137,40,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,6, 15,21,38,50,43,28,32,49,68,79,101,143,215,204,214,218, 233,237,112,75,130,136,111,81,88,82,68,49,26,11,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,2,2,20,18,14,24,28,31,30, 40,48,77,96,94,81,64,43,18,22,101,153,80,30,132,158, 229,203,192,94,76,100,72,37,18,16,14,0,0,4,18,19, 21,21,20,9,4,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,3,14,32,52,71,82,65,58,80,84,52,110,209,234,221, 226,199,225,189,123,86,38,12,14,18,14,10,9,4,0,0, 6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,12,99,199,238,211,186,163,142,123,105,90,76,64, 53,43,35,28,21,16,12,6,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,4,12,14,20,26,33,41,49,61,72, 88,104,120,136,158,180,204,231,223,124,24,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,12, 23,15,14,3,12,37,53,48,59,62,83,145,174,141,222,157, 159,225,158,35,48,88,97,99,63,49,60,60,50,44,38,20, 8,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,3,8,21,43, 48,57,52,27,14,0,2,3,35,100,106,40,3,78,94,152, 238,153,181,127,56,28,60,61,43,21,3,0,0,0,0,0, 0,0,0,3,4,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,8, 18,18,37,57,52,33,20,35,56,26,8,68,131,165,178,144, 174,173,152,192,135,88,71,34,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,3,81,177,242,217,191,168,147,128,112,96,80,68, 56,47,37,30,24,19,13,11,4,0,0,0,0,0,0,0, 0,0,0,0,0,2,11,12,18,22,29,35,45,55,64,78, 90,106,123,142,163,185,210,236,202,105,16,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,2, 0,0,10,31,43,27,33,50,30,48,95,121,117,127,222,105, 82,184,164,89,7,34,69,55,79,68,33,30,46,44,34,25, 32,26,13,4,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,3,16,21,25,26, 17,8,0,0,0,0,9,48,81,58,16,0,20,106,38,168, 243,144,156,133,95,39,6,38,46,33,25,10,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,16, 31,42,37,20,3,17,36,22,3,3,50,84,110,129,106,74, 127,168,103,141,146,102,65,58,43,7,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,60,155,235,223,197,174,152,133,116,99,86,72, 60,51,41,35,27,21,16,12,11,4,0,0,0,0,0,0, 0,0,0,0,2,8,12,16,20,27,32,39,48,57,70,81, 96,112,128,147,168,191,217,242,179,84,5,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 9,25,32,16,13,37,34,6,26,74,78,126,62,145,190,76, 51,133,164,104,45,0,24,60,36,45,62,47,15,17,34,38, 20,12,16,20,9,2,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,8,8,7,2,0, 0,0,0,0,0,14,48,58,21,5,0,0,68,65,19,178, 195,171,102,161,86,71,28,0,18,38,22,16,6,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,2,12,26,34, 21,5,0,3,22,20,5,0,0,42,54,58,87,86,56,52, 99,139,102,85,117,100,77,50,37,45,18,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,35,131,225,231,205,181,160,140,122,106,91,79, 65,55,47,38,31,26,20,16,12,11,5,2,0,0,0,0, 0,0,0,4,11,12,16,20,24,29,37,44,53,63,75,88, 102,118,135,154,176,199,224,236,155,60,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,19, 21,11,2,20,33,14,0,7,53,52,110,58,57,130,146,57, 25,87,139,91,74,16,0,16,54,27,16,31,45,31,5,8, 22,32,19,7,2,2,2,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,10,35,33,5,0,0,0,16,96,15,26,150, 144,177,54,155,98,63,60,20,0,5,24,25,3,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,2,9,22,18,11,0, 0,0,4,9,5,0,0,0,31,48,26,58,54,58,28,40, 81,100,108,52,86,86,67,59,41,18,38,24,3,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,14,100,195,240,214,189,168,147,129,112,98,85, 72,62,52,43,37,29,24,20,16,13,12,10,6,4,4,4, 4,4,10,12,12,16,20,24,29,35,42,49,58,69,81,94, 109,126,142,162,184,208,233,219,124,29,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,6,10,6, 0,4,23,18,3,0,5,45,36,76,71,18,57,117,117,35, 14,52,110,88,63,50,3,0,7,46,27,3,8,24,34,17, 2,3,12,22,12,7,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,4,20,12,2,0,0,0,0,62,66,0,26,123, 98,135,42,87,127,59,46,50,12,0,0,10,14,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,8,6,2,0,0,0, 0,0,0,0,0,0,0,25,45,10,37,44,42,35,16,22, 60,89,102,42,60,70,59,54,43,37,8,22,32,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,68,162,237,224,199,177,156,138,122,106,91, 79,68,58,50,42,35,29,25,21,19,14,12,12,12,12,12, 12,12,12,14,18,20,24,29,35,40,48,56,65,77,89,102, 116,133,152,172,194,217,241,183,92,10,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 4,13,4,0,0,3,35,27,46,76,11,20,55,98,82,28, 9,27,72,89,52,52,27,0,0,5,36,26,2,0,5,20, 25,8,0,0,3,8,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,2,6,0,0,0,0,0,14,96,19,0,28,106, 80,102,56,26,124,65,48,31,46,7,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,18,40,5,20,33,27,42,16,4,5, 32,81,79,66,24,57,65,36,50,31,28,5,10,20,13,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,32,123,214,235,210,187,166,147,130,115,100, 87,76,66,56,48,42,35,31,27,23,20,19,17,14,14,14, 14,17,18,20,22,27,29,35,40,46,54,63,73,85,97,110, 126,142,162,181,204,230,231,146,55,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,0,0,0,3,32,21,24,72,22,0,16,42,94,59,24, 7,18,55,74,56,36,43,5,0,0,3,25,28,3,0,0, 7,21,12,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,58,70,0,0,35,90, 75,77,52,12,76,96,33,41,23,37,3,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,12,37,6,5,15,24,15,39,0,0,0, 14,80,52,79,18,49,43,62,21,47,22,12,0,3,12,6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,7,84,172,239,222,199,178,157,139,124,109, 97,85,74,64,56,49,43,37,33,29,27,24,22,20,20,20, 20,22,23,26,29,32,37,42,48,54,62,72,82,93,107,122, 137,154,172,194,216,241,195,105,19,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,28,22,9,56,34,0,0,14,38,98,38,22, 0,10,39,59,61,27,30,31,0,0,0,0,18,25,3,0, 0,0,6,9,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,9,89,22,0,0,40,78, 62,63,37,15,28,95,43,29,23,20,29,2,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,5,32,5,0,5,10,13,21,21,0,0,0, 0,78,42,69,35,16,48,33,39,14,41,7,2,3,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,39,128,215,236,212,190,171,153,133,122, 107,94,83,74,65,58,51,45,41,37,33,31,29,28,28,27, 28,28,30,33,35,39,44,49,56,63,72,82,92,104,116,131, 147,164,186,206,230,230,149,62,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,18,19,3,38,34,3,0,2,11,39,94,19,16, 0,0,20,41,58,32,17,30,11,0,0,0,0,12,13,3, 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,45,63,0,0,0,34,47, 56,55,34,12,4,60,62,13,32,10,19,20,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,2,25,5,0,0,0,10,2,28,9,0,0,0, 0,72,40,60,47,3,36,23,29,17,15,35,5,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,7,81,166,239,227,203,185,163,147,131, 117,107,93,85,75,67,60,55,49,45,41,39,37,36,34,34, 35,36,39,41,45,48,53,58,65,73,82,92,102,116,129,145, 162,179,198,221,240,187,102,20,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,11,14,0,22,33,3,0,0,0,12,41,82,3,0, 0,0,15,28,45,40,9,9,28,2,0,0,0,0,3,15, 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,7,66,15,0,0,0,16,16, 42,44,33,12,0,24,56,19,8,26,0,15,6,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,2,3,0,0,0,0,0,7,20,0,0,0,0, 0,56,38,45,51,17,7,40,7,25,5,16,28,3,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,30,115,197,241,219,197,179,163,147, 131,117,107,96,87,79,71,65,60,55,51,48,46,45,44,44, 44,46,48,49,55,57,63,69,77,85,93,104,116,128,140,155, 173,195,213,237,218,134,52,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,7,7,0,8,29,5,0,0,0,0,10,39,56,0,0, 0,0,5,15,34,42,10,0,15,14,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,34,44,0,0,0,3,29,16, 28,29,21,11,0,4,40,34,3,10,8,0,5,6,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,9,0,0,0,0,0,0,0,8,8,0,0,0,0, 0,40,46,27,44,28,0,22,23,5,19,0,13,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,3,60,141,220,236,214,195,179,163, 147,131,120,108,99,91,83,76,71,65,63,58,56,56,54,54, 55,56,57,61,64,70,75,81,89,97,107,116,129,140,155,171, 189,211,231,232,161,80,8,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,6,0,2,22,3,0,0,0,0,0,10,31,28,0,0, 0,0,0,0,27,33,23,0,0,10,2,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,5,53,12,0,0,0,0,5,3, 0,14,14,0,0,0,16,32,9,0,12,5,0,5,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,2,0,0,0,0,0,0,0,2,0,0,0,0,0, 0,27,51,17,40,34,3,3,32,5,3,2,0,0,6,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,11,82,159,231,234,211,195,179, 163,147,133,124,114,104,96,89,83,79,73,72,68,66,64,64, 65,68,71,72,78,81,88,94,102,110,122,131,145,155,171,188, 207,227,240,179,104,27,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,15,7,0,0,0,0,0,0,0,25,12,0,0, 0,0,0,0,14,20,35,0,0,3,5,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,23,34,0,0,0,0,0,0,0, 0,14,20,0,0,0,3,21,16,0,0,2,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,12,45,2,36,25,14,0,15,19,0,0,0,0,11,7, 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,24,97,173,236,231,211,195, 179,163,149,139,129,120,111,104,97,92,88,84,80,80,80,80, 80,80,82,88,90,96,102,109,116,126,137,147,162,173,189,207, 227,239,191,118,39,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,6,7,0,0,0,0,0,0,0,0,21,3,0,0, 0,0,0,0,3,12,27,13,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,3,34,6,0,0,0,0,0,0,0, 0,7,13,0,0,0,0,10,16,2,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,30,3,29,22,11,0,0,23,7,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,33,107,178,237,233,213, 197,181,170,155,146,135,128,120,112,106,104,98,96,96,96,96, 96,96,98,104,106,112,118,126,133,142,154,164,179,195,211,227, 239,195,125,51,3,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,2,11,0,0,0, 0,0,0,0,0,6,12,23,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,12,18,0,0,0,0,0,0,0,0, 0,3,18,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,16,6,15,20,14,3,0,7,12,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,36,107,174,231,235, 219,203,188,175,164,154,144,136,129,125,120,116,112,112,112,112, 112,112,114,120,123,128,135,142,152,162,172,186,198,213,231,240, 191,125,54,5,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,27,3,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,16,3,0,0,0,0,0,0,0,0, 16,0,6,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,10,8,5,23,8,7,0,0,9,5,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,34,102,165,223, 241,225,210,196,186,174,164,156,150,143,136,134,131,128,128,128, 128,129,134,136,142,147,154,162,172,181,194,206,221,237,232,179, 118,51,5,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,12,9,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,6,8,0,0,0,0,0,0,0,0,0, 16,0,6,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,2,2,0,20,4,2,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,27,88,145, 204,241,233,220,208,196,186,177,170,163,158,154,151,149,148,148, 149,151,152,158,163,168,176,184,194,204,216,230,240,218,161,104, 39,3,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,2,11,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,12,0,0,0,0,0,0,0,0,0,0, 12,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,2,2,0,10,7,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,14,66, 123,174,223,241,232,220,210,201,193,187,181,176,174,171,169,169, 170,172,176,180,185,191,199,208,217,230,241,230,187,134,80,27, 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,6,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,5, 36,90,138,184,225,241,235,226,218,212,205,202,197,195,194,193, 195,196,200,204,210,217,224,233,241,231,195,149,102,52,8,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,12,51,95,136,175,211,233,242,238,233,227,224,220,219,219, 220,223,227,231,236,242,236,219,183,146,105,62,20,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,14,45,83,116,147,173,197,216,228,232,236,239,239, 238,233,231,223,202,179,155,124,92,55,19,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,5,22,52,78,102,120,135,147,155,161,162, 156,150,137,124,105,84,60,29,10,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,3,13,24,39,49,57,61,61, 59,51,40,24,16,5,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,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,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,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,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,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,2,4,6,8,10,10,10,10, 10,10,10,6,5,2,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,8,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,4,8,11,13,14,16,17,18,18,18,18, 18,18,18,16,15,13,11,8,5,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,1,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,2,8,11,14,17,19,20,22,24,25,26,26,26,26, 26,26,25,24,22,21,19,17,15,12,8,2,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,2,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, 2,8,12,15,19,21,24,26,28,30,32,33,34,34,34,34, 34,34,33,32,30,29,27,25,22,19,17,13,8,2,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,2,6,6,5, 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,3,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,6, 12,16,19,23,26,29,31,34,36,38,40,40,42,42,42,42, 42,42,41,40,38,36,35,32,29,27,23,20,17,13,8,2, 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,3,15,28,48,63,73,83,85,86,84, 77,64,50,31,18,5,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,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,2,12,19,24,30,36,36, 35,26,20,12,3,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,2,11,15, 19,23,27,30,33,36,39,42,44,46,47,48,50,50,50,50, 50,50,49,48,46,44,42,39,37,34,31,27,24,20,16,11, 5,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,2,18,44,76,102,126,143,159,172,180,186,187,182, 174,163,149,129,108,84,52,22,5,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,10,29,54,77,96,112,123,131,135,137, 132,126,113,99,81,60,35,14,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,6,13,17,21, 27,29,33,37,41,44,47,49,51,53,55,56,58,58,58,58, 58,58,57,56,54,52,50,47,45,41,38,35,31,27,23,19, 13,8,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,5,28,69,107,139,171,197,222,226,225,227,222,218,218,220, 227,227,227,222,203,179,147,116,77,38,7,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,4,24,60,92,124,149,173,191,207,222,228,231,231, 229,224,214,199,177,155,131,100,68,32,7,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,8,13,19,24,28, 33,37,41,45,47,51,54,57,59,61,63,64,66,66,66,66, 66,66,64,63,62,60,57,55,52,49,45,41,37,33,29,25, 20,15,11,2,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,2, 28,73,119,158,196,226,227,209,183,161,144,133,124,117,117,123, 129,143,159,177,203,225,227,207,168,128,84,36,5,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,4,30,73,114,151,187,219,236,247,247,246,245,243,243,243, 243,245,245,247,246,238,225,195,162,123,84,39,7,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,9,15,20,25,29,35, 39,43,47,51,55,59,61,65,67,69,71,72,74,74,74,74, 74,74,72,71,69,67,65,62,59,55,53,49,45,40,36,31, 27,21,16,11,2,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,13,59, 111,159,206,229,212,175,141,114,88,65,48,32,25,22,22,24, 31,44,62,82,108,133,167,203,228,216,171,124,72,23,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 20,68,116,162,204,235,247,245,242,239,238,236,233,233,233,233, 233,233,235,237,239,241,244,247,239,214,172,128,81,30,3,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,9,16,21,27,32,37,41, 45,51,55,59,62,66,69,71,75,77,78,80,82,82,82,82, 82,82,80,79,77,75,73,69,67,63,59,55,51,47,43,37, 32,27,21,16,11,2,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,28,87,142, 195,228,207,163,121,84,50,22,8,0,0,0,0,0,0,0, 0,0,0,4,18,42,76,112,152,196,231,210,156,101,42,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,46, 101,154,203,239,246,242,239,236,232,230,228,225,224,223,223,223, 223,223,225,227,230,231,234,238,242,246,244,215,166,115,60,11, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,9,16,21,27,32,37,43,48, 53,57,61,65,69,73,76,79,82,84,86,88,89,90,90,90, 90,90,88,87,85,83,80,77,74,70,67,62,59,53,49,44, 38,34,28,22,16,11,2,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,4,4,4, 4,2,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,3,42,105,167,220, 218,170,121,74,32,6,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,3,24,63,109,156,210,226,181,121,58, 7,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,12,66,128, 183,231,248,242,238,234,230,226,223,220,217,215,215,214,213,213, 213,215,215,217,220,222,225,229,232,236,241,246,240,197,141,82, 24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,6,14,21,27,32,37,43,48,53, 59,64,68,72,77,80,83,87,89,92,94,96,97,98,98,98, 98,98,96,94,92,90,87,84,81,77,73,69,65,60,55,51, 45,40,34,28,21,16,11,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,2,4,7,10,10,10,10,10, 10,10,10,8,4,4,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,5,53,120,183,231,197, 139,85,35,5,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,2,24,72,126,183,229,199,135, 71,9,0,0,0,0,0,0,0,0,0,0,0,0,10,0, 0,0,0,0,0,0,0,0,0,0,0,0,21,81,143,207, 245,244,238,234,229,224,220,216,214,210,208,207,205,204,203,203, 203,205,206,207,210,213,216,220,224,228,232,238,243,246,220,159, 97,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,5,13,19,26,32,37,43,50,54,60, 65,69,75,79,83,87,91,94,97,100,102,104,105,106,106,106, 106,105,104,102,100,98,95,91,88,84,80,75,71,67,61,56, 51,45,40,34,27,21,15,6,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,4,8,10,12,12,12,12,12,12,12, 12,12,12,12,12,10,8,4,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,5,55,125,192,230,177,119, 58,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,5,44,104,161,222,209, 142,72,9,0,0,0,0,0,0,0,0,0,0,0,8,0, 0,0,0,0,0,0,0,0,0,0,0,24,89,156,221,248, 242,236,230,225,220,216,211,207,204,200,199,197,194,193,193,193, 193,194,196,198,200,203,206,210,214,219,224,229,234,240,246,233, 173,107,36,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,2,11,19,24,31,37,43,49,54,61,67, 71,77,81,85,91,93,98,101,105,107,109,111,113,114,114,114, 114,113,112,110,108,105,102,99,95,91,87,83,77,72,67,61, 56,51,45,38,32,27,19,13,5,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,4,8,11,12,12,12,14,14,18,18,18,18, 18,18,15,14,13,12,12,11,8,4,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,2,48,123,194,225,168,104,39, 3,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,27,88,152,218, 212,140,68,7,0,0,0,0,0,0,0,0,0,0,3,0, 0,0,0,0,0,0,0,0,0,0,21,89,159,225,247,240, 234,228,222,216,211,206,202,198,194,191,189,186,184,183,183,183, 183,184,186,188,191,194,198,200,206,210,215,220,226,232,239,245, 237,178,107,34,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,8,16,23,29,35,43,48,54,61,67,72, 77,83,88,92,97,101,105,109,111,115,117,119,121,122,122,122, 122,121,120,118,115,113,109,106,101,99,93,88,83,78,73,67, 61,56,50,43,37,31,24,18,11,2,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,2,5,11,12,12,13,16,18,20,20,20,20,22,22, 21,20,20,20,19,18,14,12,12,11,8,2,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,35,113,190,227,167,97,30,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,18,80,148, 219,207,133,56,3,0,0,0,0,0,0,0,0,0,4,0, 0,0,0,0,0,0,0,0,0,12,81,156,225,247,239,233, 226,220,214,208,203,198,193,190,184,182,179,176,175,174,173,173, 174,175,176,178,182,184,188,192,196,202,206,212,218,224,231,237, 244,237,174,102,27,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,5,13,21,27,34,40,47,53,59,66,72,77, 83,88,93,99,103,108,112,116,119,122,125,127,128,129,129,129, 129,128,127,125,123,119,117,113,109,104,100,95,90,85,78,73, 67,61,55,48,43,35,29,21,15,8,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,2,8,12,12,13,16,19,20,21,23,26,26,28,28,28, 28,27,26,24,22,20,20,18,14,12,12,8,4,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,21,96,175,231,173,99,29,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,16,81, 153,223,195,118,36,0,0,0,0,0,0,0,0,0,10,0, 0,0,0,0,0,0,0,0,5,66,143,221,247,239,231,225, 218,212,206,200,194,189,184,180,176,172,169,167,165,164,163,163, 164,165,167,168,172,175,179,184,188,193,198,204,210,217,223,231, 237,245,233,165,88,14,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,11,17,25,31,37,45,51,59,64,70,77,83, 88,94,99,105,109,115,119,123,126,128,131,134,135,137,137,137, 137,136,134,132,130,127,123,120,115,111,107,101,96,91,85,78, 72,67,59,53,46,40,33,27,19,12,2,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,8,12,12,14,19,20,22,26,28,28,30,32,34,34,34, 34,32,30,29,28,26,23,20,19,16,13,12,11,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,6,74,155,227,185,111,33,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,20, 90,167,231,175,95,16,0,0,0,0,0,0,0,0,11,0, 0,0,0,0,0,0,0,0,46,128,207,248,240,233,225,218, 211,204,198,192,186,180,176,171,167,163,160,158,156,153,153,153, 153,155,157,159,162,166,170,174,179,184,190,196,203,209,217,223, 231,238,246,223,145,66,5,0,0,0,0,0,0,0,0,0, 0,0,0,2,14,21,28,35,43,49,56,63,69,75,83,88, 93,100,106,111,116,121,125,128,132,136,139,141,143,145,145,145, 145,143,142,140,137,134,130,127,123,117,112,107,101,96,90,83, 77,71,64,57,51,44,37,29,23,15,8,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, 8,12,13,16,20,21,25,28,29,33,35,37,38,40,40,40, 40,39,37,36,34,31,28,26,21,20,18,13,12,11,5,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,43,128,211,208,128,48,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, 28,107,188,224,148,64,3,0,0,0,0,0,0,0,6,0, 0,0,0,0,0,0,0,20,101,183,245,242,234,226,218,211, 204,197,190,184,178,172,166,162,158,154,150,148,145,143,143,143, 143,145,148,150,152,156,160,166,171,176,182,189,195,202,209,217, 224,232,240,248,204,123,36,0,0,0,0,0,0,0,0,0, 0,0,0,0,16,25,32,39,45,53,60,67,73,80,87,93, 99,106,112,117,123,127,131,136,140,144,146,149,151,153,153,153, 153,151,149,147,144,140,136,132,128,123,117,112,107,101,94,88, 83,75,69,61,55,48,41,34,27,19,12,2,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,8, 12,13,16,20,22,27,29,33,36,39,42,44,46,48,48,48, 48,46,45,43,39,37,35,29,28,24,20,19,13,12,11,4, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,14,92,179,226,154,71,6,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,51,132,218,200,115,29,0,0,0,0,0,0,0,3,0, 0,0,0,0,0,0,4,68,154,231,244,236,228,220,212,204, 197,189,183,176,170,164,158,153,148,144,142,138,135,135,133,133, 135,135,137,140,144,148,152,157,162,168,175,181,188,195,202,210, 218,226,234,242,244,174,90,12,0,0,0,0,0,0,0,0, 0,0,0,0,15,28,35,43,50,57,64,71,77,85,91,98, 104,110,117,123,128,132,138,142,146,150,154,156,159,160,161,161, 161,159,157,154,152,148,143,138,133,129,123,117,112,106,99,93, 85,79,73,65,59,51,45,37,29,23,15,5,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,12, 12,16,20,24,28,31,35,39,43,45,49,52,54,56,56,56, 56,55,53,50,47,43,40,36,32,28,24,20,19,13,12,8, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,51,139,223,187,102,23,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,7,81,165,229,161,73,5,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,30,116,203,248,238,230,222,214,206,198, 190,183,175,169,162,156,150,144,140,136,132,128,127,126,124,124, 126,127,128,130,134,138,144,149,154,161,167,173,181,188,196,204, 212,220,228,236,245,223,138,51,0,0,0,0,0,0,0,0, 0,0,0,0,12,31,39,45,53,61,67,75,82,89,95,102, 109,115,122,128,132,138,143,148,154,158,161,164,166,168,169,169, 169,167,164,162,158,154,150,146,140,135,129,123,117,110,104,97, 91,83,77,69,62,55,47,41,33,26,18,11,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,5,11,12, 16,20,24,28,32,36,40,45,49,53,57,61,64,65,66,66, 65,64,61,58,55,51,45,43,37,32,28,24,20,16,12,12, 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,13,94,184,224,140,53,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,33,119,207,206,116,27,0,0,0,0,0,0,4,0, 0,0,0,0,0,4,73,162,239,242,234,225,216,208,200,192, 184,176,169,161,155,148,142,136,131,127,123,120,118,115,114,114, 114,117,119,122,127,130,135,140,147,153,159,167,175,182,190,198, 206,214,222,232,240,245,184,95,14,0,0,0,0,0,0,0, 0,0,0,0,8,34,41,49,57,63,71,78,85,93,99,107, 113,120,126,132,138,143,149,155,160,164,168,172,174,176,177,177, 177,175,172,170,164,162,156,151,146,140,133,128,122,115,108,101, 94,87,80,73,65,59,51,43,36,28,21,13,2,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,2,10,12,14, 19,21,27,32,36,42,46,51,57,61,65,71,73,75,78,78, 75,73,71,67,63,58,53,48,43,37,32,28,24,20,16,12, 11,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,42,132,220,187,97,15,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,5,74,164,229,156,64,0,0,0,0,0,0,3,0, 0,0,0,0,0,24,114,204,246,238,229,220,211,203,194,186, 178,170,162,155,147,141,134,128,123,119,113,111,107,105,104,104, 105,107,110,113,117,122,127,133,139,146,153,160,168,176,184,192, 200,209,218,226,236,244,225,136,45,0,0,0,0,0,0,0, 0,0,0,0,5,37,44,52,59,67,74,81,89,96,103,111, 117,124,130,137,143,149,155,161,166,171,175,179,182,184,185,185, 184,182,180,176,172,167,162,156,151,145,138,132,125,119,112,105, 98,91,83,76,69,61,53,46,38,31,23,15,6,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,5,12,12,18, 20,27,29,36,41,46,53,59,65,70,76,80,84,87,88,88, 88,85,81,77,71,66,60,54,48,43,37,32,27,21,19,13, 12,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,3,76,170,227,147,56,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,33,125,218,194,100,14,0,0,0,0,0,3,0, 0,0,0,0,0,60,151,235,242,234,224,216,206,198,189,180, 172,164,156,148,141,133,128,121,115,110,105,101,97,96,95,94, 96,97,101,104,109,114,120,126,132,139,146,154,162,170,178,187, 196,204,214,222,231,240,246,175,83,5,0,0,0,0,0,0, 0,0,0,0,5,39,46,54,62,69,77,84,92,99,107,114, 121,128,134,140,148,154,161,167,172,178,182,186,189,192,193,193, 192,190,187,183,178,173,167,162,156,149,143,136,130,123,115,109, 101,93,86,79,71,63,56,49,41,33,25,18,10,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,2,10,12,14,20, 24,28,35,40,45,53,59,66,72,79,86,91,96,98,102,102, 98,96,92,87,81,74,68,61,54,48,41,36,29,26,20,16, 12,11,4,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,18,108,203,204,112,22,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,10,91,181,223,131,35,0,0,0,0,0,3,0, 0,0,0,0,10,92,187,247,239,230,220,211,202,193,184,176, 166,158,150,142,134,128,120,114,107,101,97,92,88,86,85,84, 86,88,91,95,100,106,112,118,126,132,140,148,156,165,174,182, 191,200,208,218,227,236,246,211,116,22,0,0,0,0,0,0, 0,0,0,0,5,41,49,56,64,72,79,87,95,102,109,117, 124,130,138,146,152,159,165,172,178,183,188,194,196,199,201,201, 200,197,194,190,185,179,173,167,160,154,146,140,132,126,119,111, 104,97,89,81,74,66,58,51,43,35,27,20,12,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,4,12,12,18,21, 27,31,37,44,51,58,66,73,81,88,95,103,108,112,113,113, 112,110,104,97,90,83,75,67,60,53,45,39,33,28,22,19, 13,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,42,137,227,173,80,5,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,56,149,227,161,66,0,0,0,0,0,2,0, 0,0,0,0,29,124,219,245,236,226,216,207,198,190,180,171, 162,153,144,136,128,121,114,106,99,93,87,83,79,77,74,74, 75,79,81,87,92,98,104,112,119,127,134,142,152,160,168,178, 186,196,206,214,224,232,242,235,147,52,0,0,0,0,0,0, 0,0,0,0,5,43,50,58,66,74,82,89,97,105,112,119, 127,134,141,148,156,163,170,176,183,188,194,199,204,207,209,209, 208,204,201,196,191,185,178,172,164,158,150,142,136,128,122,114, 107,99,91,83,76,68,60,52,44,37,29,21,13,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,8,12,14,20,23, 28,35,41,47,55,63,71,80,89,98,107,115,121,127,128,128, 128,122,117,109,100,92,82,74,65,57,49,43,36,29,26,20, 16,12,10,2,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,65,161,227,147,52,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,29,124,219,185,90,8,0,0,0,0,2,0, 0,0,0,0,54,149,236,242,232,223,214,204,194,184,176,167, 158,148,140,131,123,115,107,99,92,85,79,74,70,66,64,64, 65,69,73,78,84,90,98,105,113,121,128,138,146,156,164,174, 183,192,202,211,221,230,239,245,173,78,3,0,0,0,0,0, 0,0,0,0,5,44,52,60,68,76,83,91,99,107,114,122, 129,136,144,152,158,166,174,180,188,194,200,205,210,214,217,217, 215,212,207,202,196,188,182,176,168,161,154,146,138,131,124,116, 108,101,93,85,77,70,62,54,46,38,30,22,14,4,0,0, 0,0,0,0,0,0,0,0,0,0,2,10,12,16,20,26, 30,37,44,51,59,68,78,87,97,107,117,127,134,141,143,143, 143,135,128,120,110,100,89,79,71,61,53,45,39,33,27,21, 18,12,11,4,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,7,88,183,222,126,29,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,14,101,198,207,112,19,0,0,0,0,1,0, 0,0,0,2,77,173,247,239,230,220,210,200,191,182,172,163, 154,144,136,127,119,110,101,93,85,78,72,65,61,57,55,55, 56,59,64,70,76,83,91,99,108,116,125,134,142,152,160,170, 180,190,199,208,217,228,238,247,197,102,13,0,0,0,0,0, 0,0,0,0,6,45,53,61,69,77,84,92,100,108,116,124, 131,139,146,154,162,169,177,184,192,198,204,212,218,222,224,225, 222,218,212,207,200,194,186,178,171,163,156,148,140,133,126,118, 110,102,94,86,78,71,63,55,47,39,32,24,16,6,0,0, 0,0,0,0,0,0,0,0,0,0,4,11,12,18,21,28, 33,39,47,55,63,73,83,94,105,117,128,138,148,157,160,160, 159,150,140,130,119,108,97,86,75,65,57,49,41,35,28,22, 19,13,12,4,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,16,104,199,201,104,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,3,80,177,223,128,31,0,0,0,0,0,0, 0,0,0,12,96,191,247,238,228,217,208,199,189,179,169,160, 150,142,132,123,113,105,97,87,79,72,64,57,52,47,46,45, 47,51,56,62,69,77,85,95,103,112,121,128,138,148,158,167, 176,186,196,206,215,225,234,245,216,120,24,0,0,0,0,0, 0,0,0,0,6,46,54,62,70,78,86,94,102,110,118,125, 132,140,148,155,163,171,179,187,194,202,210,216,223,228,232,233, 229,224,218,211,204,196,188,181,173,165,157,150,142,134,127,119, 112,104,96,88,80,72,64,56,48,40,32,24,16,6,0,0, 0,0,0,0,0,0,0,0,0,0,4,12,13,19,22,28, 35,42,49,57,67,77,88,100,112,125,137,149,163,173,179,179, 175,164,154,140,127,115,103,89,80,69,59,51,43,36,30,25, 20,14,12,7,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,21,119,215,187,89,8,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,64,163,227,142,44,0,0,0,0,1,0, 0,0,0,19,112,207,246,236,225,215,207,197,186,176,167,158, 148,138,128,120,111,101,92,83,74,65,57,50,43,39,35,34, 37,42,48,56,63,71,81,89,99,108,118,127,135,145,154,165, 175,184,193,204,214,223,233,243,229,135,39,0,0,0,0,0, 0,0,0,0,6,46,54,62,70,78,86,94,102,110,118,126, 133,141,149,157,165,173,181,189,196,204,212,219,227,234,239,240, 236,228,221,214,206,198,191,183,175,167,159,151,143,135,128,120, 112,104,96,88,80,72,64,56,48,40,32,24,16,6,0,0, 0,0,0,0,0,0,0,0,0,0,5,12,14,20,23,29, 36,43,51,59,70,80,90,104,118,129,145,161,175,187,198,199, 192,179,163,149,134,120,106,95,82,72,62,53,45,37,30,26, 20,14,12,10,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,27,128,226,176,79,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,54,152,226,152,53,0,0,0,0,0,0, 0,0,0,24,123,222,245,233,224,215,205,194,184,175,165,156, 145,135,127,118,107,97,88,79,70,61,52,43,36,29,25,24, 28,34,42,49,58,67,77,87,96,105,114,125,134,143,152,162, 173,183,192,201,213,222,231,241,236,147,49,0,0,0,0,0, 0,0,0,0,6,46,54,62,70,78,86,94,102,110,118,126, 133,141,149,157,165,173,181,189,197,205,213,221,229,237,244,246, 239,231,223,215,207,199,191,183,175,167,159,151,143,135,128,120, 112,104,96,88,80,72,64,56,48,40,32,24,16,6,0,0, 0,0,0,0,0,0,0,0,0,0,7,12,14,20,25,30, 36,44,52,62,72,81,95,105,120,135,151,167,185,203,218,220, 205,189,173,154,137,124,111,96,86,73,64,54,46,38,32,26, 20,15,12,10,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,35,132,226,170,71,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,45,146,226,158,60,0,0,0,0,0,0, 0,0,0,30,131,228,243,233,223,214,204,193,183,174,164,153, 143,135,126,115,105,96,86,77,66,57,47,39,29,22,16,16, 20,27,36,45,55,64,73,83,94,104,112,122,132,142,151,161, 171,181,191,201,211,221,231,241,239,155,57,0,0,0,0,0, 0,0,0,0,6,46,54,62,70,78,86,94,102,110,118,126, 133,141,149,157,165,173,181,189,197,205,212,220,228,235,242,242, 236,230,222,214,206,199,191,183,175,167,159,151,143,135,128,120, 112,104,96,88,80,72,64,56,48,40,32,24,16,6,0,0, 0,0,0,0,0,0,0,0,0,0,7,12,14,20,26,30, 36,44,52,62,72,82,96,107,120,135,151,170,191,210,231,236, 215,195,175,159,143,128,112,96,86,74,64,54,46,38,32,26, 20,18,12,10,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,36,137,227,165,68,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,44,141,227,162,62,0,0,0,0,2,0, 0,0,0,36,135,231,243,233,223,213,203,193,183,173,163,153, 143,133,124,114,104,95,85,74,64,55,46,35,25,16,6,5, 15,23,32,42,53,62,72,82,92,102,112,122,131,141,151,160, 170,181,191,199,209,221,231,239,241,161,61,0,0,0,0,0, 0,0,0,0,6,46,54,62,70,78,86,94,102,110,118,126, 133,140,148,156,164,172,179,187,195,202,210,218,224,229,234,235, 231,226,219,212,204,197,189,181,173,166,158,150,142,135,128,120, 112,104,96,88,80,72,64,56,48,40,32,24,16,6,0,0, 0,0,0,0,0,0,0,0,0,0,7,12,14,20,26,30, 36,44,52,62,72,81,95,106,120,135,151,168,186,205,221,225, 211,192,174,157,139,126,112,96,86,73,64,54,46,38,32,26, 20,17,12,10,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,36,135,227,170,69,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,44,143,227,159,60,0,0,0,0,2,0, 0,0,0,36,137,231,243,233,223,213,203,193,183,173,163,153, 143,133,124,114,104,94,84,74,64,55,45,34,24,16,5,2, 13,23,32,42,52,62,72,82,92,102,112,122,131,141,151,160, 169,181,191,199,209,221,231,239,241,162,61,0,0,0,0,0, 0,0,0,0,6,46,54,61,69,77,85,93,100,108,116,124, 131,139,147,154,162,170,178,185,192,200,206,212,218,223,226,227, 224,220,214,208,202,194,187,179,172,164,156,149,141,133,126,118, 110,102,95,87,79,71,63,56,48,40,32,24,16,6,0,0, 0,0,0,0,0,0,0,0,0,0,7,12,14,20,24,29, 36,44,51,60,70,80,92,104,119,132,147,163,179,193,202,206, 195,181,166,151,135,120,108,96,82,72,63,54,45,38,30,26, 20,14,12,10,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,30,129,226,174,77,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,51,150,227,154,55,0,0,0,0,2,0, 0,0,0,35,132,229,243,233,223,213,203,193,183,174,164,153, 143,135,126,114,105,96,86,75,65,56,47,37,28,20,15,13, 18,26,35,45,54,64,73,83,93,103,112,122,132,141,151,161, 171,181,191,201,211,221,231,240,241,156,59,0,0,0,0,0, 0,0,0,0,5,44,52,60,68,76,84,92,99,107,115,123, 129,137,145,152,160,167,174,182,188,195,202,207,212,216,219,219, 217,213,209,203,196,190,184,176,169,162,154,146,139,131,124,117, 109,101,93,86,78,70,62,54,46,38,30,22,15,5,0,0, 0,0,0,0,0,0,0,0,0,0,4,12,13,20,22,28, 35,42,50,58,67,79,88,100,113,127,139,153,164,177,183,184, 179,169,155,142,128,117,104,92,80,71,61,52,44,36,30,25, 20,14,12,8,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,24,120,219,184,88,7,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,63,159,225,144,47,0,0,0,0,2,0, 0,0,0,26,126,224,245,233,223,215,205,194,184,175,165,155, 145,135,127,117,107,97,88,79,69,59,51,42,34,27,23,23, 26,32,40,49,57,67,75,85,95,104,114,124,133,143,152,162, 173,183,191,201,212,222,231,241,237,150,51,0,0,0,0,0, 0,0,0,0,5,43,51,59,66,74,82,90,97,105,113,121, 128,134,142,149,156,164,170,178,184,191,196,202,206,209,211,211, 209,206,202,197,191,186,179,172,166,158,152,144,136,129,122,115, 107,99,92,84,76,68,60,53,45,37,29,22,14,4,0,0, 0,0,0,0,0,0,0,0,0,0,4,12,12,18,22,28, 34,40,47,55,64,73,84,95,107,119,130,140,152,160,167,167, 161,155,144,132,121,109,97,87,76,67,57,49,42,35,28,22, 20,14,12,5,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,16,106,207,199,102,14,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,2,78,175,227,131,31,0,0,0,0,3,0, 0,0,0,20,113,214,245,235,225,215,206,196,186,176,167,157, 148,137,128,119,110,101,91,81,73,64,56,48,42,36,32,32, 35,40,46,54,62,71,79,89,97,107,117,127,135,144,154,164, 174,183,193,204,213,223,232,242,232,137,40,0,0,0,0,0, 0,0,0,0,5,41,49,57,65,72,80,87,95,103,110,117, 125,132,139,146,154,160,166,172,179,185,190,194,198,201,203,203, 202,200,196,191,186,180,175,168,162,154,148,140,133,127,119,112, 105,97,89,82,74,67,59,51,43,36,28,20,12,0,0,0, 0,0,0,0,0,0,0,0,0,0,2,10,12,18,20,26, 31,37,45,53,61,70,79,89,99,109,120,129,137,143,149,151, 145,139,131,123,112,102,92,81,71,63,55,47,39,33,28,21, 18,12,12,4,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,8,90,189,215,120,24,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,11,96,191,214,114,20,0,0,0,0,4,0, 0,0,0,12,99,199,247,237,227,217,207,198,188,178,168,159, 150,140,130,122,113,104,95,87,78,70,62,56,49,45,42,42, 45,49,54,60,68,76,84,93,102,111,120,128,138,148,157,167, 176,185,196,206,215,224,234,245,223,124,24,0,0,0,0,0, 0,0,0,0,5,39,47,55,62,70,77,85,93,100,107,115, 122,128,135,142,148,156,162,167,173,179,184,188,191,194,195,195, 194,192,188,185,180,175,170,164,156,150,144,138,130,124,117,109, 101,94,87,79,72,64,57,49,41,34,26,18,10,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,8,12,14,20,24, 29,36,42,49,57,65,73,82,92,101,109,117,125,128,133,134, 129,127,119,111,102,94,84,76,67,59,51,43,37,30,26,20, 16,12,10,2,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,72,167,226,141,46,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,23,118,213,191,96,12,0,0,0,0,2,0, 0,0,0,3,81,177,246,239,230,220,210,200,191,182,172,162, 152,144,134,127,117,109,100,92,84,76,69,63,58,55,53,52, 54,57,62,68,74,82,90,98,106,115,124,132,142,150,160,169, 178,188,198,207,217,226,237,247,202,105,16,0,0,0,0,0, 0,0,0,0,4,37,45,52,60,67,75,83,89,97,104,111, 118,125,131,138,144,151,156,162,167,172,178,180,184,186,187,187, 186,184,182,178,174,170,164,158,152,146,140,132,127,120,113,106, 99,91,84,77,69,61,54,47,39,31,24,16,8,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,5,12,13,19,21, 28,33,38,45,51,59,67,75,83,91,99,105,112,114,120,120, 116,112,107,100,93,85,77,69,61,53,47,40,35,28,22,20, 14,12,8,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,48,143,228,169,74,3,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,50,145,228,167,72,0,0,0,0,0,3,0, 0,0,0,0,60,155,238,241,231,222,213,203,194,184,175,166, 156,148,138,130,122,114,106,98,90,83,77,71,67,64,62,62, 64,67,71,76,82,88,96,104,112,120,128,136,145,154,164,173, 182,191,200,210,220,230,239,246,179,84,5,0,0,0,0,0, 0,0,0,0,4,35,42,50,57,65,71,79,86,93,101,107, 115,121,128,132,140,146,151,156,162,166,170,173,176,178,179,179, 178,177,174,171,167,162,157,153,146,140,135,128,123,116,109,101, 95,88,81,73,67,59,51,44,37,29,21,14,4,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,2,10,12,16,20, 24,29,35,41,47,53,61,68,74,81,87,95,97,103,104,104, 104,100,95,89,84,76,70,62,56,49,43,36,30,27,20,18, 12,11,4,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,22,116,211,195,104,18,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,5,80,173,227,139,44,0,0,0,0,0,3,0, 0,0,0,0,35,131,225,244,234,225,216,206,198,188,179,170, 160,152,144,135,127,120,112,104,98,91,85,81,77,73,72,72, 73,75,79,84,90,96,102,110,118,126,133,142,150,158,168,176, 186,195,204,214,223,232,242,239,155,60,0,0,0,0,0,0, 0,0,0,0,4,31,39,47,53,61,69,75,83,89,97,103, 109,117,123,128,134,140,146,150,155,159,163,166,168,170,171,171, 171,169,166,164,160,156,151,146,140,135,130,125,117,112,105,99, 91,85,77,70,63,55,49,41,34,27,19,11,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,5,12,13,19, 21,27,31,37,43,48,54,61,67,73,78,82,87,89,90,90, 89,88,84,79,73,68,62,56,50,44,37,32,28,22,20,14, 12,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,5,84,179,225,139,47,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,26,116,207,202,108,18,0,0,0,0,0,2,0, 0,0,0,0,14,100,195,247,238,229,220,210,200,192,184,174, 166,157,149,140,133,126,118,112,105,99,95,89,87,83,82,82, 83,85,89,93,98,104,110,117,124,131,138,147,155,164,172,181, 190,199,208,216,226,236,246,219,124,29,0,0,0,0,0,0, 0,0,0,0,3,29,36,43,51,58,65,72,79,85,93,99, 105,112,117,123,129,134,139,144,148,152,156,158,161,162,163,163, 163,161,159,156,154,148,146,140,135,130,125,120,113,107,101,93, 87,81,73,67,59,53,45,37,31,23,16,8,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,2,10,12,14, 20,23,28,32,37,43,48,53,59,63,68,72,76,79,80,80, 79,77,73,69,65,60,55,50,44,38,35,28,24,20,16,12, 11,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,51,142,226,176,87,9,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,2,64,154,228,164,75,3,0,0,0,0,0,2,0, 0,0,0,0,0,68,162,239,242,232,224,214,206,196,188,179, 171,162,154,147,139,132,126,119,113,108,103,99,96,94,92,92, 93,95,97,102,106,112,118,124,130,137,145,152,160,168,177,186, 194,203,212,222,230,239,246,183,92,10,0,0,0,0,0,0, 0,0,0,0,3,25,33,40,47,53,61,68,75,81,88,94, 101,107,112,117,123,128,132,138,141,145,148,151,153,155,155,155, 155,153,152,149,146,142,138,134,130,125,120,115,108,101,96,89, 83,77,69,63,56,49,42,35,27,20,13,2,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,5,12,12, 16,20,24,28,32,37,43,47,51,55,59,63,65,67,70,70, 68,66,64,61,57,53,48,43,38,35,29,26,20,19,13,12, 8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,18,104,193,218,129,42,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,23,108,196,216,127,34,0,0,0,0,0,0,2,0, 0,0,0,0,0,32,123,214,246,236,228,219,210,202,193,184, 176,168,161,153,146,139,132,127,121,116,112,108,105,104,102,102, 103,104,107,111,115,120,126,131,137,143,151,159,166,174,182,191, 200,208,216,226,234,244,233,146,55,0,0,0,0,0,0,0, 0,0,0,0,2,22,29,36,43,51,57,63,69,77,83,89, 96,101,107,112,117,123,127,130,134,138,140,143,145,147,147,147, 147,145,144,141,138,136,132,128,123,119,114,109,102,96,91,85, 78,72,65,59,52,45,37,31,24,17,8,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,2,8,12, 13,19,20,24,28,32,36,40,44,47,51,54,56,58,58,58, 58,57,55,52,49,45,41,37,33,29,27,21,19,13,12,10, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,63,150,227,175,90,12,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,4,68,154,229,173,84,7,0,0,0,0,0,0,1,0, 0,0,0,0,0,7,84,172,244,241,232,224,215,206,198,190, 182,175,167,159,153,146,140,134,128,125,121,118,114,112,112,112, 112,114,117,120,124,128,133,138,145,151,159,165,173,180,188,196, 205,213,222,230,238,248,195,105,19,0,0,0,0,0,0,0, 0,0,0,0,2,19,25,32,39,45,53,59,66,72,77,84, 91,96,101,107,111,116,121,125,128,130,133,136,137,139,139,139, 139,138,136,134,131,128,125,121,117,112,107,102,97,91,85,80, 74,67,61,53,47,41,35,27,20,13,2,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,10, 12,13,19,20,24,28,31,35,37,41,44,46,48,50,50,50, 50,48,47,44,42,38,35,32,28,24,21,19,14,12,11,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,20,105,191,222,140,57,3,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,35,120,203,212,126,38,0,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,39,128,215,246,238,229,220,212,204,196, 189,181,173,167,160,154,148,142,138,134,128,127,125,122,122,122, 122,124,127,128,132,136,142,147,152,159,165,172,179,187,194,202, 210,218,227,235,244,232,149,62,0,0,0,0,0,0,0,0, 0,0,0,0,1,15,21,28,35,41,48,54,61,67,72,78, 85,91,95,100,105,109,113,117,121,124,127,128,129,131,131,131, 131,130,128,127,125,122,119,115,111,107,101,96,91,85,80,75, 69,62,56,50,43,37,29,23,16,8,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5, 11,12,13,18,20,22,27,28,31,35,36,38,40,42,42,42, 42,41,39,37,35,33,29,27,24,20,19,14,12,11,5,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,55,140,221,194,113,33,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, 18,94,174,230,162,77,7,0,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,7,81,166,240,243,234,226,218,210,203, 195,188,181,175,168,162,156,152,146,142,138,135,134,132,131,131, 132,133,135,138,142,145,150,155,160,166,173,179,186,193,201,209, 216,224,232,240,245,187,102,20,0,0,0,0,0,0,0,0, 0,0,0,0,0,11,17,24,30,37,43,50,56,61,67,74, 78,84,89,93,99,103,107,110,114,117,119,121,122,124,124,124, 124,123,122,119,117,115,111,107,103,99,95,91,85,80,75,69, 63,57,51,45,38,32,25,19,12,2,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,11,12,13,16,20,21,24,27,28,30,33,34,35,36,36, 35,34,33,30,28,27,25,21,20,18,13,12,11,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,12,87,169,231,173,95,21,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,8, 73,151,223,190,108,28,0,0,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,0,30,115,197,246,240,232,224,217,209, 202,195,188,182,176,170,165,160,156,152,148,145,143,142,141,141, 141,143,144,148,150,154,158,164,168,174,180,187,193,201,207,215, 223,230,238,246,218,134,52,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,2,13,19,26,32,38,45,51,56,61,67, 72,77,83,87,91,96,99,103,107,109,111,113,115,116,116,116, 116,115,114,112,109,107,103,101,97,93,88,84,79,75,69,64, 58,51,45,40,34,27,21,14,6,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,5,10,12,12,14,18,20,21,22,26,27,28,28,28,28, 28,28,27,26,23,21,20,19,16,12,12,11,5,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,33,112,191,223,157,82,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,7,64, 137,215,209,133,52,0,0,0,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,0,3,60,141,220,246,239,231,223,217, 209,202,196,190,184,178,174,168,164,160,158,154,152,151,151,151, 151,152,154,157,160,164,168,172,177,182,188,194,201,207,215,221, 229,236,244,234,161,80,8,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,6,14,21,27,33,39,45,51,56,61, 67,72,77,81,85,89,93,95,99,101,104,106,107,108,108,108, 108,107,106,104,102,99,97,93,90,85,83,77,73,68,62,58, 52,46,40,35,29,22,16,9,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,2,8,11,12,12,14,18,20,20,20,22,22,22,22, 22,22,20,20,20,18,16,13,12,12,8,4,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,2,52,128,206,219,150,80,17,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,7,62,132, 204,219,149,72,7,0,0,0,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,0,0,11,82,159,233,245,237,231,223, 217,210,204,198,192,187,182,178,174,170,167,165,162,161,160,160, 161,162,164,167,169,173,176,181,186,191,196,202,209,215,221,228, 236,243,242,179,104,27,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,9,16,21,27,34,40,45,51,56, 61,65,69,75,77,82,85,89,91,94,96,98,99,100,100,100, 100,100,98,96,94,92,89,86,83,79,75,71,67,61,56,51, 45,40,35,29,24,18,11,2,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,5,10,12,12,12,14,14,18,18,18,20,20, 19,18,18,16,14,12,12,12,10,5,2,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,6,65,140,212,217,150,86,23, 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,12,68,134,202, 222,158,85,14,0,0,0,0,0,0,0,0,0,0,3,0, 0,0,0,0,0,0,0,0,0,24,97,173,237,244,237,231, 224,218,212,206,200,196,191,186,183,180,176,175,173,171,170,169, 171,173,174,176,178,182,186,190,194,200,205,210,216,223,229,236, 243,244,191,118,39,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,2,11,16,22,28,34,39,44,49, 53,59,63,67,71,75,78,81,84,86,88,90,91,92,92,92, 92,92,90,89,87,84,82,79,75,72,68,64,59,55,51,45, 40,35,29,24,19,12,2,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,2,5,10,11,12,12,12,12,12,13,14, 12,12,12,12,12,12,10,5,2,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,9,72,142,211,220,159,96, 36,4,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,27,82,143,207,222, 159,90,22,0,0,0,0,0,0,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0,0,0,33,107,178,237,245,238, 232,226,220,214,209,204,200,196,192,190,186,184,183,181,181,181, 181,183,183,185,188,191,195,199,203,208,213,218,224,230,236,243, 244,195,125,51,3,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,2,11,16,22,27,33,37,43, 47,52,56,60,64,67,71,74,76,78,80,82,83,84,84,84, 84,84,82,81,79,77,75,71,68,65,61,57,53,49,44,39, 35,29,24,19,13,3,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,2,4,7,10,10,11,12,12,12, 12,12,10,10,8,4,2,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,9,71,137,201,228,175, 120,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,12,51,105,161,219,217,153, 88,23,0,0,0,0,0,0,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,0,0,0,0,0,36,107,174,233,246, 240,234,228,222,218,214,208,206,202,199,196,193,192,191,191,191, 191,191,193,196,198,200,204,208,212,216,222,227,232,238,244,242, 191,125,54,5,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,2,11,16,21,27,32,37, 41,45,49,53,57,60,63,66,69,71,73,74,76,76,76,76, 76,76,74,73,71,69,67,64,61,58,54,51,46,43,37,33, 28,23,18,13,3,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,2,4,4,4,4, 4,4,4,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,8,64,128,185,231, 202,148,100,52,16,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,41,87,136,188,231,201,142,80, 20,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,0,0,0,0,0,0,34,102,165,223, 248,242,236,232,226,222,218,214,211,208,206,204,201,201,199,199, 201,201,204,206,207,210,214,216,222,226,230,235,240,246,234,179, 118,51,5,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,2,11,16,21,25,29, 35,39,43,46,50,53,56,59,61,63,65,66,68,68,68,68, 68,68,66,65,64,61,59,57,53,51,47,43,39,35,31,27, 21,17,11,3,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,5,48,106,163, 218,226,185,140,99,60,28,10,0,0,0,0,0,0,0,0, 0,0,0,0,5,20,52,89,129,174,219,221,176,121,64,9, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,27,88,145, 204,244,245,240,236,231,227,224,221,217,215,214,213,211,209,209, 211,212,213,215,217,220,223,226,230,234,238,244,245,218,161,104, 39,3,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,2,8,13,19,23, 27,31,35,39,43,45,49,51,53,55,57,58,60,60,60,60, 60,60,59,58,56,54,52,49,46,43,39,37,33,29,24,20, 15,11,2,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,28,80, 131,181,224,224,190,154,119,90,64,40,24,17,12,10,10,11, 16,22,36,58,84,111,143,180,219,228,193,145,93,38,5,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,66, 123,174,223,245,244,240,236,232,230,228,225,223,222,221,221,221, 221,222,223,224,226,230,232,236,239,244,248,232,187,134,80,27, 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,6,12,17, 21,25,29,31,35,38,41,43,46,48,49,50,52,52,52,52, 52,52,51,50,48,46,44,42,39,36,33,29,25,21,17,13, 8,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,7, 46,95,139,182,220,228,211,185,159,137,120,108,99,93,92,97, 105,120,135,153,179,205,228,223,192,150,106,60,16,0,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,5, 36,90,138,184,225,246,246,242,239,238,234,233,231,231,231,231, 231,231,232,234,237,239,242,246,246,233,195,149,102,52,8,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,2,11, 13,17,21,25,28,31,33,36,38,40,42,42,44,44,44,44, 44,44,43,42,40,38,36,34,31,29,25,22,19,15,11,5, 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,15,50,91,129,163,195,221,226,227,219,207,198,194,193,196, 204,215,227,226,223,203,171,138,101,60,20,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,12,51,95,136,175,211,235,245,247,245,243,241,241,239,239, 240,241,242,245,247,246,239,219,183,146,105,62,20,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, 5,11,13,17,21,23,26,28,30,32,34,35,36,36,36,36, 36,36,35,34,32,31,29,27,24,21,19,15,11,5,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,11,35,68,100,126,149,167,183,197,204,211,211,207, 199,187,174,153,131,108,76,44,16,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,14,45,83,116,147,173,197,216,229,236,239,241,241, 241,237,232,223,202,179,155,124,92,55,19,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,5,10,13,15,18,20,22,24,26,27,28,28,28,28, 28,28,27,26,25,23,21,19,17,13,11,5,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,14,30,52,72,88,98,107,110,112,108, 101,89,74,56,35,18,3,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,5,22,52,78,102,120,135,147,155,161,162, 156,150,137,124,105,84,60,29,10,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,2,6,11,13,15,16,18,19,20,20,20,20, 20,20,20,18,17,15,13,11,8,4,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,7,12,16,18,18,17, 13,8,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,14,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,3,13,24,39,49,57,61,61, 59,51,40,24,16,5,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,2,5,6,10,11,12,12,11,10, 10,10,10,8,7,4,3,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,4,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,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,2,5,8,7,4, 3,3,2,2,2,1,0,0,0,0,2,8,12,14,10,5, 1,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,1,1,1,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 } ; unsigned char *_ssgaGetLensFlareTexture () { return lens_flare_texture ; } plib-1.8.5/src/ssgAux/ssgaFire.cxx0000644000175000001440000002072110765364435013737 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "ssg.h" #include "ssgAux.h" #define EMBER_SCALE 3.0f void _ssgaFireParticleCreate ( ssgaParticleSystem *ps, int idx, ssgaParticle *p ) { ((ssgaFire *) ps) -> createParticle ( idx, p ) ; } void _ssgaFireParticleUpdate ( float, ssgaParticleSystem *ps, int idx, ssgaParticle *p ) { ((ssgaFire *) ps) -> updateParticle ( idx, p ) ; } void ssgaFire::reInit () { setCreationRate ( (float)(getNumParticles()) / max_ttl ) ; delete colourTable ; delete sizeTable ; tableSize = (int)( 10.0f * max_ttl ) ; colourTable = new float [ tableSize * 4 ] ; sizeTable = new float [ tableSize ] ; sgCopyVec4 ( & colourTable [ 0 ], hot_colour ) ; sizeTable [ 0 ] = start_size ; for ( int i = 1 ; i < tableSize ; i++ ) { sizeTable [ i ] = sizeTable [ i-1 ] * 1.06f ; if ( sizeTable [ i ] >= 1.5 ) sizeTable [ i ] = 1.5 ; sgScaleVec3 ( & colourTable [ i * 4 ], & colourTable [ (i-1)* 4 ], 0.90f ) ; colourTable [ i * 4 + 3 ] = 1.0f ; } } void ssgaFire::createParticle ( int idx, ssgaParticle *p ) { float xx = (float)(rand()%1000)/500.0f * radius - radius ; float yy = (float)sqrt ( radius * radius - xx * xx ) ; yy = (float)(rand()%1000)/500.0f * yy - yy ; p -> time_to_live = max_ttl ; p -> size = sizeTable [ 0 ] ; sgCopyVec4 ( p -> col, & colourTable [ 0 ] ) ; if ( (idx & 3) != 0 ) { sgSetVec3 ( p -> pos, xx, yy, -p->size ) ; sgSetVec3 ( p -> vel, 0, 0, upward_speed ) ; } else { p->size *= EMBER_SCALE ; sgSetVec3 ( p -> pos, xx, yy, 0.0f ) ; sgSetVec3 ( p -> vel, 0, 0, 0 ) ; } sgSetVec3 ( p -> acc, 0, 0, 0 ) ; } void ssgaFire::updateParticle ( int idx, ssgaParticle *p ) { int tick = (int)( ( max_ttl - p->time_to_live ) * 10.0f ) ; if ( tick >= tableSize ) { p->time_to_live = 0.0f ; return ; } if ( (idx & 3) != 0 ) p -> size = sizeTable [ tick ] ; else p -> size = sizeTable [ tick ] * EMBER_SCALE ; sgCopyVec4 ( p -> col, & colourTable [ tick * 4 ] ) ; } static ssgSimpleState *fireState = NULL ; static ssgTexture *fireTexture = NULL ; static bool isfogged = true ; static int preFireDraw ( ssgEntity * ) { isfogged = ( glIsEnabled ( GL_FOG ) == GL_TRUE ) ; if ( isfogged ) glDisable ( GL_FOG ) ; glBlendFunc ( GL_ONE, GL_ONE ) ; return TRUE ; } static int postFireDraw ( ssgEntity * ) { glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; if ( isfogged ) glEnable ( GL_FOG ) ; return TRUE ; } ssgaFire::ssgaFire ( int num, float _radius, float height, float speed ) : ssgaParticleSystem ( num/2, 0, 0, // <== Don't Change this!! TRUE, 1.0f, height * 2.0f, _ssgaFireParticleCreate, _ssgaFireParticleUpdate ) { radius = _radius ; upward_speed = speed ; start_size = 0.6f ; if ( fireState == NULL ) { /* The texture constructor deletes the texture from main memory after it's finished with it!! YIKES!! */ unsigned char *t = new unsigned char [ 32 * 32 ] ; memcpy ( t, _ssgaGetFireTexture(), 32 * 32 ) ; fireTexture = new ssgTexture ( "NONE", t, 32, 32, 1 ) ; fireState = new ssgSimpleState () ; fireState -> setTexture ( fireTexture ) ; fireState -> setTranslucent () ; fireState -> enable ( GL_TEXTURE_2D ) ; fireState -> enable ( GL_BLEND ) ; fireState -> disable ( GL_LIGHTING ) ; fireState -> ref () ; } tableSize = 0 ; colourTable = NULL ; sizeTable = NULL ; sgSetVec4 ( hot_colour, 1.0f, 0.2f, 0.1f, 1.0f ) ; setHeight ( height ) ; /* Forces a reInit */ setState ( fireState ) ; setCallback ( SSG_CALLBACK_PREDRAW , preFireDraw ) ; setCallback ( SSG_CALLBACK_POSTDRAW, postFireDraw ) ; update ( 2.0f * max_ttl / (float)(getNumParticles()) ) ; } void ssgaFire::update ( float t ) { ssgaParticleSystem::update ( t ) ; } unsigned char *_ssgaGetFireTexture () ; ssgaFire::~ssgaFire () { tableSize = 0 ; delete [] colourTable ; delete [] sizeTable ; } static unsigned char fuzzyBlob [] = { 0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,5,4,3,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,1,5,9,14,17,19,20,20,20,17,14,10,5,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,5,12,19,25,29,33,35,36,37,36,33,30,25,20,13,6,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,2,10,19,27,34,40,45,48,51,52,53,51,49,45,40,35,28,20,11,3,0,0,0,0,0,0, 0,0,0,0,0,4,13,23,33,41,48,55,60,64,67,69,69,67,65,61,56,49,42,34,25,15,5,0,0,0,0,0, 0,0,0,0,4,14,26,36,46,55,63,70,75,80,83,85,85,83,80,76,70,64,56,47,37,27,16,5,0,0,0,0, 0,0,0,2,13,26,37,48,59,68,77,84,91,95,99,101,101,99,96,91,85,78,69,60,50,39,27,15,3,0,0,0, 0,0,1,10,23,36,48,60,71,81,90,99,105,111,115,117,117,115,111,106,100,92,82,72,61,50,38,25,12,1,0,0, 0,0,5,19,33,46,59,71,83,94,104,113,120,126,130,133,133,131,127,121,114,105,95,84,72,60,47,34,21,7,0,0, 0,1,12,27,41,55,68,81,94,105,116,126,134,141,146,149,149,147,142,135,127,118,107,95,83,70,56,43,29,14,2,0, 0,5,19,34,48,63,77,90,104,116,128,139,148,156,162,165,165,162,157,149,140,129,118,105,92,78,64,50,36,21,6,0, 0,9,25,40,55,70,84,99,113,126,139,151,161,170,177,181,181,178,171,163,152,140,128,114,100,86,72,57,42,27,11,0, 1,14,29,45,60,75,91,105,120,134,148,161,173,184,192,196,197,193,185,175,163,150,136,122,107,92,77,62,47,31,16,2, 3,17,33,48,64,80,95,111,126,141,156,170,184,196,206,212,212,207,197,185,172,158,143,128,113,97,82,66,50,35,19,4, 4,19,35,51,67,83,99,115,130,146,162,177,192,206,219,227,228,220,208,194,179,163,148,132,117,101,85,69,53,37,21,5, 5,20,36,52,69,85,101,117,133,149,165,181,196,212,227,241,242,229,214,198,182,167,151,135,119,103,87,71,54,38,22,6, 5,20,37,53,69,85,101,117,133,149,165,181,197,212,228,242,243,230,214,199,183,167,151,135,119,103,87,71,55,39,22,6, 4,20,36,51,67,83,99,115,131,147,162,178,193,207,220,229,230,221,209,194,179,164,148,133,117,101,85,69,53,38,22,6, 3,17,33,49,65,80,96,111,127,142,157,171,185,197,208,214,214,209,199,187,173,159,144,129,113,98,82,67,51,35,19,4, 1,14,30,45,61,76,91,106,121,135,149,163,175,185,194,198,199,194,187,176,164,151,137,123,108,93,78,63,47,32,16,2, 0,10,25,40,56,70,85,100,114,127,140,152,163,172,179,182,183,179,173,164,154,142,129,115,101,87,72,57,42,27,12,1, 0,5,20,35,49,64,78,92,105,118,129,140,150,158,163,167,167,164,159,151,142,131,119,106,93,79,65,51,36,22,7,0, 0,1,13,28,42,56,69,82,95,107,118,128,136,143,148,151,151,148,144,137,129,119,108,96,84,71,57,44,30,15,2,0, 0,0,6,20,34,47,60,72,84,95,105,114,122,128,132,135,135,133,129,123,115,106,96,85,74,61,49,35,22,8,0,0, 0,0,1,11,25,37,50,61,72,83,92,100,107,113,117,119,119,117,113,108,101,93,84,74,63,51,39,26,13,2,0,0, 0,0,0,3,15,27,39,50,60,70,78,86,92,97,101,103,103,101,98,93,87,79,71,61,51,40,28,16,4,0,0,0, 0,0,0,0,5,16,27,38,47,56,64,72,77,82,85,87,87,85,82,78,72,65,57,49,39,28,17,6,0,0,0,0, 0,0,0,0,0,5,15,25,34,43,50,57,62,66,69,71,71,69,67,63,57,51,44,35,26,16,6,0,0,0,0,0, 0,0,0,0,0,0,3,12,21,29,36,42,47,50,53,54,55,53,51,47,42,36,30,22,13,4,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,7,14,21,27,31,35,37,38,39,38,35,32,27,22,15,8,2,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,2,6,11,16,19,21,22,22,22,19,16,12,7,2,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,2,4,5,6,6,6,4,2,1,0,0,0,0,0,0,0,0,0,0,0 } ; unsigned char *_ssgaGetFireTexture () { return fuzzyBlob ; } plib-1.8.5/src/ssgAux/Makefile.am0000644000175000001440000000270610765364435013507 00000000000000if BUILD_SSGAUX lib_LIBRARIES = libplibssgaux.a include_HEADERS = ssgAux.h \ ssgaShapes.h \ ssgaLensFlare.h \ ssgaParticleSystem.h \ ssgaWaveSystem.h \ ssgaScreenDump.h \ ssgaSky.h \ ssgaSphere.h \ ssgaFire.h \ ssgaBillboards.h libplibssgaux_a_SOURCES = ssgAux.cxx \ ssgaShapes.cxx \ ssgaPatch.cxx \ ssgaParticleSystem.cxx \ ssgaWaveSystem.cxx \ ssgaLensFlare.cxx \ ssgaLensFlareTexture.cxx \ ssgaFire.cxx \ ssgaScreenDump.cxx \ ssgaSphere.cxx \ ssgaCelestialBody.cxx \ ssgaCloudLayer.cxx \ ssgaStars.cxx \ ssgaSkyDome.cxx \ ssgaSky.cxx \ ssgaTeapot.cxx \ ssgaBillboards.cxx INCLUDES = -I$(top_srcdir)/src/sg -I$(top_srcdir)/src/ssg INCLUDES += -I$(top_srcdir)/src/util endif EXTRA_DIST = ssgAux.dsp plib-1.8.5/src/ssgAux/ssgAux.cxx0000644000175000001440000000262210765364435013446 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgAux.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgAux.h" static ssgBase *createCube () { return new ssgaCube ( 0 ) ; } static ssgBase *createSphere () { return new ssgaSphere ( 0 ) ; } static ssgBase *createCylinder () { return new ssgaCylinder ( 0 ) ; } void ssgaInit () { ssgRegisterType ( ssgaTypeCube () , createCube ) ; ssgRegisterType ( ssgaTypeSphere () , createSphere ) ; ssgRegisterType ( ssgaTypeCylinder () , createCylinder ) ; } plib-1.8.5/src/ssgAux/ssgaWaveSystem.h0000644000175000001440000000702310765364435014606 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "ssgaShapes.h" typedef float (* ssgaWSDepthCallback ) ( float x, float y ) ; #define SSGA_MAX_WAVETRAIN 16 class ssgaWaveTrain { float height ; float length ; float lambda ; float speed ; float heading; public: ssgaWaveTrain () { height = 0.5f ; length = 0.8f ; lambda = 1.0f ; speed = (float) sqrt ( 2.0f/3.0f ) ; heading = 0.0f ; } float getSpeed () { return speed ; } void setSpeed ( float h ) { speed = h ; } float getLength () { return length ; } void setLength ( float h ) { length = h ; } float getLambda () { return lambda ; } void setLambda ( float h ) { lambda = h ; } float getHeading () { return heading ; } void setHeading ( float h ) { heading = h ; } float getWaveHeight () { return height ; } void setWaveHeight ( float h ) { height = h ; } } ; class ssgaWaveSystem : public ssgaShape { ssgaWSDepthCallback gridGetter ; sgVec2 offset ; sgVec3 *normals ; sgVec4 *colours ; sgVec2 *texcoords ; sgVec3 *vertices ; sgVec3 *orig_vertices ; ssgaWaveTrain *train [ SSGA_MAX_WAVETRAIN ] ; float windSpeed ; float windHeading ; float edgeFlatten ; float tu, tv ; int nstrips ; int nstacks ; protected: virtual void copy_from ( ssgaWaveSystem *src, int clone_flags ) ; public: ssgaWaveSystem ( int ntri ) ; virtual ~ssgaWaveSystem () ; virtual ssgBase *clone ( int clone_flags = 0 ) ; virtual void regenerate () ; virtual const char *getTypeName ( void ) ; virtual int load ( FILE * ) ; virtual int save ( FILE * ) ; ssgaWSDepthCallback getDepthCallback () { return gridGetter ; } ssgaWaveTrain *getWaveTrain ( int i ) { return ( i < 0 || i >= SSGA_MAX_WAVETRAIN ) ? NULL : train [ i ] ; } void setWaveTrain ( int i, ssgaWaveTrain *t ) { assert ( i >= 0 && i < SSGA_MAX_WAVETRAIN ) ; train [ i ] = t ; } float getWindSpeed () { return windSpeed ; } float getWindDirn () { return windHeading ; } float getEdgeFlatten () { return edgeFlatten ; } float getTexScaleU () { return tu ; } float getTexScaleV () { return tv ; } void setDepthCallback ( ssgaWSDepthCallback cb ) { gridGetter = cb ; } void setWindSpeed ( float speed ) { windSpeed = speed ; } void setWindDirn ( float dirn ) { windHeading = dirn ; } void setEdgeFlatten ( float dist ) { edgeFlatten = dist ; } void setTexScale ( float u, float v ) { tu = u ; tv = v ; } void setOffset ( sgVec2 _offset ) { sgCopyVec2 ( offset, _offset ) ; } void updateAnimation ( float t ) ; } ; plib-1.8.5/src/ssgAux/ssgaCloudLayer.cxx0000644000175000001440000003443710765364435015126 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaCloudLayer.cxx 1793 2003-08-26 21:36:53Z nmcevoy $ */ // Written by Curtis Olson, started June 2000. // // Moved into ssgAux, July 2003. #include "ssgaSky.h" /* Nautical Miles to Meters */ #define SG_NM_TO_METER 1852.0000 /* Radians to Nautical Miles. 1 nm = 1/60 of a degree */ #define SG_NM_TO_RAD 0.00029088820866572159 /* Nautical Miles to Radians */ #define SG_RAD_TO_NM 3437.7467707849392526 /* For divide by zero avoidance, this will be close enough to zero */ #define SG_EPSILON 0.0000001 void calc_gc_course_dist( const sgVec2& start, const sgVec2& dest, double *course, double *dist ); // make an ssgSimpleState for a cloud layer given the named texture ssgSimpleState *sgCloudMakeState( const char* path ); ssgaCloudLayer::ssgaCloudLayer( void ) : layer_root(new ssgRoot), layer_transform(new ssgTransform), enabled(true), layer_span(0.0), layer_asl(0.0), layer_thickness(0.0), layer_transition(0.0), scale(4000.0), speed(0.0), direction(0.0), last_lon(0.0), last_lat(0.0), last_x(0.0), last_y(0.0) { cl[0] = cl[1] = cl[2] = cl[3] = NULL; vl[0] = vl[1] = vl[2] = vl[3] = NULL; tl[0] = tl[1] = tl[2] = tl[3] = NULL; layer[0] = layer[1] = layer[2] = layer[3] = NULL; layer_root->addKid(layer_transform); } ssgaCloudLayer::~ssgaCloudLayer() { delete layer_root; // deletes layer_transform and layer as well } void ssgaCloudLayer::build( const char *cloud_tex_path, float span, float elevation, float thickness, float transition ) { ssgSimpleState *cloud_state = sgCloudMakeState( cloud_tex_path ); build(cloud_state, span, elevation, thickness, transition); } void ssgaCloudLayer::build( ssgSimpleState *cloud_state, float span, float elevation, float thickness, float transition ) { layer_span = span; layer_asl = elevation; layer_thickness = thickness; layer_transition = transition; scale = 4000.0; last_lon = last_lat = -999.0f; last_x = last_y = 0.0f; sgVec2 base; sgSetVec2( base, (float)ssgaRandom(), (float)ssgaRandom() ); // build the cloud layer sgVec4 color; sgVec3 vertex; sgVec2 tc; const float layer_scale = layer_span / scale; const float mpi = SG_PI/4; const float alt_diff = layer_asl * 1.5f; for (int i = 0; i < 4; i++) { if ( layer[i] != NULL ) { layer_transform->removeKid(layer[i]); // automatic delete } vl[i] = new ssgVertexArray( 10 ); cl[i] = new ssgColourArray( 10 ); tl[i] = new ssgTexCoordArray( 10 ); sgSetVec3( vertex, layer_span*(i-2)/2, -layer_span, (float)(alt_diff * (sin(i*mpi) - 2)) ); sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] ); sgSetVec4( color, 1.0f, 1.0f, 1.0f, (i == 0) ? 0.0f : 0.15f ); cl[i]->add( color ); vl[i]->add( vertex ); tl[i]->add( tc ); for (int j = 0; j < 4; j++) { sgSetVec3( vertex, layer_span*(i-1)/2, layer_span*(j-2)/2, (float)(alt_diff * (sin((i+1)*mpi) + sin(j*mpi) - 2)) ); sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, base[1] + layer_scale * j/4 ); sgSetVec4( color, 1.0f, 1.0f, 1.0f, ( (j == 0) || (i == 3)) ? ( (j == 0) && (i == 3)) ? 0.0f : 0.15f : 1.0f ); cl[i]->add( color ); vl[i]->add( vertex ); tl[i]->add( tc ); sgSetVec3( vertex, layer_span*(i-2)/2, layer_span*(j-1)/2, (float)(alt_diff * (sin(i*mpi) + sin((j+1)*mpi) - 2)) ); sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] + layer_scale * (j+1)/4 ); sgSetVec4( color, 1.0f, 1.0f, 1.0f, ((j == 3) || (i == 0)) ? ((j == 3) && (i == 0)) ? 0.0f : 0.15f : 1.0f ); cl[i]->add( color ); vl[i]->add( vertex ); tl[i]->add( tc ); } sgSetVec3( vertex, layer_span*(i-1)/2, layer_span, (float)(alt_diff * (sin((i+1)*mpi) - 2)) ); sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, base[1] + layer_scale ); sgSetVec4( color, 1.0f, 1.0f, 1.0f, (i == 3) ? 0.0f : 0.15f ); cl[i]->add( color ); vl[i]->add( vertex ); tl[i]->add( tc ); layer[i] = new ssgVtxTable(GL_TRIANGLE_STRIP, vl[i], NULL, tl[i], cl[i]); layer_transform->addKid( layer[i] ); layer[i]->setState( cloud_state ); } // force a repaint of the sky colors with arbitrary defaults repaint( color ); } bool ssgaCloudLayer::repositionFlat( sgVec3 p, double dt ) { sgMat4 T1; // combine p and asl (meters) to get translation offset sgVec3 asl_offset; if ( p[SG_Z] <= layer_asl ) { sgSetVec3( asl_offset, p[SG_X], p[SG_Y], layer_asl ); } else { sgSetVec3( asl_offset, p[SG_X], p[SG_Y], layer_asl + layer_thickness ); } // Translate to elevation sgMakeTransMat4( T1, asl_offset ); sgMat4 TRANSFORM; sgCopyMat4( TRANSFORM, T1 ); sgCoord layerpos; sgSetCoord( &layerpos, TRANSFORM ); layer_transform->setTransform( &layerpos ); // now calculate update texture coordinates double sp_dist = speed*dt; if ( p[SG_X] != last_x || p[SG_Y] != last_y || sp_dist != 0 ) { // calculate cloud movement double ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0; ax = p[SG_X] - last_x; ay = p[SG_Y] - last_y; if (sp_dist > 0) { bx = cos(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist; by = sin(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist; } float xoff = (float)((ax + bx) / (2 * scale)); float yoff = (float)((ay + by) / (2 * scale)); const float layer_scale = layer_span / scale; float *base, *tc; base = tl[0]->get( 0 ); base[0] += xoff; // the while loops can lead to *long* pauses if base[0] comes // with a bogus value. // while ( base[0] > 1.0 ) { base[0] -= 1.0; } // while ( base[0] < 0.0 ) { base[0] += 1.0; } if ( base[0] > -10.0 && base[0] < 10.0 ) { base[0] -= (int)base[0]; } else { base[0] = 0.0; ulSetError(UL_WARNING, "Warning: base1\n"); } base[1] += yoff; // the while loops can lead to *long* pauses if base[0] comes // with a bogus value. // while ( base[1] > 1.0 ) { base[1] -= 1.0; } // while ( base[1] < 0.0 ) { base[1] += 1.0; } if ( base[1] > -10.0 && base[1] < 10.0 ) { base[1] -= (int)base[1]; } else { base[1] = 0.0; ulSetError(UL_WARNING, "Warning: base2\n"); } for (int i = 0; i < 4; i++) { tc = tl[i]->get( 0 ); sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] ); for (int j = 0; j < 4; j++) { tc = tl[i]->get( j*2+1 ); sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, base[1] + layer_scale * j/4 ); tc = tl[i]->get( (j+1)*2 ); sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] + layer_scale * (j+1)/4 ); } tc = tl[i]->get( 9 ); sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, base[1] + layer_scale ); } last_x = p[SG_X]; last_y = p[SG_Y]; } return true; } bool ssgaCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double dt ) { sgMat4 T1, LON, LAT; sgVec3 axis; // combine p and asl (meters) to get translation offset sgVec3 asl_offset; sgCopyVec3( asl_offset, up ); sgNormalizeVec3( asl_offset ); if ( alt <= layer_asl ) { sgScaleVec3( asl_offset, layer_asl ); } else { sgScaleVec3( asl_offset, layer_asl + layer_thickness ); } sgAddVec3( asl_offset, p ); // Translate to zero elevation sgMakeTransMat4( T1, asl_offset ); // Rotate to proper orientation sgSetVec3( axis, 0.0, 0.0, 1.0 ); sgMakeRotMat4( LON, (float)(lon * SGD_RADIANS_TO_DEGREES), axis ); sgSetVec3( axis, 0.0, 1.0, 0.0 ); sgMakeRotMat4( LAT, (float)(90.0 - lat * SGD_RADIANS_TO_DEGREES), axis ); sgMat4 TRANSFORM; sgCopyMat4( TRANSFORM, T1 ); sgPreMultMat4( TRANSFORM, LON ); sgPreMultMat4( TRANSFORM, LAT ); sgCoord layerpos; sgSetCoord( &layerpos, TRANSFORM ); layer_transform->setTransform( &layerpos ); // now calculate update texture coordinates if ( last_lon < -900 ) { last_lon = lon; last_lat = lat; } double sp_dist = speed*dt; if ( lon != last_lon || lat != last_lat || sp_dist != 0 ) { double course = 0.0, dist = 0.0; if ( lon != last_lon || lat != last_lat ) { sgVec2 start, dest; sgSetVec2(start, (float)last_lon, (float)last_lat); sgSetVec2(dest, (float)lon, (float)lat); calc_gc_course_dist( dest, start, &course, &dist ); } // calculate cloud movement double ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0; if (dist > 0.0) { ax = cos(course) * dist; ay = sin(course) * dist; } if (sp_dist > 0) { bx = cos(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist; by = sin(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist; } float xoff = (float)((ax + bx) / (2 * scale)); float yoff = (float)((ay + by) / (2 * scale)); const float layer_scale = layer_span / scale; float *base, *tc; base = tl[0]->get( 0 ); base[0] += xoff; // the while loops can lead to *long* pauses if base[0] comes // with a bogus value. // while ( base[0] > 1.0 ) { base[0] -= 1.0; } // while ( base[0] < 0.0 ) { base[0] += 1.0; } if ( base[0] > -10.0 && base[0] < 10.0 ) { base[0] -= (int)base[0]; } else { base[0] = 0.0; ulSetError(UL_WARNING, "Warning: base1\n"); } base[1] += yoff; // the while loops can lead to *long* pauses if base[0] comes // with a bogus value. // while ( base[1] > 1.0 ) { base[1] -= 1.0; } // while ( base[1] < 0.0 ) { base[1] += 1.0; } if ( base[1] > -10.0 && base[1] < 10.0 ) { base[1] -= (int)base[1]; } else { base[1] = 0.0; ulSetError(UL_WARNING, "Warning: base2\n"); } for (int i = 0; i < 4; i++) { tc = tl[i]->get( 0 ); sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] ); for (int j = 0; j < 4; j++) { tc = tl[i]->get( j*2+1 ); sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, base[1] + layer_scale * j/4 ); tc = tl[i]->get( (j+1)*2 ); sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] + layer_scale * (j+1)/4 ); } tc = tl[i]->get( 9 ); sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, base[1] + layer_scale ); } last_lon = lon; last_lat = lat; } return true; } bool ssgaCloudLayer::repaint( sgVec3 fog_color ) { float *color; for ( int i = 0; i < 4; i++ ) for ( int j = 0; j < 10; ++j ) { color = cl[i]->get( j ); sgCopyVec3( color, fog_color ); } return true; } void ssgaCloudLayer::draw() { if (!enabled) return; ssgCullAndDraw( layer_root ); } ssgSimpleState *sgCloudMakeState( const char* path ) { ssgSimpleState *state = new ssgSimpleState(); state->setTexture( path ); state->setShadeModel( GL_SMOOTH ); state->disable( GL_LIGHTING ); state->disable( GL_CULL_FACE ); state->enable( GL_TEXTURE_2D ); state->enable( GL_COLOR_MATERIAL ); state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); state->enable( GL_BLEND ); state->enable( GL_ALPHA_TEST ); state->setAlphaClamp( 0.01f ); return state; } void calc_gc_course_dist( const sgVec2& start, const sgVec2& dest, double *course, double *dist ) { // d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 + // cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2)) double cos_start_y = cos( start[SG_Y] ); volatile double tmp1 = sin( (start[SG_Y] - dest[SG_Y]) * 0.5 ); volatile double tmp2 = sin( (start[SG_X] - dest[SG_X]) * 0.5 ); double d = 2.0 * asin( sqrt( tmp1 * tmp1 + cos_start_y * cos(dest[SG_Y]) * tmp2 * tmp2)); *dist = d * SG_RAD_TO_NM * SG_NM_TO_METER; // We obtain the initial course, tc1, (at point 1) from point 1 to // point 2 by the following. The formula fails if the initial // point is a pole. We can special case this with: // // IF (cos(lat1) < EPS) // EPS a small number ~ machine precision // IF (lat1 > 0) // tc1= pi // starting from N pole // ELSE // tc1= 0 // starting from S pole // ENDIF // ENDIF // // For starting points other than the poles: // // IF sin(lon2-lon1)<0 // tc1=acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1))) // ELSE // tc1=2*pi-acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1))) // ENDIF // if ( cos(start[SG_Y]) < SG_EPSILON ) { // doing it this way saves a transcendental call double sin_start_y = sin( start[SG_Y] ); if ( fabs(1.0-sin_start_y) < SG_EPSILON ) { // EPS a small number ~ machine precision if ( start[SG_Y] > 0 ) { *course = SGD_PI; // starting from N pole } else { *course = 0; // starting from S pole } } else { // For starting points other than the poles: // double tmp3 = sin(d)*cos_start_y); // double tmp4 = sin(dest[SG_Y])-sin(start[SG_Y])*cos(d); // double tmp5 = acos(tmp4/tmp3); // Doing this way gaurentees that the temps are // not stored into memory double tmp5 = acos( (sin(dest[SG_Y]) - sin_start_y * cos(d)) / (sin(d) * cos_start_y) ); // if ( sin( dest[SG_X] - start[SG_X] ) < 0 ) { // the sin of the negative angle is just the opposite sign // of the sin of the angle so tmp2 will have the opposite // sign of sin( dest[SG_X] - start[SG_X] ) if ( tmp2 >= 0 ) { *course = tmp5; } else { *course = 2 * SGD_PI - tmp5; } } } plib-1.8.5/src/ssgAux/ssgAux.h0000644000175000001440000000461510765364435013077 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgAux.h 1772 2003-06-27 08:15:15Z sjbaker $ */ #ifndef _SSGAUX_H_ #define _SSGAUX_H_ 1 #include "ssg.h" #include "ssgaShapes.h" #include "ssgaParticleSystem.h" #include "ssgaFire.h" #include "ssgaWaveSystem.h" #include "ssgaLensFlare.h" #include "ssgaScreenDump.h" #define _SSGA_TYPE_SHAPE 0x00008000 #define _SSGA_TYPE_CUBE 0x00004000 #define _SSGA_TYPE_SPHERE 0x00002000 #define _SSGA_TYPE_CYLINDER 0x00001000 #define _SSGA_TYPE_PATCH 0x00010000 #define _SSGA_TYPE_TEAPOT 0x00020000 #define _SSGA_TYPE_PARTICLESYSTEM 0x00040000 #define _SSGA_TYPE_WAVESYSTEM 0x00080000 #define _SSGA_TYPE_LENSFLARE 0x00100000 inline int ssgaTypeShape () { return _SSGA_TYPE_SHAPE | ssgTypeBranch ();} inline int ssgaTypeCube () { return _SSGA_TYPE_CUBE | ssgaTypeShape ();} inline int ssgaTypeSphere () { return _SSGA_TYPE_SPHERE | ssgaTypeShape ();} inline int ssgaTypeCylinder() { return _SSGA_TYPE_CYLINDER | ssgaTypeShape ();} inline int ssgaTypePatch () { return _SSGA_TYPE_PATCH | ssgaTypeShape ();} inline int ssgaTypeTeapot () { return _SSGA_TYPE_TEAPOT | ssgaTypeShape ();} inline int ssgaTypeParticleSystem () { return _SSGA_TYPE_PARTICLESYSTEM | ssgaTypeShape ();} inline int ssgaTypeWaveSystem () { return _SSGA_TYPE_WAVESYSTEM | ssgaTypeShape ();} inline int ssgaTypeLensFlare () { return _SSGA_TYPE_LENSFLARE | ssgaTypeShape ();} void ssgaInit () ; #endif plib-1.8.5/src/ssgAux/ssgaCelestialBody.cxx0000644000175000001440000002455310765364435015604 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaCelestialBody.cxx 1798 2003-09-26 14:54:20Z sjbaker $ */ // Written by Durk Talsma. Originally started October 1997, for distribution // with the FlightGear project. Version 2 was written in August and // September 1998. This code is based upon algorithms and data kindly // provided by Mr. Paul Schlyter. (pausch@saaf.se). // // Separated out rendering pieces and converted to ssg by Curt Olson, // March 2000 // // Moved into ssgAux, July 2003. #include #include "ssgaSky.h" #include "ssgaSphere.h" static int ssgaCelestialBodyOrbPreDraw( ssgEntity *e ) { ssgLeaf *f = (ssgLeaf *)e; if ( f -> hasState () ) f->getState()->apply() ; glPushAttrib( GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT ); //glDisable( GL_DEPTH_TEST ); glDisable( GL_FOG ); glBlendFunc ( GL_SRC_ALPHA, GL_ONE ) ; return true; } static int ssgaCelestialBodyOrbPostDraw( ssgEntity *e ) { glPopAttrib(); return true; } static int ssgaCelestialBodyHaloPreDraw( ssgEntity *e ) { ssgLeaf *f = (ssgLeaf *)e; if ( f -> hasState () ) f->getState()->apply() ; glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); glDisable( GL_DEPTH_TEST ); glDisable( GL_FOG ); glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; return true; } static int ssgaCelestialBodyHaloPostDraw( ssgEntity *e ) { glPopAttrib(); return true; } ssgaCelestialBody::ssgaCelestialBody( void ) { transform = 0; body_angle = 0; body_rotation = 0; body_right_ascension = 0; body_declination = 0; body_dist = 0; } ssgaCelestialBody::~ssgaCelestialBody( void ) { ssgDeRefDelete( transform ); } ssgBranch * ssgaCelestialBody::build( const char* body_tex_path, const char* halo_tex_path, double body_size ) { ssgSimpleState *orb_state = NULL; ssgSimpleState *halo_state = NULL; // set up the orb state orb_state = new ssgSimpleState(); if (body_tex_path) { orb_state->setTexture( body_tex_path ); orb_state->setShadeModel( GL_SMOOTH ); orb_state->enable( GL_LIGHTING ); orb_state->enable( GL_CULL_FACE ); orb_state->enable( GL_TEXTURE_2D ); orb_state->enable( GL_COLOR_MATERIAL ); orb_state->setColourMaterial( GL_DIFFUSE ); orb_state->setMaterial( GL_AMBIENT, 0, 0, 0, 1 ); orb_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); orb_state->enable( GL_BLEND ); orb_state->enable( GL_ALPHA_TEST ); orb_state->setAlphaClamp( 0.01f ); } else { orb_state->setShadeModel( GL_SMOOTH ); orb_state->disable( GL_LIGHTING ); orb_state->enable( GL_CULL_FACE ); orb_state->disable( GL_TEXTURE_2D ); orb_state->enable( GL_COLOR_MATERIAL ); orb_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); orb_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); orb_state->disable( GL_BLEND ); orb_state->disable( GL_ALPHA_TEST ); } if (halo_tex_path) { // build the halo // GLuint texid; // GLubyte *texbuf; // texbuf = new GLubyte[64*64*3]; // texid = makeHalo( texbuf, 64 ); // my_glWritePPMFile("halo.ppm", texbuf, 64, 64, RGB); // set up the halo state halo_state = new ssgSimpleState(); halo_state->setTexture( halo_tex_path ); halo_state->enable( GL_TEXTURE_2D ); halo_state->disable( GL_LIGHTING ); halo_state->setShadeModel( GL_SMOOTH ); halo_state->disable( GL_CULL_FACE ); halo_state->enable( GL_COLOR_MATERIAL ); halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); halo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); halo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); halo_state->enable( GL_ALPHA_TEST ); halo_state->setAlphaClamp(0.01f); halo_state->enable ( GL_BLEND ) ; } return build( orb_state, halo_state, body_size ); } ssgBranch * ssgaCelestialBody::build( ssgSimpleState *orb_state, ssgSimpleState *halo_state, double body_size ) { ssgVertexArray *halo_vl; ssgTexCoordArray *halo_tl; // clean-up previous ssgDeRefDelete( transform ); // build the ssg scene graph sub tree for the sky and connected // into the provide scene graph branch transform = new ssgTransform; transform->ref(); cl = new ssgColourArray( 1 ); sgVec4 color; sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); cl->add( color ); ssgBranch *orb = ssgaMakeSphere( orb_state, cl, (float)body_size, 15, 15, ssgaCelestialBodyOrbPreDraw, ssgaCelestialBodyOrbPostDraw ); transform->addKid( orb ); // force a repaint of the colors with arbitrary defaults repaint( 0.0 ); if (halo_state) { // Build ssg structure float size = float(body_size * 10.0); sgVec3 v3; halo_vl = new ssgVertexArray; sgSetVec3( v3, -size, 0.0, -size ); halo_vl->add( v3 ); sgSetVec3( v3, size, 0.0, -size ); halo_vl->add( v3 ); sgSetVec3( v3, -size, 0.0, size ); halo_vl->add( v3 ); sgSetVec3( v3, size, 0.0, size ); halo_vl->add( v3 ); sgVec2 v2; halo_tl = new ssgTexCoordArray; sgSetVec2( v2, 0.0f, 0.0f ); halo_tl->add( v2 ); sgSetVec2( v2, 1.0, 0.0 ); halo_tl->add( v2 ); sgSetVec2( v2, 0.0, 1.0 ); halo_tl->add( v2 ); sgSetVec2( v2, 1.0, 1.0 ); halo_tl->add( v2 ); ssgLeaf *halo = new ssgVtxTable ( GL_TRIANGLE_STRIP, halo_vl, NULL, halo_tl, cl ); halo->setState( halo_state ); halo->setCallback( SSG_CALLBACK_PREDRAW, ssgaCelestialBodyHaloPreDraw ); halo->setCallback( SSG_CALLBACK_POSTDRAW, ssgaCelestialBodyHaloPostDraw ); transform->addKid( halo ); } return transform; } bool ssgaCelestialBody::reposition( sgVec3 p, double angle, double rightAscension, double declination, double sol_dist ) { sgMat4 T1, T2, GST, RA, DEC; sgVec3 axis; sgVec3 v; sgMakeTransMat4( T1, p ); sgSetVec3( axis, 0.0, 0.0, -1.0 ); sgMakeRotMat4( GST, (float)angle, axis ); sgSetVec3( axis, 0.0, 0.0, 1.0 ); sgMakeRotMat4( RA, (float)((rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0), axis ); sgSetVec3( axis, 1.0, 0.0, 0.0 ); sgMakeRotMat4( DEC, (float)(declination * SGD_RADIANS_TO_DEGREES), axis ); sgSetVec3( v, 0.0, (float)sol_dist, 0.0 ); sgMakeTransMat4( T2, v ); sgMat4 TRANSFORM; sgCopyMat4( TRANSFORM, T1 ); sgPreMultMat4( TRANSFORM, GST ); sgPreMultMat4( TRANSFORM, RA ); sgPreMultMat4( TRANSFORM, DEC ); sgPreMultMat4( TRANSFORM, T2 ); sgCoord skypos; sgSetCoord( &skypos, TRANSFORM ); transform->setTransform( &skypos ); return true; } bool ssgaCelestialBody::repaint( double angle ) { static double prev_angle = 9999.0; if (prev_angle != angle) { prev_angle = angle; double factor = 4*cos(angle); if (factor > 1) factor = 1.0; if (factor < -1) factor = -1.0; factor = factor/2 + 0.5f; sgVec4 color; color[0] = (float)pow(factor, 0.25); color[1] = (float)pow(factor, 0.50); color[2] = (float)pow(factor, 4.0); color[3] = 1.0; ssgaGammaCorrectRGB( color ); float *ptr; ptr = cl->get( 0 ); sgCopyVec4( ptr, color ); } return true; } #if 0 static GLuint makeHalo( GLubyte *texbuf, int width ) { int texSize; GLuint texid; GLubyte *p; int i,j; double radius; // create a texture id #ifdef GL_VERSION_1_1 glGenTextures(1, &texid); glBindTexture(GL_TEXTURE_2D, texid); #elif GL_EXT_texture_object glGenTexturesEXT(1, &texid); glBindTextureEXT(GL_TEXTURE_2D, texid); #else # error port me #endif glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ; // create the actual texture contents texSize = width * width; if ( !texbuf ) { cout << "ouch ..." << endl; exit(-1); // Ugly! } p = texbuf; radius = (double)(width / 2); GLubyte value; double x, y, d; for ( i = 0; i < width; i++ ) { for ( j = 0; j < width; j++ ) { x = fabs((double)(i - (width / 2))); y = fabs((double)(j - (width / 2))); d = sqrt((x * x) + (y * y)); if (d < radius) { // t is 1.0 at center, 0.0 at edge double t = 1.0 - (d / radius); // inverse square looks nice value = (int)((double) 0xff * (t*t)); } else { value = 0x00; } *p = value; *(p+1) = value; *(p+2) = value; // *(p+3) = value; p += 3; } } /* glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, width, 0, GL_RGBA, GL_UNSIGNED_BYTE, texbuf ); */ return texid; } #define RGB 3 // 3 bytes of color info per pixel #define RGBA 4 // 4 bytes of color+alpha info void my_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int win_height, int mode) { int i, j, k, q; unsigned char *ibuffer; FILE *fp; int pixelSize = mode==GL_RGBA?4:3; ibuffer = (unsigned char *) malloc(win_width*win_height*RGB); fp = fopen(filename, "wb"); fprintf(fp, "P6\n# CREATOR: glReadPixel()\n%d %d\n%d\n", win_width, win_height, UCHAR_MAX); q = 0; for (i = 0; i < win_height; i++) { for (j = 0; j < win_width; j++) { for (k = 0; k < RGB; k++) { ibuffer[q++] = (unsigned char) *(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k)); } } } // *(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k)); fwrite(ibuffer, sizeof(unsigned char), RGB*win_width*win_height, fp); fclose(fp); free(ibuffer); printf("wrote file (%d x %d pixels, %d bytes)\n", win_width, win_height, RGB*win_width*win_height); } #endif plib-1.8.5/src/ssgAux/ssgaLensFlare.h0000644000175000001440000000307710765364435014357 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "ssgaShapes.h" class ssgaLensFlare : public ssgaShape { ssgVtxTable *vt ; ssgVertexArray *v0 ; ssgNormalArray *n0 ; ssgColourArray *c0 ; ssgTexCoordArray *t0 ; void update ( sgMat4 m ) ; protected: virtual void copy_from ( ssgaLensFlare *src, int clone_flags ) ; public: ssgaLensFlare () ; ssgaLensFlare ( int nt ) ; virtual ~ssgaLensFlare () ; virtual ssgBase *clone ( int clone_flags = 0 ) ; virtual void regenerate () ; virtual const char *getTypeName ( void ) ; virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ; } ; unsigned char *_ssgaGetLensFlareTexture () ; plib-1.8.5/src/ssgAux/ssgaFire.h0000644000175000001440000000373710765364435013374 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ #include "ssgAux.h" class ssgaFire : public ssgaParticleSystem { int tableSize ; float *colourTable ; float *sizeTable ; sgVec4 hot_colour ; float max_ttl ; float start_size ; float upward_speed ; float radius ; void reInit () ; public: void createParticle ( int idx, ssgaParticle *p ) ; void updateParticle ( int idx, ssgaParticle *p ) ; ssgaFire ( int num_tris, float _radius = 1.0f, float height = 5.0f, float speed = 2.0f ) ; virtual ~ssgaFire () ; virtual void update ( float t ) ; void setUpwardSpeed ( float spd ) { upward_speed = spd ; } void setHeight ( float hgt ) { max_ttl = hgt / upward_speed ; getBSphere () -> setRadius ( hgt * 2.0f ) ; getBSphere () -> setCenter ( 0, 0, 0 ) ; reInit () ; } void setHotColour ( sgVec4 col ) { sgCopyVec4 ( hot_colour, col ) ; reInit () ; } void getHotColour ( sgVec4 col ) { sgCopyVec4 ( col, hot_colour ) ; } } ; unsigned char *_ssgaGetFireTexture () ; plib-1.8.5/src/ssgAux/Makefile.in0000644000175000001440000004577610765365024013531 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/ssgAux DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibssgaux_a_AR = $(AR) $(ARFLAGS) libplibssgaux_a_LIBADD = am__libplibssgaux_a_SOURCES_DIST = ssgAux.cxx ssgaShapes.cxx \ ssgaPatch.cxx ssgaParticleSystem.cxx ssgaWaveSystem.cxx \ ssgaLensFlare.cxx ssgaLensFlareTexture.cxx ssgaFire.cxx \ ssgaScreenDump.cxx ssgaSphere.cxx ssgaCelestialBody.cxx \ ssgaCloudLayer.cxx ssgaStars.cxx ssgaSkyDome.cxx ssgaSky.cxx \ ssgaTeapot.cxx ssgaBillboards.cxx @BUILD_SSGAUX_TRUE@am_libplibssgaux_a_OBJECTS = ssgAux.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaShapes.$(OBJEXT) ssgaPatch.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaParticleSystem.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaWaveSystem.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaLensFlare.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaLensFlareTexture.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaFire.$(OBJEXT) ssgaScreenDump.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaSphere.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaCelestialBody.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaCloudLayer.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaStars.$(OBJEXT) ssgaSkyDome.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaSky.$(OBJEXT) ssgaTeapot.$(OBJEXT) \ @BUILD_SSGAUX_TRUE@ ssgaBillboards.$(OBJEXT) libplibssgaux_a_OBJECTS = $(am_libplibssgaux_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libplibssgaux_a_SOURCES) DIST_SOURCES = $(am__libplibssgaux_a_SOURCES_DIST) am__include_HEADERS_DIST = ssgAux.h ssgaShapes.h ssgaLensFlare.h \ ssgaParticleSystem.h ssgaWaveSystem.h ssgaScreenDump.h \ ssgaSky.h ssgaSphere.h ssgaFire.h ssgaBillboards.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_SSGAUX_TRUE@lib_LIBRARIES = libplibssgaux.a @BUILD_SSGAUX_TRUE@include_HEADERS = ssgAux.h \ @BUILD_SSGAUX_TRUE@ ssgaShapes.h \ @BUILD_SSGAUX_TRUE@ ssgaLensFlare.h \ @BUILD_SSGAUX_TRUE@ ssgaParticleSystem.h \ @BUILD_SSGAUX_TRUE@ ssgaWaveSystem.h \ @BUILD_SSGAUX_TRUE@ ssgaScreenDump.h \ @BUILD_SSGAUX_TRUE@ ssgaSky.h \ @BUILD_SSGAUX_TRUE@ ssgaSphere.h \ @BUILD_SSGAUX_TRUE@ ssgaFire.h \ @BUILD_SSGAUX_TRUE@ ssgaBillboards.h @BUILD_SSGAUX_TRUE@libplibssgaux_a_SOURCES = ssgAux.cxx \ @BUILD_SSGAUX_TRUE@ ssgaShapes.cxx \ @BUILD_SSGAUX_TRUE@ ssgaPatch.cxx \ @BUILD_SSGAUX_TRUE@ ssgaParticleSystem.cxx \ @BUILD_SSGAUX_TRUE@ ssgaWaveSystem.cxx \ @BUILD_SSGAUX_TRUE@ ssgaLensFlare.cxx \ @BUILD_SSGAUX_TRUE@ ssgaLensFlareTexture.cxx \ @BUILD_SSGAUX_TRUE@ ssgaFire.cxx \ @BUILD_SSGAUX_TRUE@ ssgaScreenDump.cxx \ @BUILD_SSGAUX_TRUE@ ssgaSphere.cxx \ @BUILD_SSGAUX_TRUE@ ssgaCelestialBody.cxx \ @BUILD_SSGAUX_TRUE@ ssgaCloudLayer.cxx \ @BUILD_SSGAUX_TRUE@ ssgaStars.cxx \ @BUILD_SSGAUX_TRUE@ ssgaSkyDome.cxx \ @BUILD_SSGAUX_TRUE@ ssgaSky.cxx \ @BUILD_SSGAUX_TRUE@ ssgaTeapot.cxx \ @BUILD_SSGAUX_TRUE@ ssgaBillboards.cxx @BUILD_SSGAUX_TRUE@INCLUDES = -I$(top_srcdir)/src/sg \ @BUILD_SSGAUX_TRUE@ -I$(top_srcdir)/src/ssg \ @BUILD_SSGAUX_TRUE@ -I$(top_srcdir)/src/util EXTRA_DIST = ssgAux.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/ssgAux/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/ssgAux/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibssgaux.a: $(libplibssgaux_a_OBJECTS) $(libplibssgaux_a_DEPENDENCIES) -rm -f libplibssgaux.a $(libplibssgaux_a_AR) libplibssgaux.a $(libplibssgaux_a_OBJECTS) $(libplibssgaux_a_LIBADD) $(RANLIB) libplibssgaux.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgAux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaBillboards.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaCelestialBody.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaCloudLayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaFire.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaLensFlare.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaLensFlareTexture.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaParticleSystem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaPatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaScreenDump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaShapes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaSky.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaSkyDome.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaSphere.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaStars.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaTeapot.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssgaWaveSystem.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/ssgAux/ssgaParticleSystem.h0000644000175000001440000000623410765364435015452 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net */ class ssgaParticle { public: sgVec4 col ; sgVec3 pos ; sgVec3 vel ; sgVec3 acc ; float size ; float time_to_live ; void *userData ; void update ( float dt ) { sgAddScaledVec3 ( vel, acc, dt ) ; sgAddScaledVec3 ( pos, vel, dt ) ; time_to_live -= dt ; } ssgaParticle () { sgSetVec4 ( col, 1, 1, 1, 1 ) ; sgZeroVec3 ( pos ) ; sgZeroVec3 ( vel ) ; sgZeroVec3 ( acc ) ; time_to_live = 0 ; userData = NULL ; size = 1.0f ; } } ; class ssgaParticleSystem ; typedef void (* ssgaParticleCreateFunc) ( ssgaParticleSystem *ps, int index, ssgaParticle *p ) ; typedef void (* ssgaParticleUpdateFunc) ( float deltaTime, ssgaParticleSystem *ps, int index, ssgaParticle *p ) ; typedef void (* ssgaParticleDeleteFunc) ( ssgaParticleSystem *ps, int index, ssgaParticle *p ) ; class ssgaParticleSystem : public ssgVtxTable { int num_particles ; int num_verts ; int turn_to_face ; int num_active ; ssgaParticle *particle ; float create_error ; float create_rate ; float size ; ssgaParticleCreateFunc particle_create ; ssgaParticleUpdateFunc particle_update ; ssgaParticleDeleteFunc particle_delete ; public: ssgaParticleSystem ( int num, int initial_num, float _create_rate, int _turn_to_face, float sz, float bsphere_size, ssgaParticleCreateFunc _particle_create, ssgaParticleUpdateFunc _particle_update = NULL, ssgaParticleDeleteFunc _particle_delete = NULL ) ; virtual ~ssgaParticleSystem () ; virtual void update ( float t ) ; void setSize ( float sz ) { size = sz ; } float getSize () { return size ; } void draw_geometry () ; void setCreationRate ( float cr ) { create_rate = cr ; } float getCreationRate () { return create_rate ; } int getNumParticles () { return num_particles ; } int getNumActiveParticles () { return num_active ; } } ; plib-1.8.5/src/ssgAux/ssgaSky.cxx0000644000175000001440000002373510765364435013630 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaSky.cxx 1798 2003-09-26 14:54:20Z sjbaker $ */ // Written by Curtis Olson, started December 1997. // SSG-ified by Curtis Olson, February 2000. // // Moved into ssgAux, July 2003. #include "ssgaSky.h" // Used for rise/set effects (flat earth - no rotation of skydome considered here ) void calc_celestial_angles( const sgVec3 body, const sgVec3 view, double& angle, double& rotation ) { sgVec3 pos; sgSubVec3(pos, body, view); angle = (90*SGD_DEGREES_TO_RADIANS) - atan2(pos[2], sqrt(pos[0]*pos[0] + pos[1]*pos[1])); rotation = (90*SGD_DEGREES_TO_RADIANS) - atan2(pos[0], pos[1]); } ssgaSky::ssgaSky( void ) { dome = 0; planets = 0; stars = 0; sol_ref = 0; pre_root = 0; post_root = 0; effective_visibility = visibility = 10000.0; // near cloud visibility state variables in_puff = false; puff_length = 0; puff_progression = 0; ramp_up = 0.15; ramp_down = 0.15; } ssgaSky::~ssgaSky( void ) { delete dome; delete planets; delete stars; delete pre_root; delete post_root; } void ssgaSky::build( double h_radius, double v_radius, int nplanets, sgdVec3 *planet_data, int nstars, sgdVec3 *star_data ) { // clean-up previous delete dome; delete planets; delete stars; delete pre_root; delete post_root; bodies.removeAll(); clouds.removeAll(); // build new pre_root = new ssgRoot; post_root = new ssgRoot; pre_selector = new ssgSelector; post_selector = new ssgSelector; pre_transform = new ssgTransform; post_transform = new ssgTransform; bodies_transform = new ssgTransform; stars_transform = new ssgTransform; dome = new ssgaSkyDome; pre_transform -> addKid( dome->build( h_radius, v_radius ) ); planets = new ssgaStars; stars_transform -> addKid( planets->build( nplanets, planet_data, h_radius ) ); stars = new ssgaStars; stars_transform -> addKid( stars->build( nstars, star_data, h_radius ) ); pre_transform -> addKid( bodies_transform ); pre_transform -> addKid( stars_transform ); pre_selector->addKid( pre_transform ); pre_selector->clrTraversalMaskBits( SSGTRAV_HOT ); post_selector->addKid( post_transform ); post_selector->clrTraversalMaskBits( SSGTRAV_HOT ); pre_root->addKid( pre_selector ); post_root->addKid( post_selector ); } ssgaCelestialBody* ssgaSky::addBody( const char *body_tex_path, const char *halo_tex_path, double size, double dist, bool sol ) { ssgaCelestialBody* body = new ssgaCelestialBody; bodies_transform->addKid( body->build( body_tex_path, halo_tex_path, size ) ); bodies.add( body ); body -> setDist( dist ); if ( sol ) sol_ref = body; return body; } ssgaCelestialBody* ssgaSky::addBody( ssgSimpleState *orb_state, ssgSimpleState *halo_state, double size, double dist, bool sol ) { ssgaCelestialBody* body = new ssgaCelestialBody; bodies_transform->addKid( body->build( orb_state, halo_state, size ) ); bodies.add( body ); body -> setDist( dist ); if ( sol ) sol_ref = body; return body; } ssgaCloudLayer* ssgaSky::addCloud( const char *cloud_tex_path, float span, float elevation, float thickness, float transition ) { ssgaCloudLayer* cloud = new ssgaCloudLayer; cloud->build ( cloud_tex_path, span, elevation, thickness, transition ); clouds.add( cloud ); return cloud; } ssgaCloudLayer* ssgaSky::addCloud( ssgSimpleState *cloud_state, float span, float elevation, float thickness, float transition ) { ssgaCloudLayer* cloud = new ssgaCloudLayer; cloud->build ( cloud_state, span, elevation, thickness, transition ); clouds.add( cloud ); return cloud; } bool ssgaSky::repositionFlat( sgVec3 view_pos, double spin, double dt ) { int i; double angle; double rotation; sgCoord pos; for ( i = 0; i < bodies.getNum (); i++ ) { ssgaCelestialBody *body = bodies.get(i); body->reposition( view_pos, 0 ); // Calc angles for rise/set effects body->getPosition ( & pos ); calc_celestial_angles( pos.xyz, view_pos, angle, rotation ); body->setAngle( angle ); body->setRotation( rotation ); } for ( i = 0; i < clouds.getNum (); i++ ) { clouds.get(i)->repositionFlat( view_pos, dt ); } planets->reposition( view_pos, 0 ); stars->reposition( view_pos, 0 ); if ( sol_ref ) { dome->repositionFlat( view_pos, sol_ref->getRotation() ); } else { dome->repositionFlat( view_pos, spin ); } return true; } bool ssgaSky::reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up, double lon, double lat, double alt, double spin, double gst, double dt ) { int i; double angle = gst * 15; // degrees dome->reposition( zero_elev, lon, lat, spin ); for ( i = 0; i < bodies.getNum (); i++ ) bodies.get(i)->reposition( view_pos, angle ); for ( i = 0; i < clouds.getNum (); i++ ) clouds.get(i)->reposition( zero_elev, view_up, lon, lat, alt, dt ); planets->reposition( view_pos, angle ); stars->reposition( view_pos, angle ); return true; } bool ssgaSky::repaint( sgVec4 sky_color, sgVec4 fog_color, sgVec4 cloud_color, double sol_angle, int nplanets, sgdVec3 *planet_data, int nstars, sgdVec3 *star_data ) { int i; if ( effective_visibility > 1000.0 ) { // turn on sky enable(); dome->repaint( sky_color, fog_color, sol_angle, effective_visibility ); for ( i = 0; i < bodies.getNum (); i++ ) bodies.get(i)->repaint(); for ( i = 0; i < clouds.getNum (); i++ ) clouds.get(i)->repaint( cloud_color ); planets->repaint( sol_angle, nplanets, planet_data ); stars->repaint( sol_angle, nstars, star_data ); } else { // turn off sky disable(); } return true; } void ssgaSky::preDraw() { ssgCullAndDraw( pre_root ); } void ssgaSky::postDraw( float alt ) { // Sort clouds in order of distance from alt (furthest to closest) int i, j; int num = clouds.getNum (); if ( num > 0 ) { // Initialise cloud index int *index = new int [ num ]; for ( i = 0; i < num; i++ ) { index [i] = i; } // Sort cloud index int temp; // holding variable for ( i = 0; i < ( num - 1 ); i++ ) // to represent element to be compared { for( j = ( i + 1 ); j < num; j++ ) // to represent the rest of the elements { float d1 = (float)(fabs(alt - clouds.get(i)->getElevation())); float d2 = (float)(fabs(alt - clouds.get(j)->getElevation())); if (d1 < d2) { temp = index[i]; index[i] = index[j]; index[j] = temp; } } } float slop = 5.0; // if we are closer than this to a cloud layer, don't draw cloud for ( int i = 0; i < num; i++ ) { ssgaCloudLayer *cloud = clouds.get(index[i]); float asl = cloud->getElevation(); float thickness = cloud->getThickness(); // draw cloud only if below or above cloud layer if ( alt < asl - slop || alt > asl + thickness + slop ) cloud->draw(); } delete [] index; } } void ssgaSky::modifyVisibility( float alt, float time_factor ) { float effvis = visibility; for ( int i = 0; i < clouds.getNum (); ++i ) { ssgaCloudLayer *cloud = clouds.get(i); if ( cloud->isEnabled() ) { float asl = cloud->getElevation(); float thickness = cloud->getThickness(); float transition = cloud->getTransition(); float ratio = 1.0; if ( alt < asl - transition ) { // below cloud layer ratio = 1.0; } else if ( alt < asl ) { // in lower transition ratio = (asl - alt) / transition; } else if ( alt < asl + thickness ) { // in cloud layer ratio = 0.0; } else if ( alt < asl + thickness + transition ) { // in upper transition ratio = (alt - (asl + thickness)) / transition; } else { // above cloud layer ratio = 1.0; } // accumulate effects from multiple cloud layers effvis *= ratio; if ( ratio < 1.0 ) { if ( ! in_puff ) { // calc chance of entering cloud puff double rnd = ssgaRandom(); double chance = rnd * rnd * rnd; if ( chance > 0.95 ) { // * (diff - 25) / 50.0 in_puff = true; puff_length = ssgaRandom() * 2.0; // up to 2 seconds puff_progression = 0.0; } } if ( in_puff ) { // modify actual_visibility based on puff envelope if ( puff_progression <= ramp_up ) { double x = 0.5 * SGD_PI * puff_progression / ramp_up; double factor = 1.0 - sin( x ); effvis = (float)(effvis * factor); } else if ( puff_progression >= ramp_up + puff_length ) { double x = 0.5 * SGD_PI * (puff_progression - (ramp_up + puff_length)) / ramp_down; double factor = sin( x ); effvis = (float)(effvis * factor); } else { effvis = 0.0; } puff_progression += time_factor; if ( puff_progression > puff_length + ramp_up + ramp_down) { in_puff = false; } } // never let visibility drop below 25 meters if ( effvis <= 25.0 ) { effvis = 25.0; } } } } // for effective_visibility = effvis; } plib-1.8.5/src/ssgAux/ssgaShapes.h0000644000175000001440000001351610765364435013726 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaShapes.h 1568 2002-09-02 06:05:49Z sjbaker $ */ #ifndef _SSGASHAPES_H_ #define _SSGASHAPES_H_ 1 #include "ssg.h" typedef float sgVec9 [ 9 ] ; /* Needed for ssgaPatch */ class ssgaShape : public ssgBranch { int corrupted ; protected: virtual void copy_from ( ssgaShape *src, int clone_flags ) ; sgVec4 colour ; sgVec3 center ; sgVec3 size ; int ntriangles ; ssgState *kidState ; ssgCallback kidPreDrawCB ; ssgCallback kidPostDrawCB ; void init () ; protected: ssgState *getKidState () { return kidState ; } ssgCallback getKidPreDrawCB () { return kidPreDrawCB ; } ssgCallback getKidPostDrawCB () { return kidPostDrawCB ; } public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgaShape (void) ; ssgaShape ( int numtris ) ; virtual ~ssgaShape (void) ; virtual const char *getTypeName(void) ; void makeCorrupt () { corrupted = TRUE ; } int isCorrupt () { return corrupted ; } float *getCenter () { return center ; } float *getSize () { return size ; } int getNumTris () { return ntriangles ; } void setColour ( sgVec4 c ) { sgCopyVec4 ( colour, c ) ; regenerate () ; } void setCenter ( sgVec3 c ) { sgCopyVec3 ( center, c ) ; regenerate () ; } void setSize ( sgVec3 s ) { sgCopyVec3 ( size , s ) ; regenerate () ; } void setSize ( float s ) { sgSetVec3 ( size,s,s,s) ; regenerate () ; } void setNumTris ( int ntri ) { ntriangles = ntri ; regenerate () ; } void setKidState ( ssgState *s ) { kidState = s ; for ( int i = 0 ; i < getNumKids() ; i++ ) ((ssgLeaf *)getKid(i)) -> setState ( s ) ; } void setKidCallback ( int cb_type, ssgCallback cb ) { if ( cb_type == SSG_CALLBACK_PREDRAW ) kidPreDrawCB = cb ; else kidPostDrawCB = cb ; for ( int i = 0 ; i < getNumKids() ; i++ ) ((ssgLeaf *)getKid(i)) -> setCallback ( cb_type, cb ) ; } virtual void regenerate () = 0 ; virtual int load ( FILE * ) ; virtual int save ( FILE * ) ; } ; class ssgaCube : public ssgaShape { protected: virtual void copy_from ( ssgaCube *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgaCube (void) ; ssgaCube ( int numtris ) ; virtual ~ssgaCube (void) ; virtual const char *getTypeName(void) ; virtual void regenerate () ; } ; #define SSGA_HAVE_PATCH 1 class ssgaPatch : public ssgaShape { int levels ; sgVec9 control_points[4][4] ; void makePatch ( sgVec9 points[4][4], int levels ) ; void writePatch ( sgVec9 points[4][4] ) ; void makeHSpline ( sgVec9 points[4] , sgVec9 nv[7] ) ; void makeVSplines ( sgVec9 points[4][7], sgVec9 nv[7][7] ) ; protected: virtual void copy_from ( ssgaPatch *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgaPatch (void) ; ssgaPatch ( int numtris ) ; void setControlPoint ( int s, int t, sgVec3 xyz, sgVec2 uv, sgVec4 rgba ) ; void setControlPoint ( int s, int t, float x, float y, float z, float u, float v, float r, float g, float b, float a ) ; void getControlPoint ( int s, int t, sgVec3 xyz, sgVec2 uv, sgVec4 rgba ) ; virtual ~ssgaPatch (void) ; virtual const char *getTypeName(void) ; virtual void regenerate () ; virtual int load ( FILE * ) ; virtual int save ( FILE * ) ; } ; #define SSGA_HAVE_TEAPOT 1 class ssgaTeapot : public ssgaShape { protected: virtual void copy_from ( ssgaTeapot *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgaTeapot (void) ; ssgaTeapot ( int numtris ) ; virtual ~ssgaTeapot (void) ; virtual const char *getTypeName(void) ; virtual void regenerate () ; virtual int load ( FILE * ) ; virtual int save ( FILE * ) ; } ; class ssgaSphere : public ssgaShape { int latlong_style ; void regenerateLatLong () ; void regenerateTessellatedIcosahedron () ; protected: virtual void copy_from ( ssgaSphere *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgaSphere (void) ; ssgaSphere ( int numtris ) ; virtual ~ssgaSphere (void) ; virtual const char *getTypeName(void) ; virtual void regenerate () ; void setLatLongStyle ( int ll ) { latlong_style = ll ; regenerate () ; } int isLatLongStyle () { return latlong_style ; } virtual int load ( FILE * ) ; virtual int save ( FILE * ) ; } ; class ssgaCylinder : public ssgaShape { int capped ; protected: virtual void copy_from ( ssgaCylinder *src, int clone_flags ) ; public: virtual ssgBase *clone ( int clone_flags = 0 ) ; ssgaCylinder (void) ; ssgaCylinder ( int numtris ) ; virtual ~ssgaCylinder (void) ; virtual const char *getTypeName(void) ; virtual void regenerate () ; void makeCapped ( int c ) { capped = c ; regenerate () ; } int isCapped () { return capped ; } virtual int load ( FILE * ) ; virtual int save ( FILE * ) ; } ; #endif plib-1.8.5/src/ssgAux/ssgaSky.h0000644000175000001440000002465210765364435013254 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaSky.h 2073 2006-03-27 08:09:54Z bram $ */ // Written by Curtis Olson, started December 1997. // SSG-ified by Curtis Olson, February 2000. // // Moved into ssgAux, July 2003. #ifndef _INCLUDED_SSGASKY_H_ #define _INCLUDED_SSGASKY_H_ #include "ssg.h" class ssgaCelestialBody; class ssgaCelestialBodyList; class ssgaCloudLayer; class ssgaCloudLayerList; class ssgaStars; class ssgaSkyDome; class ssgaSky; class ssgaCelestialBody { private: ssgTransform *transform; ssgColourArray *cl; // used by repaint for rise/set effects double body_angle; double body_rotation; // used by reposition double body_right_ascension; double body_declination; double body_dist; public: ssgaCelestialBody( void ); ~ssgaCelestialBody( void ); ssgBranch *build( const char* body_tex_path, const char* halo_tex_path, double body_size ); ssgBranch *build( ssgSimpleState *orb_state, ssgSimpleState *halo_state, double body_size ); bool reposition( sgVec3 p, double angle ) { return reposition ( p, angle, body_right_ascension, body_declination, body_dist ); } bool reposition( sgVec3 p, double angle, double rightAscension, double declination, double dist ); bool repaint() { return repaint ( body_angle ); } bool repaint( double angle ); void getPosition ( sgCoord* p ) { sgMat4 Xform; transform->getTransform(Xform); sgSetCoord(p, Xform); } void setAngle ( double angle ) { body_angle = angle; } double getAngle () { return body_angle; } void setRotation ( double rotation ) { body_rotation = rotation; } double getRotation () { return body_rotation; } void setRightAscension ( double ra ) { body_right_ascension = ra; } double getRightAscension () { return body_right_ascension; } void setDeclination ( double decl ) { body_declination = decl; } double getDeclination () { return body_declination; } void setDist ( double dist ) { body_dist = dist; } double getDist () { return body_dist; } inline float *getColor() { return cl->get( 0 ); } } ; class ssgaCelestialBodyList : private ssgSimpleList { public: ssgaCelestialBodyList ( int init = 3 ) : ssgSimpleList ( sizeof(ssgaCelestialBody*), init ) { } ~ssgaCelestialBodyList () { removeAll(); } int getNum (void) { return total ; } ssgaCelestialBody* get ( unsigned int n ) { assert(nselect( 1 ); post_selector->select( 1 ); } // disable the sky inline void disable() { pre_selector->select( 0 ); post_selector->select( 0 ); } // current effective visibility inline float getVisibility() const { return effective_visibility; } inline void setVisibility( float v ) { effective_visibility = visibility = v; } } ; // return a random number between [0.0, 1.0) inline double ssgaRandom(void) { return(rand() / (double)RAND_MAX); } //#if defined( macintosh ) //const float system_gamma = 1.4; //#elif defined (sgi) //const float system_gamma = 1.7; //#else // others const float system_gamma = 2.5; //#endif // simple architecture independant gamma correction function. inline void ssgaGammaCorrectRGB(float *color, float reff = 2.5, float system = system_gamma) { color[0] = (float)pow(color[0], reff/system); color[1] = (float)pow(color[1], reff/system); color[2] = (float)pow(color[2], reff/system); }; inline void ssgaGammaCorrectC(float *color, float reff = 2.5, float system = system_gamma) { *color = (float)pow(*color, reff/system); }; inline void ssgaGammaRestoreRGB(float *color, float reff = 2.5, float system = system_gamma) { color[0] = (float)pow(color[0], system/reff); color[1] = (float)pow(color[1], system/reff); color[2] = (float)pow(color[2], system/reff); }; inline void ssgaGammaRestoreC(float *color, float reff = 2.5, float system = system_gamma) { *color = (float)pow(*color, system/reff); }; #endif plib-1.8.5/src/ssgAux/ssgaPatch.cxx0000644000175000001440000001641710765364435014120 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaPatch.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "ssgAux.h" #include typedef float sgVec9 [9] ; void ssgaPatch::regenerate () { if ( kidState != NULL ) kidState -> ref () ; removeAllKids () ; if ( kidState != NULL ) kidState -> deRef () ; if ( ntriangles <= 2 ) levels = -1 ; else if ( ntriangles <= 18 ) levels = 0 ; else if ( ntriangles <= 4*18 ) levels = 1 ; else if ( ntriangles <= 16*18 ) levels = 2 ; else if ( ntriangles <= 64*18 ) levels = 3 ; else if ( ntriangles <= 256*18 ) levels = 4 ; else if ( ntriangles <= 1024*18 ) levels = 5 ; else if ( ntriangles <= 4096*18 ) levels = 6 ; else levels = 7 ; if ( ntriangles == 0 || control_points == NULL ) return ; makePatch ( control_points, levels ) ; /* vt0 -> setState ( getKidState () ) ; vt0 -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt0 -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; vt0 -> recalcBSphere () ; */ recalcBSphere () ; } static float *sgMidPointVec9 ( sgVec9 a, sgVec9 b ) { static sgVec9 r ; r[0] = (a[0] + b[0])/2.0f ; r[1] = (a[1] + b[1])/2.0f ; r[2] = (a[2] + b[2])/2.0f ; r[3] = (a[3] + b[3])/2.0f ; r[4] = (a[4] + b[4])/2.0f ; r[5] = (a[5] + b[5])/2.0f ; r[6] = (a[6] + b[6])/2.0f ; r[7] = (a[7] + b[7])/2.0f ; r[8] = (a[8] + b[8])/2.0f ; return r ; } void ssgaPatch::makeHSpline ( sgVec9 points[4], sgVec9 newVts[7] ) { sgVec9 temp ; memcpy ( newVts[0], points[0],sizeof(sgVec9)); memcpy ( newVts[1], sgMidPointVec9 ( points[0], points[1] ),sizeof(sgVec9)); memcpy ( temp , sgMidPointVec9 ( points[1], points[2] ),sizeof(sgVec9)); memcpy ( newVts[2], sgMidPointVec9 ( newVts[1], temp ),sizeof(sgVec9)); memcpy ( newVts[5], sgMidPointVec9 ( points[2], points[3] ),sizeof(sgVec9)); memcpy ( newVts[4], sgMidPointVec9 ( temp , newVts[5] ),sizeof(sgVec9)); memcpy ( newVts[3], sgMidPointVec9 ( newVts[2], newVts[4] ),sizeof(sgVec9)); memcpy ( newVts[6], points[3],sizeof(sgVec9)); } void ssgaPatch::makeVSplines ( sgVec9 hv[4][7], sgVec9 nv[7][7] ) { sgVec9 temp ; for ( int col = 0 ; col < 7 ; col++ ) { memcpy ( nv[0][col], hv[0][col], sizeof(sgVec9) ) ; memcpy ( nv[1][col],sgMidPointVec9(hv[0][col], hv[1][col]), sizeof(sgVec9)); memcpy ( temp ,sgMidPointVec9(hv[1][col], hv[2][col]), sizeof(sgVec9)); memcpy ( nv[2][col],sgMidPointVec9(nv[1][col], temp ), sizeof(sgVec9)); memcpy ( nv[5][col],sgMidPointVec9(hv[2][col], hv[3][col]), sizeof(sgVec9)); memcpy ( nv[4][col],sgMidPointVec9(temp , nv[5][col]), sizeof(sgVec9)); memcpy ( nv[3][col],sgMidPointVec9(nv[2][col], nv[4][col]), sizeof(sgVec9)); memcpy ( nv[6][col], hv[3][col], sizeof(sgVec9) ) ; } } void ssgaPatch::writePatch ( sgVec9 points[4][4] ) { sgVec3 nn = { 0,0,1 } ; /* Write three strips of 8 vertices each */ for ( int i = 0 ; i < 3 ; i++ ) { ssgVertexArray *va = new ssgVertexArray ( 8 ) ; ssgTexCoordArray *ta = new ssgTexCoordArray ( 8 ) ; ssgColourArray *ca = new ssgColourArray ( 8 ) ; ssgNormalArray *na = new ssgNormalArray ( 8 ) ; for ( int j = 0 ; j < 4 ; j++ ) { sgVec3 vv ; sgSetVec3 ( vv, points [ i ][j][0] * size[0] + center[0], points [ i ][j][1] * size[1] + center[1], points [ i ][j][2] * size[2] + center[2] ) ; va -> add ( vv ) ; ta -> add ( & ( points [ i ][j][ 3 ] ) ) ; ca -> add ( & ( points [ i ][j][ 5 ] ) ) ; na -> add ( nn ) ; sgSetVec3 ( vv, points [i+1][j][0] * size[0] + center[0], points [i+1][j][1] * size[1] + center[1], points [i+1][j][2] * size[2] + center[2] ) ; va -> add ( vv ) ; ta -> add ( & ( points [i+1][j][ 3 ] ) ) ; ca -> add ( & ( points [i+1][j][ 5 ] ) ) ; na -> add ( nn ) ; } ssgVtxTable *vt = new ssgVtxTable ( GL_TRIANGLE_STRIP, va,na,ta,ca ) ; vt -> setState ( getKidState () ) ; vt -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB () ) ; vt -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ; addKid ( vt ) ; } } void ssgaPatch::makePatch ( float points[4][4][9], int level ) { if ( level <= 0 ) { writePatch ( points ) ; return ; } sgVec9 newHVerts [ 4 ][ 7 ] ; sgVec9 newVertices [ 7 ][ 7 ] ; makeHSpline ( points[0], newHVerts[0] ) ; makeHSpline ( points[1], newHVerts[1] ) ; makeHSpline ( points[2], newHVerts[2] ) ; makeHSpline ( points[3], newHVerts[3] ) ; makeVSplines ( newHVerts, newVertices ) ; sgVec9 patch[4][4] ; int i ; for ( i = 0 ; i < 16 ; i++ ) memcpy ( patch[i>>2][i&3], newVertices[i>>2][i&3], 9*sizeof(float) ) ; makePatch ( patch, level-1 ) ; for ( i = 0 ; i < 16 ; i++ ) memcpy ( patch[i>>2][i&3], newVertices[i>>2][3+(i&3)], 9*sizeof(float) ) ; makePatch ( patch, level-1 ) ; for ( i = 0 ; i < 16 ; i++ ) memcpy ( patch[i>>2][i&3], newVertices[3+(i>>2)][i&3], 9*sizeof(float) ) ; makePatch ( patch, level-1 ) ; for ( i = 0 ; i < 16 ; i++ ) memcpy ( patch[i>>2][i&3], newVertices[3+(i>>2)][3+(i&3)], 9*sizeof(float)); makePatch ( patch, level-1 ) ; } void ssgaPatch::setControlPoint ( int s, int t, float x, float y, float z, float u, float v, float r, float g, float b, float a ) { control_points[s][t][0] = x ; control_points[s][t][1] = y ; control_points[s][t][2] = z ; control_points[s][t][3] = u ; control_points[s][t][4] = v ; control_points[s][t][5] = r ; control_points[s][t][6] = g ; control_points[s][t][7] = b ; control_points[s][t][8] = a ; } void ssgaPatch::setControlPoint ( int s, int t, sgVec3 xyz, sgVec2 uv, sgVec4 rgba ) { memcpy ( &(control_points[s][t][0]), xyz , sizeof(sgVec3) ) ; memcpy ( &(control_points[s][t][3]), uv , sizeof(sgVec2) ) ; memcpy ( &(control_points[s][t][5]), rgba, sizeof(sgVec4) ) ; } void ssgaPatch::getControlPoint ( int s, int t, sgVec3 xyz, sgVec2 uv, sgVec4 rgba ) { memcpy ( xyz, &(control_points[s][t][0]), sizeof(sgVec3) ) ; memcpy ( uv , &(control_points[s][t][3]), sizeof(sgVec2) ) ; memcpy ( rgba, &(control_points[s][t][5]), sizeof(sgVec4) ) ; } plib-1.8.5/src/ssgAux/ssgaBillboards.h0000644000175000001440000001660210765364435014557 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaBillboards.h 1844 2004-01-21 16:30:20Z stromberg $ */ /* * ssgaBillboards * * Each billboard is represented by four values: X, Y, Z and scale. * They are drawn as GL_QUADS using the texture defined in the state. * * Set the basic billboard size (each can be individually scaled): * * bb->setWidth(3.0f); * bb->setHeight(8.0f); * * Set a texture image: * * bb->initTexAlpha(texture, 0.3f); // only once per texture, choose a suitable alpha threshold * bb->setTexture(texture); * * Instantiate some billboards: * * for (i = 0; i < 1000; i++) * bb->add( (drand48() - 0.5) * WORLD_SIZE_X, * (drand48() - 0.5) * WORLD_SIZE_Y, * Z, 0.75 + 0.5 * drand48() ); * * * The billboards can be faded: * * bb->setClipRange(300.0f); // i.e. far clip * bb->setFadeRange(200.0f); // starting fade here * * or, equivalently: * * bb->setFarRange(300.0f, 200.0f); // clip, fade * * * The number of billboards drawn can be a function of distance: * * bb->setNearRange(50.0f); // draw all at this distance * bb->setFadeNum(100); // number drawn at the fade distance (or clip distance if unset) * * Limit the number at the near range (defaults to all): * * bb->setDrawNum(500); * * * Example code: plib/examples/src/ssg/shrubs/shrubs.cxx * * * November 2003, Marten Stromberg * */ #include "ssg.h" class ssgaBillboards : public ssgLeaf { protected: sgVec3 up; // vector pointing up (default: 0, 0, 1) ssgColourArray array; // position and scale for each billboard int draw_num; // only draw this many (-1 for all) float width, height; // basic size of billboard float clip_dist; // far clip distance (-1 disables) float fade_dist; // fade-out distance (fade iff fade_dist < d < clip_dist) float near_dist; // near distance for adjusting number of trees int fade_num; // optionally adjust number of trees as a function of distance float alpha_ref; // default 0.1 (initTexAlpha relies on that) public: ssgaBillboards(); ~ssgaBillboards(); void setUp(const sgVec3 v) { sgNormaliseVec3(up, v); } void setUp(float x, float y, float z) { sgVec3 v = { x, y, z }; setUp(v); } const float *getUp() const { return up; } int getNum() { return array.getNum(); } // const const float *get(int i) { return array.get((unsigned) i); } // const inline void add(float x, float y, float z, float scale = 1.0f); inline void add(const sgVec4 xyzs); void removeLast() { array.removeLast(); dirtyBSphere(); } void removeAll() { array.removeAll(); dirtyBSphere(); } void setWidth(float w) { width = w; } float getWidth() const { return width; } void setHeight(float h) { height = h; } float getHeight() const { return height; } void setClipRange(float d) { clip_dist = d; } float getClipRange() const { return clip_dist; } void setFadeRange(float d) { fade_dist = d; } float getFadeRange() const { return fade_dist; } void setNearRange(float d) { near_dist = d; } float getNearRange() const { return near_dist; } void setFarRange(float clip, float fade) { setFadeRange(fade); setClipRange(clip); } void setFarRange(float clip) { setFarRange(clip, 0.75f * clip); } void setNearFarRange(float near_, float clip, float fade) { setNearRange(near_); setFarRange(clip, fade); } void setNearFarRange(float near_, float clip) { setNearRange(near_); setFarRange(clip); } void setDrawNum(int n) { draw_num = n; } int getDrawNum() const { return draw_num; } void setFadeNum(int n) { fade_num = n; } int getFadeNum() const { return fade_num; } inline void setTexture(ssgTexture *tex); inline ssgTexture *getTexture(); // const void setAlphaRef(float aref) { alpha_ref = aref; } // only when not using initTexAlpha float getAlphaRef() const { return alpha_ref; } static void initTexAlpha(GLuint handle, float aref = 0.3f); // initialize alpha channel for smooth fading static void initTexAlpha(ssgTexture *tex, float aref = 0.3f) { initTexAlpha(tex->getHandle(), aref); } /* methods derived from ssgEntity and ssgLeaf */ virtual void recalcBSphere(); virtual void cull(sgFrustum *, sgMat4, int); virtual void draw(); void draw(const sgMat4 m); virtual void draw_geometry() {} virtual void pick(int) {} virtual void drawHighlight(sgVec4) {} virtual void drawHighlight(sgVec4, int) {} virtual void isect_triangles(sgSphere *, sgMat4, int) {} virtual void hot_triangles(sgVec3, sgMat4, int) {} virtual void los_triangles(sgVec3, sgMat4, int) {} virtual const char *getTypeName() { return "ssgaBillboards"; } virtual GLenum getPrimitiveType() { return GL_QUADS; } virtual int getNumVertices() { return 4 * getNum(); } virtual int getNumTexCoords() { return 4 * getNum(); } virtual int getNumNormals() { return 0; } virtual int getNumColours() { return 0; } virtual float *getVertex(int i); virtual float *getTexCoord(int i); virtual float *getNormal(int) { return _ssgNormalUp; } virtual float *getColour(int) { return _ssgColourWhite; } virtual int getNumTriangles() { return 2 * getNum(); } virtual void getTriangle(int n, short *v1, short *v2, short *v3); virtual int getNumLines() { return 0; } virtual void getLine(int, short *v1, short *v2) {} virtual void transform(const sgMat4 m); // incremented each draw, use it as you like static int total_drawn; }; inline void ssgaBillboards::add(float x, float y, float z, float w) { array.add(x, y, z, w); dirtyBSphere(); } inline void ssgaBillboards::add(const sgVec4 xyzs) { array.add((float *) xyzs); dirtyBSphere(); } inline void ssgaBillboards::setTexture(ssgTexture *tex) { ssgSimpleState *ss = (ssgSimpleState *) getState(); assert( ss && ss->isAKindOf( ssgTypeSimpleState() )); ss->setTexture(tex); } inline ssgTexture *ssgaBillboards::getTexture() { ssgSimpleState *ss = (ssgSimpleState *) getState(); assert( ss && ss->isAKindOf( ssgTypeSimpleState() )); return ss->getTexture(); } /* Local Variables: mode: C++ c-basic-offset: 4 c-file-offsets: ((substatement-open 0) (case-label 0)) End: */ plib-1.8.5/src/ssgAux/ssgaScreenDump.h0000644000175000001440000000123510765364435014543 00000000000000 /* Dump to disk in '.rgb' format */ void ssgaScreenDump ( char *filename, int width, int height, int frontBuffer = TRUE ) ; /* Put low order 24 bits to disk (R=lsb, G=middle byte, B=msb) */ void ssgaScreenDepthDump ( char *filename, int width, int height, int frontBuffer = TRUE ) ; /* Dump to a memory buffer - three bytes per pixel */ unsigned char *ssgaScreenDump ( int width, int height, int frontBuffer = TRUE ) ; unsigned int *ssgaScreenDepthDump ( int width, int height, int frontBuffer = TRUE ) ; plib-1.8.5/src/ssgAux/ssgaSphere.cxx0000644000175000001440000000701510765364435014301 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaSphere.cxx 2015 2005-02-02 15:48:09Z sjbaker $ */ // Pulled straight out of MesaGLU/quadratic.c // // Original gluSphere code is Copyright (C) 1999-2000 Brian Paul and // licensed under the GPL // // Moved into ssgAux, July 2003. #include "ul.h" #include "ssgaSphere.h" ssgBranch *ssgaMakeSphere( ssgSimpleState *state, ssgColourArray *cl, float radius, int slices, int stacks, ssgCallback predraw, ssgCallback postdraw ) { double rho, drho, theta, dtheta; float x, y, z; float s, t, ds, dt; int i, j, imin, imax; float nsign = 1.0; ssgBranch *sphere = new ssgBranch; sgVec2 vec2; sgVec3 vec3; drho = SGD_PI / stacks; dtheta = (2.0 * SGD_PI) / slices; /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */ ds = 1.0f / slices; dt = 1.0f / stacks; t = 1.0; /* because loop now runs from 0 */ imin = 0; imax = stacks; /* build slices as quad strips */ for ( i = imin; i < imax; i++ ) { ssgVertexArray *vl = new ssgVertexArray(); ssgNormalArray *nl = new ssgNormalArray(); ssgTexCoordArray *tl = new ssgTexCoordArray(); rho = i * drho; s = 0.0; for ( j = 0; j <= slices; j++ ) { theta = (j == slices) ? 0.0 : j * dtheta; x = (float)(-sin(theta) * sin(rho)); y = (float)(cos(theta) * sin(rho)); z = (float)(nsign * cos(rho)); sgSetVec3( vec3, x*nsign, y*nsign, z*nsign ); sgNormalizeVec3( vec3 ); nl->add( vec3 ); sgSetVec2( vec2, s, t ); tl->add( vec2 ); sgSetVec3( vec3, x*radius, y*radius, z*radius ); vl->add( vec3 ); x = (float)(-sin(theta) * sin(rho+drho)); y = (float)(cos(theta) * sin(rho+drho)); z = (float)(nsign * cos(rho+drho)); sgSetVec3( vec3, x*nsign, y*nsign, z*nsign ); sgNormalizeVec3( vec3 ); nl->add( vec3 ); sgSetVec2( vec2, s, t-dt ); tl->add( vec2 ); s += ds; sgSetVec3( vec3, x*radius, y*radius, z*radius ); vl->add( vec3 ); } ssgLeaf *slice = new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl ); if ( vl->getNum() != nl->getNum() ) { ulSetError(UL_FATAL, "bad sphere1\n"); exit(-1); } if ( vl->getNum() != tl->getNum() ) { ulSetError(UL_FATAL, "bad sphere2\n"); exit(-1); } slice->setState( state ); slice->setCallback( SSG_CALLBACK_PREDRAW, predraw ); slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw ); sphere->addKid( slice ); t -= dt; } return sphere; } plib-1.8.5/src/ssgAux/ssgaSphere.h0000644000175000001440000000233310765364435013724 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: ssgaSphere.h 2000 2005-01-09 13:13:12Z bram $ */ #include "ssg.h" // return a sphere object as an ssgBranch (connected to the specified ssgSimpleState) ssgBranch *ssgaMakeSphere( ssgSimpleState *state, ssgColourArray *cl, float radius, int slices, int stacks, ssgCallback predraw, ssgCallback postdraw ); plib-1.8.5/src/psl/0000777000175000001440000000000010765365521011053 500000000000000plib-1.8.5/src/psl/pslError.cxx0000644000175000001440000000707310765364440013331 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslError.cxx 1685 2002-09-15 14:32:53Z ude $ */ #include "pslLocal.h" static char _pslErrorBuffer [ 1024 ] = { '\0' } ; void (*_pslErrorCB) ( pslProgram *p, int severity, const char *progname, int line_no , const char *message ) = NULL ; void pslSetErrorCallback ( void (*CB) ( pslProgram *, int, const char *, int, const char * ) ) { _pslErrorCB = CB ; } int pslCompiler::warning ( const char *fmt, ... ) { va_list argp; va_start ( argp, fmt ) ; vsprintf ( _pslErrorBuffer, fmt, argp ) ; va_end ( argp ) ; if ( _pslErrorCB != NULL ) (*_pslErrorCB)( program, PSL_COMPILETIME_WARNING, _pslGetFname(), _pslGetLineNo(), _pslErrorBuffer ) ; else fprintf ( stderr, "PSL: \"%s\" line %3d: WARNING - %s\n", _pslGetFname(), _pslGetLineNo(), _pslErrorBuffer ) ; bumpWarnings () ; return FALSE ; } int pslCompiler::error ( const char *fmt, ... ) { va_list argp; va_start ( argp, fmt ) ; vsprintf ( _pslErrorBuffer, fmt, argp ) ; va_end ( argp ) ; if ( _pslErrorCB != NULL ) (*_pslErrorCB)( program, PSL_COMPILETIME_ERROR, _pslGetFname(), _pslGetLineNo(), _pslErrorBuffer ) ; else fprintf ( stderr, "PSL: \"%s\" line %3d: *ERROR* - %s\n", _pslGetFname(), _pslGetLineNo(), _pslErrorBuffer ) ; bumpErrors () ; return FALSE ; } void pslContext::warning ( const char *fmt, ... ) { va_list argp; va_start ( argp, fmt ) ; vsprintf ( _pslErrorBuffer, fmt, argp ) ; va_end ( argp ) ; if ( _pslErrorCB != NULL ) (*_pslErrorCB)( program, PSL_RUNTIME_WARNING, getProgName(), getLineNo(), _pslErrorBuffer ) ; else if ( getLineNo () >= 0 ) fprintf ( stderr, "PSL: \"%s\" Line %d: WARNING - %s\n", getProgName(), getLineNo(), _pslErrorBuffer ) ; else fprintf ( stderr, "PSL: \"%s\": WARNING - %s\n", getProgName(), _pslErrorBuffer ) ; bumpWarnings () ; } void pslContext::error ( const char *fmt, ... ) { va_list argp; va_start ( argp, fmt ) ; vsprintf ( _pslErrorBuffer, fmt, argp ) ; va_end ( argp ) ; if ( _pslErrorCB != NULL ) (*_pslErrorCB)( program, PSL_RUNTIME_ERROR, getProgName(), getLineNo(), _pslErrorBuffer ) ; else if ( getLineNo () >= 0 ) fprintf ( stderr, "PSL: \"%s\" Line %d: *ERROR* - %s\n", getProgName(), getLineNo(), _pslErrorBuffer ) ; else fprintf ( stderr, "PSL: \"%s\": *ERROR* - %s\n", getProgName(), _pslErrorBuffer ) ; bumpErrors () ; } plib-1.8.5/src/psl/pslOpcodes.h0000644000175000001440000000710510765364440013255 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslOpcodes.h 1700 2002-09-22 18:25:16Z sjbaker $ */ /* Code Opcodes */ #define OPCODE_BAD 0x00 #define OPCODE_PUSH_INT_CONSTANT 0x01 #define OPCODE_PUSH_FLOAT_CONSTANT 0x02 #define OPCODE_PUSH_STRING_CONSTANT 0x03 #define OPCODE_CALL 0x04 #define OPCODE_SUB 0x05 #define OPCODE_ADD 0x06 #define OPCODE_DIV 0x07 #define OPCODE_MULT 0x08 #define OPCODE_MOD 0x09 #define OPCODE_NEG 0x0A #define OPCODE_NOT 0x0B #define OPCODE_TWIDDLE 0x0C #define OPCODE_OROR 0x0D #define OPCODE_ANDAND 0x0E #define OPCODE_SHIFTLEFT 0x0F #define OPCODE_SHIFTRIGHT 0x10 #define OPCODE_OR 0x11 #define OPCODE_AND 0x12 #define OPCODE_XOR 0x13 #define OPCODE_LESS 0x14 #define OPCODE_LESSEQUAL 0x15 #define OPCODE_GREATER 0x16 #define OPCODE_GREATEREQUAL 0x17 #define OPCODE_NOTEQUAL 0x18 #define OPCODE_EQUAL 0x19 #define OPCODE_JUMP_FALSE 0x1A #define OPCODE_JUMP_TRUE 0x1B #define OPCODE_JUMP 0x1C #define OPCODE_POP 0x1D #define OPCODE_HALT 0x1E #define OPCODE_CALLEXT 0x1F #define OPCODE_PAUSE 0x20 #define OPCODE_RETURN 0x21 #define OPCODE_PUSH_VARIABLE 0x22 #define OPCODE_POP_VARIABLE 0x23 #define OPCODE_SET_INT_VARIABLE 0x24 #define OPCODE_SET_FLOAT_VARIABLE 0x25 #define OPCODE_SET_STRING_VARIABLE 0x26 #define OPCODE_STACK_DUPLICATE 0x27 #define OPCODE_GET_PARAMETER 0x28 #define OPCODE_PEEK_JUMP_FALSE 0x2B #define OPCODE_PEEK_JUMP_TRUE 0x2C #define OPCODE_LINE_NUMBER 0x2D #define OPCODE_POP_ADD_VARIABLE 0x30 #define OPCODE_POP_SUB_VARIABLE 0x31 #define OPCODE_POP_MUL_VARIABLE 0x32 #define OPCODE_POP_MOD_VARIABLE 0x33 #define OPCODE_POP_DIV_VARIABLE 0x34 #define OPCODE_POP_AND_VARIABLE 0x35 #define OPCODE_POP_OR_VARIABLE 0x36 #define OPCODE_POP_XOR_VARIABLE 0x37 #define OPCODE_POP_SHL_VARIABLE 0x38 #define OPCODE_POP_SHR_VARIABLE 0x39 #define OPCODE_EXCHANGE 0x3A #define OPCODE_SET_INT_ARRAY 0x3B #define OPCODE_SET_FLOAT_ARRAY 0x3C #define OPCODE_SET_STRING_ARRAY 0x3D #define OPCODE_FETCH 0x40 #define OPCODE_INCREMENT_FETCH 0x41 #define OPCODE_DECREMENT_FETCH 0x42 #define OPCODE_INCREMENT_LVALUE 0x43 #define OPCODE_DECREMENT_LVALUE 0x44 plib-1.8.5/src/psl/pslDump.cxx0000644000175000001440000002053710765364440013145 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslDump.cxx 1700 2002-09-22 18:25:16Z sjbaker $ */ #include "pslLocal.h" struct OpcodeDecode { const char *s ; unsigned char opcode ; int numArgBytes ; } ; static const OpcodeDecode opcodeDecode [] = { { "**BAD_INSTRUCTION**", OPCODE_BAD , 0 }, { "SOURCE LINE NUMBER:", OPCODE_LINE_NUMBER, 2 }, /* Stack operations */ { "PUSH_INT_CONSTANT" , OPCODE_PUSH_INT_CONSTANT , sizeof(int) }, { "PUSH_FLOAT_CONSTANT", OPCODE_PUSH_FLOAT_CONSTANT, sizeof(float) }, { "PUSH_STRING_CONSTANT",OPCODE_PUSH_STRING_CONSTANT, 0 }, { "PUSH_VARIABLE" , OPCODE_PUSH_VARIABLE , 1 }, { "STACK_DUPLICATE" , OPCODE_STACK_DUPLICATE , 0 }, { "POP_VARIABLE" , OPCODE_POP_VARIABLE , 0 }, { "POP" , OPCODE_POP , 0 }, { "FETCH" , OPCODE_FETCH , 0 }, { "INCREMENT_FETCH" , OPCODE_INCREMENT_FETCH , 0 }, { "DECREMENT_FETCH" , OPCODE_DECREMENT_FETCH , 0 }, { "INCREMENT_LVALUE" , OPCODE_INCREMENT_LVALUE , 0 }, { "DECREMENT_LVALUE" , OPCODE_DECREMENT_LVALUE , 0 }, /* Variable creation */ { "SET_INT_ARRAY" , OPCODE_SET_INT_ARRAY , 1 }, { "SET_FLOAT_ARRAY" , OPCODE_SET_FLOAT_ARRAY , 1 }, { "SET_STRING_ARRAY" , OPCODE_SET_STRING_ARRAY , 1 }, { "SET_INT_VARIABLE" , OPCODE_SET_INT_VARIABLE , 1 }, { "SET_FLOAT_VARIABLE" , OPCODE_SET_FLOAT_VARIABLE , 1 }, { "SET_STRING_VARIABLE", OPCODE_SET_STRING_VARIABLE, 1 }, { "GET_PARAMETER" , OPCODE_GET_PARAMETER , 2 }, /* Flow Control */ { "CALLEXT", OPCODE_CALLEXT , 2 }, { "CALL", OPCODE_CALL , 3 }, { "RETURN", OPCODE_RETURN , 0 }, { "PEEK_JUMP_FALSE", OPCODE_PEEK_JUMP_FALSE, 2 }, { "PEEK_JUMP_TRUE", OPCODE_PEEK_JUMP_TRUE , 2 }, { "JUMP_FALSE", OPCODE_JUMP_FALSE , 2 }, { "JUMP_TRUE", OPCODE_JUMP_TRUE , 2 }, { "JUMP", OPCODE_JUMP , 2 }, { "PAUSE", OPCODE_PAUSE , 0 }, { "HALT", OPCODE_HALT , 0 }, /* Math operators */ { "SUB", OPCODE_SUB , 0 }, { "ADD", OPCODE_ADD , 0 }, { "DIV", OPCODE_DIV , 0 }, { "MULT", OPCODE_MULT , 0 }, { "MOD", OPCODE_MOD , 0 }, { "NEG", OPCODE_NEG , 0 }, { "EXCHG", OPCODE_EXCHANGE , 0 }, /* Bitwise operators */ { "NOT", OPCODE_NOT , 0 }, { "TWIDDLE", OPCODE_TWIDDLE , 0 }, { "OROR", OPCODE_OROR , 0 }, { "ANDAND", OPCODE_ANDAND , 0 }, { "OR", OPCODE_OR , 0 }, { "AND", OPCODE_AND , 0 }, { "XOR", OPCODE_XOR , 0 }, { "SHIFT_LEFT", OPCODE_SHIFTLEFT , 0 }, { "SHIFT_RIGHT", OPCODE_SHIFTRIGHT , 0 }, /* Boolean operators */ { "LESS", OPCODE_LESS , 0 }, { "LESSEQUAL", OPCODE_LESSEQUAL , 0 }, { "GREATER", OPCODE_GREATER , 0 }, { "GREATEREQUAL", OPCODE_GREATEREQUAL, 0 }, { "NOTEQUAL", OPCODE_NOTEQUAL , 0 }, { "EQUAL", OPCODE_EQUAL , 0 }, { "POP_ADD_VARIABLE", OPCODE_POP_ADD_VARIABLE, 0 }, { "POP_SUB_VARIABLE", OPCODE_POP_SUB_VARIABLE, 0 }, { "POP_MUL_VARIABLE", OPCODE_POP_MUL_VARIABLE, 0 }, { "POP_MOD_VARIABLE", OPCODE_POP_MOD_VARIABLE, 0 }, { "POP_DIV_VARIABLE", OPCODE_POP_DIV_VARIABLE, 0 }, { "POP_AND_VARIABLE", OPCODE_POP_AND_VARIABLE, 0 }, { "POP_OR_VARIABLE" , OPCODE_POP_OR_VARIABLE , 0 }, { "POP_XOR_VARIABLE", OPCODE_POP_XOR_VARIABLE, 0 }, { "POP_SHL_VARIABLE", OPCODE_POP_SHL_VARIABLE, 0 }, { "POP_SHR_VARIABLE", OPCODE_POP_SHR_VARIABLE, 0 }, { NULL, 0, 0 } } ; int pslCompiler::printOpcode ( FILE *fd, int addr ) const { fprintf ( fd, "%3d: 0x%02x ", addr, (unsigned int)( code [ addr ] ) ) ; unsigned char op = code [ addr ] ; for ( int i = 0 ; opcodeDecode [ i ] . s != NULL ; i++ ) if ( opcodeDecode [ i ] . opcode == op ) { for ( int j = 0 ; j < 4 ; j++ ) if ( j < opcodeDecode [ i ] . numArgBytes ) fprintf ( fd, "0x%02x ", code [ addr + j + 1 ] ) ; else fprintf ( fd, " " ) ; fprintf ( fd, " %s", opcodeDecode [ i ] . s ) ; return 1 + opcodeDecode [ i ] . numArgBytes ; } fprintf ( fd, "**** UNRECOGNISED OPCODE **** " ) ; return 1 ; } void pslCompiler::dump () const { int i ; printf ( "\n" ) ; printf ( "Bytecode:\n" ) ; for ( i = 0 ; i < next_code ; ) i += printInstruction ( stdout, i ) ; printf ( "\n" ) ; printf ( "Global Variables:\n" ) ; for ( i = 0 ; i < MAX_SYMBOL ; i++ ) if ( symtab [ i ] . symbol != NULL ) { printf ( "\t%5s => %4d", symtab[i].symbol, symtab[i].address ) ; if ( i & 1 ) printf ( "\n" ) ; else printf ( " " ) ; } printf ( "\n" ) ; printf ( "Functions:\n" ) ; for ( i = 0 ; i < MAX_SYMBOL ; i++ ) if ( code_symtab [ i ] . symbol != NULL ) { printf ( "\t%5s => %4d", code_symtab[i].symbol, code_symtab[i].address ) ; if ( i & 1 ) printf ( "\n" ) ; else printf ( " " ) ; } printf ( "\n" ) ; if ( num_errors > 0 ) printf ( "PROGRAM FAILED TO COMPILE WITH %d WARNINGS AND %d ERRORS\n", num_warnings, num_errors ) ; else if ( num_warnings > 0 ) printf ( "PROGRAM COMPILED WITH %d WARNINGS\n", num_warnings ) ; else printf ( "PROGRAM COMPILED OK\n" ) ; printf ( "\n" ) ; } int pslCompiler::printInstruction ( FILE *fd, int addr ) const { int skip = printOpcode ( fd, addr ) ; switch ( code [ addr ] ) { case OPCODE_LINE_NUMBER : fprintf ( fd, "%d =====================", code[addr+1] + ( code[addr+2] << 8 ) ) ; break ; case OPCODE_SET_INT_ARRAY : case OPCODE_SET_FLOAT_ARRAY : case OPCODE_SET_STRING_ARRAY : case OPCODE_SET_INT_VARIABLE : case OPCODE_SET_FLOAT_VARIABLE : case OPCODE_SET_STRING_VARIABLE : case OPCODE_PUSH_VARIABLE : fprintf ( fd, "\t\t[%d]", code [ addr+1 ] ) ; break ; case OPCODE_GET_PARAMETER : fprintf ( fd, "\t\t[%d],off=%d", code [ addr+1 ], code [ addr+2 ] ) ; break ; case OPCODE_PUSH_INT_CONSTANT : { int f ; memcpy ( &f, &code[addr+1], sizeof(int) ) ; fprintf ( fd, "\t%d", f ) ; } break ; case OPCODE_PUSH_FLOAT_CONSTANT : { float f ; memcpy ( &f, &code[addr+1], sizeof(float) ) ; fprintf ( fd, "\t%f", f ) ; } break ; case OPCODE_PUSH_STRING_CONSTANT : { fprintf ( fd, "\t\"%s\"", &code[addr+1] ) ; skip += strlen ( (char *) &code[addr+1] ) + 1 ; } break ; case OPCODE_CALLEXT : fprintf ( fd, "\t\t\t%s,nargs=%d", extensions[code[addr+1]].symbol, code[addr+2] ); break ; case OPCODE_CALL : fprintf ( fd, "\t\t\t%d,nargs=%d", code[addr+1] + ( code[addr+2] << 8 ), code[addr+3] ) ; break ; case OPCODE_PEEK_JUMP_FALSE : case OPCODE_PEEK_JUMP_TRUE : case OPCODE_JUMP_FALSE : case OPCODE_JUMP_TRUE : fprintf ( fd, "\t\t%d", code[addr+1] + ( code[addr+2] << 8 ) ) ; break ; case OPCODE_JUMP : fprintf ( fd, "\t\t\t%d", code[addr+1] + ( code[addr+2] << 8 ) ) ; break ; default : break ; } fprintf ( fd, "\n" ) ; return skip ; } plib-1.8.5/src/psl/pslToken.cxx0000644000175000001440000002756510765364440013330 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslToken.cxx 1686 2002-09-15 17:45:53Z sjbaker $ */ #include "pslLocal.h" static char ungotten_token [ MAX_UNGET ][ MAX_TOKEN ] ; static int unget_token_stack_depth = 0 ; void pslCompiler::skipToEOL () { int c ; do { c = getChar () ; } while ( c != '\n' && c != -1 ) ; } int pslCompiler::getChar () { int c ; /* Skip characters so long as the 'skipping' flag is set */ do { /* If we got a newline then we have to test to see whether a '#' preprocessor directive is on this line. */ c = _pslGetChar () ; if ( c == '\n' ) { int d = _pslGetChar () ; if ( d == '#' ) { skipOverride = TRUE ; c = doPreProcessorCommand () ; skipOverride = FALSE ; if ( ! skipping () ) return c ; } else _pslUnGetChar ( d ) ; } } while ( skipping () && c != -1 ) ; /* All done - return the character. */ return c ; } int pslCompiler::searchDefines ( const char *token ) const { if ( ( token[0] < 'a' || token[0] > 'z' ) && ( token[0] < 'A' || token[0] > 'Z' ) && token[0] != '_' ) return -1 ; for ( int i = 0 ; i < next_define ; i++ ) if ( define_token [ i ] != NULL && strcmp ( token, define_token [ i ] ) == 0 ) return i ; return -1 ; } void pslCompiler::doUndefStatement () { char token [ MAX_TOKEN ] ; /* It's tempting to just getToken to get the undefined token but that doesn't work because it get's define-processed. */ getToken ( token, FALSE ) ; if ( ( token[0] < 'a' || token[0] > 'z' ) && ( token[0] < 'A' || token[0] > 'Z' ) && token[0] != '_' ) { error ( "#undef token is not a legal identifier" ) ; skipToEOL () ; return ; } skipToEOL () ; int def = searchDefines ( token ) ; if ( def == -1 ) return ; /* Not an error to have undefined undef's */ if ( ! skipping () ) { delete define_token [ def ] ; delete define_replacement [ def ] ; define_token [ def ] = NULL ; define_replacement [ def ] = NULL ; } } void pslCompiler::doIfdefStatement () { char token [ MAX_TOKEN ] ; getToken ( token, FALSE ) ; if ( next_skippingLevel >= 30 ) { error ( "Too many levels of #ifdef/#ifndef processing." ) ; skipToEOL () ; return ; } if ( searchDefines ( token ) == -1 ) skippingFlag |= ( 1 << next_skippingLevel++ ) ; else skippingFlag &= ~( 1 << next_skippingLevel++ ) ; } void pslCompiler::doIfndefStatement () { char token [ MAX_TOKEN ] ; getToken ( token, FALSE ) ; if ( next_skippingLevel >= 30 ) { error ( "Too many levels of #ifdef/#ifndef processing." ) ; skipToEOL () ; return ; } if ( searchDefines ( token ) == -1 ) skippingFlag &= ~( 1 << next_skippingLevel++ ) ; else skippingFlag |= ( 1 << next_skippingLevel++ ) ; skipToEOL () ; } void pslCompiler::doElseStatement () { if ( next_skippingLevel <= 1 ) error ( "#else without prior matching #ifdef/#ifndef." ) ; skipToEOL () ; skippingFlag ^= ( 1 << (next_skippingLevel-1) ) ; } void pslCompiler::doEndifStatement () { if ( next_skippingLevel <= 1 ) error ( "#endif without prior matching #ifdef/#ifndef." ) ; skipToEOL () ; skippingFlag &= ~( 1 << (--next_skippingLevel) ) ; } void pslCompiler::doDefineStatement () { char token [ MAX_TOKEN ] ; char subst [ 1024 ] ; char *p ; getToken ( token, FALSE ) ; if ( ( token[0] < 'a' || token[0] > 'z' ) && ( token[0] < 'A' || token[0] > 'Z' ) && token[0] != '_' ) { error ( "#define token is not a legal identifier" ) ; skipToEOL () ; return ; } int c ; p = subst ; do { c = getChar () ; *(p++) = c ; } while ( c != -1 && c != '\n' ) ; *(p-1) = '\0' ; if ( ! skipping () ) { if ( searchDefines ( token ) != -1 ) error ( "Attempt to re-#define %s", token ) ; else if ( next_define >= MAX_SYMBOL - 1 ) error ( "Too many #define's\n" ) ; else { define_token [ next_define ] = ulStrDup ( token ) ; define_replacement [ next_define ] = ulStrDup ( subst ) ; next_define++ ; } } } void pslCompiler::doIncludeStatement () { char token [ MAX_TOKEN ] ; char *p ; getToken ( token ) ; if ( token[0] == '"' ) p = token + 1 ; else if ( token[0] == '<' ) { p = token ; do { *p = getChar () ; } while ( *(p++) != '>' ) ; *(p-1) = '\0' ; p = token ; } else { error ( "Illegal character after '#include'" ) ; skipToEOL () ; return ; } /* Skip to the end of this line of text BEFORE we hand control over to the next file. */ skipToEOL () ; if ( ! skipping () ) _pslPushDefaultFile ( p ) ; } int pslCompiler::doPreProcessorCommand () { char token [ MAX_TOKEN ] ; getToken ( token ) ; if ( strcmp ( token, "include" ) == 0 ) { doIncludeStatement () ; return getChar () ; } if ( strcmp ( token, "undef" ) == 0 ) { doUndefStatement () ; return '\n' ; } if ( strcmp ( token, "define" ) == 0 ) { doDefineStatement () ; return '\n' ; } if ( strcmp ( token, "ifndef" ) == 0 ) { doIfndefStatement () ; return getChar () ; } if ( strcmp ( token, "ifdef" ) == 0 ) { doIfdefStatement () ; return getChar () ; } if ( strcmp ( token, "endif" ) == 0 ) { doEndifStatement () ; return getChar () ; } if ( strcmp ( token, "else" ) == 0 ) { doElseStatement () ; return getChar () ; } error ( "Unrecognised preprocessor directive '%s'", token ) ; skipToEOL () ; return '\n' ; } void pslCompiler::getToken ( char *res, int define_sub ) { /* WARNING -- RECURSIVE -- WARNING -- RECURSIVE -- WARNING -- RECURSIVE */ if ( unget_token_stack_depth > 0 ) { strcpy ( res, ungotten_token [ --unget_token_stack_depth ] ) ; return ; } int c ; do { c = getChar () ; if ( c < 0 ) { res [ 0 ] = '\0' ; return ; } if ( c == '/' ) { int d = getChar () ; if ( d == '/' ) /* C++ style comment */ { do { d = getChar () ; } while ( d != '\n' && d != -1 ) ; c = ' ' ; } else if ( d == '*' ) /* C style comment */ { /* YUK! This is *so* horrible to get right. Just think about this case! ==> **/ do { /* Search for a star or an EOF */ do { d = getChar () ; } while ( d != '*' && d != -1 ) ; c = getChar () ; /* If you get two stars in a row - unget the second one */ if ( c == '*' ) _pslUnGetChar ( '*' ) ; } while ( c != '/' ) ; c = ' ' ; } else _pslUnGetChar ( d ) ; } } while ( isspace ( c ) ) ; int tp = 0 ; if ( c == '"' ) { int isBkSlash = FALSE ; do { if ( c == '\\' ) { if ( isBkSlash ) { isBkSlash = FALSE ; res [ tp++ ] = c ; } else isBkSlash = TRUE ; } else if ( isBkSlash ) { switch ( c ) { case '0' : res [ tp++ ] = '\0' ; break ; case 'r' : res [ tp++ ] = '\r' ; break ; case 't' : res [ tp++ ] = '\t' ; break ; case 'n' : res [ tp++ ] = '\n' ; break ; case 'f' : res [ tp++ ] = '\f' ; break ; case 'b' : res [ tp++ ] = '\b' ; break ; case 'a' : res [ tp++ ] = '\a' ; break ; default : res [ tp++ ] = c ; break ; } isBkSlash = FALSE ; } else res [ tp++ ] = c ; c = getChar () ; if ( tp >= MAX_TOKEN - 1 ) { error ( "Input string is bigger than %d characters!", MAX_TOKEN - 1 ) ; tp-- ; } } while ( ( isBkSlash || c != '"' ) && c != -1 ) ; if ( c == -1 ) error ( "Missing \\\" character" ) ; /* The trailing quotes character is not included into the string */ res [ tp ] = '\0' ; return ; } if ( c == '\'' ) { res [ tp++ ] = '\'' ; c = getChar () ; if ( c == '\\' ) { c = getChar () ; switch ( c ) { case '0' : res [ tp++ ] = '\0' ; break ; case 'r' : res [ tp++ ] = '\r' ; break ; case 't' : res [ tp++ ] = '\t' ; break ; case 'n' : res [ tp++ ] = '\n' ; break ; case 'f' : res [ tp++ ] = '\f' ; break ; case 'b' : res [ tp++ ] = '\b' ; break ; case 'a' : res [ tp++ ] = '\a' ; break ; default : res [ tp++ ] = c ; break ; } } else res [ tp++ ] = c ; c = getChar () ; if ( c != '\'' ) error ( "Missing \\' character" ) ; /* The trailing quote character is not included into the string */ res [ tp ] = '\0' ; return ; } if ( isalnum ( c ) || c == '.' || c == '_' ) /* variables and numbers */ { while ( isalnum ( c ) || c == '.' || c == '_' ) { res [ tp++ ] = c ; c = getChar () ; if ( tp >= MAX_TOKEN - 1 ) { error ( "Input string is bigger than %d characters!", MAX_TOKEN - 1 ) ; tp-- ; } } _pslUnGetChar ( c ) ; } else /* Deal with: <<, >>, <<=, >>=, /=, +=, -=, *=, %=, &=, |=, <=, >=, ==, !=, ++, -- */ if ( c == '*' || c == '/' || c == '%' || c == '<' || c == '>' || c == '=' || c == '!' || c == '&' || c == '|' || c == '+' || c == '-' ) { res [ tp++ ] = c ; int c2 = getChar () ; if ( c2 == '=' || ( c == '>' && c2 == '>' ) || ( c == '<' && c2 == '<' ) || ( c == '&' && c2 == '&' ) || ( c == '|' && c2 == '|' ) || ( c == '+' && c2 == '+' ) || ( c == '-' && c2 == '-' ) ) { res [ tp++ ] = c2 ; if ( ( c == '<' && c2 == '<' ) || ( c == '>' && c2 == '>' ) ) { int c3 = getChar () ; if ( c3 == '=' ) res [ tp++ ] = c3 ; else _pslUnGetChar ( c3 ) ; } } else _pslUnGetChar ( c2 ) ; } else { res [ 0 ] = c ; tp = 1 ; } res [ tp ] = '\0' ; /* Don't do define substituting if told not to */ if ( ! define_sub ) return ; /* Do #define expansion. */ int def = searchDefines ( res ) ; if ( def == -1 ) return ; /* If there is a replacement for this token, un-get it so it's the next thing we'll read. */ for ( int i = strlen ( define_replacement [ def ] ) - 1 ; i >= 0 ; i-- ) _pslUnGetChar ( define_replacement [ def ][ i ] ) ; /* Then have another try at reading the token. */ getToken ( res ) ; } void pslCompiler::ungetToken ( const char *s ) { if ( unget_token_stack_depth >= MAX_UNGET-1 ) { error ( "Too many ungetTokens! This must be an *UGLY* PSL program!" ) ; exit ( -1 ) ; } strcpy ( ungotten_token[unget_token_stack_depth++], s ) ; } plib-1.8.5/src/psl/psl.cxx0000644000175000001440000000337610765364440012321 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: psl.cxx 1708 2002-09-27 21:19:59Z ude $ */ #include "pslLocal.h" int _pslInitialised = FALSE ; static char *_pslScriptPath = NULL ; void pslInit () { _pslInitialised = TRUE ; } void pslScriptPath ( const char *path ) { delete [] _pslScriptPath ; _pslScriptPath = ulStrDup ( path ) ; } char* _pslMakeScriptPath ( char* path, const char* fname ) { if ( fname != NULL && fname [ 0 ] != '\0' ) { if ( ! ulIsAbsolutePathName ( fname ) && _pslScriptPath != NULL && _pslScriptPath[0] != '\0' ) { strcpy ( path, _pslScriptPath ) ; strcat ( path, "/" ) ; strcat ( path, fname ) ; } else strcpy ( path, fname ) ; /* Convert backward slashes to forward slashes */ for ( char* ptr = path ; *ptr ; ptr ++ ) if ( *ptr == '\\' ) *ptr = '/' ; } else path [0] = 0 ; return path ; } plib-1.8.5/src/psl/Makefile.am0000644000175000001440000000100210765364440013013 00000000000000 if BUILD_PSL lib_LIBRARIES = libplibpsl.a include_HEADERS = psl.h libplibpsl_a_SOURCES = psl.cxx pslCodeGen.cxx pslContext.cxx \ pslCompiler.cxx pslSymbols.cxx pslToken.cxx \ pslExpression.cxx pslProgram.cxx pslDump.cxx \ pslError.cxx pslFileIO.cxx pslCompiler.h \ pslContext.h pslFileIO.h pslLocal.h \ pslOpcodes.h pslSymbol.h INCLUDES = -I$(top_srcdir)/src/util endif EXTRA_DIST = psl.dsp plib-1.8.5/src/psl/pslCodeGen.cxx0000644000175000001440000002112010765364440013531 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslCodeGen.cxx 1891 2004-03-18 22:09:07Z sjbaker $ */ #include "pslLocal.h" void pslCompiler::genCodeByte ( pslOpcode op ) { if ( next_code >= MAX_CODE - 1 ) error ( "Program too big!" ) ; else code [ next_code++ ] = op ; } void pslCompiler::genCodeAddr ( pslAddress a ) { genCodeByte ( a & 0xFF ) ; genCodeByte ( ( a >> 8 ) & 0xFF ) ; } void pslCompiler::genLineNumber ( int l ) { genCodeByte ( OPCODE_LINE_NUMBER ) ; genCodeByte ( l & 0xFF ) ; genCodeByte ( ( l >> 8 ) & 0xFF ) ; } void pslCompiler::genCharConstant ( char c ) { /* A bit wasteful but... */ genCodeByte ( OPCODE_PUSH_INT_CONSTANT ) ; genCodeByte ( c ) ; genCodeByte ( 0 ) ; genCodeByte ( 0 ) ; genCodeByte ( 0 ) ; } void pslCompiler::genConstant ( const char *c ) { int isInteger = TRUE ; for ( const char *p = c ; *p != '\0' ; p++ ) if ( *p == '.' || *p == 'f' || *p == 'F' ) { isInteger = FALSE ; break ; } if ( isInteger ) genIntConstant ( c ) ; else genFloatConstant ( c ) ; } void pslCompiler::genStringConstant ( const char *c ) { genCodeByte ( OPCODE_PUSH_STRING_CONSTANT ) ; for ( int i = 0 ; c [ i ] != '\0' ; i++ ) genCodeByte ( (unsigned char)( c [ i ]) ) ; genCodeByte ( '\0' ) ; } void pslCompiler::genIntConstant ( int i ) { char *ii = (char *) & i ; genCodeByte ( OPCODE_PUSH_INT_CONSTANT ) ; genCodeByte ( ii [ 0 ] ) ; genCodeByte ( ii [ 1 ] ) ; genCodeByte ( ii [ 2 ] ) ; genCodeByte ( ii [ 3 ] ) ; } void pslCompiler::genIntConstant ( const char *c ) { int i = (int) strtol ( c, NULL, 0 ) ; genIntConstant ( i ) ; } void pslCompiler::genFloatConstant ( const char *c ) { float f = (float) atof ( c ) ; char *ff = (char *) & f ; genCodeByte ( OPCODE_PUSH_FLOAT_CONSTANT ) ; genCodeByte ( ff [ 0 ] ) ; genCodeByte ( ff [ 1 ] ) ; genCodeByte ( ff [ 2 ] ) ; genCodeByte ( ff [ 3 ] ) ; } void pslCompiler::genGetParameter ( pslAddress var, int argpos ) { genCodeByte ( OPCODE_GET_PARAMETER ) ; genCodeByte ( (unsigned char) var ) ; genCodeByte ( argpos ) ; } int pslCompiler::genMakeIntArray ( const char *c ) { int a = getVarSymbol ( c ) ; genCodeByte ( OPCODE_SET_INT_ARRAY ) ; genCodeByte ( a ) ; return a ; } int pslCompiler::genMakeFloatArray ( const char *c ) { int a = getVarSymbol ( c ) ; genCodeByte ( OPCODE_SET_FLOAT_ARRAY ) ; genCodeByte ( a ) ; return a ; } int pslCompiler::genMakeStringArray ( const char *c ) { int a = getVarSymbol ( c ) ; genCodeByte ( OPCODE_SET_STRING_ARRAY ) ; genCodeByte ( a ) ; return a ; } int pslCompiler::genMakeIntVariable ( const char *c ) { int a = getVarSymbol ( c ) ; genCodeByte ( OPCODE_SET_INT_VARIABLE ) ; genCodeByte ( a ) ; return a ; } int pslCompiler::genMakeFloatVariable ( const char *c ) { int a = getVarSymbol ( c ) ; genCodeByte ( OPCODE_SET_FLOAT_VARIABLE ) ; genCodeByte ( a ) ; return a ; } int pslCompiler::genMakeStringVariable ( const char *c ) { int a = getVarSymbol ( c ) ; genCodeByte ( OPCODE_SET_STRING_VARIABLE ) ; genCodeByte ( a ) ; return a ; } void pslCompiler::genVariable ( const char *c, int array_ref ) { int a = getVarSymbol ( c ) ; genIntConstant ( array_ref ) ; genIntConstant ( a ) ; } void pslCompiler::genFetch () { genCodeByte ( OPCODE_FETCH ) ; } void pslCompiler::genIncrementFetch () { genCodeByte ( OPCODE_INCREMENT_FETCH ) ; } void pslCompiler::genDecrementFetch () { genCodeByte ( OPCODE_DECREMENT_FETCH ) ; } void pslCompiler::genIncrementLValue () { genCodeByte ( OPCODE_INCREMENT_LVALUE ) ; } void pslCompiler::genDecrementLValue () { genCodeByte ( OPCODE_DECREMENT_LVALUE ) ; } void pslCompiler::genAssignment () { genCodeByte ( OPCODE_POP_VARIABLE ) ; } void pslCompiler::genAddAssignment () { genCodeByte ( OPCODE_POP_ADD_VARIABLE ) ; } void pslCompiler::genSubAssignment () { genCodeByte ( OPCODE_POP_SUB_VARIABLE ) ; } void pslCompiler::genMulAssignment () { genCodeByte ( OPCODE_POP_MUL_VARIABLE ) ; } void pslCompiler::genModAssignment () { genCodeByte ( OPCODE_POP_MOD_VARIABLE ) ; } void pslCompiler::genDivAssignment () { genCodeByte ( OPCODE_POP_DIV_VARIABLE ) ; } void pslCompiler::genAndAssignment () { genCodeByte ( OPCODE_POP_AND_VARIABLE ) ; } void pslCompiler::genOrAssignment () { genCodeByte ( OPCODE_POP_OR_VARIABLE ) ; } void pslCompiler::genXorAssignment () { genCodeByte ( OPCODE_POP_XOR_VARIABLE ) ; } void pslCompiler::genSHLAssignment () { genCodeByte ( OPCODE_POP_SHL_VARIABLE ) ; } void pslCompiler::genSHRAssignment () { genCodeByte ( OPCODE_POP_SHR_VARIABLE ) ; } void pslCompiler::genCall ( const char *c, int argc ) { int ext = getExtensionSymbol ( c ) ; if ( ext < 0 ) { genIntConstant ( argc ) ; genCodeByte ( OPCODE_CALL ) ; int a = getCodeSymbol ( c, next_code ) ; genCodeAddr ( a ) ; genCodeByte ( argc ) ; } else { genCodeByte ( OPCODE_CALLEXT ) ; genCodeByte ( ext ) ; genCodeByte ( argc ) ; } } void pslCompiler::genExchange () { genCodeByte ( OPCODE_EXCHANGE ) ; } void pslCompiler::genReturn () { genCodeByte ( OPCODE_RETURN ) ; } void pslCompiler::genPop () { genCodeByte ( OPCODE_POP ) ; } void pslCompiler::genSubtract () { genCodeByte ( OPCODE_SUB ) ; } void pslCompiler::genAdd () { genCodeByte ( OPCODE_ADD ) ; } void pslCompiler::genDivide () { genCodeByte ( OPCODE_DIV ) ; } void pslCompiler::genMultiply () { genCodeByte ( OPCODE_MULT ) ; } void pslCompiler::genModulo () { genCodeByte ( OPCODE_MOD ) ; } void pslCompiler::genNegate () { genCodeByte ( OPCODE_NEG ) ; } void pslCompiler::genNot () { genCodeByte ( OPCODE_NOT ) ; } void pslCompiler::genTwiddle () { genCodeByte ( OPCODE_TWIDDLE ) ; } void pslCompiler::genOrOr () { genCodeByte ( OPCODE_OROR ) ; } void pslCompiler::genAndAnd () { genCodeByte ( OPCODE_ANDAND ) ; } void pslCompiler::genOr () { genCodeByte ( OPCODE_OR ) ; } void pslCompiler::genAnd () { genCodeByte ( OPCODE_AND ) ; } void pslCompiler::genXor () { genCodeByte ( OPCODE_XOR ) ; } void pslCompiler::genShiftLeft () { genCodeByte ( OPCODE_SHIFTLEFT ) ; } void pslCompiler::genShiftRight () { genCodeByte ( OPCODE_SHIFTRIGHT ) ; } void pslCompiler::genLess () { genCodeByte ( OPCODE_LESS ) ; } void pslCompiler::genLessEqual () { genCodeByte ( OPCODE_LESSEQUAL ) ; } void pslCompiler::genGreater () { genCodeByte ( OPCODE_GREATER ) ; } void pslCompiler::genGreaterEqual () { genCodeByte ( OPCODE_GREATEREQUAL); } void pslCompiler::genNotEqual () { genCodeByte ( OPCODE_NOTEQUAL ) ; } void pslCompiler::genEqual () { genCodeByte ( OPCODE_EQUAL ) ; } void pslCompiler::genStackDup () { genCodeByte ( OPCODE_STACK_DUPLICATE ) ; } int pslCompiler::genPeekJumpIfTrue ( int l ) { genCodeByte ( OPCODE_PEEK_JUMP_TRUE ) ; int res = next_code ; genCodeAddr ( l ) ; return res ; } int pslCompiler::genPeekJumpIfFalse ( int l ) { genCodeByte ( OPCODE_PEEK_JUMP_FALSE ) ; int res = next_code ; genCodeAddr ( l ) ; return res ; } int pslCompiler::genJumpIfTrue ( int l ) { genCodeByte ( OPCODE_JUMP_TRUE ) ; int res = next_code ; genCodeAddr ( l ) ; return res ; } int pslCompiler::genJumpIfFalse ( int l ) { genCodeByte ( OPCODE_JUMP_FALSE ) ; int res = next_code ; genCodeAddr ( l ) ; return res ; } int pslCompiler::genJump ( int l ) { genCodeByte ( OPCODE_JUMP ) ; int res = next_code ; genCodeAddr ( l ) ; return res ; } int pslCompiler::genPauseStatement() { genCodeByte ( OPCODE_PAUSE ) ; return TRUE ; } plib-1.8.5/src/psl/pslFileIO.h0000644000175000001440000000245010765364440012766 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslFileIO.h 1745 2003-01-06 05:10:14Z sjbaker $ */ char *_pslGetFname () ; int _pslGetLineNo () ; void _pslPopDefaultFile () ; void _pslPushDefaultFile ( FILE *fd, const char *fname ) ; void _pslPushDefaultFile ( const char *memptr, const char *fname ) ; void _pslPushDefaultFile ( const char *fname ) ; void _pslUnGetChar ( int c ) ; int _pslGetChar () ; plib-1.8.5/src/psl/psl.dsp0000644000175000001440000001004610765364440012275 00000000000000# Microsoft Developer Studio Project File - Name="psl" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=psl - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "psl.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "psl.mak" CFG="psl - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "psl - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "psl - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "psl - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\util" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy psl.h ..\..\psl.h # End Special Build Tool !ELSEIF "$(CFG)" == "psl - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\util" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\psl_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy psl.h ..\..\psl.h # End Special Build Tool !ENDIF # Begin Target # Name "psl - Win32 Release" # Name "psl - Win32 Debug" # Begin Source File SOURCE=.\pslCodeGen.cxx # End Source File # Begin Source File SOURCE=.\pslCompiler.cxx # End Source File # Begin Source File SOURCE=.\pslCompiler.h # End Source File # Begin Source File SOURCE=.\pslContext.cxx # End Source File # Begin Source File SOURCE=.\pslContext.h # End Source File # Begin Source File SOURCE=.\psl.cxx # End Source File # Begin Source File SOURCE=.\pslDump.cxx # End Source File # Begin Source File SOURCE=.\pslError.cxx # End Source File # Begin Source File SOURCE=.\pslExpression.cxx # End Source File # Begin Source File SOURCE=.\pslFileIO.cxx # End Source File # Begin Source File SOURCE=.\pslFileIO.h # End Source File # Begin Source File SOURCE=.\psl.h # End Source File # Begin Source File SOURCE=.\pslLocal.h # End Source File # Begin Source File SOURCE=.\pslOpcodes.h # End Source File # Begin Source File SOURCE=.\pslProgram.cxx # End Source File # Begin Source File SOURCE=.\pslSymbol.h # End Source File # Begin Source File SOURCE=.\pslSymbols.cxx # End Source File # Begin Source File SOURCE=.\pslToken.cxx # End Source File # End Target # End Project plib-1.8.5/src/psl/pslContext.cxx0000644000175000001440000005147210765364440013666 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslContext.cxx 1703 2002-09-22 20:49:05Z ude $ */ #include "pslLocal.h" pslVariable *pslContext::peekLValue () { return ( stack[sp-2].getInt() == 0 ) ? & ( variable [ stack[sp-1].getInt() ] ) : variable [ stack[sp-1].getInt() ] . getIndex ( stack [ sp-3 ].getInt() ) ; } pslVariable *pslContext::popLValue () { if ( stack[sp-2].getInt() == 0 ) { sp -= 2 ; return & ( variable [ stack[sp+1].getInt() ] ) ; } else { sp -= 3 ; return variable [ stack[sp+2].getInt() ] . getIndex ( stack [ sp ].getInt() ) ; } } pslResult pslContext::step () { switch ( code [ pc ] ) { case OPCODE_BAD : error ( "Suspicious opcode 0x00?!", code[pc] ) ; pc++ ; return PSL_PROGRAM_END ; case OPCODE_LINE_NUMBER : line_no = code [ pc + 1 ] + ( code [ pc + 2 ] << 8 ) ; pc+=3 ; return PSL_PROGRAM_CONTINUE ; case OPCODE_PUSH_INT_CONSTANT : { int ii ; memcpy ( & ii, & code [ pc+1 ], sizeof(int) ) ; pushInt ( ii ) ; pc += sizeof(int) + 1 ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_PUSH_FLOAT_CONSTANT : { float ff ; memcpy ( & ff, & code [ pc+1 ], sizeof(float) ) ; pushFloat ( ff ) ; pc += sizeof(float) + 1 ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_PUSH_STRING_CONSTANT : { char *ff = (char *) & code [ pc+1 ] ; pushString ( ff ) ; pc += strlen ( ff ) + 1 + 1 ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_GET_PARAMETER : { int var = code [ ++pc ] ; int nargs = stack [ sp - 2 ] . getInt () ; int off = sp - ( nargs + 2 ) + code [ ++pc ] ; variable [ var ] . set ( & stack [ off ] ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP : popVoid() ; pc++ ; return PSL_PROGRAM_CONTINUE ; case OPCODE_CALLEXT : { int ext = code [ ++pc ] ; int argc = code [ ++pc ] ; int required_argc = extensions [ ext ] . argc ; if ( required_argc >= 0 && argc != required_argc ) { warning ( "Wrong number of parameters for function %s\n", extensions [ ext ] . symbol ) ; } pslValue argv [ MAX_ARGS ] ; /* Pop args off the stack in reverse order */ for ( int i = argc-1 ; i >= 0 ; i-- ) popNumber ( & argv[i] ) ; /* Euwww! */ pslValue v = (*(extensions [ ext ] . func)) (argc,argv,program) ; pushNumber ( & v ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_CALL : pushInt ( pc+4 ) ; memcpy ( & pc, & code [ pc+1 ], sizeof ( int ) ) ; return PSL_PROGRAM_CONTINUE ; case OPCODE_RETURN : { int nargs ; pslValue result ; popNumber ( &result ) ; pc = popInt () ; nargs = popInt () ; popVoid ( nargs ) ; pushNumber ( &result ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_STACK_DUPLICATE : { pslValue *v1 = & stack [ sp - 1 ] ; pushNumber ( v1 ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_SUB : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() - v1 -> getFloat() ) ; else v2 -> set ( v2 -> getInt() - v1 -> getInt() ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_SHIFTLEFT : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; v2 -> set ( v2 -> getInt () << v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_SHIFTRIGHT : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; v2 -> set ( v2 -> getInt () >> v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_ADD : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() + v1 -> getFloat() ) ; else if ( v1->getType() == PSL_STRING && v2->getType() == PSL_STRING ) { int v1_len = strlen ( v1 -> getString () ) ; int v2_len = strlen ( v2 -> getString () ) ; char *s = new char [ v1_len + v2_len + 1 ] ; memcpy ( s, v2 -> getString (), v2_len ) ; memcpy ( s+v2_len, v1 -> getString (), v1_len+1 ) ; v2 -> set ( s ) ; delete [] s ; } else v2 -> set ( v2 -> getInt () + v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_NOT : { pslValue *v1 = & stack [ sp - 1 ] ; v1 -> set ( ! v1 -> getInt () ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_TWIDDLE : { pslValue *v1 = & stack [ sp - 1 ] ; v1 -> set ( ~ v1 -> getInt () ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_OROR : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; v2 -> set ( v2 -> getInt () || v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_ANDAND : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; v2 -> set ( v2 -> getInt () && v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_OR : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; v2 -> set ( v2 -> getInt () | v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_AND : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; v2 -> set ( v2 -> getInt () & v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_XOR : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; v2 -> set ( v2 -> getInt () ^ v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_DIV : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) { if ( v1 -> getFloat() != 0.0f ) v2 -> set ( v2 -> getFloat() / v1 -> getFloat() ) ; else warning ( "Floating Point Divide by Zero!" ) ; } else { if ( v1 -> getInt() != 0 ) v2 -> set ( v2 -> getInt() / v1 -> getInt() ) ; else warning ( "Integer Divide by Zero!" ) ; } popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_MOD : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) { warning ( "Floating Point Modulo!" ) ; } else { if ( v1 -> getInt() != 0 ) v2 -> set ( v2 -> getInt () % v1 -> getInt () ) ; else warning ( "Integer Modulo Zero!" ) ; } popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_MULT : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() * v1 -> getFloat() ) ; else v2 -> set ( v2 -> getInt () * v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_NEG : { pslValue *v1 = & stack [ sp - 1 ] ; if ( v1->getType() == PSL_FLOAT ) v1 -> set ( - v1 -> getFloat() ) ; else v1 -> set ( - v1 -> getInt () ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_LESS : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() < v1 -> getFloat() ) ; else v2 -> set ( v2 -> getInt () < v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_LESSEQUAL : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() <= v1 -> getFloat() ) ; else v2 -> set ( v2 -> getInt () <= v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_GREATER : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() > v1 -> getFloat() ) ; else v2 -> set ( v2 -> getInt () > v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_GREATEREQUAL : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() >= v1 -> getFloat() ) ; else v2 -> set ( v2 -> getInt () >= v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_NOTEQUAL : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() != v1 -> getFloat() ) ; else v2 -> set ( v2 -> getInt () != v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_EQUAL : { pslValue *v1 = & stack [ sp - 1 ] ; pslValue *v2 = & stack [ sp - 2 ] ; if ( v1->getType() == PSL_FLOAT || v2->getType() == PSL_FLOAT ) v2 -> set ( v2 -> getFloat() == v1 -> getFloat() ) ; else v2 -> set ( v2 -> getInt () == v1 -> getInt () ) ; popVoid () ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_PAUSE : pc++ ; return PSL_PROGRAM_PAUSE ; case OPCODE_HALT : return PSL_PROGRAM_END ; /* Note: PC is *NOT* incremented. */ case OPCODE_PEEK_JUMP_TRUE : if ( peekInt () ) pc = code [ pc + 1 ] + ( code [ pc + 2 ] << 8 ) ; else { sp-- ; pc += 3 ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_PEEK_JUMP_FALSE : if ( peekInt () ) { sp-- ; pc += 3 ; } else pc = code [ pc + 1 ] + ( code [ pc + 2 ] << 8 ) ; return PSL_PROGRAM_CONTINUE ; case OPCODE_JUMP_TRUE : if ( popInt () ) pc = code [ pc + 1 ] + ( code [ pc + 2 ] << 8 ) ; else pc += 3 ; return PSL_PROGRAM_CONTINUE ; case OPCODE_JUMP_FALSE : if ( popInt () ) pc += 3 ; else pc = code [ pc + 1 ] + ( code [ pc + 2 ] << 8 ) ; return PSL_PROGRAM_CONTINUE ; case OPCODE_JUMP : pc = code [ pc + 1 ] + ( code [ pc + 2 ] << 8 ) ; return PSL_PROGRAM_CONTINUE ; case OPCODE_PUSH_VARIABLE : pushNumber ( & variable [ code[++pc] ] ) ; pc++ ; return PSL_PROGRAM_CONTINUE ; case OPCODE_EXCHANGE : { pslValue n = stack [ sp - 1 ] ; stack [ sp - 1 ] = stack [ sp - 2 ] ; stack [ sp - 2 ] = n ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_ADD_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; if ( v -> getType () == PSL_INT ) v -> set ( v -> getInt() + s -> getInt() ) ; else if ( v -> getType () == PSL_STRING ) { int s1_len = strlen ( v -> getString () ) ; int s2_len = strlen ( s -> getString () ) ; char *str = new char [ s1_len + s2_len + 1 ] ; memcpy ( str, v -> getString (), s1_len ) ; memcpy ( str+s1_len, s -> getString (), s2_len+1 ) ; v -> set ( str ) ; delete [] str ; } else v -> set ( v -> getFloat() + s -> getFloat() ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_SUB_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; if ( v -> getType () == PSL_INT ) v -> set ( v -> getInt() - s -> getInt() ) ; else v -> set ( v -> getFloat() - s -> getFloat() ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_MUL_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; if ( v -> getType () == PSL_INT ) v -> set ( v -> getInt() * s -> getInt() ) ; else v -> set ( v -> getFloat() * s -> getFloat() ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_MOD_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; if ( v -> getType () == PSL_INT ) { if ( s -> getInt () != 0 ) v -> set ( v -> getInt() % s -> getInt() ) ; else warning ( "Integer Modulo by Zero!" ) ; } else warning ( "Floating Point Modulo!" ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_DIV_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; if ( v -> getType () == PSL_INT ) { if ( s -> getInt () != 0 ) v -> set ( v -> getInt() / s -> getInt() ) ; else warning ( "Integer Divide by Zero!" ) ; } else { if ( s -> getFloat () != 0.0f ) v -> set ( v -> getFloat() / s -> getFloat() ) ; else warning ( "Floating Point Divide by Zero!" ) ; } pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_AND_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; v -> set ( v -> getInt() & s -> getInt() ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_OR_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; v -> set ( v -> getInt() | s -> getInt() ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_XOR_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; v -> set ( v -> getInt() ^ s -> getInt() ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_SHL_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; v -> set ( v -> getInt() << s -> getInt() ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_SHR_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; v -> set ( v -> getInt() >> s -> getInt() ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_POP_VARIABLE : { pslValue *s = & stack[--sp] ; pslVariable *v = popLValue () ; if ( v -> getType () == PSL_INT ) v -> set ( s -> getInt () ) ; else if ( v -> getType () == PSL_FLOAT ) v -> set ( s -> getFloat () ) ; else v -> set ( s -> getString () ) ; pc++ ; pushNumber ( v ) ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_SET_INT_ARRAY : variable [ code[++pc] ] . setArrayType ( PSL_INT, stack[--sp].getInt() ) ; pc++ ; return PSL_PROGRAM_CONTINUE ; case OPCODE_SET_FLOAT_ARRAY : variable [ code[++pc] ] . setArrayType ( PSL_FLOAT, stack[--sp].getInt() ) ; pc++ ; return PSL_PROGRAM_CONTINUE ; case OPCODE_SET_STRING_ARRAY : variable [ code[++pc] ] . setArrayType ( PSL_STRING, stack[--sp].getInt() ) ; pc++ ; return PSL_PROGRAM_CONTINUE ; case OPCODE_SET_INT_VARIABLE : { pslVariable *v = & ( variable [ code[++pc] ] ) ; v -> setType ( PSL_INT ) ; v -> set ( 0 ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_SET_FLOAT_VARIABLE : { pslVariable *v = & ( variable [ code[++pc] ] ) ; v -> setType ( PSL_FLOAT ) ; v -> set ( 0.0f ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_SET_STRING_VARIABLE : { pslVariable *v = & ( variable [ code[++pc] ] ) ; v -> setType ( PSL_STRING ) ; v -> set ( "" ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_FETCH : { pslVariable *v = popLValue () ; pushNumber ( v ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_INCREMENT_LVALUE : { pslVariable *v = peekLValue () ; if ( v -> getType () == PSL_INT ) v -> set ( v -> getInt () + 1 ) ; else v -> set ( v -> getFloat () + 1 ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_DECREMENT_LVALUE : { pslVariable *v = peekLValue () ; if ( v -> getType () == PSL_INT ) v -> set ( v -> getInt () - 1 ) ; else v -> set ( v -> getFloat () - 1 ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_INCREMENT_FETCH : { pslVariable *v = popLValue () ; pushNumber ( v ) ; if ( v -> getType () == PSL_INT ) v -> set ( v -> getInt () + 1 ) ; else v -> set ( v -> getFloat () + 1 ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; case OPCODE_DECREMENT_FETCH : { pslVariable *v = popLValue () ; pushNumber ( v ) ; if ( v -> getType () == PSL_INT ) v -> set ( v -> getInt () - 1 ) ; else v -> set ( v -> getFloat () - 1 ) ; pc++ ; } return PSL_PROGRAM_CONTINUE ; default : error ( "Suspicious opcode 0x02x?!", code[pc] ) ; return PSL_PROGRAM_END ; } } void pslContext::printStack ( FILE *fd ) const { fprintf ( fd, "STACK [%d deep] : ", sp ) ; if ( sp >= 8 ) fprintf ( stderr, "..." ) ; for ( int i = (sp<8)? 0 : (sp-8) ; i < sp ; i++ ) switch ( stack[i].getType () ) { case PSL_INT : fprintf ( fd, "%d " , stack[i].getInt () ) ; break ; case PSL_FLOAT : fprintf ( fd, "%gf " , stack[i].getFloat () ) ; break ; case PSL_STRING : fprintf ( fd, "'%s' ", stack[i].getString() ) ; break ; case PSL_VOID : fprintf ( fd, " " ) ; break ; } fprintf ( fd, "\n" ) ; } plib-1.8.5/src/psl/psl.h0000644000175000001440000001733210765364440011743 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: psl.h 2072 2006-03-25 00:35:57Z bram $ */ #ifndef _PSL_H #define _PSL_H 1 #include #include "ul.h" enum pslResult { PSL_PROGRAM_END, PSL_PROGRAM_PAUSE, PSL_PROGRAM_CONTINUE } ; #define PSL_COMPILETIME_WARNING 1 #define PSL_COMPILETIME_ERROR 2 #define PSL_RUNTIME_WARNING 3 #define PSL_RUNTIME_ERROR 4 typedef unsigned char pslOpcode ; class pslContext ; class pslCompiler ; class pslProgram ; enum pslType { PSL_INT = 0, PSL_FLOAT = 1, PSL_STRING = 3, PSL_VOID = 4 } ; class pslNumber { protected: union { int i ; float f ; } ; char *s ; pslType t ; public: pslNumber () { t = PSL_VOID ; s = NULL ; } virtual ~pslNumber () { } virtual void set ( int ) = 0 ; virtual void set ( float ) = 0 ; virtual void set ( const char * ) = 0 ; virtual void set ( const pslNumber * ) = 0 ; void reset () { t = PSL_VOID ; i = 0 ; delete [] s ; s = NULL ; } pslType getType () const { return t ; } void setType ( pslType _type ) { t = _type ; } int getInt () const { switch ( t ) { case PSL_INT : return i ; case PSL_FLOAT : return (int) f ; case PSL_STRING : return (int) strtol(s,NULL,0) ; case PSL_VOID : return 0 ; } return 0 ; } float getFloat () const { switch ( t ) { case PSL_INT : return (float) i ; case PSL_FLOAT : return f ; case PSL_STRING : return (float) atof( s ) ; case PSL_VOID : return 0.0f ; } return 0.0f ; } char *getString () const { switch ( t ) { case PSL_STRING : return s ; case PSL_INT : case PSL_FLOAT : case PSL_VOID : return NULL ; } return NULL ; } } ; /* psVariables can change value - but their type is fixed once set. */ class pslVariable : public pslNumber { pslVariable *array ; int array_size ; public: pslVariable () { array = NULL ; array_size = 0 ; } virtual ~pslVariable () { } void setArrayType ( pslType _type, int arraysize ) { setType ( _type ) ; delete [] array ; array_size = arraysize ; array = new pslVariable [ array_size ] ; for ( int i = 0 ; i < array_size ; i++ ) { array [ i ] . setType ( getType () ) ; array [ i ] . set ( 0 ) ; } } virtual void set ( int v ) { switch ( t ) { case PSL_INT : i = v ; return ; case PSL_FLOAT : f = (float) v ; return ; case PSL_STRING : case PSL_VOID : return ; } } virtual void set ( float v ) { switch ( t ) { case PSL_INT : i = (int) v ; return ; case PSL_FLOAT : f = v ; return ; case PSL_STRING : case PSL_VOID : return ; } } virtual void set ( const char *v ) { switch ( t ) { case PSL_INT : i = (int) strtol ( v, NULL, 0 ) ; return ; case PSL_FLOAT : f = (float) atof ( v ) ; return ; case PSL_STRING : delete [] s ; if ( v == NULL ) s = ulStrDup ( "" ) ; else s = ulStrDup ( v ) ; return ; case PSL_VOID : return ; } } virtual void set ( const pslNumber *v ) { switch ( t ) { case PSL_INT : set ( v -> getInt () ) ; return ; case PSL_FLOAT : set ( v -> getFloat () ) ; return ; case PSL_STRING : set ( v -> getString () ) ; return ; case PSL_VOID : return ; } } pslVariable *getIndex ( int index ) { if ( index < 0 || index >= array_size || array == NULL ) return this ; return & ( array [ index ] ) ; } virtual void set ( int v, int index ) { if ( index < 0 || index >= array_size || array == NULL ) set ( v ) ; array [ index ] . set ( v ) ; } virtual void set ( float v, int index ) { if ( index < 0 || index >= array_size || array == NULL ) set ( v ) ; array [ index ] . set ( v ) ; } virtual void set ( const char *v, int index ) { if ( index < 0 || index >= array_size || array == NULL ) set ( v ) ; array [ index ] . set ( v ) ; } virtual void set ( const pslNumber *v, int index ) { if ( index < 0 || index >= array_size || array == NULL ) set ( v ) ; array [ index ] . set ( v ) ; } } ; /* psValues can change their type as needed. */ class pslValue : public pslNumber { public: virtual ~pslValue () { } virtual void set () { t = PSL_VOID ; } virtual void set ( int v ) { t = PSL_INT ; i = v ; } virtual void set ( float v ) { t = PSL_FLOAT ; f = v ; } virtual void set ( const char *v ) { t = PSL_STRING ; delete [] s ; if ( v == NULL ) s = ulStrDup ( "" ) ; else s = ulStrDup ( v ) ; } virtual void set ( const pslNumber *v ) { t = v -> getType () ; switch ( t ) { case PSL_INT : set ( v -> getInt () ) ; break ; case PSL_FLOAT : set ( v -> getFloat () ) ; break ; case PSL_STRING : set ( v -> getString () ) ; break ; case PSL_VOID : break ; } } } ; class pslExtension { public: const char *symbol ; int argc ; pslValue (*func) ( int, pslValue *, pslProgram *p ) ; } ; class pslProgram { pslOpcode *code ; pslContext *context ; pslCompiler *compiler ; const pslExtension *extensions ; void *userData ; char *progName ; int force_trace ; int force_stacktrace ; public: pslProgram ( const pslExtension *ext, const char *_progName = NULL ) ; pslProgram ( pslProgram *src, const char *_progName = NULL ) ; ~pslProgram () ; pslContext *getContext () const { return context ; } pslOpcode *getCode () const { return code ; } pslCompiler *getCompiler () const { return compiler ; } const pslExtension *getExtensions () const { return extensions ; } int getStackTraceFlag () const { return force_stacktrace ; } char *getProgName () const { return progName ; } void setProgName ( const char *nm ) { delete [] progName ; progName = ulStrDup ( nm ) ; } void *getUserData () const { return userData ; } void setUserData ( void *ud ) { userData = ud ; } void dump () const ; int compile ( const char *fname ) ; int compile ( const char *memptr, const char *fname ) ; int compile ( FILE *fd ) ; void reset () ; pslResult step () ; pslResult trace () ; } ; void pslInit () ; void pslScriptPath ( const char *path ) ; void pslSetErrorCallback ( void (*CB) ( pslProgram *, int, char *, int, char * ) ) ; #endif plib-1.8.5/src/psl/Makefile.in0000644000175000001440000004137110765365023013037 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/psl DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibpsl_a_AR = $(AR) $(ARFLAGS) libplibpsl_a_LIBADD = am__libplibpsl_a_SOURCES_DIST = psl.cxx pslCodeGen.cxx pslContext.cxx \ pslCompiler.cxx pslSymbols.cxx pslToken.cxx pslExpression.cxx \ pslProgram.cxx pslDump.cxx pslError.cxx pslFileIO.cxx \ pslCompiler.h pslContext.h pslFileIO.h pslLocal.h pslOpcodes.h \ pslSymbol.h @BUILD_PSL_TRUE@am_libplibpsl_a_OBJECTS = psl.$(OBJEXT) \ @BUILD_PSL_TRUE@ pslCodeGen.$(OBJEXT) pslContext.$(OBJEXT) \ @BUILD_PSL_TRUE@ pslCompiler.$(OBJEXT) pslSymbols.$(OBJEXT) \ @BUILD_PSL_TRUE@ pslToken.$(OBJEXT) pslExpression.$(OBJEXT) \ @BUILD_PSL_TRUE@ pslProgram.$(OBJEXT) pslDump.$(OBJEXT) \ @BUILD_PSL_TRUE@ pslError.$(OBJEXT) pslFileIO.$(OBJEXT) libplibpsl_a_OBJECTS = $(am_libplibpsl_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libplibpsl_a_SOURCES) DIST_SOURCES = $(am__libplibpsl_a_SOURCES_DIST) am__include_HEADERS_DIST = psl.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_PSL_TRUE@lib_LIBRARIES = libplibpsl.a @BUILD_PSL_TRUE@include_HEADERS = psl.h @BUILD_PSL_TRUE@libplibpsl_a_SOURCES = psl.cxx pslCodeGen.cxx pslContext.cxx \ @BUILD_PSL_TRUE@ pslCompiler.cxx pslSymbols.cxx pslToken.cxx \ @BUILD_PSL_TRUE@ pslExpression.cxx pslProgram.cxx pslDump.cxx \ @BUILD_PSL_TRUE@ pslError.cxx pslFileIO.cxx pslCompiler.h \ @BUILD_PSL_TRUE@ pslContext.h pslFileIO.h pslLocal.h \ @BUILD_PSL_TRUE@ pslOpcodes.h pslSymbol.h @BUILD_PSL_TRUE@INCLUDES = -I$(top_srcdir)/src/util EXTRA_DIST = psl.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/psl/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/psl/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibpsl.a: $(libplibpsl_a_OBJECTS) $(libplibpsl_a_DEPENDENCIES) -rm -f libplibpsl.a $(libplibpsl_a_AR) libplibpsl.a $(libplibpsl_a_OBJECTS) $(libplibpsl_a_LIBADD) $(RANLIB) libplibpsl.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslCodeGen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslCompiler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslContext.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslDump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslError.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslExpression.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslFileIO.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslProgram.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslSymbols.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pslToken.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/psl/pslSymbols.cxx0000644000175000001440000000772410765364440013673 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslSymbols.cxx 1626 2002-09-08 22:17:32Z sjbaker $ */ #include "pslLocal.h" pslAddress pslCompiler::setVarSymbol ( const char *s ) { for ( int i = 0 ; i < next_var ; i++ ) if ( strcmp ( s, symtab [ i ] . symbol ) == 0 && symtab [ i ] . locality >= locality_sp ) { error ( "Multiple definition of '%s'.", s ) ; return symtab [ i ] . address ; } if ( next_var >= MAX_VARIABLE-1 ) { error ( "Too many variables." ) ; next_var-- ; } symtab [ next_var ] . set ( s, next_var, locality_sp ) ; return symtab [ next_var++ ] . address ; } pslAddress pslCompiler::getVarSymbol ( const char *s ) { /* Search Backwards so most local variable shows up first */ for ( int i = next_var-1 ; i >= 0 ; i-- ) if ( strcmp ( s, symtab [ i ] . symbol ) == 0 ) return symtab [ i ] . address ; error ( "Undefined symbol '%s'.", s ) ; return setVarSymbol ( s ) ; } int pslCompiler::getExtensionSymbol ( const char *s ) const { for ( int i = 0 ; extensions [ i ] . symbol != NULL ; i++ ) if ( strcmp ( s, extensions [ i ] . symbol ) == 0 ) return i ; return -1 ; } void pslCompiler::addFwdRef ( const char *s, pslAddress where ) { for ( int i = 0 ; i < next_fwdref ; i++ ) { if ( forward_ref [ i ] . symbol == NULL ) { forward_ref [ i ] . set ( s, where ) ; return ; } } if ( next_fwdref >= MAX_SYMBOL ) { error ( "Too many unresolved forward references." ) ; return ; } forward_ref [ next_fwdref++ ] . set ( s, where ) ; } void pslCompiler::fixup ( const char *s, pslAddress v ) { for ( int i = 0 ; i < next_fwdref ; i++ ) { if ( forward_ref [ i ] . matches ( s ) ) { pslAddress p = forward_ref [ i ] . getWhere () ; code [ p ] = v & 0xFF ; code [ p+1 ] = (v >> 8) & 0xFF ; delete [] forward_ref[i].symbol ; forward_ref[i].symbol = NULL ; } } } void pslCompiler::checkUnresolvedSymbols () { for ( int i = 0 ; i < next_fwdref ; i++ ) { if ( forward_ref [ i ] . symbol != NULL ) { error ( "'%s' does not exist.", forward_ref [ i ] . symbol ) ; /* Prevent multiple errors for same symbol */ fixup ( forward_ref [ i ] . symbol, 0 ) ; } } } pslAddress pslCompiler::getCodeSymbol ( const char *s, pslAddress where ) { for ( int i = 0 ; i < next_code_symbol ; i++ ) if ( strcmp ( s, code_symtab [ i ] . symbol ) == 0 ) return code_symtab [ i ] . address ; /* Symbol is undefined - so make a forward reference to it */ addFwdRef ( s, where ) ; return 0 ; } void pslCompiler::setCodeSymbol ( const char *s, pslAddress v ) { for ( int i = 0 ; i < next_code_symbol ; i++ ) if ( strcmp ( s, code_symtab [ i ] . symbol ) == 0 ) { error ( "Multiple definition of '%s'.", s ) ; return ; } if ( next_code_symbol >= MAX_VARIABLE-1 ) { error ( "Too many labels." ) ; next_code_symbol-- ; } code_symtab [ next_code_symbol++ ] . set ( s, v, locality_sp ) ; fixup ( s, v ) ; } plib-1.8.5/src/psl/pslProgram.cxx0000644000175000001440000000672010765364440013645 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslProgram.cxx 1941 2004-08-05 00:57:38Z puggles $ */ #include "pslLocal.h" pslProgram::pslProgram ( const pslExtension *ext, const char *_prgnm ) { if ( ! _pslInitialised ) ulSetError ( UL_FATAL, "PSL: You didn't call pslInit() before using PSL functions." ) ; code = new pslOpcode [ MAX_CODE ] ; extensions = ext ; progName = NULL ; if ( _prgnm == NULL ) _prgnm = "PSLprogram" ; setProgName ( _prgnm ) ; compiler = new pslCompiler ( this, code, ext, getProgName () ) ; context = new pslContext ( this ) ; compiler-> init () ; context -> reset () ; const char *force_trace_env = getenv ( "PSL_TRACE" ) ; const char *force_stack_env = getenv ( "PSL_STACK" ) ; force_trace = ( force_trace_env != NULL && ulStrEqual ( force_trace_env, "always" ) ) ; force_stacktrace = ( force_stack_env != NULL && ulStrEqual ( force_stack_env, "always" ) ) ; if ( force_trace ) compiler -> generateLineNumbers () ; } pslProgram::pslProgram ( pslProgram *src, const char *_prgnm ) { progName = NULL ; if ( _prgnm == NULL ) _prgnm = src -> getProgName () ; setProgName ( _prgnm ) ; /* This will fail if this pslProgram is ever deleted */ /* We need ref-counting on code/compiler */ code = src -> getCode () ; compiler = src -> getCompiler () ; extensions = src -> getExtensions () ; userData = src -> getUserData () ; context = new pslContext ( this ) ; context -> reset () ; } pslProgram::~pslProgram () { /* This will fail if this pslProgram was copy-constructed */ /* We need ref-counting on code/compiler */ /* DEBUG-ME! */ delete [] progName ; delete context ; compiler -> ref(); } void pslProgram::dump () const { compiler-> dump () ; } void pslProgram::reset () { context -> reset () ; } pslResult pslProgram::step () { return force_trace ? context -> trace () : context -> step () ; } pslResult pslProgram::trace () { return context -> trace () ; } int pslProgram::compile ( const char *memptr, const char *fname ) { if ( strcmp ( getProgName(), "PSLprogram" ) == 0 ) setProgName ( fname ) ; return compiler -> compile ( memptr, fname ) ; } int pslProgram::compile ( const char *fname ) { if ( strcmp ( getProgName(), "PSLprogram" ) == 0 ) setProgName ( fname ) ; return compiler -> compile ( fname ) ; } int pslProgram::compile ( FILE *fd ) { return compiler -> compile ( fd ) ; } plib-1.8.5/src/psl/pslCompiler.cxx0000644000175000001440000004454210765364440014014 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslCompiler.cxx 1745 2003-01-06 05:10:14Z sjbaker $ */ #include "pslLocal.h" #include "ul.h" int pslCompiler::compile ( const char *fname ) { char filename [ 1024 ] ; _pslMakeScriptPath ( filename, fname ) ; FILE *fd = fopen ( filename, "ra" ) ; if ( fd == NULL ) { perror ( "PSL:" ) ; ulSetError ( UL_WARNING, "PSL: Failed while opening '%s' for reading.", filename ); return FALSE ; } return compile ( fd, fname ) ; } int pslCompiler::compile ( const char *memptr, const char *fname ) { init () ; _pslPushDefaultFile ( memptr, (fname == NULL) ? progName : fname ) ; genProgram () ; _pslPopDefaultFile () ; return cleanup () ; } int pslCompiler::compile ( FILE *fd, const char *fname ) { init () ; _pslPushDefaultFile ( fd, (fname == NULL) ? progName : fname ) ; genProgram () ; _pslPopDefaultFile () ; return cleanup () ; } int pslCompiler::cleanup () { const char *dump_env = getenv ( "PSL_DUMP" ) ; if ( num_errors != 0 || num_warnings != 0 ) fprintf ( stderr, "PSL: '%s' Compiled with %d Warnings, %d Fatal Errors\n", progName, num_warnings, num_errors ) ; /* If there are errors, prevent the program from running. */ if ( num_errors != 0 ) { if ( dump_env != NULL && ulStrEqual ( dump_env, "on_error" ) ) dump () ; next_code = 0 ; genCodeByte ( OPCODE_HALT ) ; } else if ( dump_env != NULL && ulStrEqual ( dump_env, "always" ) ) dump () ; return num_errors ; } int pslCompiler::genReturnStatement () { char c [ MAX_TOKEN ] ; getToken ( c ) ; if ( c [ 0 ] == ';' ) /* Return without data == "return 0" */ { ungetToken ( c ) ; genConstant ( "0.0" ) ; } else { ungetToken ( c ) ; genExpression () ; } genReturn () ; return TRUE ; } /* Administer the break/continue jump addresses */ void pslCompiler::pushBreakToLabel () { if ( next_break >= MAX_LABEL-1 ) error ( "Too many nested 'break' contexts" ) ; else breakToAddressStack [ next_break++ ] = next_tmp_label++ ; } void pslCompiler::pushNoContinue () { continueToAddressStack [ next_continue++ ] = -1 ; } int pslCompiler::pushContinueToLabel () { if ( next_continue >= MAX_LABEL-1 ) error ( "Too many nested 'continue' contexts" ) ; else continueToAddressStack [ next_continue++ ] = next_tmp_label++ ; return next_tmp_label-1 ; } void pslCompiler::setContinueToLabel ( int which ) { char s [ 10 ] ; sprintf ( s, "L%d", which ) ; setCodeSymbol ( s, next_code ) ; } void pslCompiler::popBreakToLabel () { char s [ 10 ] ; sprintf ( s, "L%d", breakToAddressStack[next_break-1] ) ; setCodeSymbol ( s, next_code ) ; next_break-- ; } void pslCompiler::popContinueToLabel () { next_continue-- ; } /* Implement actual break and continue statements. */ int pslCompiler::genBreakStatement () { if ( next_break <= 0 ) return error ( "'break' statement is not inside a 'switch' or a loop." ) ; char s [ 10 ] ; sprintf ( s, "L%d", breakToAddressStack [ next_break-1 ] ) ; genJump ( getCodeSymbol ( s, next_code+1 ) ) ; return TRUE ; } int pslCompiler::genContinueStatement () { if ( next_break <= 0 ) return error ( "'continue' statement is not inside a loop." ) ; if ( continueToAddressStack [ next_continue-1 ] < 0 ) return error ( "'continue' statement not allowed inside a 'switch'." ) ; char s [ 10 ] ; sprintf ( s, "L%d", continueToAddressStack [ next_continue-1 ] ) ; genJump ( getCodeSymbol ( s, next_code+1 ) ) ; return TRUE ; } int pslCompiler::genSwitchStatement () { if ( ! genExpression () ) return error ( "Missing control expression for 'switch'" ) ; char c [ MAX_TOKEN ] ; getToken ( c ) ; /* Hopefully, the word 'while' */ if ( c [ 0 ] != '{' ) return error ( "Missing '{' after 'switch'" ) ; int jumpToNextCase = genJump ( 0 ) ; int jumpAfterTest = 0 ; pushBreakToLabel () ; pushNoContinue () ; while ( TRUE ) { getToken ( c ) ; if ( strcmp ( c, "case" ) == 0 ) { jumpAfterTest = genJump ( 0 ) ; code [ jumpToNextCase ] = next_code & 0xFF ; code [ jumpToNextCase+1 ] = ( next_code >> 8 ) & 0xFF ; genStackDup () ; if ( ! genExpression () ) error ( "Missing expression after 'case'." ) ; getToken ( c ) ; if ( c[0] != ':' ) error ( "Missing ':' after 'case' expression." ) ; genEqual () ; jumpToNextCase = genJumpIfFalse ( 0 ) ; code [ jumpAfterTest ] = next_code & 0xFF ; code [ jumpAfterTest+1 ] = ( next_code >> 8 ) & 0xFF ; } else if ( strcmp ( c, "default" ) == 0 ) { code [ jumpToNextCase ] = next_code & 0xFF ; code [ jumpToNextCase+1 ] = ( next_code >> 8 ) & 0xFF ; getToken ( c ) ; if ( c[0] != ':' ) error ( "Missing ':' after 'default'." ) ; } else if ( strcmp ( c, "}" ) == 0 ) { ungetToken ( ";" ) ; break ; } else { ungetToken ( c ) ; if ( ! genStatement () ) error ( "Missing statement within switch." ) ; getToken ( c ) ; if ( c [ 0 ] != ';' ) error ( "Missing semicolon." ) ; } } popBreakToLabel () ; popContinueToLabel () ; genPop () ; return TRUE ; } int pslCompiler::genDoWhileStatement () { /* Remember place to jump back to */ int start_loc = next_code ; pushBreakToLabel () ; setContinueToLabel ( pushContinueToLabel () ) ; if ( ! genStatement () ) return error ( "Missing statement for 'do/while'" ) ; char c [ MAX_TOKEN ] ; getToken ( c ) ; /* The final ';' of the action */ getToken ( c ) ; /* Hopefully, the word 'while' */ if ( strcmp ( c, "while" ) != 0 ) return error ( "Missing 'while' for 'do/while'" ) ; if ( ! genExpression () ) return error ( "Missing expression for 'while' in a 'do/while'" ) ; genJumpIfTrue ( start_loc ) ; popBreakToLabel () ; popContinueToLabel () ; return TRUE ; } int pslCompiler::genForStatement () { char c [ MAX_TOKEN ] ; pushLocality () ; pushBreakToLabel () ; int ct_lab = pushContinueToLabel () ; getToken ( c ) ; /* The initial '(' of the action */ if ( c [ 0 ] != '(' ) { popLocality () ; return error ( "Missing '(' for 'for' loop" ) ; } if ( ! genStatement () ) { popLocality () ; return error ( "Missing initialiser for 'if'" ) ; } getToken ( c ) ; /* The ';' after the initialiser */ if ( c [ 0 ] != ';' ) { popLocality () ; return error ( "Missing ';' after 'for' loop initialisation" ) ; } /* Remember place to jump back to */ int start_loc = next_code ; /* The test */ if ( ! genExpression () ) return error ( "Missing test for 'for' loop" ) ; getToken ( c ) ; /* The ';' after the initialiser */ if ( c [ 0 ] != ';' ) { popLocality () ; return error ( "Missing ';' after 'for' loop test" ) ; } char saved [ MAX_UNGET ][ MAX_TOKEN ] ; int next_saved = 0 ; int paren_counter = 0 ; do { getToken ( saved [ next_saved ] ) ; if ( saved [ next_saved ][ 0 ] == '(' ) paren_counter++ ; if ( saved [ next_saved ][ 0 ] == ')' ) paren_counter-- ; if ( next_saved >= MAX_UNGET-1 ) { popLocality () ; return error ( "Too many tokens in 'increment' part of 'for' loop" ) ; } next_saved++ ; } while ( paren_counter >= 0 ) ; next_saved-- ; /* Throw away the ')' */ int label_loc = genJumpIfFalse ( 0 ) ; if ( ! genStatement () ) { popLocality () ; return error ( "Missing action body for 'for' loop" ) ; } setContinueToLabel ( ct_lab ) ; getToken ( c ) ; /* Throw away the ';' */ /* Put the increment test back onto the token stream */ ungetToken ( ";" ) ; for ( int i = next_saved-1 ; i >= 0 ; i-- ) ungetToken ( saved[i] ) ; if ( ! genStatement () ) { popLocality () ; return error ( "Missing 'increment' part of 'for' loop" ) ; } genJump ( start_loc ) ; code [ label_loc ] = next_code & 0xFF ; code [ label_loc+1 ] = ( next_code >> 8 ) & 0xFF ; popBreakToLabel () ; popContinueToLabel () ; popLocality () ; return TRUE ; } int pslCompiler::genWhileStatement () { /* Remember place to jump back to */ pushBreakToLabel () ; setContinueToLabel ( pushContinueToLabel () ) ; int start_loc = next_code ; if ( ! genExpression () ) return error ( "Missing expression for 'while'" ) ; int label_loc = genJumpIfFalse ( 0 ) ; if ( ! genStatement () ) return error ( "Missing statement for 'while'" ) ; genJump ( start_loc ) ; code [ label_loc ] = next_code & 0xFF ; code [ label_loc+1 ] = ( next_code >> 8 ) & 0xFF ; popBreakToLabel () ; popContinueToLabel () ; return TRUE ; } int pslCompiler::genIfStatement () { if ( ! genExpression () ) return error ( "Missing expression for 'if'" ) ; int else_loc = genJumpIfFalse ( 0 ) ; if ( ! genStatement () ) return error ( "Missing statement for 'if'" ) ; char c [ MAX_TOKEN ] ; getToken ( c ) ; if ( c [ 0 ] != ';' ) { ungetToken ( c ) ; return error ( "Missing ';' or 'else' after 'if' statement" ) ; } getToken ( c ) ; if ( strcmp ( c, "else" ) != 0 ) { code [ else_loc ] = next_code & 0xFF ; code [ else_loc+1 ] = ( next_code >> 8 ) & 0xFF ; ungetToken ( c ) ; ungetToken ( ";" ) ; return TRUE ; } int label_loc = genJump ( 0 ) ; code [ else_loc ] = next_code & 0xFF ; code [ else_loc+1 ] = ( next_code >> 8 ) & 0xFF ; if ( ! genStatement () ) return error ( "Missing statement for 'else'" ) ; code [ label_loc ] = next_code & 0xFF ; code [ label_loc+1 ] = ( next_code >> 8 ) & 0xFF ; return TRUE ; } int pslCompiler::genFunctionCall ( const char *var ) { char c [ MAX_TOKEN ] ; getToken ( c ) ; /* 'var' should be the name of a function, 'c' should be an '(' */ if ( c[0] != '(' ) return error ( "Missing '(' in call to '%s'", var ) ; getToken ( c ) ; int argc = 0 ; while ( c[0] != ')' ) { ungetToken ( c ) ; genExpression () ; argc++ ; getToken ( c ) ; if ( c[0] == ')' ) break ; if ( c[0] != ',' ) return error ( "Missing ')' or ',' in call to '%s'", var ) ; getToken ( c ) ; } genCall ( var, argc ) ; return TRUE ; } int pslCompiler::genCompoundStatement () { char c [ MAX_TOKEN ] ; pushLocality () ; while ( genStatement () ) { getToken ( c ) ; if ( c[0] != ';' ) { popLocality () ; return warning ( "Unexpected '%s' in Compound statement", c ) ; } } getToken ( c ) ; if ( c[0] == '}' ) { popLocality () ; ungetToken ( ";" ) ; return TRUE ; } popLocality () ; ungetToken ( c ) ; return warning ( "Unexpected '%s' in Compound statement", c ) ; } int pslCompiler::genStatement () { char c [ MAX_TOKEN ] ; if ( generate_line_numbers ) genLineNumber ( _pslGetLineNo () ) ; getToken ( c ) ; if ( strcmp ( c, "static" ) == 0 ) return genStaticVarDecl () ; if ( strcmp ( c, "string" ) == 0 ) return genLocalVarDecl ( PSL_STRING) ; if ( strcmp ( c, "int" ) == 0 ) return genLocalVarDecl ( PSL_INT ) ; if ( strcmp ( c, "float" ) == 0 ) return genLocalVarDecl ( PSL_FLOAT ) ; if ( strcmp ( c, "return" ) == 0 ) return genReturnStatement () ; if ( strcmp ( c, "break" ) == 0 ) return genBreakStatement () ; if ( strcmp ( c, "continue" ) == 0 ) return genContinueStatement () ; if ( strcmp ( c, "pause" ) == 0 ) return genPauseStatement () ; if ( strcmp ( c, "for" ) == 0 ) return genForStatement () ; if ( strcmp ( c, "do" ) == 0 ) return genDoWhileStatement () ; if ( strcmp ( c, "switch" ) == 0 ) return genSwitchStatement () ; if ( strcmp ( c, "while" ) == 0 ) return genWhileStatement () ; if ( strcmp ( c, "if" ) == 0 ) return genIfStatement () ; if ( strcmp ( c, "case" ) == 0 || strcmp ( c, "default" ) == 0 ) return error ( "'%s' encountered - not inside 'switch' statement", c ) ; if ( c [ 0 ] == '{' ) return genCompoundStatement () ; ungetToken ( c ) ; if ( genExpression () ) { genPop () ; /* Discard result */ return TRUE ; } return FALSE ; } void pslCompiler::genProgram () { char c [ MAX_TOKEN ] ; /* Compile the program */ while ( TRUE ) { getToken ( c ) ; if ( c[0] == '\0' ) break ; ungetToken ( c ) ; genGlobalDeclaration () ; } /* Have the program call 'main' and then halt */ genIntConstant ( 0 ) ; /* No arguments to main *YET* */ genCodeByte ( OPCODE_CALL ) ; genCodeAddr ( getCodeSymbol ( "main", next_code ) ) ; genCodeByte ( 0 ) ; /* Argc */ genCodeByte ( OPCODE_HALT ) ; checkUnresolvedSymbols () ; } int pslCompiler::genLocalVarDecl ( pslType t ) { char c [ MAX_TOKEN ] ; char s [ MAX_TOKEN ] ; getToken ( s ) ; setVarSymbol ( s ) ; getToken ( c ) ; if ( c[0] == '[' ) { genExpression () ; switch ( t ) { case PSL_FLOAT : genMakeFloatArray ( s ) ; break ; case PSL_STRING : genMakeStringArray ( s ) ; break ; default : genMakeIntArray ( s ) ; break ; } getToken ( c ) ; if ( c[0] != ']' ) return error ( "Missing ']' after array declaration" ) ; return TRUE ; } switch ( t ) { case PSL_FLOAT : genMakeFloatVariable ( s ) ; break ; case PSL_STRING : genMakeStringVariable ( s ) ; break ; default : genMakeIntVariable ( s ) ; break ; } if ( strcmp ( c, "=" ) == 0 ) { genVariable ( s, FALSE ) ; genExpression () ; genAssignment () ; genPop () ; return TRUE ; } ungetToken ( c ) ; return TRUE ; } int pslCompiler::genStaticVarDecl () { return error ( "Static Local Variables are Not Supported Yet." ) ; } int pslCompiler::genGlobalVarDecl ( const char *s, pslType t ) { char c [ MAX_TOKEN ] ; setVarSymbol ( s ) ; getToken ( c ) ; if ( c[0] == '[' ) { genExpression () ; switch ( t ) { case PSL_FLOAT : genMakeFloatArray ( s ) ; break ; case PSL_STRING : genMakeStringArray ( s ) ; break ; default : genMakeIntArray ( s ) ; break ; } getToken ( c ) ; if ( c[0] != ']' ) return error ( "Missing ']' after array declaration" ) ; } else { switch ( t ) { case PSL_FLOAT : genMakeFloatVariable ( s ) ; break ; case PSL_STRING : genMakeStringVariable ( s ) ; break ; default : genMakeIntVariable ( s ) ; break ; } if ( strcmp ( c, "=" ) == 0 ) { genVariable ( s, FALSE ) ; genExpression () ; genAssignment () ; genPop () ; getToken ( c ) ; } } if ( c[0] != ';' ) return error ( "Missing ';' after declaration of '%s'", s ) ; return TRUE ; } int pslCompiler::genGlobalDeclaration () { char c [ MAX_TOKEN ] ; char fn [ MAX_TOKEN ] ; getToken ( c ) ; if ( strcmp ( c, "static" ) == 0 || strcmp ( c, "extern" ) == 0 ) { /* Something complicated should probably happen here! */ getToken ( c ) ; } pslType t ; if ( strcmp ( c, "void" ) == 0 ) t = PSL_VOID ; else if ( strcmp ( c, "int" ) == 0 ) t = PSL_INT ; else if ( strcmp ( c, "float" ) == 0 ) t = PSL_FLOAT ; else if ( strcmp ( c, "string" ) == 0 ) t = PSL_STRING ; else return error ( "Expected declaration - but got '%s'", c ) ; getToken ( fn ) ; getToken ( c ) ; if ( c[0] == '(' ) { ungetToken ( c ) ; return genFunctionDeclaration ( fn ) ; } if ( c[0] == '[' || strcmp ( c, "=" ) == 0 || c[0] == ';' ) { ungetToken ( c ) ; return genGlobalVarDecl ( fn, t ) ; } return error ( "Expected a declaration - but got '%s'", c); } int pslCompiler::genFunctionDeclaration ( const char *fn ) { char c [ MAX_TOKEN ] ; pslAddress jump_target = genJump ( 0 ) ; setCodeSymbol ( fn, next_code ) ; getToken ( c ) ; if ( c[0] != '(' ) return error ( "Missing '(' in declaration of '%s'", fn ) ; pushLocality () ; int argpos = 0 ; while ( 1 ) { getToken ( c ) ; if ( c [ 0 ] == ')' || c [ 0 ] == '\0' ) break ; char s [ MAX_TOKEN ] ; getToken ( s ) ; pslAddress a = setVarSymbol ( s ) ; if ( strcmp ( c, "int" ) == 0 ) genMakeIntVariable ( s ) ; else if ( strcmp ( c, "float" ) == 0 ) genMakeFloatVariable ( s ) ; else if ( strcmp ( c, "string" ) == 0 ) genMakeStringVariable ( s ) ; else { popLocality () ; return error ( "Missing ')' in declaration of '%s'", fn ) ; } genGetParameter ( a, argpos++ ) ; getToken ( c ) ; if ( c[0] == ',' ) continue ; if ( c[0] == ')' ) break ; popLocality () ; return error ( "Missing ',' or ')' in declaration of '%s'", fn ) ; } if ( c[0] != ')' ) { popLocality () ; return error ( "Missing ')' in declaration of '%s'", fn ) ; } getToken ( c ) ; if ( c [ 0 ] != '{' ) { popLocality () ; return error ( "Missing '{' in function '%s'", fn ) ; } if ( ! genCompoundStatement () ) { popLocality () ; return error ( "Missing '}' in function '%s'", fn ) ; } getToken ( c ) ; /* If we fall off the end of the function, we still need a return value */ genConstant ( "0.0" ) ; genReturn () ; code [ jump_target ] = next_code & 0xFF ; code [ jump_target+1 ] = (next_code >> 8) & 0xFF ; popLocality () ; return TRUE ; } plib-1.8.5/src/psl/pslFileIO.cxx0000644000175000001440000001133310765364440013341 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslFileIO.cxx 1745 2003-01-06 05:10:14Z sjbaker $ */ #include "pslLocal.h" class pslFile ; static pslFile *defaultFileStack [ MAX_INCLUDE_DEPTH ] ; static int fileStackPointer = 0 ; class pslFile { FILE *fd ; const char *memptr ; char *fname ; int ungetStack [ MAX_UNGET_CHAR ] ; int ungetSP ; int line_no ; void init () { ungetSP = 0 ; line_no = 0 ; if ( fileStackPointer >= MAX_INCLUDE_DEPTH - 1 ) fprintf ( stderr, "PSL: ERROR - Too many nested #includes" ) ; else defaultFileStack [ fileStackPointer++ ] = this ; /* This is a kludge to get preprocessor directives to see a '#' as the very first character in the file as if it came immediately after a newline...also accounted for by line_no starting at zero instead of 1. */ unGetChar ( '\n' ) ; line_no = 0 ; } public: pslFile ( const char *_memptr, const char *_fname ) { fname = ulStrDup ( _fname ) ; memptr = _memptr ; fd = NULL ; init () ; } pslFile ( FILE *_fd, const char *_fname ) { fname = ulStrDup ( _fname ) ; memptr = NULL ; fd = _fd ; init () ; } ~pslFile () { if ( fileStackPointer <= 0 ) fprintf ( stderr, "PSL: ERROR - #include stack underflow?!?" ) ; else { if ( defaultFileStack [ --fileStackPointer ] != this ) fprintf ( stderr, "PSL: ERROR - #include nesting problem?!?" ) ; else if ( fd != NULL ) fclose ( fd ) ; } delete [] fname ; } void unGetChar ( int c ) { if ( ungetSP < MAX_UNGET_CHAR-1 ) ungetStack [ ungetSP++ ] = c ; else fprintf ( stderr, "PSL: ERROR - Too many ungotten characters?!?" ) ; if ( c == '\n' ) line_no-- ; } int getChar () { int c ; /* Get a new character - either from the 'undo' stack or from the file or from the memory pointer. Return -1 on EOF. */ if ( ungetSP > 0 ) c = ungetStack [ --ungetSP ] ; else if ( fd != NULL ) c = getc ( fd ) ; else if ( memptr != NULL ) { c = (int)((unsigned char)(*(memptr++))) ; if ( c == '\0' ) { memptr = NULL ; c = -1 ; } } else c = -1 ; if ( c == '\n' ) line_no++ ; return c ; } int getLineNo () const { return line_no ; } char *getFname () const { return fname ; } } ; char *_pslGetFname () { return defaultFileStack [ fileStackPointer - 1 ] -> getFname () ; } int _pslGetLineNo () { return defaultFileStack [ fileStackPointer - 1 ] -> getLineNo () ; } void _pslPopDefaultFile () { delete defaultFileStack [ fileStackPointer - 1 ] ; } void _pslPushDefaultFile ( FILE *fd, const char *fname ) { new pslFile ( fd, fname ) ; } void _pslPushDefaultFile ( const char *memptr, const char *fname ) { new pslFile ( memptr, fname ) ; } void _pslPushDefaultFile ( const char *fname ) { char filename [ 1024 ] ; _pslMakeScriptPath ( filename, fname ) ; FILE *fd = fopen ( filename, "ra" ) ; if ( fd == NULL ) { fprintf ( stderr, "PSL: ERROR - Can't open #include'ed file '%s'", filename ) ; return ; } _pslPushDefaultFile ( fd, fname ) ; } int _pslGetChar () { /* WARNING -- RECURSIVE -- WARNING -- RECURSIVE -- WARNING -- RECURSIVE */ int c = defaultFileStack [ fileStackPointer-1 ] -> getChar () ; /* If we hit the end of the current file, then if this is an included file, just pop the file stack and carry on reading from the place we left off. Otherwise just return an EOF. */ if ( c < 0 ) /* EOF */ { if ( fileStackPointer > 1 ) { _pslPopDefaultFile () ; return _pslGetChar () ; } return -1 ; } return c ; } void _pslUnGetChar ( int c ) { defaultFileStack [ fileStackPointer-1 ] -> unGetChar ( c ) ; } plib-1.8.5/src/psl/pslLocal.h0000644000175000001440000000331010765364440012705 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslLocal.h 1707 2002-09-27 15:45:06Z sjbaker $ */ #include #include #include #include #include "psl.h" #include "ul.h" #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* Limits */ #define MAX_ARGS 64 #define MAX_VARIABLE 256 #define MAX_LABEL 256 #define MAX_TOKEN 1024 #define MAX_CODE 65536 #define MAX_STACK 256 #define MAX_NESTING 32 #define MAX_UNGET 64 #define MAX_UNGET_CHAR 1024 #define MAX_SYMBOL (MAX_VARIABLE + MAX_LABEL) #define MAX_INCLUDE_DEPTH 8 typedef unsigned short pslAddress ; extern int _pslInitialised ; #include "pslFileIO.h" #include "pslOpcodes.h" #include "pslSymbol.h" #include "pslCompiler.h" #include "pslContext.h" char* _pslMakeScriptPath ( char* path, const char* fname ) ; plib-1.8.5/src/psl/pslContext.h0000644000175000001440000000610410765364440013303 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslContext.h 1703 2002-09-22 20:49:05Z ude $ */ class pslContext { pslOpcode *code ; const pslExtension *extensions ; pslProgram *program ; pslVariable variable [ MAX_VARIABLE ] ; pslValue stack [ MAX_STACK ] ; int sp ; pslAddress pc ; int num_errors ; int num_warnings ; int line_no ; void bumpErrors () { num_errors++ ; } void bumpWarnings () { num_warnings++ ; } char *getProgName () const { return program -> getProgName () ; } void error ( const char *fmt, ... ) ; void warning ( const char *fmt, ... ) ; pslVariable *popLValue () ; pslVariable *peekLValue () ; public: pslContext ( pslProgram *p ) { code = p -> getCode () ; extensions = p -> getExtensions () ; program = p ; reset () ; } ~pslContext () {} ; int getLineNo () const { return line_no ; } void printStack ( FILE *fd ) const ; void pushInt ( int x ) { stack [ sp++ ] . set ( x ) ; } void pushFloat ( float x ) { stack [ sp++ ] . set ( x ) ; } void pushString ( const char *x ) { stack [ sp++ ] . set ( x ) ; } void pushNumber ( const pslNumber *x ) { stack [ sp++ ] . set ( x ) ; } int peekInt () const { return stack [ sp-1 ] . getInt () ; } float peekFloat () const { return stack [ sp-1 ] . getFloat () ; } char *peekString () const { return stack [ sp-1 ] . getString () ; } void popVoid ( int n = 1 ) { sp -= n ; } int popInt () { return stack [ --sp ] . getInt () ; } float popFloat () { return stack [ --sp ] . getFloat () ; } char *popString () { return stack [ --sp ] . getString () ; } void popNumber ( pslNumber *v ) { v -> set ( & stack [ --sp ] ) ; } pslResult step () ; pslResult trace () { if ( program -> getStackTraceFlag () ) printStack ( stdout ) ; program -> getCompiler () -> printInstruction ( stdout, pc ) ; fflush ( stdout ) ; return step () ; } void reset () { for ( int i = 0 ; i < MAX_VARIABLE ; i++ ) variable [ i ] . reset () ; line_no = -1 ; sp = 0 ; pc = 0 ; } } ; plib-1.8.5/src/psl/pslSymbol.h0000644000175000001440000000246410765364440013131 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslSymbol.h 1612 2002-09-06 19:17:23Z ude $ */ class pslSymbol { public: char *symbol ; pslAddress address ; int locality ; pslSymbol () { symbol = NULL ; address = 0 ; locality = 0 ; } void set ( const char *s, pslAddress v, int loc ) { symbol = ulStrDup ( s ) ; address = v ; locality = loc ; } ~pslSymbol () { delete [] symbol ; } } ; plib-1.8.5/src/psl/pslExpression.cxx0000644000175000001440000002571310765364440014400 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslExpression.cxx 1700 2002-09-22 18:25:16Z sjbaker $ */ #include "pslLocal.h" int pslCompiler::genLValue () { /* Expect: variable ...or... arrayname [ expression ] ...or... structure . lvalue ...or... structure -> lvalue */ char c [ MAX_TOKEN ] ; char n [ MAX_TOKEN ] ; getToken ( c ) ; getToken ( n ) ; int isArray = ( n[0] == '[' ) ; int isStruct = ( strcmp ( n, "." ) == 0 || strcmp ( n, "->" ) == 0 ) ; if ( ! isArray && ! isStruct ) { ungetToken ( n ) ; genVariable ( c, FALSE ) ; return TRUE ; } if ( isStruct ) return error ( "Structures are not supported yet." ) ; /* An array + index */ if ( ! genExpression () ) return error ( "Missing expression for array index." ) ; getToken ( n ) ; if ( n[0] != ']' ) return error ( "Missing ']' after array index." ) ; genVariable ( c, TRUE ) ; return TRUE ; } int pslCompiler::genPrimitive () { /* Expect: 'x' ...or... "xxxxxx" ...or... number ...or... ( expression ) ...or... + primitive ...or... - primitive ...or... ! primitive ...or... ~ primitive ...or... ++ lvalue ...or... -- lvalue ...or... function ( expression ) ...or... lvalue ...or... lvalue ++ ...or... lvalue -- ...or... lvalue = expression ...or... lvalue += expression ...or... lvalue -= expression (etc) */ char c [ MAX_TOKEN ] ; getToken ( c ) ; /* Constant ? */ if ( c [ 0 ] == '\'' ) { genCharConstant ( c [ 1 ] ) ; return TRUE ; } if ( c [ 0 ] == '"' ) { genStringConstant ( & c [ 1 ] ) ; return TRUE ; } if ((c [ 0 ] == '.' && c [ 1 ] != '\0' ) || isdigit ( c[0] ) ) { genConstant ( c ) ; return TRUE ; } /* Bracketed expression */ if ( strcmp ( c, "(" ) == 0 ) { if ( ! genExpression () ) { ungetToken ( c ) ; return error ( "Missing expression after '('" ) ; } getToken ( c ) ; if ( strcmp ( c, ")" ) != 0 ) { ungetToken ( c ) ; return error ( "Missing ')' (found '%s')", c ); } return TRUE ; } /* Various unary operators */ if ( strcmp ( c, "+" ) == 0 ) /* Skip over redundant unary '+' symbol */ { if ( genPrimitive () ) { /* Nothing */ return TRUE ; } else { ungetToken ( c ) ; return FALSE ; } } if ( strcmp ( c, "-" ) == 0 ) /* Unary '-' symbol */ { if ( genPrimitive () ) { genNegate () ; return TRUE ; } else { ungetToken ( c ) ; return FALSE ; } } if ( strcmp ( c, "!" ) == 0 ) /* Unary '!' symbol */ { if ( genPrimitive () ) { genNot () ; return TRUE ; } else { ungetToken ( c ) ; return FALSE ; } } if ( strcmp ( c, "~" ) == 0 ) /* Unary '~' symbol */ { if ( genPrimitive () ) { genTwiddle () ; return TRUE ; } else { ungetToken ( c ) ; return FALSE ; } } /* Pre-increment and pre-decrement */ if ( strcmp ( c, "++" ) == 0 ) { genLValue () ; genIncrementLValue () ; genFetch () ; return TRUE ; } if ( strcmp ( c, "--" ) == 0 ) { genLValue () ; genDecrementLValue () ; genFetch () ; return TRUE ; } /* Something illegal ?!? */ if ( ! isalpha ( c [ 0 ] ) && c [ 0 ] != '_' ) { ungetToken ( c ) ; return FALSE ; } /* An LValue or a function call... */ char n [ MAX_TOKEN ] ; getToken ( n ) ; if ( n[0] == '(' ) { ungetToken ( n ) ; genFunctionCall ( c ) ; return TRUE ; } /* An LValue. */ ungetToken ( n ) ; ungetToken ( c ) ; if ( ! genLValue () ) return error ( "Illegal expression." ) ; getToken ( n ) ; if ( strcmp ( n, "++" ) == 0 ) { genIncrementFetch () ; return TRUE ; } if ( strcmp ( n, "--" ) == 0 ) { genDecrementFetch () ; return TRUE ; } if ( strcmp ( n, "=" ) == 0 ) { if ( genExpression () ) { genAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "+=" ) == 0 ) { if ( genExpression () ) { genAddAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "-=" ) == 0 ) { if ( genExpression () ) { genSubAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "*=" ) == 0 ) { if ( genExpression () ) { genMulAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "%=" ) == 0 ) { if ( genExpression () ) { genModAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "/=" ) == 0 ) { if ( genExpression () ) { genDivAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "&=" ) == 0 ) { if ( genExpression () ) { genAndAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "|=" ) == 0 ) { if ( genExpression () ) { genOrAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "^=" ) == 0 ) { if ( genExpression () ) { genXorAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, "<<=" ) == 0 ) { if ( genExpression () ) { genSHLAssignment () ; return TRUE ; } else return FALSE ; } if ( strcmp ( n, ">>=" ) == 0 ) { if ( genExpression () ) { genSHRAssignment () ; return TRUE ; } else return FALSE ; } ungetToken ( n ) ; genFetch () ; return TRUE ; } int pslCompiler::genMultExpression () { /* Expect: primitive ...or... primitive * primitive primitive / primitive primitive % primitive */ if ( ! genPrimitive () ) return FALSE ; while ( TRUE ) { char c [ MAX_TOKEN ] ; getToken ( c ) ; if ( strcmp ( c, "*" ) != 0 && strcmp ( c, "/" ) != 0 && strcmp ( c, "%" ) != 0 ) { ungetToken ( c ) ; return TRUE ; } if ( ! genPrimitive () ) return FALSE ; if ( strcmp ( c, "*" ) == 0 ) genMultiply () ; else if ( strcmp ( c, "/" ) == 0 ) genDivide () ; else genModulo () ; } } int pslCompiler::genAddExpression () { /* Expect: multExp ...or... multExp + multExp multExp - multExp */ if ( ! genMultExpression () ) return FALSE ; while ( TRUE ) { char c [ MAX_TOKEN ] ; getToken ( c ) ; if ( strcmp ( c, "+" ) != 0 && strcmp ( c, "-" ) != 0 ) { ungetToken ( c ) ; return TRUE ; } if ( ! genMultExpression () ) return FALSE ; if ( strcmp ( c, "+" ) == 0 ) genAdd () ; else genSubtract () ; } } int pslCompiler::genShiftExpression () { /* Expect: addExp ...or... addExp << addExp addExp >> addExp */ if ( ! genAddExpression () ) return FALSE ; while ( TRUE ) { char c [ MAX_TOKEN ] ; getToken ( c ) ; if ( strcmp ( c, "<<" ) != 0 && strcmp ( c, ">>" ) != 0 ) { ungetToken ( c ) ; return TRUE ; } if ( ! genAddExpression () ) return FALSE ; if ( strcmp ( c, "<<" ) == 0 ) genShiftLeft () ; else genShiftRight () ; } } int pslCompiler::genBitwiseExpression () { /* Expect: shiftExp ...or... shiftExp & shiftExp shiftExp | shiftExp shiftExp ^ shiftExp */ if ( ! genShiftExpression () ) return FALSE ; while ( TRUE ) { char c [ MAX_TOKEN ] ; getToken ( c ) ; if ( strcmp ( c, "|" ) != 0 && strcmp ( c, "&" ) != 0 && strcmp ( c, "^" ) != 0 ) { ungetToken ( c ) ; return TRUE ; } if ( ! genShiftExpression () ) return FALSE ; if ( strcmp ( c, "|" ) == 0 ) genOr () ; else if ( strcmp ( c, "&" ) == 0 ) genAnd () ; else genXor () ; } } int pslCompiler::genRelExpression () { /* Expect: bitwiseExp ...or... bitwiseExp < bitwiseExp bitwiseExp > bitwiseExp bitwiseExp == bitwiseExp bitwiseExp <= bitwiseExp bitwiseExp >= bitwiseExp bitwiseExp != bitwiseExp */ if ( ! genBitwiseExpression () ) return FALSE ; while ( TRUE ) { char c [ MAX_TOKEN ] ; getToken ( c ) ; if ( strcmp ( c, "<" ) != 0 && strcmp ( c, ">" ) != 0 && strcmp ( c, "<=" ) != 0 && strcmp ( c, ">=" ) != 0 && strcmp ( c, "!=" ) != 0 && strcmp ( c, "==" ) != 0 ) { ungetToken ( c ) ; return TRUE ; } if ( ! genBitwiseExpression () ) return FALSE ; if ( strcmp ( c, "<" ) == 0 ) genLess () ; else if ( strcmp ( c, ">" ) == 0 ) genGreater () ; else if ( strcmp ( c, "<=" ) == 0 ) genLessEqual () ; else if ( strcmp ( c, ">=" ) == 0 ) genGreaterEqual () ; else if ( strcmp ( c, "!=" ) == 0 ) genNotEqual () ; else if ( strcmp ( c, "==" ) == 0 ) genEqual () ; } } int pslCompiler::genBoolExpression () { /* Expect: relExp ...or... relExp && boolExp ...or... relExp || boolExp */ if ( ! genRelExpression () ) return FALSE ; char c [ MAX_TOKEN ] ; int shortcut ; getToken ( c ) ; if ( strcmp ( c, "&&" ) == 0 ) shortcut = genPeekJumpIfFalse ( 0 ) ; else if ( strcmp ( c, "||" ) == 0 ) shortcut = genPeekJumpIfTrue ( 0 ) ; else { ungetToken ( c ) ; return TRUE ; } if ( ! genBoolExpression () ) return error ( "Missing expression following '&&' or '||'" ) ; code [ shortcut ] = next_code & 0xFF ; code [ shortcut+1 ] = ( next_code >> 8 ) & 0xFF ; return TRUE ; } int pslCompiler::genExpression () { /* All expressions can be bool expressions */ return genBoolExpression () ; } plib-1.8.5/src/psl/pslCompiler.h0000644000175000001440000002520210765364440013431 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: pslCompiler.h 1941 2004-08-05 00:57:38Z puggles $ */ struct pslFwdRef { char *symbol ; pslAddress where ; void set ( const char *s, pslAddress w ) { symbol = ulStrDup ( s ) ; where = w ; } pslAddress getWhere () const { return where ; } int matches ( const char *s ) const { return symbol != NULL && strcmp ( s, symbol ) == 0 ; } pslFwdRef () { symbol = NULL ; } ~pslFwdRef () { delete [] symbol ; } } ; class pslProgram ; class pslCompiler { int ref_count; // reference count. Clean up when this reaches zero /* File I/O and preprocessor */ int getChar () ; void doIncludeStatement () ; void doDefineStatement () ; void doIfdefStatement () ; void doUndefStatement () ; void doIfndefStatement () ; void doElseStatement () ; void doEndifStatement () ; int doPreProcessorCommand () ; void getToken ( char *s, int define_sub = TRUE ) ; void ungetToken ( const char *s ) ; void skipToEOL () ; /* Write data into Code space */ void genCodeByte ( unsigned char b ) ; void genCodeAddr ( pslAddress a ) ; int printOpcode ( FILE *fd, int addr ) const ; void genLineNumber ( int l ) ; /* Write single byte-coded instructions into code space. */ void genStackDup () ; void genPop () ; void genSubtract () ; void genAdd () ; void genDivide () ; void genMultiply () ; void genModulo () ; void genNegate () ; void genNot () ; void genTwiddle () ; void genOrOr () ; void genAndAnd () ; void genOr () ; void genAnd () ; void genXor () ; void genShiftLeft () ; void genShiftRight () ; void genLess () ; void genLessEqual () ; void genGreater () ; void genGreaterEqual () ; void genNotEqual () ; void genEqual () ; void genExchange () ; int genPeekJumpIfFalse ( int l ) ; int genPeekJumpIfTrue ( int l ) ; int genJumpIfFalse ( int l ) ; int genJumpIfTrue ( int l ) ; int genJump ( int l ) ; void genGetParameter ( pslAddress var, int argpos ) ; int genMakeIntVariable ( const char *s ) ; int genMakeFloatVariable ( const char *s ) ; int genMakeStringVariable ( const char *s ) ; int genMakeIntArray ( const char *s ) ; int genMakeFloatArray ( const char *s ) ; int genMakeStringArray ( const char *s ) ; void genConstant ( const char *s ) ; void genIntConstant ( const char *s ) ; void genFloatConstant ( const char *s ) ; void genStringConstant ( const char *s ) ; void genCharConstant ( char c ) ; void genIntConstant ( int i ) ; void genVoidConstant () ; void genFetch () ; void genIncrementLValue () ; void genDecrementLValue () ; void genIncrementFetch () ; void genDecrementFetch () ; void genVariable ( const char *s, int dimension ) ; void genAssignment () ; void genAddAssignment () ; void genSubAssignment () ; void genMulAssignment () ; void genModAssignment () ; void genDivAssignment () ; void genAndAssignment () ; void genOrAssignment () ; void genXorAssignment () ; void genSHLAssignment () ; void genSHRAssignment () ; void genCall ( const char *s, int argc ) ; void genReturn () ; /* Expression parsers & code generators. */ int genLValue () ; int genPrimitive () ; int genBitwiseExpression () ; int genMultExpression () ; int genAddExpression () ; int genShiftExpression () ; int genRelExpression () ; int genBoolExpression () ; int genExpression () ; /* Statement-level parsers & code generators. */ int genBreakStatement () ; int genContinueStatement() ; int genReturnStatement () ; int genPauseStatement () ; int genSwitchStatement () ; int genWhileStatement () ; int genDoWhileStatement () ; int genForStatement () ; int genIfStatement () ; int genFunctionCall ( const char *s ) ; int genCompoundStatement() ; int genStatement () ; int genLocalVarDecl ( pslType t ) ; int genGlobalVarDecl ( const char *fn, pslType t ) ; int genStaticVarDecl () ; /* Top level constructs */ int genFunctionDeclaration ( const char *fn ) ; int genGlobalDeclaration () ; void genProgram () ; /* The symbol tables for variables, code and define's */ int next_label ; int next_code_symbol ; int next_define ; int generate_line_numbers ; char *define_token [ MAX_SYMBOL ] ; char *define_replacement [ MAX_SYMBOL ] ; int searchDefines ( const char *s ) const ; int skipOverride ; int skippingFlag ; int next_skippingLevel ; int skipping () const { return ! skipOverride && skippingFlag != 0 ; } pslSymbol symtab [ MAX_SYMBOL ] ; pslSymbol code_symtab [ MAX_SYMBOL ] ; pslAddress getVarSymbol ( const char *s ) ; pslAddress setVarSymbol ( const char *s ) ; pslAddress getCodeSymbol ( const char *s, pslAddress fixupLoc ) ; void setCodeSymbol ( const char *s, pslAddress v ) ; int getExtensionSymbol ( const char *s ) const ; const pslExtension *extensions ; /* Forward references to code symbols that are not yet defined */ int next_fwdref ; pslFwdRef forward_ref [ MAX_SYMBOL ] ; int locality_stack [ MAX_NESTING ] ; int locality_sp ; void fixup ( const char *s, pslAddress v ) ; void addFwdRef ( const char *s, pslAddress where ) ; void checkUnresolvedSymbols () ; int cleanup () ; /* Report errors, etc after a compile */ void pushLocality () { if ( locality_sp >= MAX_NESTING-1 ) error ( "Too many nested {}'s" ) ; else locality_stack [ locality_sp++ ] = next_var ; } void popLocality () { if ( locality_sp <= 0 ) error ( "Locality stack underflow !!" ) ; /* Delete any local symbols */ for ( int i = locality_stack [ locality_sp-1 ] ; i < next_var ; i++ ) { delete [] symtab [ i ] . symbol ; symtab [ i ] . symbol = NULL ; } /* Put the next_var pointer back where it belongs */ next_var = locality_stack [ --locality_sp ] ; } /* Ikky stuff to remember where break and continue should jump */ int breakToAddressStack [ MAX_LABEL ] ; int continueToAddressStack [ MAX_LABEL ] ; int next_break ; int next_tmp_label ; int next_continue ; void pushBreakToLabel () ; int pushContinueToLabel () ; void setContinueToLabel ( int which ) ; void pushNoContinue () ; void popBreakToLabel () ; void popContinueToLabel () ; /* Error and warning handlers */ int num_errors ; int num_warnings ; void bumpErrors () { num_errors++ ; } void bumpWarnings () { num_warnings++ ; } int error ( const char *fmt, ... ) ; int warning ( const char *fmt, ... ) ; /* Remember the name of the program for debug purposes */ char *progName ; char *getProgName () const { return progName ; } /* Major storage for symbols and byte-codes */ int next_var ; int next_code ; pslOpcode *code ; pslContext *context ; pslProgram *program ; public: pslCompiler ( pslProgram *prog, pslOpcode *_code, const pslExtension *_extn, const char *_progName ) { ref_count = 1; program = prog ; progName = ulStrDup ( _progName ) ; generate_line_numbers = FALSE ; code = _code ; extensions = _extn ; for ( int i = 0 ; i < MAX_SYMBOL ; i++ ) { define_token [ i ] = NULL ; define_replacement [ i ] = NULL ; symtab [ i ] . symbol = NULL ; forward_ref [ i ] . symbol = NULL ; code_symtab [ i ] . symbol = NULL ; } init () ; } ~pslCompiler () { for ( int i = 0 ; i < MAX_SYMBOL ; i++ ) { delete [] define_token [ i ] ; delete [] define_replacement [ i ] ; delete [] symtab [ i ] . symbol ; symtab [ i ] . symbol = NULL ; delete [] code_symtab [ i ] . symbol ; code_symtab [ i ] . symbol = NULL ; delete [] forward_ref [ i ] . symbol ; forward_ref [ i ] . symbol = NULL ; } } void ref() { ref_count++; } void deref() { ref_count--; if(ref_count < 1) { delete [] code; delete this; } } const pslExtension *getExtensions () const { return extensions ; } int printInstruction ( FILE *fd, int addr ) const ; void generateLineNumbers () { generate_line_numbers = TRUE ; } void init () { int i ; for ( i = 0 ; i < MAX_CODE ; i++ ) code [ i ] = OPCODE_HALT ; for ( i = 0 ; i < MAX_SYMBOL ; i++ ) { delete [] define_token [ i ] ; define_token [ i ] = NULL ; delete [] define_replacement [ i ] ; define_replacement [ i ] = NULL ; delete [] symtab [ i ] . symbol ; symtab [ i ] . symbol = NULL ; delete [] code_symtab [ i ] . symbol ; code_symtab [ i ] . symbol = NULL ; delete [] forward_ref [ i ] . symbol ; forward_ref [ i ] . symbol = NULL ; } num_errors = num_warnings = 0 ; locality_sp = 0 ; next_define = 0 ; next_continue = 0 ; next_break = 0 ; next_tmp_label= 0 ; next_fwdref = 0 ; next_label = 0 ; next_code_symbol = 0 ; next_code = 0 ; next_var = 0 ; skippingFlag = 0 ; next_skippingLevel = 1 ; } void dump () const ; int compile ( const char *fname ) ; int compile ( FILE *fd, const char *fname = NULL ) ; int compile ( const char *memptr, const char *prog_name ) ; } ; plib-1.8.5/src/net/0000777000175000001440000000000010765365521011043 500000000000000plib-1.8.5/src/net/netChat.cxx0000644000175000001440000000676010765364434013104 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netChat.cxx 2117 2007-09-13 23:21:09Z fayjf $ */ #include "netChat.h" void netChat::setTerminator (const char* t) { if (terminator) delete[] terminator; terminator = ulStrDup(t); } const char* netChat::getTerminator (void) { return terminator; } // return the size of the largest prefix of needle at the end // of haystack #define MAX(a,b) (((a)>(b))?(a):(b)) static int find_prefix_at_end (const netBuffer& haystack, const char* needle) { const char* hd = haystack.getData(); int hl = haystack.getLength(); int nl = strlen(needle); for (int i = MAX (nl-hl, 0); i < nl; i++) { //if (haystack.compare (needle, hl-(nl-i), nl-i) == 0) { if (memcmp(needle, &hd[hl-(nl-i)], nl-i) == 0) { return (nl-i); } } return 0; } static int find_terminator (const netBuffer& haystack, const char* needle) { if (needle && *needle) { const char* data = haystack.getData(); const char* ptr = strstr(data,needle); if (ptr != NULL) return(ptr-data); } return -1; } void netChat::handleBufferRead (netBuffer& in_buffer) { // Continue to search for terminator in in_buffer, // while calling collect_incoming_data. The while loop is // necessary because we might read several data+terminator combos // with a single recv(). while (in_buffer.getLength()) { // special case where we're not using a terminator if (terminator == 0 || *terminator == 0) { collectIncomingData (in_buffer.getData(),in_buffer.getLength()); in_buffer.remove (); return; } int terminator_len = strlen(terminator); int index = find_terminator ( in_buffer, terminator ) ; // 3 cases: // 1) end of buffer matches terminator exactly: // collect data, transition // 2) end of buffer matches some prefix: // collect data to the prefix // 3) end of buffer does not match any prefix: // collect data if (index != -1) { // we found the terminator collectIncomingData ( in_buffer.getData(), index ) ; in_buffer.remove (0, index + terminator_len); foundTerminator(); } else { // check for a prefix of the terminator int num = find_prefix_at_end (in_buffer, terminator); if (num) { int bl = in_buffer.getLength(); // we found a prefix, collect up to the prefix collectIncomingData ( in_buffer.getData(), bl - num ) ; in_buffer.remove (0, bl - num); break; } else { // no prefix, collect it all collectIncomingData (in_buffer.getData(), in_buffer.getLength()); in_buffer.remove(); } } } } plib-1.8.5/src/net/netMessage.h0000644000175000001440000001502010765364434013223 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netMessage.h 2112 2006-12-12 18:45:28Z fayjf $ */ /**** * NAME * netMessage - message buffer and channel classes * * DESCRIPTION * messages are a binary format for sending buffers over a channel. * message headers contain a type field and length. * * AUTHOR * Dave McClurg * * CREATION DATE * Dec-2000 ****/ #ifndef __NET_MESSAGE__ #define __NET_MESSAGE__ #include "netBuffer.h" // ntohs() etc prototypes #ifdef UL_MSVC #include #else #include #endif #ifdef __FreeBSD__ #include #endif class netGuid //Globally Unique IDentifier { public: unsigned char data [ 16 ] ; netGuid () {} netGuid ( unsigned int l, unsigned short w1, unsigned short w2, unsigned char b1, unsigned char b2, unsigned char b3, unsigned char b4, unsigned char b5, unsigned char b6, unsigned char b7, unsigned char b8 ) { //store in network format (big-endian) data[ 0] = (unsigned char)(l>>24) ; data[ 1] = (unsigned char)(l>>16) ; data[ 2] = (unsigned char)(l>> 8) ; data[ 3] = (unsigned char)(l ) ; data[ 4] = (unsigned char)(w1>>8) ; data[ 5] = (unsigned char)(w1 ) ; data[ 6] = (unsigned char)(w2>>8) ; data[ 7] = (unsigned char)(w2 ) ; data[ 8] = b1 ; data[ 9] = b2 ; data[10] = b3 ; data[11] = b4 ; data[12] = b5 ; data[13] = b6 ; data[14] = b7 ; data[15] = b8 ; } bool operator ==( const netGuid& guid ) const { return memcmp ( data, guid.data, sizeof(data) ) == 0 ; } bool operator !=( const netGuid& guid ) const { return memcmp ( data, guid.data, sizeof(data) ) != 0 ; } } ; class netMessage : public netBuffer { int pos ; void seek ( int new_pos ) const { if ( new_pos < 0 ) new_pos = 0 ; else if ( new_pos > length ) new_pos = length ; //logical const-ness ((netMessage*)this) -> pos = new_pos ; } void skip ( int off ) const { seek(pos+off); } public: // incoming message; header is already there netMessage ( const char* s, int n ) : netBuffer(n) { assert ( n >= 5 ) ; append(s,n); pos = 5 ; // seek past header } // outgoing message netMessage ( int type, int to_id, int from_id=0, int n=256 ) : netBuffer(n) { // output header putw ( 0 ) ; //msg_len putbyte ( type ) ; putbyte ( to_id ) ; putbyte ( from_id ) ; } int getType () const { return ( (unsigned char*)data )[ 2 ] ; } int getToID () const { return ( (unsigned char*)data )[ 3 ] ; } int getFromID () const { return ( (unsigned char*)data )[ 4 ] ; } void setFromID ( int from_id ) { ( (unsigned char*)data )[ 4 ] = (unsigned char)from_id; } void geta ( void* a, int n ) const { assert (pos>=0 && pos=0 && pospos++; if (ch==0) break; } *dst = 0 ; } void puts ( const char* s ) { puta(s,strlen(s)+1); } void print ( FILE *fd = stderr ) const { fprintf ( fd, "netMessage: %p, length=%d\n", this, length ) ; fprintf ( fd, " header (type,to,from) = (%d,%d,%d)\n", getType(), getToID(), getFromID() ) ; fprintf ( fd, " data = " ) ; for ( int i=0; i #endif #include #include #include #include #include #include /* Need both for Mandrake 8.0!! */ #include #include #include #else #include #include #endif #if defined(UL_MSVC) && !defined(socklen_t) #define socklen_t int #endif /* Paul Wiltsey says we need this for Solaris 2.8 */ #ifndef INADDR_NONE #define INADDR_NONE ((unsigned long)-1) #endif netAddress::netAddress ( const char* host, int port ) { set ( host, port ) ; } void netAddress::set ( const char* host, int port ) { memset(this, 0, sizeof(netAddress)); sin_family = AF_INET ; sin_port = htons (port); /* Convert a string specifying a host name or one of a few symbolic ** names to a numeric IP address. This usually calls gethostbyname() ** to do the work; the names "" and "" are special. */ if (host[0] == '\0') sin_addr = INADDR_ANY; else if (host[0] == '<' && strcmp(host, "") == 0) sin_addr = INADDR_BROADCAST; else { sin_addr = inet_addr ( host ) ; if ( sin_addr == INADDR_NONE ) { struct hostent *hp = gethostbyname ( host ) ; if ( hp != NULL ) memcpy ( (char *) &sin_addr, hp->h_addr, hp->h_length ) ; else { perror ( "netAddress::set" ) ; sin_addr = INADDR_ANY ; } } } } /* Create a string object representing an IP address. This is always a string of the form 'dd.dd.dd.dd' (with variable size numbers). */ const char* netAddress::getHost () const { #if 0 const char* buf = inet_ntoa ( sin_addr ) ; #else static char buf [32]; long x = ntohl(sin_addr); sprintf(buf, "%d.%d.%d.%d", (int) (x>>24) & 0xff, (int) (x>>16) & 0xff, (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff ); #endif return buf; } unsigned int netAddress::getIP () const { return sin_addr; } unsigned int netAddress::getPort() const { return ntohs(sin_port); } unsigned int netAddress::getFamily () const { return sin_family; } const char* netAddress::getLocalHost () { //gethostbyname(gethostname()) char buf[256]; memset(buf, 0, sizeof(buf)); gethostname(buf, sizeof(buf)-1); const hostent *hp = gethostbyname(buf); if (hp && *hp->h_addr_list) { in_addr addr = *((in_addr*)*hp->h_addr_list); const char* host = inet_ntoa(addr); if ( host ) return host ; } return "127.0.0.1" ; } bool netAddress::getBroadcast () const { return sin_addr == INADDR_BROADCAST; } netSocket::netSocket () { handle = -1 ; } netSocket::~netSocket () { close () ; } void netSocket::setHandle (int _handle) { close () ; handle = _handle ; } bool netSocket::open ( bool stream ) { close () ; handle = ::socket ( AF_INET, (stream? SOCK_STREAM: SOCK_DGRAM), 0 ) ; return (handle != -1); } void netSocket::setBlocking ( bool blocking ) { assert ( handle != -1 ) ; #if defined(UL_CYGWIN) || !defined (UL_WIN32) int delay_flag = ::fcntl (handle, F_GETFL, 0); if (blocking) delay_flag &= (~O_NDELAY); else delay_flag |= O_NDELAY; ::fcntl (handle, F_SETFL, delay_flag); #else u_long nblocking = blocking? 0: 1; ::ioctlsocket(handle, FIONBIO, &nblocking); #endif } void netSocket::setBroadcast ( bool broadcast ) { assert ( handle != -1 ) ; int result; if ( broadcast ) { int one = 1; #ifdef UL_WIN32 result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, (char*)&one, sizeof(one) ); #else result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one) ); #endif } else { result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, NULL, 0 ); } if ( result < 0 ) { perror("set broadcast:"); } assert ( result != -1 ); } int netSocket::bind ( const char* host, int port ) { assert ( handle != -1 ) ; netAddress addr ( host, port ) ; return ::bind(handle,(const sockaddr*)&addr,sizeof(netAddress)); } int netSocket::listen ( int backlog ) { assert ( handle != -1 ) ; return ::listen(handle,backlog); } int netSocket::accept ( netAddress* addr ) { assert ( handle != -1 ) ; if ( addr == NULL ) { return ::accept(handle,NULL,NULL); } else { socklen_t addr_len = (socklen_t) sizeof(netAddress) ; return ::accept(handle,(sockaddr*)addr,&addr_len); } } int netSocket::connect ( const char* host, int port ) { assert ( handle != -1 ) ; netAddress addr ( host, port ) ; if ( addr.getBroadcast() ) { setBroadcast( true ); } return ::connect(handle,(const sockaddr*)&addr,sizeof(netAddress)); } int netSocket::send (const void * buffer, int size, int flags) { assert ( handle != -1 ) ; return ::send (handle, (const char*)buffer, size, flags); } int netSocket::sendto ( const void * buffer, int size, int flags, const netAddress* to ) { assert ( handle != -1 ) ; return ::sendto(handle,(const char*)buffer,size,flags, (const sockaddr*)to,sizeof(netAddress)); } int netSocket::recv (void * buffer, int size, int flags) { assert ( handle != -1 ) ; return ::recv (handle, (char*)buffer, size, flags); } int netSocket::recvfrom ( void * buffer, int size, int flags, netAddress* from ) { assert ( handle != -1 ) ; socklen_t fromlen = (socklen_t) sizeof(netAddress) ; return ::recvfrom(handle,(char*)buffer,size,flags,(sockaddr*)from,&fromlen); } void netSocket::close (void) { if ( handle != -1 ) { #if defined(UL_CYGWIN) || !defined (UL_WIN32) ::close( handle ); #else ::closesocket( handle ); #endif handle = -1 ; } } bool netSocket::isNonBlockingError () { #if defined(UL_CYGWIN) || !defined (UL_WIN32) switch (errno) { case EWOULDBLOCK: // always == NET_EAGAIN? case EALREADY: case EINPROGRESS: return true; } return false; #else int wsa_errno = WSAGetLastError(); if ( wsa_errno != 0 ) { WSASetLastError(0); ulSetError(UL_WARNING,"WSAGetLastError() => %d",wsa_errno); switch (wsa_errno) { case WSAEWOULDBLOCK: // always == NET_EAGAIN? case WSAEALREADY: case WSAEINPROGRESS: return true; } } return false; #endif } ////////////////////////////////////////////////////////////////////// // // modified version by os // ////////////////////////////////////////////////////////////////////// int netSocket::select ( netSocket** reads, netSocket** writes, int timeout ) { fd_set r,w; int retval; FD_ZERO (&r); FD_ZERO (&w); int i, k ; int num = 0 ; if ( reads ) { for ( i=0; reads[i]; i++ ) { int fd = reads[i]->getHandle(); FD_SET (fd, &r); num++; } } if ( writes ) { for ( i=0; writes[i]; i++ ) { int fd = writes[i]->getHandle(); FD_SET (fd, &w); num++; } } if (!num) return num ; /* Set up the timeout */ struct timeval tv ; tv.tv_sec = timeout/1000; tv.tv_usec = (timeout%1000)*1000; // It bothers me that select()'s first argument does not appear to // work as advertised... [it hangs like this if called with // anything less than FD_SETSIZE, which seems wasteful?] // Note: we ignore the 'exception' fd_set - I have never had a // need to use it. The name is somewhat misleading - the only // thing I have ever seen it used for is to detect urgent data - // which is an unportable feature anyway. retval = ::select (FD_SETSIZE, &r, &w, 0, &tv); //remove sockets that had no activity num = 0 ; if ( reads ) { for ( k=i=0; reads[i]; i++ ) { int fd = reads[i]->getHandle(); if ( FD_ISSET (fd, &r) ) { reads[k++] = reads[i]; num++; } } reads[k] = NULL ; } if ( writes ) { for ( k=i=0; writes[i]; i++ ) { int fd = writes[i]->getHandle(); if ( FD_ISSET (fd, &w) ) { writes[k++] = writes[i]; num++; } } writes[k] = NULL ; } if (retval == 0) // timeout return (-2); if (retval == -1)// error return (-1); return num ; } /* Init/Exit functions */ static void netExit ( void ) { #if defined(UL_CYGWIN) || !defined (UL_WIN32) #else /* Clean up windows networking */ if ( WSACleanup() == SOCKET_ERROR ) { if ( WSAGetLastError() == WSAEINPROGRESS ) { WSACancelBlockingCall(); WSACleanup(); } } #endif } int netInit ( int* argc, char** argv ) { /* Legacy */ return netInit () ; } int netInit () { assert ( sizeof(sockaddr_in) == sizeof(netAddress) ) ; #if defined(UL_CYGWIN) || !defined (UL_WIN32) #else /* Start up the windows networking */ WORD version_wanted = MAKEWORD(1,1); WSADATA wsaData; if ( WSAStartup(version_wanted, &wsaData) != 0 ) { ulSetError(UL_WARNING,"Couldn't initialize Winsock 1.1"); return(-1); } #endif atexit( netExit ) ; return(0); } const char* netFormat ( const char* format, ... ) { static char buffer[ 256 ]; va_list argptr; va_start(argptr, format); vsprintf( buffer, format, argptr ); va_end(argptr); return( buffer ); } plib-1.8.5/src/net/netChannel.cxx0000644000175000001440000001307710765364434013574 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netChannel.cxx 1906 2004-03-22 19:44:50Z sjbaker $ */ // TODO: // have all socket-related functions assert that the socket has not // been closed. [a read event may close it, and a write event may try // to write or something...] // Maybe assert valid handle, too? #include "netChannel.h" static netChannel* channels = 0 ; netChannel::netChannel () { closed = true ; connected = false ; accepting = false ; write_blocked = false ; should_delete = false ; next_channel = channels ; channels = this ; } netChannel::~netChannel () { close(); netChannel* prev = NULL ; for ( netChannel* ch = channels; ch != NULL; ch = ch -> next_channel ) { if (ch == this) { ch = ch -> next_channel ; if ( prev != NULL ) prev -> next_channel = ch ; else channels = ch ; next_channel = 0 ; break; } prev = ch ; } } void netChannel::setHandle (int handle, bool is_connected) { close () ; netSocket::setHandle ( handle ) ; connected = is_connected ; //if ( connected ) this->handleConnect(); closed = false ; } bool netChannel::open (void) { close(); if (netSocket::open(true)) { closed = false ; setBlocking ( false ) ; return true ; } return false ; } int netChannel::listen ( int backlog ) { accepting = true ; return netSocket::listen ( backlog ) ; } int netChannel::connect ( const char* host, int port ) { int result = netSocket::connect ( host, port ) ; if (result == 0) { connected = true ; //this->handleConnect(); return 0; } else if (isNonBlockingError ()) { return 0; } else { // some other error condition this->handleError (result); close(); return -1; } } int netChannel::send (const void * buffer, int size, int flags) { int result = netSocket::send (buffer, size, flags); if (result == (int)size) { // everything was sent write_blocked = false ; return result; } else if (result >= 0) { // not all of it was sent, but no error write_blocked = true ; return result; } else if (isNonBlockingError ()) { write_blocked = true ; return 0; } else { this->handleError (result); close(); return -1; } } int netChannel::recv (void * buffer, int size, int flags) { int result = netSocket::recv (buffer, size, flags); if (result > 0) { return result; } else if (result == 0) { close(); return 0; } else if (isNonBlockingError ()) { return 0; } else { this->handleError (result); close(); return -1; } } void netChannel::close (void) { if ( !closed ) { this->handleClose(); closed = true ; connected = false ; accepting = false ; write_blocked = false ; } netSocket::close () ; } void netChannel::handleReadEvent (void) { if (accepting) { if (!connected) { connected = true ; //this->handleConnect(); } this->handleAccept(); } else if (!connected) { connected = true ; //this->handleConnect(); this->handleRead(); } else { this->handleRead(); } } void netChannel::handleWriteEvent (void) { if (!connected) { connected = true ; //this->handleConnect(); } write_blocked = false ; this->handleWrite(); } bool netChannel::poll (unsigned int timeout) { if (!channels) return false ; enum { MAX_SOCKETS = 256 } ; netSocket* reads [ MAX_SOCKETS+1 ] ; netSocket* writes [ MAX_SOCKETS+1 ] ; netSocket* deletes [ MAX_SOCKETS+1 ] ; int nreads = 0 ; int nwrites = 0 ; int ndeletes = 0 ; int nopen = 0 ; netChannel* ch; for ( ch = channels; ch != NULL; ch = ch -> next_channel ) { if ( ch -> should_delete ) { assert(ndeletes closed ) { nopen++ ; if (ch -> readable()) { assert(nreads writable()) { assert(nwrites closed ) ch -> handleReadEvent(); } for ( i=0; writes[i]; i++ ) { ch = (netChannel*)writes[i]; if ( ! ch -> closed ) ch -> handleWriteEvent(); } return true ; } void netChannel::loop (unsigned int timeout) { while ( poll (timeout) ) ; } plib-1.8.5/src/net/netMessage.cxx0000644000175000001440000000310710765364434013601 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netMessage.cxx 1899 2004-03-21 17:41:07Z sjbaker $ */ #include "netMessage.h" void netMessageChannel::handleBufferRead (netBuffer& in_buffer) { int n = in_buffer.getLength () ; while ( n >= 2 ) { unsigned short msg_len = *( (unsigned short*)in_buffer.getData() ) ; if ( n >= msg_len ) { //we have a complete message; handle it netMessage msg(in_buffer.getData(),msg_len); in_buffer.remove(0,msg_len); handleMessage ( msg ); //ulSetError ( UL_DEBUG, "netMessageChannel: %d read", msg_len ) ; n -= msg_len ; } else { //ulSetError ( UL_DEBUG, "netMessageChannel: %d waiting", n ) ; break ; } } } plib-1.8.5/src/net/README0000644000175000001440000000304310765364434011641 00000000000000PLIB Network Library ------------------- DESCRIPTION: This is a C++ library for making networked games. It includes event-driven channels, support for buffering and pipelining, a monitor server for remote telnet admin, and binary messages. HISTORY Initial work by Dave McClurg This library is based on from a high-performance internet server architecture for Python called Medusa. http://www.nightmare.com/medusa/medusa.html Added binary messages and PLIB naming conventions LICENSING: This library is distributed with PLIB under the GNU LGPL. MEDUSA COPYRIGHT: --- Copyright 1996 by Sam Rushing All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Sam Rushing not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --- plib-1.8.5/src/net/netSocket.h0000644000175000001440000000566110765364434013101 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netSocket.h 2052 2005-11-10 20:55:54Z fayjf $ */ /**** * NAME * netSocket - network sockets * * DESCRIPTION * netSocket is a thin C++ wrapper over bsd sockets to * facilitate porting to other platforms * * AUTHOR * Dave McClurg * * CREATION DATE * Dec-2000 * ****/ #ifndef NET_SOCKET_H #define NET_SOCKET_H #include "ul.h" #include /* * Socket address, internet style. */ class netAddress { /* DANGER!!! This MUST match 'struct sockaddr_in' exactly! */ short sin_family ; unsigned short sin_port ; unsigned int sin_addr ; char sin_zero [ 8 ] ; public: netAddress () {} netAddress ( const char* host, int port ) ; void set ( const char* host, int port ) ; const char* getHost () const ; unsigned int getPort() const ; unsigned int getIP () const ; unsigned int getFamily () const ; static const char* getLocalHost () ; bool getBroadcast () const ; }; /* * Socket type */ class netSocket { int handle ; public: netSocket () ; virtual ~netSocket () ; int getHandle () const { return handle; } void setHandle (int handle) ; bool open ( bool stream=true ) ; void close ( void ) ; int bind ( const char* host, int port ) ; int listen ( int backlog ) ; int accept ( netAddress* addr ) ; int connect ( const char* host, int port ) ; int send ( const void * buffer, int size, int flags = 0 ) ; int sendto ( const void * buffer, int size, int flags, const netAddress* to ) ; int recv ( void * buffer, int size, int flags = 0 ) ; int recvfrom ( void * buffer, int size, int flags, netAddress* from ) ; void setBlocking ( bool blocking ) ; void setBroadcast ( bool broadcast ) ; static bool isNonBlockingError () ; static int select ( netSocket** reads, netSocket** writes, int timeout ) ; } ; int netInit ( int* argc, char** argv = NULL ) ; /* Legacy */ int netInit () ; const char* netFormat ( const char* fmt, ... ) ; #endif // NET_SOCKET_H plib-1.8.5/src/net/Makefile.am0000644000175000001440000000050310765364434013013 00000000000000if BUILD_NET lib_LIBRARIES = libplibnet.a include_HEADERS = netBuffer.h netChannel.h netChat.h netMessage.h \ netMonitor.h netSocket.h net.h libplibnet_a_SOURCES = netBuffer.cxx netChannel.cxx netChat.cxx \ netMessage.cxx netMonitor.cxx netSocket.cxx INCLUDES = -I$(top_srcdir)/src/util endif EXTRA_DIST = net.dsp plib-1.8.5/src/net/netBuffer.cxx0000644000175000001440000000363410765364434013433 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netBuffer.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "netBuffer.h" void netBufferChannel::handleRead (void) { int max_read = in_buffer.getMaxLength() - in_buffer.getLength() ; if (max_read) { char* data = in_buffer.getData() + in_buffer.getLength() ; int num_read = recv (data, max_read) ; if (num_read > 0) { in_buffer.append (num_read) ; //ulSetError ( UL_DEBUG, "netBufferChannel: %d read", num_read ) ; } } if (in_buffer.getLength()) { handleBufferRead (in_buffer); } } void netBufferChannel::handleWrite (void) { if (out_buffer.getLength()) { if (isConnected()) { int length = out_buffer.getLength() ; if (length>512) length=512; int num_sent = netChannel::send ( out_buffer.getData(), length); if (num_sent > 0) { out_buffer.remove (0, num_sent); //ulSetError ( UL_DEBUG, "netBufferChannel: %d sent", num_sent ) ; } } } else if (should_close) { close(); } } plib-1.8.5/src/net/net.h0000644000175000001440000000034310765364434011720 00000000000000#ifndef __PLIB_NET_H__ #define __PLIB_NET_H__ 1 #include #include #include #include #include #include #endif plib-1.8.5/src/net/Makefile.in0000644000175000001440000003742210765365022013030 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/net DIST_COMMON = README $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibnet_a_AR = $(AR) $(ARFLAGS) libplibnet_a_LIBADD = am__libplibnet_a_SOURCES_DIST = netBuffer.cxx netChannel.cxx \ netChat.cxx netMessage.cxx netMonitor.cxx netSocket.cxx @BUILD_NET_TRUE@am_libplibnet_a_OBJECTS = netBuffer.$(OBJEXT) \ @BUILD_NET_TRUE@ netChannel.$(OBJEXT) netChat.$(OBJEXT) \ @BUILD_NET_TRUE@ netMessage.$(OBJEXT) netMonitor.$(OBJEXT) \ @BUILD_NET_TRUE@ netSocket.$(OBJEXT) libplibnet_a_OBJECTS = $(am_libplibnet_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libplibnet_a_SOURCES) DIST_SOURCES = $(am__libplibnet_a_SOURCES_DIST) am__include_HEADERS_DIST = netBuffer.h netChannel.h netChat.h \ netMessage.h netMonitor.h netSocket.h net.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_NET_TRUE@lib_LIBRARIES = libplibnet.a @BUILD_NET_TRUE@include_HEADERS = netBuffer.h netChannel.h netChat.h netMessage.h \ @BUILD_NET_TRUE@ netMonitor.h netSocket.h net.h @BUILD_NET_TRUE@libplibnet_a_SOURCES = netBuffer.cxx netChannel.cxx netChat.cxx \ @BUILD_NET_TRUE@ netMessage.cxx netMonitor.cxx netSocket.cxx @BUILD_NET_TRUE@INCLUDES = -I$(top_srcdir)/src/util EXTRA_DIST = net.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/net/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/net/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibnet.a: $(libplibnet_a_OBJECTS) $(libplibnet_a_DEPENDENCIES) -rm -f libplibnet.a $(libplibnet_a_AR) libplibnet.a $(libplibnet_a_OBJECTS) $(libplibnet_a_LIBADD) $(RANLIB) libplibnet.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netBuffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netChannel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netChat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netMonitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netSocket.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/net/netMonitor.h0000644000175000001440000000501610765364434013272 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netMonitor.h 1899 2004-03-21 17:41:07Z sjbaker $ */ /**** * NAME * netMonitor - network monitor server * * DESCRIPTION * netMonitor is a telnet command port with * password authorization. It can be paired * with and used to remotely admin another server. * * AUTHORS * Sam Rushing - original version for Medusa * Dave McClurg - modified for use in PLIB * * CREATION DATE * Dec-2000 * ****/ #ifndef NET_MONITOR_H #define NET_MONITOR_H #include "netChat.h" class netMonitorServer : private netChannel { char* name ; char* password ; char* prompt ; void (*cmdfunc)(const char*) ; class netMonitorChannel* active ; friend class netMonitorChannel ; virtual bool writable (void) { return false ; } virtual void handleAccept (void) ; public: netMonitorServer( const char* _name, int port ) { name = ulStrDup(_name); password = ulStrDup("") ; prompt = ulStrDup(">>> "); cmdfunc = 0 ; active = 0 ; open () ; bind ("", port); listen (1); ulSetError(UL_DEBUG, "Monitor \"%s\" started on port %d",name,port); } ~netMonitorServer() { delete[] name ; delete[] password ; delete[] prompt ; } const char* getPassword () const { return password; } void setPassword ( const char* string ) { delete[] password ; password = ulStrDup ( string?string:"" ) ; } void setPrompt ( const char* string ) { delete[] prompt ; prompt = ulStrDup ( string?string:"" ) ; } void setCommandFunc ( void (*func)(const char*) ) { cmdfunc = func ; } bool push (const char* s) ; } ; #endif // NET_MONITOR_H plib-1.8.5/src/net/netBuffer.h0000644000175000001440000001447410765364434013064 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netBuffer.h 1901 2004-03-21 18:19:11Z sjbaker $ */ /**** * NAME * netBuffer - network buffer class * * DESCRIPTION * Clients and servers built on top of netBufferChannel * automatically support pipelining. * * Pipelining refers to a protocol capability. Normally, * a conversation with a server has a back-and-forth * quality to it. The client sends a command, and * waits for the response. If a client needs to send * many commands over a high-latency connection, * waiting for each response can take a long time. * * For example, when sending a mail message to many recipients * with SMTP, the client will send a series of RCPT commands, one * for each recipient. For each of these commands, the server will * send back a reply indicating whether the mailbox specified is * valid. If you want to send a message to several hundred recipients, * this can be rather tedious if the round-trip time for each command * is long. You'd like to be able to send a bunch of RCPT commands * in one batch, and then count off the responses to them as they come. * * I have a favorite visual when explaining the advantages of * pipelining. Imagine each request to the server is a boxcar on a train. * The client is in Los Angeles, and the server is in New York. * Pipelining lets you hook all your cars in one long chain; send * them to New York, where they are filled and sent back to you. * Without pipelining you have to send one car at a time. * * Not all protocols allow pipelining. Not all servers support it; * Sendmail, for example, does not support pipelining because it tends * to fork unpredictably, leaving buffered data in a questionable state. * A recent extension to the SMTP protocol allows a server to specify * whether it supports pipelining. HTTP/1.1 explicitly requires that * a server support pipelining. * * NOTES * When a user passes in a buffer object, it belongs to * the user. When the library gives a buffer to the user, * the user should copy it. * * AUTHORS * Sam Rushing - original version for Medusa * Dave McClurg - modified for use in PLIB * * CREATION DATE * Dec-2000 * ****/ #ifndef NET_BUFFER_H #define NET_BUFFER_H #include "netChannel.h" // =========================================================================== // netName // =========================================================================== enum { NET_MAX_NAME = 31 } ; //eg. char name [ NET_MAX_NAME+1 ] ; inline char* netCopyName ( char* dst, const char* src ) { if ( src != NULL ) { strncpy ( dst, src, NET_MAX_NAME ) ; dst [ NET_MAX_NAME ] = 0 ; } else *dst = 0 ; return dst ; } // =========================================================================== // netBuffer // =========================================================================== class netBuffer { protected: int length ; int max_length ; char* data ; public: netBuffer ( int _max_length ) { length = 0 ; max_length = _max_length ; data = new char [ max_length+1 ] ; //for null terminator } ~netBuffer () { delete[] data ; } int getLength() const { return length ; } int getMaxLength() const { return max_length ; } /* ** getData() returns a pointer to the data ** Note: a zero (0) byte is appended for convenience ** but the data may have internal zero (0) bytes already */ char* getData() { data [length] = 0 ; return data ; } const char* getData() const { ((char*)data) [length] = 0 ; return data ; } void remove () { length = 0 ; } void remove (int pos, int n) { assert (pos>=0 && pos=0 && pos - original version for Medusa * Dave McClurg - modified for use in PLIB * * CREATION DATE * Dec-2000 * ****/ #ifndef NET_CHANNEL_H #define NET_CHANNEL_H #include "netSocket.h" class netChannel : public netSocket { bool closed, connected, accepting, write_blocked, should_delete ; netChannel* next_channel ; friend bool netPoll (unsigned int timeout); public: netChannel () ; virtual ~netChannel () ; void setHandle (int s, bool is_connected = true); bool isConnected () const { return connected; } bool isClosed () const { return closed; } void shouldDelete () { should_delete = true ; } // -------------------------------------------------- // socket methods // -------------------------------------------------- bool open ( void ) ; void close ( void ) ; int listen ( int backlog ) ; int connect ( const char* host, int port ) ; int send ( const void * buf, int size, int flags = 0 ) ; int recv ( void * buf, int size, int flags = 0 ) ; // poll() eligibility predicates virtual bool readable (void) { return (connected || accepting); } virtual bool writable (void) { return (!connected || write_blocked); } // -------------------------------------------------- // event handlers // -------------------------------------------------- void handleReadEvent (void); void handleWriteEvent (void); // These are meant to be overridden. virtual void handleClose (void) { //ulSetError(UL_WARNING,"Network: %d: unhandled close",getHandle()); } virtual void handleRead (void) { ulSetError(UL_WARNING,"Network: %d: unhandled read",getHandle()); } virtual void handleWrite (void) { ulSetError(UL_WARNING,"Network: %d: unhandled write",getHandle()); } virtual void handleAccept (void) { ulSetError(UL_WARNING,"Network: %d: unhandled accept",getHandle()); } virtual void handleError (int error) { ulSetError(UL_WARNING,"Network: %d: errno: %s(%d)",getHandle(),strerror(errno),errno); } static bool poll (unsigned int timeout = 0 ) ; static void loop (unsigned int timeout = 0 ) ; }; #endif // NET_CHANNEL_H plib-1.8.5/src/net/netChat.h0000644000175000001440000000511710765364434012524 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netChat.h 1568 2002-09-02 06:05:49Z sjbaker $ */ /**** * NAME * netChat - network chat class * * DESCRIPTION * This class adds support for 'chat' style protocols - * where one side sends a 'command', and the other sends * a response (examples would be the common internet * protocols - smtp, nntp, ftp, etc..). * * The handle_buffer_read() method looks at the input * stream for the current 'terminator' (usually '\r\n' * for single-line responses, '\r\n.\r\n' for multi-line * output), calling found_terminator() on its receipt. * * EXAMPLE * Say you build an nntp client using this class. * At the start of the connection, you'll have * terminator set to '\r\n', in order to process * the single-line greeting. Just before issuing a * 'LIST' command you'll set it to '\r\n.\r\n'. * The output of the LIST command will be accumulated * (using your own 'collect_incoming_data' method) * up to the terminator, and then control will be * returned to you - by calling your found_terminator() * * AUTHORS * Sam Rushing - original version for Medusa * Dave McClurg - modified for use in PLIB * * CREATION DATE * Dec-2000 * ****/ #ifndef NET_CHAT_H #define NET_CHAT_H #include "netBuffer.h" class netChat : public netBufferChannel { char* terminator; virtual void handleBufferRead (netBuffer& buffer) ; public: netChat () : terminator (0) {} void setTerminator (const char* t); const char* getTerminator (void); bool push (const char* s) { return bufferSend ( s, strlen(s) ) ; } virtual void collectIncomingData (const char* s, int n) {} virtual void foundTerminator (void) {} }; #endif // NET_CHAT_H plib-1.8.5/src/net/netMonitor.cxx0000644000175000001440000000733010765364434013646 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: netMonitor.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "netMonitor.h" class netMonitorChannel : public netChat { netMonitorServer* server ; bool authorized ; netBuffer buffer; void prompt () ; virtual void collectIncomingData (const char* s, int n) ; virtual void foundTerminator (void) ; public: netMonitorChannel ( netMonitorServer* server ) ; virtual void handleClose (void) { ulSetError(UL_DEBUG, "%d: Client disconnected.",getHandle()); shouldDelete () ; netChat::handleClose () ; server -> active = 0 ; } } ; // for now, we ignore any telnet option stuff sent to // us, and we process the backspace key ourselves. // gee, it would be fun to write a full-blown line-editing // environment, etc... static void clean_line (char* line) { char* dst = line ; for ( char* src = line ; *src ; src ++ ) { char ch = *src ; if (ch==8 || ch==127) { // backspace if (dst != line) dst -- ; } else if (ch<127) { *dst++ = *src ; } } *dst = 0 ; } netMonitorChannel::netMonitorChannel ( netMonitorServer* _server ) : buffer(512) { server = _server ; setTerminator("\r\n"); if ( server -> password && server -> password [0] != 0 ) { authorized = false ; push ("Enter password: ") ; } else { authorized = true ; push ( netFormat("Connected to \"%s\"... Welcome!\r\n", server -> name ) ) ; prompt(); } } void netMonitorChannel::prompt () { push ( server -> prompt ) ; } void netMonitorChannel::collectIncomingData (const char* s, int n) { if ( !buffer.append(s,n) ) { // denial of service. push ("BCNU\r\n"); closeWhenDone(); } } void netMonitorChannel::foundTerminator (void) { char* line = buffer.getData(); clean_line ( line ) ; if (!authorized) { if (strcmp(line,server -> password) == 0) { authorized = true ; push ( netFormat("Connected to \"%s\"... Welcome!\r\n",server -> name) ) ; prompt () ; } else { close(); } } else if (*line == 0) { prompt(); } else if (*line == 4 || strcmp(line,"exit") == 0) { push ("BCNU\r\n"); //Be seein' you closeWhenDone(); } else { if ( server -> cmdfunc ) { server -> cmdfunc ( line ) ; } else { ulSetError(UL_DEBUG,"echo: %s",line); push(line); push(getTerminator()); } prompt(); } buffer.remove(); } void netMonitorServer::handleAccept (void) { if ( !active ) { netAddress addr ; int s = accept ( &addr ) ; ulSetError(UL_DEBUG, "%d: Client %s:%d connected",s,addr.getHost(),addr.getPort()); active = new netMonitorChannel ( this ) ; active -> setHandle (s); } } bool netMonitorServer::push (const char* s) { if ( active ) return active -> push ( s ) ; return false ; } plib-1.8.5/src/net/net.dsp0000644000175000001440000001016510765364434012262 00000000000000# Microsoft Developer Studio Project File - Name="net" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=net - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "net.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "net.mak" CFG="net - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "net - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "net - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "net - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\util" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy net.h ..\..\net.h copy netBuffer.h ..\..\netBuffer.h copy netChannel.h ..\..\netChannel.h copy netChat.h ..\..\netChat.h copy netMessage.h ..\..\netMessage.h copy netMonitor.h ..\..\netMonitor.h copy netSocket.h ..\..\netSocket.h # End Special Build Tool !ELSEIF "$(CFG)" == "net - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\util" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\net_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy net.h ..\..\net.h copy netBuffer.h ..\..\netBuffer.h copy netChannel.h ..\..\netChannel.h copy netChat.h ..\..\netChat.h copy netMessage.h ..\..\netMessage.h copy netMonitor.h ..\..\netMonitor.h copy netSocket.h ..\..\netSocket.h # End Special Build Tool !ENDIF # Begin Target # Name "net - Win32 Release" # Name "net - Win32 Debug" # Begin Source File SOURCE=.\netBuffer.cxx # End Source File # Begin Source File SOURCE=.\netBuffer.h # End Source File # Begin Source File SOURCE=.\netChannel.cxx # End Source File # Begin Source File SOURCE=.\netChannel.h # End Source File # Begin Source File SOURCE=.\netChat.cxx # End Source File # Begin Source File SOURCE=.\netChat.h # End Source File # Begin Source File SOURCE=.\netMessage.cxx # End Source File # Begin Source File SOURCE=.\netMessage.h # End Source File # Begin Source File SOURCE=.\netMonitor.cxx # End Source File # Begin Source File SOURCE=.\netMonitor.h # End Source File # Begin Source File SOURCE=.\netSocket.cxx # End Source File # Begin Source File SOURCE=.\netSocket.h # End Source File # End Target # End Project plib-1.8.5/src/sl/0000777000175000001440000000000010765365517010700 500000000000000plib-1.8.5/src/sl/slMODnote.cxx0000644000175000001440000002243110765364440013200 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slMODnote.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "slMODPrivate.h" static SampleInfo *smp ; static unsigned char chToPlay[32]; static int masterVol = 0x30 * 4/3; static int globalVol = 0x40; static int mono; static int outRate = DEF_OUTRATE ; static int tempo = DEF_TEMPO ; /* BPM = rows/minute/4 */ static int speed = DEF_SPEED ; /* frames/row */ static int frameLen = DEF_OUTRATE * 60 / ( DEF_TEMPO * 24 ) ; static int patRepeat = 0 ; static void commonWork ( Note *np ) { _MOD_instClearPFW(); if (np->ins) _MOD_instSample(&smp[np->ins - 1], 0); if (np->note != 255) if (np->note == 254) _MOD_instNoteOff(0); else _MOD_instNote((np->note/16) * 12 + np->note%16, 0); if (np->vol != 255) _MOD_instVol(np->vol, 0); } static void noEffect ( Note *np ) { if ( np->cmd == 255 ) _MOD_instEmptyCmd () ; commonWork ( np ) ; } static void unknownEffect ( Note *np ) { ulSetError ( UL_WARNING, "Unknown effect: %c%02X", np->cmd + '@', np->info ) ; commonWork ( np ) ; } #define X (np->info/16) #define Y (np->info%16) /* Dxy, Kxy, Lxy common work */ static void dklCommonWork ( Note *np ) { if ( np->info ) { if ( Y == 0 ) /* Dx0=up */ _MOD_instSetVolSlideParams ( X, 1, 1, 1, 0 ) ; else if ( X > 0 && Y == 0xf ) /* DxF=fine up */ _MOD_instSetVolSlideParams ( X, 1, 1, 1, 1 ) ; else if ( X == 0xf ) /* DFy=fine down */ _MOD_instSetVolSlideParams ( -Y, 1, 1, 1, 1 ) ; else /* D0y=down, but also D46 or something is here */ _MOD_instSetVolSlideParams ( -Y, 1, 1, 1, 0 ) ; } _MOD_instVolSlide () ; } /* Dxy = volume slide */ static void dCmd ( Note *np ) { commonWork ( np ) ; dklCommonWork ( np ) ; } /* Exx, Fxx common work */ static void efCommonWork ( Note *np ) { if (np->info) { switch (X) { case 0xf: /* [EF]Fx = fine */ _MOD_instSetPeriodSlideParams((np->info%16)*4, 1); break; case 0xe: /* [EF]Ex = extra fine */ /* ST3 plays [EF]E0 and [EF]F0 differently */ /* so it may be incompatible.. */ _MOD_instSetPeriodSlideParams(np->info%16, 1); break; default: _MOD_instSetPeriodSlideParams(np->info*4, 0); break; } } } /* Exx = slide down */ static void eCmd(Note *np) { commonWork(np); efCommonWork(np); _MOD_instPeriodSlideDown(); } /* Fxx = slide up */ static void fCmd(Note *np) { commonWork(np); efCommonWork(np); _MOD_instPeriodSlideUp(); } /* Gxx = portamento */ static void gCmd(Note *np) { _MOD_instClearPFW(); if (np->ins) _MOD_instSetPortamentoDefaultVol(); /* only set default volume */ if (np->vol != 255) _MOD_instVol(np->vol, 0); if (np->note < 254 ) _MOD_instSetPortamentoTo((np->note/16)*12 + np->note%16); if (np->info) _MOD_instSetPortamentoSpeed(np->info*4); _MOD_instPortamento(); } /* Hxy = vibrato */ static void hCmd(Note *np) { commonWork(np); if (np->info) _MOD_instSetVibratoParams(X, Y*8); _MOD_instVibrato(); } /* Ixy = tremor */ static void iCmd(Note *np) { commonWork(np); if (np->info) _MOD_instSetTremorParams(X+1, Y+1); _MOD_instTremor(); } /* Jxy = arpeggio */ static void jCmd(Note *np) { commonWork(np); if (np->info) _MOD_instSetArpeggioParams(X, Y); _MOD_instArpeggio(); } /* Kxy = H00 and Dxy */ static void kCmd(Note *np) { commonWork(np); _MOD_instVibrato(); /* H00 */ dklCommonWork(np); } /* Lxy = G00 and Dxy */ static void lCmd(Note *np) { commonWork(np); _MOD_instPortamento(); /* G00 */ dklCommonWork(np); } /* Oxx = sample offset */ static void oCmd(Note *np) { commonWork(np); _MOD_instSampleOffset(np->info * 0x100); } /* Qxy = retrig + volumeslide */ static void qCmd(Note *np) { static int add[16]={0,-1,-2,-4,-8,-16,0,0,0,1,2,4,8,16,0,0}; static int mul[16]={1,1,1,1,1,1,2,1,1,1,1,1,1,1,3,2}; static int div[16]={1,1,1,1,1,1,3,2,1,1,1,1,1,1,2,1}; commonWork(np); if (np->info) { _MOD_instSetVolSlideParams(add[X], mul[X], div[X], Y, 0); _MOD_instSetRetrigParam(Y); } _MOD_instVolSlide(); _MOD_instRetrig(); } /* Rxy = tremolo */ static void rCmd(Note *np) { commonWork(np); if (np->info) _MOD_instSetTremoloParams(X, Y*2); _MOD_instTremolo(); } /* Uxy = fine vibrato */ static void uCmd(Note *np) { commonWork(np); if (np->info) _MOD_instSetVibratoParams(X, Y*2); _MOD_instVibrato(); } /* Sxy = misc */ static void sCmd(Note *np) { if (X == 0xd) /* notedelay */ { _MOD_instClearPFW(); if (np->ins) _MOD_instSample(&smp[np->ins - 1], Y); if (np->note != 255) if (np->note == 254) _MOD_instNoteOff(Y); else _MOD_instNote((np->note/16) * 12 + np->note%16, Y); if (np->vol != 255) _MOD_instVol(np->vol, Y); } else { commonWork ( np ) ; switch ( X ) { case 1: /* set glissando control */ _MOD_instSetPortamentoGlissando(Y); break; case 2: /* set finetune */ /* ...but not tested yet. which tune use this? */ ulSetError ( UL_DEBUG, "Got it! Set Finetune"); { static int freq[16] = { 8363,8413,8463,8529,8581,8651,8723,8757, 7895,7941,7985,8046,8107,8169,8232,8280 }; _MOD_instTuning(freq[Y]); /* the tuning effects from next key-on */ } break; case 3: /* set vibrato waveform */ _MOD_instSetVibratoWave(Y%4, Y/4); break; case 4: /* set tremolo waveform */ _MOD_instSetTremoloWave(Y%4, Y/4); break; case 8: /* set pan position */ _MOD_instPanPosition(Y*64/15); break; case 0xc: /* notecut */ _MOD_instNoteCut(Y); break; case 0xb: /* pattern loop */ case 0xe: /* pattern delay */ break; default: ulSetError ( UL_WARNING, "%c%02X not supported.", np->cmd+'@', np->info); } } } /* Vxx = set global volume */ static void setGlobalVol(void) { dacioGlobalVol ( masterVol * globalVol ) ; } void _MOD_playNoteSetMono(int m) { mono = m; _MOD_instMono(m); } void _MOD_playNoteSetMasterVol(int mv) { masterVol = mono? mv : mv * 4 / 3; setGlobalVol(); } void _MOD_playNoteSetGlobalVol(int gv) { globalVol = gv; setGlobalVol(); } static void vCmd(Note *np) { commonWork(np); _MOD_playNoteSetGlobalVol(np->info); } /* Xxx = DMP style pan position */ static void xCmd(Note *np) { commonWork(np); if (np->info <= 0x80) _MOD_instPanPosition(np->info * 64 / 0x80); else if (np->info == 0xa4) _MOD_instPanPosition(-1); /* surround */ else _MOD_instPanPosition(32); /* unknown -> center */ } static void (*cmdTbl[])( Note *np ) = { /*@*/ unknownEffect, /*A*/ noEffect , /*B*/ noEffect, /*C*/noEffect, /*D*/ dCmd , /*E*/ eCmd , /*F*/ fCmd , /*G*/gCmd, /*H*/ hCmd , /*I*/ iCmd , /*J*/ jCmd , /*K*/kCmd, /*L*/ lCmd , /*M*/ unknownEffect, /*N*/ unknownEffect, /*O*/oCmd, /*P*/ unknownEffect, /*Q*/ qCmd , /*R*/ rCmd , /*S*/sCmd, /*T*/ noEffect , /*U*/ uCmd , /*V*/ vCmd , /*W*/unknownEffect, /*X*/ xCmd , /*Y*/ unknownEffect, /*Z*/ unknownEffect } ; void _MOD_playNoteSetSample ( SampleInfo *sip ) { smp = sip ; } void _MOD_playNoteInit ( void ) { _MOD_instInit () ; } static void setFrameLen ( void ) { frameLen = outRate * 60 / (tempo * 24) ; _MOD_instHirevSetFrameLen ( frameLen ) ; } void _MOD_playNoteSetOutRate ( int _or ) { if ( _or > MAX_OUTRATE ) { ulSetError ( UL_FATAL, "Too high output sample rate." ) ; } _MOD_instOutRate ( _or ) ; outRate = _or ; setFrameLen () ; } void _MOD_playNoteSetTempo ( int n ) { if ( n < MIN_TEMPO ) { ulSetError ( UL_WARNING, "Illegal tempo (%d) ignored.", n ) ; return ; } tempo = n ; setFrameLen () ; } void _MOD_playNoteSetSpeed ( int n ) { speed = n ; } void _MOD_playNoteSetNote ( int ch, Note *np ) { chToPlay [ ch ] = 1 ; _MOD_instSelectCh ( ch ) ; if ( np->cmd == 255 ) noEffect ( np ) ; else (*cmdTbl[np->cmd]) ( np ) ; } void _MOD_playNoteSetPatRepeat ( int n ) { patRepeat = n ; } void _MOD_playNote ( void ) { for ( int r = 0 ; r <= patRepeat ; r++ ) for ( int f = 0 ; f < speed ; f++ ) { _MOD_instHirevEraseBuf () ; for ( int ch = 0 ; ch < 32 ; ch++ ) if ( chToPlay [ ch ] ) { _MOD_instSelectCh ( ch ) ; _MOD_instDoPerFrameWorks ( f ) ; _MOD_instLoop () ; } _MOD_instHirevFlushBuf () ; } patRepeat = 0 ; for ( int ch = 0 ; ch < 32 ; ch++ ) chToPlay [ ch ] = 0 ; } plib-1.8.5/src/sl/slDSP.cxx0000644000175000001440000005424110765364440012325 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slDSP.cxx 1775 2003-07-04 14:33:03Z puggles $ */ #include "sl.h" #include static int init_bytes ; #ifdef SL_USING_OSS_AUDIO /* ------------------------------------------------------------ */ /* OSSAUDIO - Linux, FreeBSD, etc */ /* ------------------------------------------------------------ */ void slDSP::open ( const char *device, int _rate, int _stereo, int _bps ) { fd = ::open ( device, O_WRONLY | O_NONBLOCK ) ; if ( fd < 0 ) { perror ( "slDSP: open" ) ; error = SL_TRUE ; stereo = SL_FALSE ; bps = 1 ; rate = 8000 ; init_bytes = 0 ; } else { error = SL_FALSE ; /* Set up a driver fragment size of 1024 (ie 2^10) */ errno = 0 ; ioctl ( SNDCTL_DSP_SETFRAGMENT, 0x7FFF000A ) ; stereo = ioctl ( SOUND_PCM_WRITE_CHANNELS, _stereo ? 2 : 1 ) >= 2 ; bps = ioctl ( SOUND_PCM_WRITE_BITS, _bps ) ; rate = ioctl ( SOUND_PCM_WRITE_RATE, _rate ) ; if ( errno != 0 ) perror ( "slDSP: ioctl" ) ; getBufferInfo () ; init_bytes = buff_info.bytes ; } } void slDSP::close () { if ( fd >= 0 ) ::close ( fd ) ; } int slDSP::getDriverBufferSize () { if ( error ) return 0 ; getBufferInfo () ; return buff_info.fragsize ; } void slDSP::getBufferInfo () { if ( error ) return ; if ( ::ioctl ( fd, SNDCTL_DSP_GETOSPACE, & buff_info ) < 0 ) { perror ( "slDSP: getBufferInfo" ) ; error = SL_TRUE ; return ; } } void slDSP::write ( void *buffer, size_t length ) { if ( error || (int)length <= 0 ) return ; size_t nwritten = ::write ( fd, (const char *) buffer, length ) ; if ( (int)nwritten < 0 ) perror ( "slDSP: write" ) ; else if ( nwritten != length ) perror ( "slDSP: short write" ) ; } float slDSP::secondsRemaining () { if ( error ) return 0.0f ; getBufferInfo () ; int samples_left = buff_info.fragments * buff_info.fragsize ; if ( stereo ) samples_left /= 2 ; if ( bps == 16 ) samples_left /= 2 ; return (float) samples_left / (float) rate ; } float slDSP::secondsUsed () { if ( error ) return 0.0f ; getBufferInfo () ; int samples_used = init_bytes - buff_info.bytes ; if ( stereo ) samples_used /= 2 ; if ( bps == 16 ) samples_used /= 2 ; return (float) samples_used / (float) rate ; } void slDSP::sync () { if ( !error) ::ioctl ( fd, SOUND_PCM_SYNC , 0 ) ; } void slDSP::stop () { if ( !error) ::ioctl ( fd, SOUND_PCM_RESET, 0 ) ; } #endif #ifdef UL_WIN32 /* ------------------------------------------------------------ */ /* win32 */ /* ------------------------------------------------------------ */ static void wperror(MMRESULT num) { char buffer[0xff]; // yes, this is hardcoded :-) waveOutGetErrorText( num, buffer, sizeof(buffer)-1); ulSetError ( UL_WARNING, "SlDSP: %s (%d)", buffer, num ); } void CALLBACK waveOutProc( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) { slDSP *pDsp = (slDSP *)dwInstance; switch( uMsg ) { case WOM_CLOSE: break; case WOM_OPEN: break; case WOM_DONE: pDsp->counter--; break; } } void slDSP::open ( const char *device, int _rate, int _stereo, int _bps ) { MMRESULT result; int i; hWaveOut = NULL; curr_header = 0; counter = 0; written = 0; for ( i = 0; i < BUFFER_COUNT; i++ ) wavehdr[i] = NULL; Format.wFormatTag = WAVE_FORMAT_PCM; Format.nChannels = _stereo ? 2 : 1; Format.nSamplesPerSec = _rate; Format.wBitsPerSample = _bps; Format.nBlockAlign = 1; Format.nAvgBytesPerSec = _rate * Format.nChannels; Format.cbSize = 0; result = waveOutOpen( & hWaveOut, WAVE_MAPPER, & Format, 0, 0L, WAVE_FORMAT_QUERY ); if ( result != MMSYSERR_NOERROR ) { wperror( result); error = SL_TRUE ; stereo = SL_FALSE ; bps = _bps ; rate = _rate ; init_bytes = 0 ; return; } #if 0 ulSetError ( UL_DEBUG, "Request: stereo=%d bps=%d rate=%d", _stereo, _bps, _rate ); ulSetError ( UL_DEBUG, "Result: channels=%d bps=%d rate=%d", Format.nChannels, Format.wBitsPerSample, Format.nSamplesPerSec ); #endif // Now the hwaveouthandle "should" be valid if ( ( result = waveOutOpen( & hWaveOut, WAVE_MAPPER, (WAVEFORMATEX *)& Format, (DWORD)waveOutProc, (DWORD)this, CALLBACK_FUNCTION )) != MMSYSERR_NOERROR ) { wperror( result); error = SL_TRUE ; stereo = SL_FALSE ; bps = _bps ; rate = _rate ; init_bytes = 0 ; return; } else { error = SL_FALSE ; stereo = _stereo; bps = _bps; rate = _rate; /* hmm ?! */ init_bytes = BUFFER_SIZE; for ( i = 0; i < BUFFER_COUNT; i++ ) { Uchar *p = new Uchar[sizeof(WAVEHDR) + BUFFER_SIZE]; wavehdr[i] = (WAVEHDR*) p; wavehdr[i]->lpData = (LPSTR) p + sizeof(WAVEHDR); wavehdr[i]->dwBufferLength = (DWORD) BUFFER_SIZE; wavehdr[i]->dwBytesRecorded = 0L; wavehdr[i]->dwUser = 0; wavehdr[i]->dwFlags = 0; wavehdr[i]->dwLoops = 0; wavehdr[i]->lpNext = 0; wavehdr[i]->reserved = 0; result = waveOutPrepareHeader( hWaveOut, wavehdr[i], sizeof(WAVEHDR) ); if ( result != MMSYSERR_NOERROR ) { wperror ( result ); error = SL_TRUE; return; } } } } void slDSP::close () { if ( hWaveOut != NULL ) { waveOutReset( hWaveOut ); for ( int i = 0; i < BUFFER_COUNT; i++ ) { waveOutUnprepareHeader( hWaveOut, wavehdr[i], sizeof(WAVEHDR) ); delete[] (Uchar*) wavehdr[i]; } waveOutClose( hWaveOut ); hWaveOut = NULL; } } int slDSP::getDriverBufferSize () { if ( error ) return 0 ; /* hmm ?! */ return BUFFER_SIZE; } void slDSP::getBufferInfo () { return ; } void slDSP::write ( void *buffer, size_t length ) { MMRESULT result; if ( error || (int)length <= 0 ) return ; #if 0 ulSetError ( UL_DEBUG, "written=%ld counter=%d curr_header=%d", written, counter, curr_header ); #endif memcpy(wavehdr[curr_header]->lpData, buffer, length); wavehdr[curr_header]->dwBufferLength = (DWORD) length; result = waveOutWrite(hWaveOut, wavehdr[curr_header], sizeof(WAVEHDR)); if ( result != MMSYSERR_NOERROR ) { wperror ( result ); error = SL_TRUE; } counter ++; written += (DWORD) BUFFER_SIZE; curr_header = ( curr_header + 1 ) % BUFFER_COUNT; } float slDSP::secondsRemaining () { if ( error ) return 0.0f ; return 10.0f ; } float slDSP::secondsUsed () { DWORD samples_used; MMRESULT result; float samp_time; if ( error ) return 0.0f ; mmt.wType = TIME_BYTES; result = waveOutGetPosition( hWaveOut, &mmt, sizeof( mmt )); if ( mmt.u.cb == 0 || counter == 0) return (float)0.0; if ( counter < BUFFER_COUNT ) samples_used = written - mmt.u.cb ; else samples_used = BUFFER_COUNT * BUFFER_SIZE ; if ( stereo ) samples_used /= 2 ; if ( bps == 16 ) samples_used /= 2 ; samp_time = (float) samples_used / (float) rate ; #if 0 ulSetError ( UL_DEBUG, "%0.2f written packets=%ld stereo=%d bps=%d rate=%d", samp_time, counter, stereo, bps, rate ); #endif return samp_time; } void slDSP::sync () { } void slDSP::stop () { if ( error ) return ; waveOutReset( hWaveOut ); written = 0 ; } /* ------------------------------------------------------------ */ /* NetBSD/OpenBSD 2.3 this should be very close to SUN Audio */ /* ------------------------------------------------------------ */ #elif (defined(UL_BSD) && !defined(__FreeBSD__)) || defined(UL_SOLARIS) void slDSP::open ( const char *device, int _rate, int _stereo, int _bps ) { counter = 0; fd = ::open ( device, O_RDWR | O_NONBLOCK ) ; if ( fd < 0 ) { perror ( "slDSP: open" ) ; error = SL_TRUE ; } else { if( ::ioctl( fd, AUDIO_GETINFO, &ainfo) == -1) { perror("slDSP: open - getinfo"); stereo = SL_FALSE ; bps = 8 ; rate = 8000 ; init_bytes = 0 ; return; } #ifdef UL_SOLARIS AUDIO_INITINFO(&ainfo); #endif ainfo.play.sample_rate = _rate; ainfo.play.precision = _bps; #ifdef UL_SOLARIS if ( ainfo.play.port == AUDIO_SPEAKER ) ainfo.play.channels = 1; else ainfo.play.channels = _stereo ? 2 : 1; ainfo.play.encoding = AUDIO_ENCODING_ALAW; // if ( _bps < 16 ) // { // ainfo.play.encoding = AUDIO_ENCODING_LINEAR8; // } // else // { // ainfo.play.encoding = AUDIO_ENCODING_LINEAR; // } #else ainfo.play.encoding = AUDIO_ENCODING_ULINEAR; #endif if( :: ioctl(fd, AUDIO_SETINFO, &ainfo) == -1) { perror("slDSP: open - setinfo"); stereo = SL_FALSE ; bps = 8 ; rate = 8000 ; init_bytes = 0 ; return; } rate = _rate; stereo = _stereo; bps = _bps; error = SL_FALSE ; getBufferInfo (); // I could not change the size, // so let's try this ... init_bytes = 1024 * 8; } } void slDSP::close () { if ( fd >= 0 ) ::close ( fd ) ; } int slDSP::getDriverBufferSize () { if ( error ) return 0 ; getBufferInfo () ; // HW buffer is 0xffff on my box #ifdef UL_SOLARIS return ainfo.play.buffer_size; #else return 1024 * 8; #endif } void slDSP::getBufferInfo () { if ( error ) return ; if( ::ioctl( fd, AUDIO_GETINFO, &ainfo) < 0) { perror ( "slDSP: getBufferInfo" ) ; error = SL_TRUE ; return ; } #ifndef UL_SOLARIS if( ::ioctl( fd, AUDIO_GETOOFFS, &audio_offset ) < 0) { perror ( "slDSP: getBufferInfo" ) ; error = SL_TRUE ; return ; } #endif } void slDSP::write ( void *buffer, size_t length ) { if ( error || (int)length <= 0 ) return ; size_t nwritten = ::write ( fd, (const char *) buffer, length ) ; if ( (int)nwritten < 0 ) perror ( "slDSP: write" ) ; else if ( nwritten != length ) perror ( "slDSP: short write" ) ; counter ++; /* hmmm */ } float slDSP::secondsRemaining () { return 10.0f ; } float slDSP::secondsUsed () { /* * original formula from Steve: * ----------------------------- * * int samples_used = init_bytes - buff_info.bytes ; * | | * | +--- current available * | space in bytes ! * +---------------- available space * when empty; * * sample_used contains the number of bytes which are * "used" or in the DSP "pipeline". */ int samples_used; if ( error ) return 0.0f ; getBufferInfo () ; //This is wrong: this is the hw queue in the kernel ! //samples_used = ainfo.play.buffer_size - audio_offset.offset ; // This is: all data written minus where we are now in the queue if ( counter == 0 ) return 0.0; #ifdef UL_SOLARIS samples_used = ( counter * init_bytes ) - ainfo.play.samples; #else samples_used = ( counter * init_bytes ) - audio_offset.samples; #endif if ( stereo ) samples_used /= 2 ; if ( bps == 16 ) samples_used /= 2 ; return (float) samples_used / (float) rate ; } void slDSP::sync () { #ifdef UL_SOLARIS if ( !error) ::ioctl ( fd, I_FLUSH, FLUSHRW ) ; #else if ( !error) ::ioctl ( fd, AUDIO_FLUSH , 0 ) ; #endif } void slDSP::stop () { // nothing found yet } /* ------------------------------------------------------------ */ /* SGI IRIX audio */ /* ------------------------------------------------------------ */ #elif defined(UL_IRIX) void slDSP::open ( const char *device, int _rate, int _stereo, int _bps ) { if ( _bps != 8 ) { perror ( "slDSP: supports only 8bit audio for sgi" ) ; error = SL_TRUE; return; } init_bytes = 1024 * 4 ; config = ALnewconfig(); ALsetchannels ( config, _stereo ? AL_STEREO : AL_MONO ); ALsetwidth ( config, _bps == 8 ? AL_SAMPLE_8 : AL_SAMPLE_16 ); ALsetqueuesize( config, init_bytes * 2 ); port = ALopenport( device, "w", config ); if ( port == NULL ) { perror ( "slDSP: open" ) ; error = SL_TRUE ; } else { long params[2] = {AL_OUTPUT_RATE, 0 }; params[1] = _rate; if ( ALsetparams(AL_DEFAULT_DEVICE, params, 2) != 0 ) { perror ( "slDSP: open - ALsetparams" ) ; error = SL_TRUE ; return; } rate = _rate; stereo = _stereo; bps = _bps; error = SL_FALSE ; } } void slDSP::close () { if ( port != NULL ) { ALcloseport ( port ); ALfreeconfig( config ); port = NULL; } } int slDSP::getDriverBufferSize () { if ( error ) return 0 ; return ALgetqueuesize( config ) / 2 ; } void slDSP::getBufferInfo () { if ( error ) return ; } void slDSP::write ( void *buffer, size_t length ) { char *buf = (char *)buffer; if ( error || (int)length <= 0 ) return ; for ( int i = 0; i < (int)length; i++ ) buf[i] = buf[i] >> 1; ALwritesamps(port, (void *)buf, length ); } float slDSP::secondsRemaining () { int samples_remain; if ( error ) return 0.0f ; samples_remain = ALgetfillable(port) ; return (float) samples_remain / (float) rate ; } float slDSP::secondsUsed () { int samples_used; if ( error ) return 0.0f ; samples_used = ALgetfilled(port) * 2 ; return (float) samples_used / (float) rate ; } void slDSP::sync () { if ( error ) return ; /* found this in the header file - but no description * or example for the long parameter. */ // ALflush(ALport, long); } void slDSP::stop () { } #endif #if defined(UL_MACINTOSH) || defined(UL_MAC_OSX) // Print out debugging info when secondsUsed is called, // track useful information, and used extended error checking. //#define SL_MAC_DEBUG pascal void sndCallbackProc ( SndChannelPtr theChan, SndCommand *theCmd ); void doError ( OSErr theError ); int bytesUsed; bool playing; //SCStatus sndChanStatus; #ifdef SL_MAC_DEBUG int underWrites; int queued; int writes; int callBacks; float roughTime; int qLength; int qHead; int qTail; #endif void doError( OSErr theError ) { const char* msg = 0 ; switch( theError ) { case 0: msg = "No Error." ; break; case notEnoughHardwareErr: msg = "Insufficient hardware available." ; break; case badChannel: msg = "Channel is corrupt or unusable." ; break; case badFormat: msg = "Resource is corrupt or unusable." ; break; case queueFull: msg = "No room in the queue." ; break; case channelBusy: msg = "Channel is busy." ; break; case siInvalidCompression: msg = "Invalid compression type." ; break; case notEnoughBufferSpace: msg = "Insufficient memory available." ; break; case buffersTooSmall: msg = "Buffer is too small." ; break; case paramErr: msg = "Invalid parameter specified." ; break; } if ( msg != 0 ) ulSetError ( UL_WARNING, "OSErr : %s", msg ) ; else ulSetError ( UL_WARNING, "OSErr : Unknown Error : %d.", theError ); } pascal void sndCallbackProc ( SndChannelPtr chan, SndCommand *cmd ) { //SndChannelStatus is a BIG waste of cpu time, but I don't know //any other way to remedy this. I will leave it out for now. //SndChannelStatus(chan, sizeof(SCStatus), &sndChanStatus); //playing = sndChanStatus.scChannelBusy ? true : false; bytesUsed -= BUFFER_SIZE ; #ifdef SL_MAC_DEBUG callBacks++; queued--; qLength = chan->qLength; qTail = chan->qTail; qHead = chan->qHead; #endif } void slDSP::open ( const char *device, int _rate, int _stereo, int _bps ) { // Check for valid ranges on inputs if ( _rate > 65535 ) { ulSetError ( UL_WARNING, "slDsp : Sample rate out of bounds! Setting to 44100hz."); _rate = 44100; } error = SL_FALSE; stereo = _stereo; rate = _rate; bps = _bps; osErr = noErr; bytesPerSample = (stereo ? 2:1) * (bps/8); bytesPerSecond = bytesPerSample * rate; secondsPerPacket = BUFFER_SIZE / bytesPerSecond; secUsed = 0; secLeft = 0; playing = false; long initOptions = 0; // Channel init options if ( stereo ) initOptions += initStereo; else initOptions += initMono; // Extra init options available //initOptions += initNoInterp; // No linear interpolation //initOptions += initNoDrop; // No drop-sample conversion //initOptions += initChanLeft; // Left stereo channel //initOptions += initChanRight; // Right stereo channel // Define a call-back routine - invoked via callBackCmd SndCallBackUPP callBackRoutine = NewSndCallBackUPP ( sndCallbackProc ); // Allocate a sound channel sndChannel = new SndChannel; sndChannel -> userInfo = 0; sndChannel -> qLength = 128; // Queue as many as 128 packets at a time; osErr = SndNewChannel( &sndChannel, sampledSynth, initOptions, callBackRoutine ); if ( osErr != noErr ) { SndDisposeChannel( sndChannel, true ); ulSetError ( UL_WARNING, "slDSP::open() Problem creating sound channel" ); doError (osErr); error = SL_TRUE; } // Format sound header structure extSndHeader.numChannels = stereo ? 2 : 1; extSndHeader.sampleRate = rate << 16; extSndHeader.encode = extSH; extSndHeader.sampleSize = bps; // Allocate the sound buffer buf = new char [VIRTUAL_BUFFER_SIZE]; if ( !buf ) { ulSetError ( UL_WARNING, "slDSP::open() Not enough memory to allocate sound buffer." ); SndDisposeChannel( sndChannel, true ); error = SL_TRUE; } rpos = buf; wpos = buf; } void slDSP::close () { SndDisposeChannel( sndChannel, true ); delete [] buf; } void slDSP::write ( void *buffer, size_t length ) { if ( error || (int)length <= 0 || length > VIRTUAL_BUFFER_SIZE ) return; // Make sure data will fit into available space if ( length >= VIRTUAL_BUFFER_SIZE - (rpos - buf) ) wpos = buf; // Copy sound data into buffer rpos = wpos; ptr = (char*)buffer; for ( int i = 0; i < length; i++ ) *wpos++ = *ptr++; // Format the sound header extSndHeader.samplePtr = rpos; extSndHeader.numFrames = length / bytesPerSample; // Format the buffer command currentCmd.cmd = bufferCmd; currentCmd.param2 = (long)&extSndHeader; // Do the sound command osErr = SndDoCommand (sndChannel, ¤tCmd, false); #ifdef SL_MAC_DEBUG if ( osErr != noErr ) { ulSetError ( UL_WARNING, "Error slDsp::write - bufferCmd() : " ); doError( osErr ); error = SL_TRUE; } #endif // Issue a callBack command when the bufferCmd has finished currentCmd.cmd = callBackCmd; osErr = SndDoCommand (sndChannel, ¤tCmd, false); #ifdef SL_MAC_DEBUG if ( osErr != noErr ) { ulSetError ( UL_WARNING, "Error slDsp::write - callBackCmd() : " ); doError( osErr ); error = SL_TRUE; } #endif // Add on time for this packet secUsed += length / bytesPerSecond; // Add on bytes used bytesUsed += BUFFER_SIZE; // Reset the timing for the buffer if (!playing) { Microseconds(&lastTime); playing = true; } #ifdef SL_MAC_DEBUG queued++; writes++; #endif } void slDSP::sync () { if ( error ) return; // flushCmd will remove all queued commands in a channel, // and the command in progress is not affected. // This is not exactly what sync() is supposed to do! currentCmd.cmd = flushCmd; osErr = SndDoImmediate ( sndChannel, ¤tCmd ); #ifdef SL_MAC_DEBUG if ( osErr != noErr ) { ulSetError ( UL_WARNING, "Error slDsp::sync() : " ); doError( osErr ); error = SL_TRUE; } #endif } void slDSP::stop () { if ( error ) return; currentCmd.cmd = quietCmd; osErr = SndDoImmediate ( sndChannel, ¤tCmd ); playing = false; #ifdef SL_MAC_DEBUG if ( osErr != noErr ) { ulSetError ( UL_WARNING, "Error slDsp::stop() : " ); doError( osErr ); error = SL_TRUE; } #endif } void slDSP::getBufferInfo () { return; } int slDSP::getDriverBufferSize () { return BUFFER_SIZE; } float slDSP::secondsRemaining () { if ( error ) return 0.0f; // sl doesn't use this, so I didn't write it! return 10.0f; } float slDSP::secondsUsed () { if ( error || secUsed <= 0 ) return secUsed = 0; Microseconds( &currTime ); secUsed -= (currTime.lo - lastTime.lo) / 1000000.0; Microseconds( &lastTime ); // This fixes inaccuracy with Microseconds if ( secUsed > bytesUsed / bytesPerSecond + secondsPerPacket ) secUsed -= secondsPerPacket; #ifdef SL_MAC_DEBUG if (queued == 0) underWrites++; roughTime = bytesUsed / bytesPerSecond; ulSetError ( UL_DEBUG, "%d\t%d\t%f\t%d\t%d\t%f\t%d\t%d\t%d\t%d", bytesUsed, queued, secUsed, callBacks, writes, roughTime, underWrites, qLength, qHead, qTail ); #endif return secUsed; } #endif plib-1.8.5/src/sl/slMODinst.cxx0000644000175000001440000005467410765364440013226 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slMODinst.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "slMODPrivate.h" /* note-period table */ #define NOTE_MAX (12*8-1) /* 8octave */ static short *note ; #define shift(x,n) ((n) >= 0? (x) << (n) : (x) >> -(n)) /* x * 2**n */ static struct { int *p0 ; int *p ; int len ; } hirev_buf ; void _MOD_instHirevInit ( void ) { hirev_buf.p0 = dacioGetBuffer () ; } void _MOD_instHirevSetFrameLen ( int l ) { dacioIncomingBufLen ( l ) ; hirev_buf.len = l ; } void _MOD_instHirevEraseBuf ( void ) { memset ( hirev_buf.p0, 0, sizeof ( int ) * hirev_buf.len * 2 ) ; } void _MOD_instHirevFlushBuf ( void ) { dacioOut () ; } static void fadeout ( InstHirevInfo *ihip ) { int lastL = ihip->lastL / 64 ; int lastR = ihip->lastR / 64 ; int f = ihip->fadeout ; if ( f > 63 ) f = 63 ; if ( lastL || lastR ) { int *bufp = hirev_buf.p ; int n = ( hirev_buf.p0 + hirev_buf.len - bufp ) / 2 ; if ( n > f ) n = f ; for ( ; n > 0 ; n--,f-- ) { *bufp++ += lastL * f ; *bufp++ += lastR * f ; } } ihip->fadeout = f ; if ( !f ) ihip->lastL = ihip->lastR = 0 ; } /* vol zero optimization: just calculates phase progress within this frame */ static void vol0Opt ( InstHirevInfo *ihip ) { if ( ihip->lastL || ihip->lastR ) { /* suddenly volume is turned to 0 -> click ( chi_mai.s3m ) */ ihip->fadeout = 256 ; fadeout ( ihip ) ; ihip->fadeout = 0 ; /* don't note off ( ambient_power.mod ) */ } ihip->wAcc = ( unsigned int ) ( unsigned short ) ihip->wAcc + ( unsigned short )( ihip->w * hirev_buf.len ) ; ihip->ptr += ( ihip->w >> 16 ) * hirev_buf.len + ( ( unsigned short ) ihip->w * hirev_buf.len >> 16 ) + ( ihip->wAcc >> 16 ) ; if ( ihip->ptr >= ihip->end ) { if ( ihip->loopBeg ) ihip->ptr = ihip->loopBeg + ( ihip->ptr - ihip->end ) % ( ihip->end - ihip->loopBeg ) ; else ihip->ptr = NULL ; /* note off */ } ihip->lastL = ihip->lastR = 0 ; } static InstHirevInfo ihi ; /* cacheing */ static void hirevLoop0 ( unsigned int n ) { int *bufp = hirev_buf.p ; unsigned char *ihiPtr = ihi.ptr ; unsigned int ihiWAcc = ihi.wAcc ; for ( ; n > 0 ; n-- ) { int d = ( signed char ) *ihiPtr ; *bufp++ += d * ihi.volL ; *bufp++ += d * ihi.volR ; ihiWAcc = ( unsigned short ) ihiWAcc + ihi.w ; /*ihiWAcc & 0xffff + w*/ ihiPtr += ihiWAcc >> 16 ; } hirev_buf.p = bufp ; ihi.ptr = ihiPtr ; ihi.wAcc = ihiWAcc ; } static void hirevLoop80 ( unsigned int n ) { int *bufp = hirev_buf.p ; unsigned char *ihiPtr = ihi.ptr ; unsigned int ihiWAcc = ihi.wAcc ; for ( ; n > 0 ; n-- ) { int d = ( signed char ) ( *ihiPtr ^ 0x80 ) ; *bufp++ += d * ihi.volL ; *bufp++ += d * ihi.volR ; ihiWAcc = ( unsigned short ) ihiWAcc + ihi.w ; /*ihiWAcc & 0xffff + w*/ ihiPtr += ihiWAcc >> 16 ; } hirev_buf.p = bufp ; ihi.ptr = ihiPtr ; ihi.wAcc = ihiWAcc ; } #define hirevLoop(x) { if ( ihi.x_or ) hirevLoop80(x) ; else hirevLoop0(x) ; } void _MOD_instHirevLoop ( InstHirevInfo *ihip ) { unsigned int restF ; unsigned int restS ; int lastD ; if ( ihip->ptr == NULL ) return ; /* note is off */ hirev_buf.p = hirev_buf.p0 ; if ( ihip->fadeout ) { fadeout ( ihip ) ; if ( !ihip->fadeout ) ihip->ptr = NULL ; /* note off */ return ; } if ( !ihip->volL && !ihip->volR ) { vol0Opt ( ihip ) ; return ; } ihi = *ihip ; /* load to cache */ restF = hirev_buf.len ; do { int l8, l0 ; ihi.wAcc = ( unsigned short ) ihi.wAcc ; l8 = ( ihi.end - ihi.ptr ) << 8 ; if ( !l8 && !ihi.wAcc ) { /* happens only on empty samples */ ihip->fadeout = 256 ; fadeout ( ihip ) ; if ( !ihip->fadeout ) ihip->ptr = NULL ; /* note off */ return ; } if ( l8 <= 0 ) { ulSetError ( UL_WARNING, "bug: restF=%u",restF ) ; ulSetError ( UL_WARNING, "end-ptr=%d w=%u",ihi.end-ihi.ptr,ihi.w ) ; ulSetError ( UL_WARNING, "wAcc = %u",ihi.wAcc ) ; } l0 = ihi.w - 1 - ihi.wAcc ; l8 += l0 >> 8 ; l0 &= 0xff ; restS = ( ( l8 / ihi.w ) << 8 ) + ( ( ( l8 % ihi.w ) << 8 ) + l0 ) / ihi.w ; if ( restF < restS ) { /* sample is longer than frame */ hirevLoop ( restF ) ; lastD = ( signed char ) ( * ( ihi.ptr - ( ihi.wAcc >> 16 ) ) ^ ihi.x_or ) ; break ; } /* restF >= restS */ hirevLoop ( restS ) ; lastD = ( signed char ) ( * ( ihi.ptr - ( ihi.wAcc >> 16 ) ) ^ ihi.x_or ) ; if ( ihi.ptr < ihi.end || ihi.end <= ihi.ptr - ( ihi.wAcc >> 16 ) ) { ulSetError ( UL_FATAL, "SL: Internal Error in _MOD_instHirevLoop." ) ; /* ulSetError ( UL_DEBUG, "bug: restS = %u restF=%u end-ptr = %d, ptr=%p", restS, restF, ihi.end-ihi.ptr, ihi.ptr ) ; ulSetError ( UL_DEBUG, "last ptr=%p", ( ihi.ptr - ( ihi.wAcc >> 16 ) ) ) ; */ } restF -= restS ; if ( ihi.loopBeg ) { ihi.ptr = ihi.loopBeg + ( ihi.ptr - ihi.end ) % ( ihi.end - ihi.loopBeg ) ; } else { ihi.lastL = lastD * ihi.volL ; ihi.lastR = lastD * ihi.volR ; ihi.fadeout = 256 ; fadeout ( &ihi ) ; if ( !ihi.fadeout ) ihi.ptr = NULL ; /* note off */ *ihip = ihi ; /* save cache */ return ; } } while ( restF ) ; ihi.lastL = lastD * ihi.volL ; ihi.lastR = lastD * ihi.volR ; *ihip = ihi ; /* save cache */ } static void makeNoteTable ( void ) { static int oct4[] = { 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 907 } ; note = new short [ NOTE_MAX + 1 ] ; for ( int i = 0 ; i <= NOTE_MAX ; i++ ) note[i] = shift ( oct4[i%12], 4-i/12 ) ; } /* period -> nearest note */ static int normalizePeriod ( int *pp ) { int i ; int s ; int p = *pp ; if ( p >= note [ 0 ] ) { *pp = note [ 0 ] ; return 0 ; } if ( p <= note [ NOTE_MAX ] ) { *pp = note [ NOTE_MAX ] ; return NOTE_MAX ; } for ( i = 0, s = 64 ; s > 0 ; s /= 2 ) /* 64: =2**n, and 64*2 > NOTE_MAX */ if ( i + s < NOTE_MAX && note [ i + s ] > p ) /* i < NOTE_MAX !! */ i += s ; if ( note [ i ] - p > p - note [ i + 1 ] ) i++ ; /* choose nearest */ *pp = note [ i ] ; return i ; } struct ModulateInfo { int type ; /* sine,ramp,square,... */ int noRetrig ; int phase ; int d ; /* phase accumlates this for each frame */ int depth ; /* org * table[phase] * depth/MAX_IN_TABLE = cur */ } ; /* output rate */ static unsigned int mclk ; #define MCLK0 ((unsigned int)3579545*4) void _MOD_instOutRate ( unsigned int rate ) { mclk = MCLK0 / rate * 65536 + MCLK0 % rate * 65536 / rate ; } #define PFW_MAX 3 /* note delay = note delay + sample delay + vol delay */ struct InstInfo { InstHirevInfo hirev ; /* for hirev loop */ struct { int cur ; /* current period */ int org ; /* original period */ int note ; /* note */ int notePer ; /* note period */ int mclk ; /* master clock in Hz (c4spd * 1712) */ struct { int speed ; /* added/sub'ed for each frame */ int fine ; /* fine slide */ } slide ; struct { int speed ; int glissando ; int nextNote ; /* (glissando) next note */ } port ; /* portamento */ ModulateInfo mod ; struct { int baseNote ; int plus[2] ; /* baseNote + plus[n] halfnote is played */ } rpgo ; /* arpeggio */ struct { int n ; int newNote ; } delay ; } per ; /* period */ struct { int cur ; /* current volume */ int org ; int pan ; /* 0(left)..64(right) */ struct { int d ; /* added for each frame */ int mul ; /* multiply for each frame */ int div ; /* divide for each frame */ int nthFrame ; /* slide every nth frame */ int fine ; /* fine slide */ int count ; /* frame counter */ } slide ; ModulateInfo mod ; struct { int onOff ; int count ; int onTime ; int offTime ; } tremor ; struct { int n ; int newest ; } delay ; } vol ; struct { int cur ; /* current frame */ int count ; /* decrement counter, 0 starts next frame */ } frame ; struct { struct { int nthFrame ; /* retrig every nth frame */ int count ; /* frame counter */ } retrig ; SampleInfo *sip ; SampleInfo *newSip ; int c4spd ; struct { int n ; SampleInfo *sip ; } delay ; int cutFrame ; } smp ; struct { void (*func[PFW_MAX])(void) ; int n ; } pfw ; /* per frame works */ } ; static InstInfo *instBank ; static InstInfo *instp ; /* select channel */ void _MOD_instSelectCh(int ch) { instp = &instBank[ch]; } /* per frame work */ void _MOD_instClearPFW(void) { instp->pfw.n = 0; } void _MOD_instDoPerFrameWorks(int frame) { instp->frame.cur = frame; for (int i = 0; i < instp->pfw.n; i++) (*instp->pfw.func[i])(); } static void addPerFrameWork(void (*f)(void)) { if (instp->pfw.n >= PFW_MAX) { ulSetError ( UL_FATAL, "Too many PFWs"); } instp->pfw.func[instp->pfw.n++] = f; } /* hirev loop */ void _MOD_instLoop(void) { _MOD_instHirevLoop(&instp->hirev); } /* initialize */ void _MOD_instInit(void) { static SampleInfo si0 ; _MOD_instHirevInit () ; makeNoteTable () ; instBank = new InstInfo [ 32 ] ; si0.beg = si0.end = NULL ; si0.c4spd = 8363 ; si0.mag = 1 ; for ( int i = 0 ; i < 32 ; i++ ) { /* prepare for "note w/o inst and volume" */ instBank[i].smp.sip = instBank[i].smp.newSip = &si0 ; instBank[i].smp.c4spd = 8363; /* dope.mod ch14 begins with GF0 */ instBank[i].hirev.end = instBank[i].hirev.ptr = NULL; instBank[i].vol.slide.div = 1; } } static void setW(void) { instp->hirev.w = (mclk * instp->smp.sip->mag) / (instp->per.cur < 16? 16 : instp->per.cur); } #define noteToPeriod(n) ((int)note[(n)] * 8363 / instp->smp.c4spd) static void setPeriod(void) { if (instp->smp.sip != instp->smp.newSip) { /* actual sample switching is carried out here */ instp->smp.sip = instp->smp.newSip ; instp->hirev.end = instp->smp.sip->end ; instp->hirev.loopBeg = instp->smp.sip->loopBeg ; instp->hirev.x_or = instp->smp.sip->x_or ; } instp->per.note = instp->per.delay.newNote; instp->per.cur = instp->per.org = instp->per.notePer = noteToPeriod(instp->per.note); instp->hirev.ptr = instp->smp.sip->beg; /* key-on */ instp->hirev.wAcc = 0; instp->hirev.fadeout = 0; if ( ! instp->per.mod.noRetrig ) instp->per.mod.phase = 0 ; if ( ! instp->vol.mod.noRetrig ) instp->vol.mod.phase = 0 ; setW () ; } static void setPeriodPFW(void) { if (instp->per.delay.n == instp->frame.cur) setPeriod() ; } void _MOD_instNote(int n, int delay) { instp->per.delay.newNote = n; if (delay == 0) setPeriod(); else { instp->per.delay.n = delay; addPerFrameWork(setPeriodPFW); } } /* set volume */ static int mono; void _MOD_instMono(int n) { mono = n; } static void setHirevVol(void) { if ( mono ) { instp->hirev.volL = instp->vol.cur ; return ; } /* currently linear, which makes front sounds rather weaker */ if (instp->vol.pan >= 0) { instp->hirev.volL = instp->vol.cur * (64 - instp->vol.pan)/64; instp->hirev.volR = instp->vol.cur * instp->vol.pan/64; } else { /* surround!! */ instp->hirev.volL = instp->vol.cur / 2; instp->hirev.volR = -instp->vol.cur / 2; } } static void setVol(void) { instp->vol.cur = instp->vol.org = instp->vol.delay.newest; setHirevVol(); } static void setVolPFW(void) { if (instp->vol.delay.n == instp->frame.cur) setVol(); } void _MOD_instVol(int v, int delay) { instp->vol.delay.newest = v > 64? 64: v; if (delay == 0) setVol(); else { instp->vol.delay.n = delay; addPerFrameWork(setVolPFW); } } /* tuning */ void _MOD_instTuning(int c4spd) { instp->smp.c4spd = c4spd; } /* set sample */ static void setSample() { /* actual sample switching is not done here.. */ instp->smp.newSip = instp->smp.delay.sip; /* set smp's default vol.. */ instp->vol.cur = instp->vol.org = instp->smp.newSip->vol; /* set smp's c4spd.. */ instp->smp.c4spd = instp->smp.newSip->c4spd; setHirevVol(); } static void setSamplePFW(void) { if (instp->smp.delay.n == instp->frame.cur) setSample(); } void _MOD_instSample(SampleInfo *sip, int delay) { instp->smp.delay.sip = sip; if (delay) { instp->smp.delay.n = delay; addPerFrameWork(setSamplePFW); } else setSample(); } /* volume slide */ inline int limitVol ( int v ) { if ( v > 64 ) return 64 ; if ( v < 0 ) return 0 ; return v ; } static int fastVolSlide; static void volSlidePFW(void) { if (!fastVolSlide && !instp->frame.cur) return; /* skip frame 0 */ if (--instp->vol.slide.count <= 0) { instp->vol.slide.count = instp->vol.slide.nthFrame; instp->vol.cur = instp->vol.cur * instp->vol.slide.mul / instp->vol.slide.div + instp->vol.slide.d; instp->vol.cur = limitVol ( instp->vol.cur ) ; setHirevVol(); } } void _MOD_instVolSlide(void) { if (instp->vol.slide.fine) { instp->vol.cur = instp->vol.cur * instp->vol.slide.mul / instp->vol.slide.div + instp->vol.slide.d; instp->vol.cur = limitVol ( instp->vol.cur ) ; setHirevVol(); } else addPerFrameWork(volSlidePFW); } void _MOD_instSetVolSlideParams(int d, int mul, int div, int nthFrame, int fine) { instp->vol.slide.d = d; instp->vol.slide.mul = mul; instp->vol.slide.div = div; instp->vol.slide.nthFrame = instp->vol.slide.count = nthFrame; instp->vol.slide.fine = fine; } void _MOD_instSetVolSlideFast(int onOff) { fastVolSlide = onOff; } /* period slide */ #define noteOff() { instp->hirev.fadeout = 256; } /* eventually note-off */ static int amigaLimit; static void limitPeriod(void) { #define p instp->per.cur if (amigaLimit) { if ((p) > note[3*12]) (p) = note[3*12]; else if ((p) < note[5*12+11]) (p) = note[5*12+11]; } else { if ((p) > 32000) (p) = 32000; else if ((p) < 0) { (p) = 0; noteOff(); /*panic.s3m needs this*/ } } #undef p } static void periodSlideUpPFW(void) { if (!instp->frame.cur) return; /* skip frame 0 */ instp->per.cur -= instp->per.slide.speed; /* ignore per.org */ limitPeriod(/*instp->per.cur*/); instp->per.org = instp->per.cur; setW(); } static void periodSlideDownPFW(void) { if (!instp->frame.cur) return; /* skip frame 0 */ instp->per.cur += instp->per.slide.speed; limitPeriod(/*instp->per.cur*/); instp->per.org = instp->per.cur; setW(); } void _MOD_instPeriodSlideUp(void) { if (instp->per.slide.fine) { instp->per.cur -= instp->per.slide.speed; limitPeriod(/*instp->per.cur*/); instp->per.org = instp->per.cur; setW(); } else addPerFrameWork(periodSlideUpPFW); } void _MOD_instPeriodSlideDown(void) { if (instp->per.slide.fine) { instp->per.cur += instp->per.slide.speed; limitPeriod(/*instp->per.cur*/); instp->per.org = instp->per.cur; setW(); } else addPerFrameWork(periodSlideDownPFW); } void _MOD_instSetPeriodSlideParams(int speed, int fine) { instp->per.slide.speed = speed; instp->per.slide.fine = fine; } void _MOD_instSetPeriodAmigaLimit(int onOff) { amigaLimit = onOff; } /* portamento */ static void portamentoPFW(void) { if (!instp->frame.cur) return; /* which S3M slides at frame 0? */ if (instp->per.org > instp->per.notePer) { /* port up now */ instp->per.org -= instp->per.port.speed; if (instp->per.org < instp->per.notePer) instp->per.cur = instp->per.org = instp->per.notePer; else { instp->per.cur = instp->per.org; if (instp->per.port.glissando) normalizePeriod(&instp->per.cur); } } else { /* port down now */ instp->per.org += instp->per.port.speed; if (instp->per.org > instp->per.notePer) instp->per.cur = instp->per.org = instp->per.notePer; else { instp->per.cur = instp->per.org; if (instp->per.port.glissando) normalizePeriod(&instp->per.cur); } } setW(); } void _MOD_instPortamento(void) { addPerFrameWork(portamentoPFW); } void _MOD_instSetPortamentoTo(int to) { instp->per.note = to; instp->per.notePer = noteToPeriod(to); } void _MOD_instSetPortamentoSpeed(int speed) { instp->per.port.speed = speed; } void _MOD_instSetPortamentoDefaultVol(void) { instp->vol.cur = instp->vol.org = instp->smp.sip->vol; setHirevVol(); } void _MOD_instSetPortamentoGlissando(int onOff) { instp->per.port.glissando = onOff; } /* arpeggio */ static void arpeggioPFW(void) { if (instp->frame.cur % 3) { instp->per.cur = note[instp->per.note + instp->per.rpgo.plus[instp->frame.cur%3 - 1]]; } else instp->per.cur = instp->per.notePer; setW(); } void _MOD_instArpeggio(void) { addPerFrameWork(arpeggioPFW); } void _MOD_instSetArpeggioParams(int plus1, int plus2) { instp->per.rpgo.plus[0] = plus1; instp->per.rpgo.plus[1] = plus2; } /* retrig */ static void retrigPFW(void) { if (--instp->smp.retrig.count <= 0) { instp->smp.retrig.count = instp->smp.retrig.nthFrame; instp->hirev.ptr = instp->smp.sip->beg; setW(); } } void _MOD_instRetrig(void) { addPerFrameWork(retrigPFW); } void _MOD_instSetRetrigParam(int nthFrame) { instp->smp.retrig.nthFrame = nthFrame; instp->smp.retrig.count = 0; } /* sample offset */ void _MOD_instSampleOffset(int offset) { instp->hirev.ptr = instp->smp.sip->beg + offset * instp->smp.sip->mag; if (instp->hirev.ptr >= instp->hirev.end) { if (instp->hirev.loopBeg) { instp->hirev.ptr = instp->hirev.loopBeg + (instp->hirev.ptr - instp->hirev.end) % (instp->hirev.end - instp->hirev.loopBeg); } else { noteOff(); } } } /* modulation */ static unsigned char sine[] = { 000, 25, 50, 74, 98, 120, 142, 162, 180, 197, 212, 225, 236, 244, 250, 254, 255 }; /* sin(x), 0 <= x < pi/4, max = 255 */ static int wave(ModulateInfo *mip) { int i; switch (mip->type) { case 1: /* ramp up (period: down) */ i = (255 * 2 * mip->phase)/63 - 255; break; case 2: /* square */ i = (mip->phase < 32)? 255 : 0; /* yes, not 255/-255 */ break; default: /* sine */ if (mip->phase < 16) i = sine[mip->phase]; else if (mip->phase < 32) i = sine[32 - mip->phase]; else if (mip->phase < 48) i = -sine[mip->phase - 32]; else i = -sine[64 - mip->phase]; } return mip->depth * i / 255; } static void vibratoPFW(void) { if (!instp->frame.cur) return; /* skip frame 0 */ instp->per.mod.phase += instp->per.mod.d; instp->per.mod.phase %= 64; /* per.org: no change.. */ instp->per.cur = instp->per.org + wave(&instp->per.mod); limitPeriod(/*instp->per.cur*/); setW(); } void _MOD_instVibrato(void) { addPerFrameWork(vibratoPFW); } /* depth = period */ void _MOD_instSetVibratoParams(int d, int depth) { if (d) instp->per.mod.d = d; instp->per.mod.depth = depth; /*if (!instp->per.mod.noRetrig) instp->per.mod.phase = 0;*/ } void _MOD_instSetVibratoWave(int type, int noRetrig) { if (type == 3) type = rand() % 3; instp->per.mod.type = type; instp->per.mod.noRetrig = noRetrig; } static void tremoloPFW(void) { if (!instp->frame.cur) return; /* skip frame 0 */ instp->vol.mod.phase += instp->vol.mod.d; instp->vol.mod.phase %= 64; instp->vol.cur = instp->vol.org + wave(&instp->vol.mod); instp->vol.cur = limitVol ( instp->vol.cur ) ; setHirevVol(); } void _MOD_instTremolo(void) { addPerFrameWork(tremoloPFW); } void _MOD_instSetTremoloParams(int d, int depth) { if (d) instp->vol.mod.d = d; instp->vol.mod.depth = depth; /*if (!instp->vol.mod.noRetrig) instp->vol.mod.phase = 0;*/ } void _MOD_instSetTremoloWave(int type, int noRetrig) { if (type == 3) type = rand() % 3; instp->vol.mod.type = type; instp->vol.mod.noRetrig = noRetrig; } /* note cut */ static void noteCutPFW(void) { /* said to be vol := 0, but ST3 seems to key-off */ if (instp->smp.cutFrame == instp->frame.cur) noteOff(); } void _MOD_instNoteCut(int frame) { if (frame) { instp->smp.cutFrame = frame; addPerFrameWork(noteCutPFW); } else noteOff(); } /* tremor */ static void tremorPFW(void) { if (--instp->vol.tremor.count <= 0) { if (instp->vol.tremor.onOff) { instp->vol.cur = 0; setHirevVol(); instp->vol.tremor.onOff = 0; instp->vol.tremor.count = instp->vol.tremor.offTime; } else { instp->vol.cur = instp->vol.org; setHirevVol(); instp->vol.tremor.onOff = 1; instp->vol.tremor.count = instp->vol.tremor.onTime; } } } void _MOD_instTremor(void) { addPerFrameWork(tremorPFW); } void _MOD_instSetTremorParams(int onTime, int offTime) { instp->vol.tremor.onTime = onTime; instp->vol.tremor.offTime = offTime; instp->vol.tremor.count = 0; instp->vol.tremor.onOff = 0; } /* note off */ static void noteOffPFW(void) { if (instp->per.delay.n == instp->frame.cur) noteOff(); } void _MOD_instNoteOff(int delay) { if (delay) { instp->per.delay.n = delay; addPerFrameWork(noteOffPFW); } else { noteOff(); } } int _MOD_instIsNoteOff(void) { return instp->hirev.ptr == NULL; } /* pan position */ /* pos = 0(left)..64(right), -1(surround) */ void _MOD_instPanPosition(int pos) { instp->vol.pan = pos; setHirevVol(); } /* empty command */ void _MOD_instEmptyCmd(void) { instp->per.cur = instp->per.org; setW(); /* empty command has some special meanings... (when after glissando portamento or vibrato) */ } plib-1.8.5/src/sl/sm.h0000644000175000001440000000544710765364440011410 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: sm.h 1732 2002-11-30 00:41:50Z sjbaker $ */ #ifndef __SM_H__ #define __SM_H__ 1 #include "slPortability.h" #ifdef SL_USING_OSS_AUDIO #define SMMIXER_DEFAULT_DEVICE "/dev/mixer" #elif defined(UL_WIN32) #define SMMIXER_DEFAULT_DEVICE "mixer" #else #endif # define SM_TRUE 1 # define SM_FALSE 0 typedef unsigned char Uchar ; typedef unsigned short Ushort ; class smMixer { private: int devices ; int error ; int fd ; #ifdef SL_USING_OSS_AUDIO int ioctl ( int cmd, int param = 0 ) { if ( error ) return param ; if ( ::ioctl ( fd, cmd, & param ) == -1 ) { perror ( "smMixer: ioctl" ) ; error = SM_TRUE ; } return param ; } #endif void open ( const char *device ) ; void close () ; public: /* Tom */ smMixer (); smMixer ( const char *device ); ~smMixer (); int notWorking () const ; int not_working () const { return notWorking () ; } /* Originally a typo! */ /* Volume controls are in integer percentages */ int getVolume ( int channel ); void setVolume ( int channel, int volume ); void getVolume ( int channel, int *left, int *right ); void setVolume ( int channel, int left, int right ); void setTreble ( int treble ); void setBass ( int bass ); void setMasterVolume ( int volume ); void setSynthVolume ( int volume ); void setPCMVolume ( int volume ); void setSpeakerVolume( int volume ); void setLineVolume ( int volume ); void setMicVolume ( int volume ); void setCDVolume ( int volume ); void setMasterVolume ( int left, int right ); void setSynthVolume ( int left, int right ); void setPCMVolume ( int left, int right ); void setSpeakerVolume( int left, int right ); void setLineVolume ( int left, int right ); void setMicVolume ( int left, int right ); void setCDVolume ( int left, int right ); } ; #endif plib-1.8.5/src/sl/sl.dsp0000644000175000001440000001034310765364440011735 00000000000000# Microsoft Developer Studio Project File - Name="sl" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=sl - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "sl.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "sl.mak" CFG="sl - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "sl - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "sl - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "sl - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MT /W3 /Zi /O2 /I "..\util" /I ".." /D "NDEBUG" /D "_LIB" /D "NEEDNAMESPACESTD" /D "HAVE_CONFIG_H" /D "HAVE_WINDOWS_H" /D "WIN32" /D "_MBCS" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy release\*.lib ..\..\*.* copy sl.h ..\..\sl.h copy slPortability.h ..\..\slPortability.h copy sm.h ..\..\sm.h # End Special Build Tool !ELSEIF "$(CFG)" == "sl - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\util" /I ".." /D "_DEBUG" /D "_LIB" /D "NEEDNAMESPACESTD" /D "HAVE_CONFIG_H" /D "HAVE_WINDOWS_H" /D "WIN32" /D "_MBCS" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\sl_d.lib" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy Library to plib directory PostBuild_Cmds=copy debug\*.lib ..\..\*.* copy sl.h ..\..\sl.h copy slPortability.h ..\..\slPortability.h copy sm.h ..\..\sm.h # End Special Build Tool !ENDIF # Begin Target # Name "sl - Win32 Release" # Name "sl - Win32 Debug" # Begin Source File SOURCE=.\sl.h # End Source File # Begin Source File SOURCE=.\slDSP.cxx # End Source File # Begin Source File SOURCE=.\slEnvelope.cxx # End Source File # Begin Source File SOURCE=.\slMODdacio.cxx # End Source File # Begin Source File SOURCE=.\slMODfile.cxx # End Source File # Begin Source File SOURCE=.\slMODfile.h # End Source File # Begin Source File SOURCE=.\slMODinst.cxx # End Source File # Begin Source File SOURCE=.\slMODnote.cxx # End Source File # Begin Source File SOURCE=.\slMODPlayer.cxx # End Source File # Begin Source File SOURCE=.\slMODPrivate.h # End Source File # Begin Source File SOURCE=.\slPlayer.cxx # End Source File # Begin Source File SOURCE=.\slPortability.h # End Source File # Begin Source File SOURCE=.\slSample.cxx # End Source File # Begin Source File SOURCE=.\slSamplePlayer.cxx # End Source File # Begin Source File SOURCE=.\slScheduler.cxx # End Source File # Begin Source File SOURCE=.\sm.h # End Source File # Begin Source File SOURCE=.\smMixer.cxx # End Source File # End Target # End Project plib-1.8.5/src/sl/slSamplePlayer.cxx0000644000175000001440000000605610765364440014276 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slSamplePlayer.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "sl.h" int slSamplePlayer::preempt ( int delay ) { slScheduler::getCurrent() -> addCallBack ( callback, sample, SL_EVENT_PREEMPTED, magic ) ; return slPlayer::preempt ( delay ) ; } slSamplePlayer::~slSamplePlayer () { if ( sample ) sample -> unRef () ; /* unRef() attached envelopes */ for ( int i = 0 ; i < SL_MAX_ENVELOPES ; i++ ) { if ( env [ i ] != NULL ) env [ i ] -> unRef(); } slScheduler::getCurrent() -> addCallBack ( callback, sample, SL_EVENT_COMPLETE, magic ) ; } void slSamplePlayer::skip ( int nframes ) { if ( nframes < lengthRemaining ) { lengthRemaining -= nframes ; bufferPos += nframes ; } else if ( replay_mode == SL_SAMPLE_LOOP ) { slScheduler::getCurrent() -> addCallBack ( callback, sample, SL_EVENT_LOOPED, magic ) ; nframes -= lengthRemaining ; while ( nframes >= sample->getLength () ) nframes -= sample->getLength () ; lengthRemaining = sample->getLength() - nframes ; bufferPos = & ( sample->getBuffer() [ nframes ] ) ; } else stop () ; } void slSamplePlayer::low_read ( int nframes, Uchar *dst ) { if ( isWaiting() ) start () ; if ( bufferPos == NULL ) /* Run out of sample & no repeats */ { memset ( dst, 0x80, nframes ) ; return ; } while ( SL_TRUE ) { /* If we can satisfy this request in one read (with data left in the sample buffer ready for next time around) - then we are done... */ if ( nframes < lengthRemaining ) { memcpy ( dst, bufferPos, nframes ) ; bufferPos += nframes ; lengthRemaining -= nframes ; return ; } memcpy ( dst, bufferPos, lengthRemaining ) ; bufferPos += lengthRemaining ; dst += lengthRemaining ; nframes -= lengthRemaining ; lengthRemaining = 0 ; if ( replay_mode == SL_SAMPLE_ONE_SHOT ) { stop () ; memset ( dst, 0x80, nframes ) ; return ; } else { slScheduler::getCurrent() -> addCallBack ( callback, sample, SL_EVENT_LOOPED, magic ) ; start () ; } } } plib-1.8.5/src/sl/slMODfile.cxx0000644000175000001440000003546210765364440013162 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slMODfile.cxx 1770 2003-06-02 23:49:44Z puggles $ */ #include "slMODPrivate.h" #include "slMODfile.h" #define NOTE_MAX (12*5-1) /* 5 octave */ #define shift(x,n) ((n)>= 0 ? (x) << (n) : (x) >> -(n)) /* x * 2**n */ #define u16LittleEndian(x) (((unsigned char *)(x))[0] + \ ((unsigned char *)(x))[1]*(unsigned short)256) #define u16BigEndian(x) (((unsigned char *)(x))[0]*(unsigned short)256 + \ ((unsigned char *)(x))[1]) static const char *transTab = "JFEGHLKRXODB.C" ; static const char *transTabE = "SFESSSSSSQ..SSSS" ; static const char transTabEX[] = { 0,0xF,0xF,1,3,2,0xB,4,8,0,0,0,0xC,0xD,0xE,0xF } ; static int oct[12] = { 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 907 } ; static int freq[16] = { 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757, 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280 } ; static unsigned char emptySample ; class SlmInfo ; static SlmInfo *top = NULL ; class SlmInfo { char *data ; SlmInfo *next ; public: SlmInfo ( unsigned int size ) { data = new char [ size ] ; next = top ; top = this ; } ~SlmInfo () { if ( this == top ) top = NULL ; delete [] data ; delete next ; } void *get () { return (void *) data ; } } ; /* Allocate song-life memory */ static void *memSong ( unsigned size ) { SlmInfo *sip = new SlmInfo ( size ) ; return sip -> get () ; } /* free all song-life memory */ static void memSongFree(void) { delete top ; } /* LPF fc=fs/4 impulse response * Hamming window (N=19) */ static int h2[][8] = /* h(n) = */ { /* n = */ /*-7 -5 -3 -1 1 3 5 7*/ { -4, 15, -42, 158, 158, -42, 15, -4} }; /* LPF fc=fs/6 impulse response * Hamming window (N=29) */ static int h3[][8] = { /*-10 -7 -4 -1 2 5 8 11*/ { -5, 16, -44, 209, 101, -31, 12, -3}, /*-11 -8 -5 -2 1 4 7 10*/ { -3, 12, -31, 101, 209, -44, 16, -5} }; /* LPF fc=fs/8 impulse response * Hamming window (N=35) */ static int h4[][8] = { /*-13 -9 -5 -1 3 7 11 15*/ { -4, 13, -38, 229, 72, -22, 7, -2}, /*-14 -10 -6 -2 2 6 10 14*/ { -3, 13, -40, 158, 158, -40, 13, -3}, /*-15 -11 -7 -3 1 5 9 13*/ { -2, 7, -22, 72, 229, -38, 13, -4} }; static int (*hn[])[8] = { h2, h3, h4 }; static SampleInfo sis; static void convolute ( int mag, char *dp ) { unsigned char *sp0; int i,j; for (sp0 = sis.beg; sp0 < sis.end; sp0++) { *dp++ = *sp0 ^ sis.x_or; for (i = 0; i < mag-1; i++,dp++) { int *hp = hn[mag-2][i]; unsigned char *sp = sp0 - 3; int sum = 0; for (j = 8; j > 0; j--,sp++,hp++) { if (sp < sis.beg) continue; if (sp >= sis.end) { if (sis.loopBeg) sp = sis.loopBeg; else break; } sum += *hp * (signed char)(*sp ^ sis.x_or); } sum /= 256; if (sum > 127) sum = 127; else if (sum < -128) sum = -128; *dp = sum; } } } static void perSampleWork(SampleInfo *sip, unsigned int c4req) { static SampleInfo sid; unsigned char *dp0; unsigned int len; int mag; mag = c4req / sip->c4spd; if (!mag) return; /* no need to oversampling */ mag++; if (mag > 4) mag = 4; /* currently max = 4x */ sis = *sip; len = sis.end - sis.beg; if (len <= 2) return; /* too short sample */ dp0 = (unsigned char *) memSong(len * mag); sid.beg = dp0 ; sid.end = dp0 + len*mag ; convolute(mag, (char *)dp0); sid.loopBeg = sis.loopBeg? (sid.beg + (sis.loopBeg - sis.beg)*mag) : (unsigned char *)NULL; sid.x_or = 0; sid.c4spd = sis.c4spd; sid.vol = sis.vol; sid.mag = sis.mag * mag; *sip = sid; } static void oversample ( int insNum, SampleInfo *sip, unsigned int c4req ) { for ( ; insNum > 0 ; insNum--, sip++ ) perSampleWork ( sip, c4req ) ; } enum MagicType { MAGIC_S3M, MAGIC_MOD ,MAGIC_MODX, MAGIC_MOD15, MAGIC_MTM } ; /* stricter 15-sample mod checking */ static int isMod15(unsigned char *p0, int size) { int ordNum, patNum ; unsigned char *p ; if ( size < 20+30*15+130+1024 ) return 0 ; /* check min length */ ordNum = p0[20+30*15] ; if (!ordNum || ordNum >= 128) return 0 ; patNum = 0 ; p = p0 + 20+30*15+2 ; /* pattern table */ for ( int i = 0 ; i < ordNum ; i++, p++ ) if (patNum < *p) patNum = *p ; if (patNum >= 64) return 0 ; if (size < 20 + 30*15 + 130 + 1024 + 1024*patNum ) return 0 ; /* sample length is not checked here */ return 1 ; } struct MagicInfo { const char *str ; int off ; MagicType type ; } ; MagicInfo magicInfo[] = { {"SCRM", 0x2c , MAGIC_S3M } , {"M.K.", 0x438 /*20+30*31+130=1080*/, MAGIC_MOD}, {"M!K!", 0x438, MAGIC_MOD }, {"FLT4", 0x438, MAGIC_MOD }, /* FLT8's pattern is different */ {"#CHN", 0x438, MAGIC_MODX }, {"##CH", 0x438, MAGIC_MODX }, /* dope.mod */ {"MTM", 0 , MAGIC_MTM }, /* check after above patterns fail. */ /* (A mod songname can be "MTMxxx") */ {0} } ; #define isnum(x) ('0' <= (x) && (x) <= '9') static int magic(unsigned char *p, int size, MagicType *mtp, int *numChp) { MagicInfo *mip; int ch; for (mip = magicInfo; mip->str != 0; mip++) { const char *ss ; char *sp ; if (mip->off + 16 >= size) continue ; /* Magicinfo.str must < 16 */ sp = (char *)p + mip->off; ch = 0; int got_it = FALSE ; for (ss = mip->str; *ss != 0; ss++,sp++) { if (*ss == '#') { if (isnum(*sp)) { ch = ch*10 + *sp - '0'; continue ; } else { got_it = TRUE ; break ; } } if (*sp != *ss) { got_it = TRUE ; break ; } } if ( ! got_it ) { *mtp = mip->type ; *numChp = ch ; return 0 ; } } if ( isMod15 ( p, size ) ) { *mtp = MAGIC_MOD15 ; return 0 ; } else return 1 ; } void MODfile::makeNoteTable(void) { note = (short *) memSong ( (NOTE_MAX+1) * sizeof(short) ) ; for ( int i = 0 ; i <= NOTE_MAX ; i++ ) note[i] = shift ( oct[i%12], -i/12 ) ; } int MODfile::roundToNote ( int p ) { if ( p == 0 ) return 0 ; if ( p >= note [ 0 ] ) return 0 ; if ( p <= note [NOTE_MAX] ) return NOTE_MAX ; /* 32: =2**n, and 32*2 > NOTE_MAX */ int i, s ; for ( i = 0, s = 32 ; s > 0 ; s /= 2 ) if ( i + s < NOTE_MAX && note[i+s] > p ) i += s ; /* i < NOTE_MAX !! */ if ( note[i] - p > p - note[i+1] ) i++ ; /* choose nearest */ return i ; } void MODfile::modToS3m(ModNote *mp, Note *np) { int X = (*mp)[3] / 16 ; int Y = (*mp)[3] % 16 ; int XY = (*mp)[3] ; int n = roundToNote ( (*mp)[0]%16 * 256 + (*mp)[1] ) ; np->note = (n!=0) ?(n/12+2)*16 + n%12 : 255 ; np->ins = ((*mp)[0] & 0xf0) | (*mp)[2]/16; np->vol = 255 ; np->cmd = 255 ; np->info = 0 ; switch ( (*mp)[2] % 16 ) { case 0x0: if (X || Y) { np->cmd = 'J' - '@'; np->info = XY; } break; case 0x1: case 0x2: if (XY) { np->cmd = transTab[(*mp)[2]%16] - '@'; np->info = (XY >= 0xE0)? 0xdf : XY; } break; case 0xA: if (!XY) break; case 0xC: np->vol = XY>64? 64 : XY; np->cmd = 255; np->info = 0; break; case 0xE: switch (X) { case 0xA: if (Y) { np->cmd = 'D' - '@'; np->info = Y*16 + 15; } break ; case 0xB: if (Y) { np->cmd = 'D' - '@'; np->info = 0xf0 + Y; } break ; default: { np->cmd = transTabE[X] - '@'; np->info = transTabEX[X]*16 + Y; } break ; } break; case 0xF: if (XY) { np->cmd = XY <= 32? 'A' - '@' : 'T' - '@'; np->info = XY? XY : 1; } break; default : { np->cmd = transTab[(*mp)[2]%16] - '@'; np->info = XY ; } break ; } } void MODfile::play_one ( int ppat ) { ModNote *np = & pat [ chNum * ( 64 * ppat + play_row ) ] ; for ( int ch = 0 ; ch < chNum ; ch++, np++ ) { Note note ; modToS3m ( np, ¬e ) ; _MOD_playNoteSetNote ( ch, ¬e ) ; switch ( note.cmd ) { case 'A' - '@': /* Set speed */ _MOD_playNoteSetSpeed ( note.info ) ; break; case 'B' - '@': play_nextOrd = note.info | 0x100 ; play_row = 64 ; break ; case 'C' - '@': play_row0 = note.info / 16 * 10 + note.info % 16 ; play_row = 64 ; break ; case 'S' - '@': switch ( note.info / 16 ) { case 0xB: /* pattern loop */ if ( note.info % 16 ) /* Jump to mark */ { if ( play_loopCnt < note.info % 16 ) { play_row = play_loopBeg - 1 ; play_loopCnt++ ; } else play_loopCnt = 0 ; } else /* Set mark */ play_loopBeg = play_row ; break; case 0xE: /* Pattern delay */ _MOD_playNoteSetPatRepeat ( note.info % 16 ) ; break; } break; case 'T' - '@': /* Set tempo */ _MOD_playNoteSetTempo ( note.info ) ; break ; } } _MOD_playNote () ; } void MODfile::tellChSettings( void ) { for ( int i = 0; i < chNum; i++ ) { _MOD_instSelectCh ( i ) ; switch ( i % 4 ) { case 0 : case 3 : _MOD_instPanPosition ( 3 * 64/15 ) ; break ; /* left */ default : _MOD_instPanPosition (12 * 64/15 ) ; break ; /* right */ } } } void MODfile::makeSampleInfo( int smp15 ) { ModSample *msp ; SampleInfo *p ; unsigned char *sp ; p = sip = (SampleInfo *) memSong ( sizeof(SampleInfo) * insNum ) ; sp = smp0p ; msp = &smpInfop[0] ; for ( int i = 0; i < insNum; i++, p++, msp++) { unsigned int lOff = 0 ; p->beg = sp ; unsigned int len = u16BigEndian(*msp+22) * 2 ; /*len*/ unsigned int lLen = u16BigEndian(*msp+28) ; /*loopLen*/ if (lLen > 1) { lLen *= smp15? 1:2; lOff = u16BigEndian(*msp+26)*(smp15? 1:2); /*loopOffset*/ p->loopBeg = sp + lOff; /*sp+loopOffset*/ p->end = p->loopBeg + lLen; } else { p->loopBeg = NULL; p->end = sp + len; /*sp+len*/ } p->x_or = 0 ; p->mag = 1 ; p->c4spd = freq[(*msp)[24]%16] ; p->vol = (*msp)[25] > 64 ? 64 : (*msp)[25] ; if (p->end > fileEnd) { if (p->beg >= fileEnd || p->loopBeg >= fileEnd) { ulSetError ( UL_WARNING, "short file (assigned an empty sample for #%d)", i+1 ) ; p->beg = &emptySample ; p->end = &emptySample+1 ; p->loopBeg = NULL ; p->vol = 0 ; } else { ulSetError ( UL_WARNING, "short file (sample #%d truncated)", i+1 ) ; p->end = fileEnd ; } } sp += u16BigEndian(*msp+22) * 2; /*sp+len*/ } } void MODfile::parseMod(unsigned char *pp0, int smp15) { int i,n; unsigned char *p; p = pp0; p0 = songName = p ; p += 20; smpInfop = (ModSample *) p ; if ( smp15 ) { p += 15*sizeof(ModSample); insNum = 15; } else { p += 31*sizeof(ModSample); insNum = 31; } ordNum = *p ; p++ ; rstOrd = *p ; p++ ; ord = p; for ( i = 0, n = 0 ; i < 128 ; i++ ) if ( n < p[i] ) n = p[i] ; /* find max pat */ patNum = n + 1 ; p += 128 + ( smp15 ? 0 : 4 ) ; pat = (ModNote *) p ; smp0p = pat [ chNum * 64 * patNum ] ; } int MODfile::update () { if ( broken ) return FALSE ; if ( firsttime ) { play_ord = play_ord0 = 0 ; memset ( repCounter, 0, ordNum ) ; firsttime = FALSE ; } play_one ( ord [ play_ord ] ) ; if ( ++play_row >= 64 ) { play_loopBeg = 0 ; play_loopCnt = 0 ; play_nextOrd = 0 ; play_row = play_row0 ; play_row0 = 0 ; play_ord = (play_nextOrd==0) ? (play_ord+1) : (play_nextOrd & 0xff) ; if ( play_ord >= ordNum ) { play_ord0 = rstOrd ; play_ord = play_ord0 ; if ( rstOrd > ordNum ) { firsttime = TRUE ; return FALSE ; } } } return TRUE ; /* Carry on playing! */ } unsigned char *MODfile::read_whole_file ( const char *fname, int *len ) { struct stat statbuf ; int l = 0 ; int fd = open ( fname, O_RDONLY ) ; if ( fd < 0 ) { perror ( "open" ) ; ulSetError ( UL_WARNING, "SL: Couldn't open MOD file '%s' for reading", fname ) ; return NULL ; } if ( fstat ( fd, &statbuf ) < 0 ) { perror ( "fstat" ) ; return NULL ; } l = statbuf.st_size ; unsigned char *p = new unsigned char [ l ] ; read ( fd, (char *)p, l ) ; close ( fd ) ; if ( len != NULL ) *len = l ; return p ; } MODfile::MODfile ( const char *fname, int speed, int stereo ) { p0 = NULL ; songName = NULL ; ord = NULL ; smpInfop = NULL ; smp0p = NULL ; pat = NULL ; note = NULL ; fileEnd = NULL ; sip = NULL ; repCounter = NULL ; play_nextOrd = play_loopBeg = play_loopCnt = play_row0 = play_row = play_ord0 = play_ord = ordNum = insNum = patNum = chNum = rstOrd = firsttime = broken = 0 ; MagicType mt ; int len = 0 ; buffer = read_whole_file ( fname, &len ) ; if ( buffer == NULL ) { broken = TRUE ; return ; } if ( magic ( buffer, len, &mt, &chNum ) ) { broken = TRUE ; ulSetError ( UL_WARNING, "Unknown format" ) ; return ; } if ( mt == MAGIC_MOD || mt == MAGIC_MOD15 ) chNum = 4 ; else if ( mt != MAGIC_MODX ) { ulSetError ( UL_WARNING, "Unknown format" ) ; broken = TRUE ; return ; } _MOD_playNoteInit () ; _MOD_playNoteSetOutRate ( speed ) ; _MOD_playNoteSetMono ( !stereo ) ; fileEnd = & buffer [ len ] ; repCounter = (unsigned char *) memSong ( 128 ) ; parseMod ( buffer, mt == MAGIC_MOD15 ) ; _MOD_instSetPeriodAmigaLimit ( 1 ) ; tellChSettings () ; makeSampleInfo ( mt == MAGIC_MOD15 ) ; oversample ( insNum, sip, (unsigned int) speed ) ; _MOD_playNoteSetSample ( sip ) ; _MOD_playNoteSetTempo ( 125 ) ; _MOD_playNoteSetSpeed ( 6 ) ; _MOD_playNoteSetMasterVol ( 0x30 ) ; _MOD_playNoteSetGlobalVol ( 0x40 ) ; makeNoteTable () ; } MODfile::~MODfile () { if ( broken ) return ; delete [] buffer ; memSongFree () ; } plib-1.8.5/src/sl/sl.h0000644000175000001440000004557710765364440011417 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: sl.h 1924 2004-04-06 13:32:26Z sjbaker $ */ #ifndef __SL_H__ #define __SL_H__ 1 #include #include "slPortability.h" #ifdef SL_USING_OSS_AUDIO #define SLDSP_DEFAULT_DEVICE "/dev/dsp" #elif defined(UL_WIN32) #define SLDSP_DEFAULT_DEVICE "dsp" #elif defined(UL_BSD) #define SLDSP_DEFAULT_DEVICE "/dev/audio" #elif defined(UL_IRIX) #define SLDSP_DEFAULT_DEVICE "dsp" // dummy ... #elif defined(UL_AIX) #define SLDSP_DEFAULT_DEVICE "dsp" // dummy ... #elif defined(UL_SOLARIS) #define SLDSP_DEFAULT_DEVICE "/dev/audio" #elif defined(UL_HPUX) #define SLDSP_DEFAULT_DEVICE "/dev/audio" #elif defined(UL_MACINTOSH) || defined(UL_MAC_OSX) #define SLDSP_DEFAULT_DEVICE "dsp" // dummy #else #error "Port me !" #endif # define SL_TRUE 1 # define SL_FALSE 0 typedef unsigned char Uchar ; typedef unsigned short Ushort ; #define SL_DEFAULT_SAMPLING_RATE 11025 class slSample ; class slPlayer ; class slSamplePlayer ; class slEnvelope ; class slScheduler ; class slDSP ; extern const char *__slPendingError ; class slDSP { private: int stereo ; int rate ; int bps ; int error ; int fd ; #if defined(SL_USING_OSS_AUDIO) audio_buf_info buff_info ; #elif defined(UL_BSD) audio_info_t ainfo; // ioctl structure audio_offset_t audio_offset; // offset in audiostream long counter; // counter-written packets #elif defined(UL_SOLARIS) audio_info_t ainfo; long counter; #elif defined(UL_IRIX) ALconfig config; // configuration stuff ALport port; // .. we are here #elif defined(UL_MACINTOSH) || defined(UL_MAC_OSX) // Size of the data chunks written with write(). // This should be a multiple of 1024. #define BUFFER_SIZE 8192 // Size of storage space for sound data. // This should be evenly divisible by BUFFER_SIZE. #define VIRTUAL_BUFFER_SIZE 131072 SndChannelPtr sndChannel ; // sound channel we are using ExtSoundHeader extSndHeader ; // sound header for bufferCmd SndCommand currentCmd ; // command we are sending to chnl OSErr osErr ; char *buf ; // buffer containing sound data char *rpos ; // read position for buffer char *wpos ; // write position for buffer char *ptr ; // ptr to data from write() float bytesPerSample ; // conversions float bytesPerSecond ; float secondsPerPacket ; float secLeft ; // seconds left in buffer float secUsed ; // seconds used in buffer UnsignedWide lastTime ; // used for timing in secondsUsed() UnsignedWide currTime ; #endif #if !defined(UL_WIN32) && !defined(UL_MACINTOSH) && !defined(UL_MAC_OSX) int ioctl ( int cmd, int param = 0 ) { if ( error ) return param ; if ( ::ioctl ( fd, cmd, & param ) == -1 ) { perror ( "slDSP: ioctl" ) ; error = SL_TRUE ; } return param ; } #elif defined(UL_WIN32) #define BUFFER_COUNT (3*8) #define BUFFER_SIZE (1024*1) friend void CALLBACK waveOutProc( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ); HWAVEOUT hWaveOut; // device handle WAVEFORMATEX Format; // open needs this MMTIME mmt; // timing WAVEHDR *wavehdr[ BUFFER_COUNT ]; // for round robin .. int curr_header; // index of actual wavehdr int counter; // counter-written packets DWORD written; // counter-written samples #endif void open ( const char *device, int _rate, int _stereo, int _bps ) ; void close () ; void getBufferInfo () ; void write ( void *buffer, size_t length ) ; protected: void setError () { error = SL_TRUE ; } int getDriverBufferSize () ; public: slDSP ( int _rate = SL_DEFAULT_SAMPLING_RATE, int _stereo = SL_FALSE, int _bps = 8 ) { open ( SLDSP_DEFAULT_DEVICE, _rate, _stereo, _bps ) ; } slDSP ( const char *device, int _rate = SL_DEFAULT_SAMPLING_RATE, int _stereo = SL_FALSE, int _bps = 8 ) { open ( device, _rate, _stereo, _bps ) ; } ~slDSP () { close () ; } float secondsRemaining () ; float secondsUsed () ; void play ( void *buffer, size_t length ) { write ( buffer, length ) ; } /* This was a typo - but people use it */ int not_working() const { return error ; } int notWorking () const { return error ; } int getBps () const { return bps ; } int getRate () const { return rate ; } int getStereo() const { return stereo ; } void sync () ; void stop () ; } ; class slSample { int ref_count ; protected: char *comment; int rate ; int bps ; int stereo ; Uchar *buffer ; int length ; void init () { ref_count = 0 ; comment = NULL ; buffer = NULL ; length = 0 ; rate = SL_DEFAULT_SAMPLING_RATE ; bps = 8 ; stereo = SL_FALSE ; } public: slSample () { init () ; } slSample ( const Uchar *buff, int leng ) { init () ; setBuffer ( buff, leng ) ; } slSample ( const char *fname, const class slDSP *dsp = NULL ) { if ( dsp != NULL && dsp->notWorking () ) dsp = NULL ; init () ; loadFile ( fname ) ; autoMatch ( dsp ) ; } ~slSample () { if ( ref_count != 0 && __slPendingError == NULL ) __slPendingError = "slSample: FATAL ERROR - Application deleted a sample while it was playing." ; delete [] buffer ; } void ref () { ref_count++ ; } void unRef () { ref_count-- ; } int getPlayCount () const { return ref_count ; } char *getComment () const { return comment ; } void setComment ( const char *nc ) { delete [] comment ; comment = ulStrDup ( nc ) ; } Uchar *getBuffer () const { return buffer ; } int getLength () const { return length ; } void autoMatch ( const slDSP *dsp ) ; void setBuffer ( const Uchar *buff, int leng ) { delete [] buffer ; buffer = new Uchar [ leng ] ; if ( buff != NULL ) memcpy ( buffer, buff, leng ) ; length = leng ; } /* These routines only set flags - use changeXXX () to convert a sound */ void setRate ( int r ) { rate = r ; } void setBps ( int b ) { bps = b ; } void setStereo ( int s ) { stereo = s ; } int getRate () const { return rate ; } int getBps () const { return bps ; } int getStereo () const { return stereo ; } float getDuration () const { return (float) getLength() / (float) ( (getStereo()?2.0f:1.0f)* (getBps()/8.0f)*getRate() ) ; } int loadFile ( const char *fname ) ; int loadRawFile ( const char *fname ) ; int loadAUFile ( const char *fname ) ; int loadWavFile ( const char *fname ) ; void changeRate ( int r ) ; void changeBps ( int b ) ; void changeStereo ( int s ) ; void changeToUnsigned () ; void adjustVolume ( float vol ) ; void print ( FILE *fd ) const { if ( buffer == NULL ) { fprintf ( fd, "Empty sample buffer\n" ) ; } else { fprintf ( fd, "\"%s\"\n",(getComment() == NULL || getComment()[0]=='\0') ? "Sample" : comment ) ; fprintf ( fd, "%s, %d bits per sample.\n", getStereo() ? "Stereo" : "Mono", getBps() ) ; fprintf ( fd, "%gKHz sample rate.\n", (float) getRate() / 1000.0f ) ; fprintf ( fd, "%d bytes of samples == %g seconds duration.\n", getLength(), getDuration() ) ; } } } ; enum slSampleStatus { SL_SAMPLE_WAITING, /* Sound hasn't started playing yet */ SL_SAMPLE_RUNNING, /* Sound has started playing */ SL_SAMPLE_DONE , /* Sound is complete */ SL_SAMPLE_PAUSED /* Sound hasn't started playing yet */ } ; enum slPreemptMode { SL_SAMPLE_CONTINUE, /* Don't allow yourself to be preempted */ SL_SAMPLE_ABORT , /* Abort playing the sound when preempted */ SL_SAMPLE_RESTART , /* Restart the sound when load permits */ SL_SAMPLE_MUTE , /* Continue silently until load permits */ SL_SAMPLE_DELAY /* Pause until load permits */ } ; enum slReplayMode { SL_SAMPLE_LOOP, /* Loop sound so that it plays forever */ SL_SAMPLE_ONE_SHOT /* Play sound just once */ } ; enum slEvent { SL_EVENT_COMPLETE, /* Sound finished playing */ SL_EVENT_LOOPED, /* Sound looped back to the start */ SL_EVENT_PREEMPTED /* Sound was preempted */ } ; typedef void (*slCallBack) ( slSample *, slEvent, int ) ; class slEnvelope { protected: float *time ; float *value ; int nsteps ; int ref_count ; float previous_value ; unsigned char prev_pitchenv ; slReplayMode replay_mode ; int getStepDelta ( float *_time, float *delta ) const ; public: slEnvelope ( int _nsteps, slReplayMode _rm, float *_times, float *_values ) { ref_count = 0 ; nsteps = _nsteps ; time = new float [ nsteps ] ; value = new float [ nsteps ] ; memcpy ( time , _times , sizeof(float) * nsteps ) ; memcpy ( value, _values, sizeof(float) * nsteps ) ; prev_pitchenv = 0x80 ; previous_value = 0.0f ; replay_mode = _rm ; } slEnvelope ( int _nsteps = 1, slReplayMode _rm = SL_SAMPLE_ONE_SHOT ) { ref_count = 0 ; nsteps = _nsteps ; time = new float [ nsteps ] ; value = new float [ nsteps ] ; prev_pitchenv = 0x80 ; previous_value = 0.0f ; for ( int i = 0 ; i < nsteps ; i++ ) time [ i ] = value [ i ] = 0.0 ; replay_mode = _rm ; } ~slEnvelope () { if ( ref_count != 0 && __slPendingError == NULL ) __slPendingError = "slEnvelope: FATAL ERROR - Application deleted an envelope while it was playing.\n" ; delete [] time ; delete [] value ; } void ref () { ref_count++ ; } void unRef () { ref_count-- ; } int getPlayCount () const { return ref_count ; } void applyToLPFilter ( unsigned char *dst, unsigned char *src, int nframes, int start ) ; void setStep ( int n, float _time, float _value ) { if ( n >= 0 && n < nsteps ) { time [ n ] = _time ; value [ n ] = _value ; } } float getStepValue ( int s ) const { return value [ s ] ; } float getStepTime ( int s ) const { return time [ s ] ; } int getNumSteps () const { return nsteps ; } float getValue ( float _time ) const ; void applyToPitch ( Uchar *dst, slPlayer *src, int nframes, int start, int next_env ) ; void applyToInvPitch ( Uchar *dst, slPlayer *src, int nframes, int start, int next_env ) ; void applyToVolume ( Uchar *dst, Uchar *src, int nframes, int start ) ; void applyToInvVolume ( Uchar *dst, Uchar *src, int nframes, int start ) ; } ; #define SL_MAX_PRIORITY 16 #define SL_MAX_SAMPLES 32 #define SL_MAX_CALLBACKS (SL_MAX_SAMPLES * 2) #define SL_MAX_ENVELOPES 32 #define SL_MAX_MIXERINPUTS 16 enum slEnvelopeType { SL_PITCH_ENVELOPE , SL_INVERSE_PITCH_ENVELOPE , SL_VOLUME_ENVELOPE, SL_INVERSE_VOLUME_ENVELOPE, SL_FILTER_ENVELOPE, SL_INVERSE_FILTER_ENVELOPE, SL_PAN_ENVELOPE , SL_INVERSE_PAN_ENVELOPE , SL_ECHO_ENVELOPE , SL_INVERSE_ECHO_ENVELOPE , SL_NULL_ENVELOPE } ; struct slPendingCallBack { slCallBack callback ; slSample *sample ; slEvent event ; int magic ; } ; class slPlayer { protected: slEnvelope *env [ SL_MAX_ENVELOPES ] ; slEnvelopeType env_type [ SL_MAX_ENVELOPES ] ; int env_start_time [ SL_MAX_ENVELOPES ] ; slReplayMode replay_mode ; slPreemptMode preempt_mode ; slSampleStatus status ; int priority ; slCallBack callback ; int magic ; virtual void low_read ( int nframes, Uchar *dest ) = 0 ; virtual void skip ( int nframes ) = 0 ; public: slPlayer ( slReplayMode rp_mode = SL_SAMPLE_ONE_SHOT, int pri = 0, slPreemptMode pr_mode = SL_SAMPLE_DELAY, int _magic = 0, slCallBack cb = NULL ) { magic = _magic ; callback = cb ; for ( int i = 0 ; i < SL_MAX_ENVELOPES ; i++ ) { env [ i ] = NULL ; env_type [ i ] = SL_NULL_ENVELOPE ; } status = SL_SAMPLE_WAITING ; replay_mode = rp_mode ; preempt_mode = pr_mode ; priority = pri ; } virtual ~slPlayer () ; slPreemptMode getPreemptMode () const { return preempt_mode ; } int getPriority () const { return ( isRunning() && preempt_mode == SL_SAMPLE_CONTINUE ) ? (SL_MAX_PRIORITY+1) : priority ; } void addEnvelope ( int i, slEnvelope *_env, slEnvelopeType _type ) ; virtual void pause () { if ( status != SL_SAMPLE_DONE ) status = SL_SAMPLE_PAUSED ; } virtual void resume () { if ( status == SL_SAMPLE_PAUSED ) status = SL_SAMPLE_RUNNING ; } virtual void reset () { status = SL_SAMPLE_WAITING ; } virtual void start () { status = SL_SAMPLE_RUNNING ; } virtual void stop () { status = SL_SAMPLE_DONE ; } int getMagic () const { return magic ; } int isWaiting () const { return status == SL_SAMPLE_WAITING ; } int isPaused () const { return status == SL_SAMPLE_PAUSED ; } int isRunning () const { return status == SL_SAMPLE_RUNNING ; } int isDone () const { return status == SL_SAMPLE_DONE ; } virtual int preempt ( int delay ) ; virtual slSample *getSample () const = 0 ; void read ( int nframes, Uchar *dest, int next_env = 0 ) ; } ; class MODfile ; class slMODPlayer : public slPlayer { MODfile *mf ; void low_read ( int nframes, Uchar *dest ) ; void init ( const char *fname ) ; public: slMODPlayer ( const char *fname, slReplayMode rp_mode = SL_SAMPLE_ONE_SHOT, int pri = 0, slPreemptMode pr_mode = SL_SAMPLE_DELAY, int _magic = 0, slCallBack cb = NULL ) : slPlayer ( rp_mode, pri, pr_mode, _magic, cb ) { init ( fname ) ; reset () ; } ~slMODPlayer () ; int preempt ( int delay ) ; virtual slSample *getSample () const { return NULL ; } void skip ( int nframes ) ; } ; class slSamplePlayer : public slPlayer { int lengthRemaining ; /* Sample frames remaining until repeat */ Uchar *bufferPos ; /* Sample frame to replay next */ slSample *sample ; void low_read ( int nframes, Uchar *dest ) ; public: slSamplePlayer ( slSample *s, slReplayMode rp_mode = SL_SAMPLE_ONE_SHOT, int pri = 0, slPreemptMode pr_mode = SL_SAMPLE_DELAY, int _magic = 0, slCallBack cb = NULL ) : slPlayer ( rp_mode, pri, pr_mode, _magic, cb ) { sample = s ; if ( sample ) sample -> ref () ; reset () ; } ~slSamplePlayer () ; int preempt ( int delay ) ; void reset () { slPlayer::reset () ; lengthRemaining = sample->getLength () ; bufferPos = sample->getBuffer () ; } void start () { slPlayer::start () ; lengthRemaining = sample->getLength () ; bufferPos = sample->getBuffer () ; } void stop () { slPlayer::stop () ; lengthRemaining = 0 ; bufferPos = NULL ; } slSample *getSample () const { return sample ; } void skip ( int nframes ) ; } ; class slScheduler : public slDSP { slPendingCallBack pending_callback [ SL_MAX_CALLBACKS ] ; int num_pending_callbacks ; float safety_margin ; int mixer_buffer_size, mixer_gain ; float seconds_per_buffer; Uchar *mixer_buffer ; Uchar *mixer_inputs [ SL_MAX_MIXERINPUTS + 1 ] ; Uchar *mixer ; int amount_left ; slPlayer *player [ SL_MAX_SAMPLES ] ; slPlayer *music ; void init () ; void realUpdate ( int dump_first = SL_FALSE ) ; void initBuffers () ; int now ; static slScheduler *current ; public: slScheduler ( int _rate = SL_DEFAULT_SAMPLING_RATE ) : slDSP ( _rate, SL_FALSE, 8 ) { init () ; } slScheduler ( const char *device, int _rate = SL_DEFAULT_SAMPLING_RATE ) : slDSP ( device, _rate, SL_FALSE, 8 ) { init () ; } ~slScheduler () ; static slScheduler *getCurrent () { return current ; } int getTimeNow () const { return now ; } float getElapsedTime ( int then ) const { return (float)(now-then)/(float)getRate() ; } void setMaxConcurrent ( int mc ); int getMaxConcurrent () const ; void flushCallBacks () ; void addCallBack ( slCallBack c, slSample *s, slEvent e, int m ) ; void update () { realUpdate ( SL_FALSE ) ; } void dumpUpdate () { realUpdate ( SL_TRUE ) ; } void resumeSample ( slSample *s = NULL, int magic = 0 ) ; void resumeMusic ( int magic = 0 ) ; void pauseSample ( slSample *s = NULL, int magic = 0 ) ; void pauseMusic ( int magic = 0 ) ; void stopSample ( slSample *s = NULL, int magic = 0 ) ; void stopMusic ( int magic = 0 ) ; void addSampleEnvelope ( slSample *s = NULL, int magic = 0, int slot = 1, slEnvelope *e = NULL, slEnvelopeType t = SL_VOLUME_ENVELOPE ) ; void addMusicEnvelope ( int magic = 0, int slot = 1, slEnvelope *e = NULL, slEnvelopeType t = SL_VOLUME_ENVELOPE ) ; int loopSample ( slSample *s, int pri = 0, slPreemptMode mode = SL_SAMPLE_MUTE, int magic = 0, slCallBack cb = NULL ) ; int loopMusic ( const char *fname, int pri = 0, slPreemptMode mode = SL_SAMPLE_MUTE, int magic = 0, slCallBack cb = NULL ) ; int playSample ( slSample *s, int pri = 1, slPreemptMode mode = SL_SAMPLE_ABORT, int magic = 0, slCallBack cb = NULL ) ; int playMusic ( const char *fname, int pri = 1, slPreemptMode mode = SL_SAMPLE_ABORT, int magic = 0, slCallBack cb = NULL ) ; void setSafetyMargin ( float seconds ) { safety_margin = seconds ; } } ; #endif plib-1.8.5/src/sl/Makefile.am0000644000175000001440000000070210765364440012641 00000000000000if BUILD_SL lib_LIBRARIES = libplibsl.a libplibsm.a include_HEADERS = sl.h slPortability.h sm.h libplibsl_a_SOURCES = \ slDSP.cxx slSample.cxx slEnvelope.cxx \ slPlayer.cxx slMODPlayer.cxx slSamplePlayer.cxx \ slScheduler.cxx slMODdacio.cxx slMODfile.cxx \ slMODinst.cxx slMODnote.cxx slMODPrivate.h slMODfile.h libplibsm_a_SOURCES = slPortability.h smMixer.cxx INCLUDES = -I$(top_srcdir)/src/util endif EXTRA_DIST = sl.dsp plib-1.8.5/src/sl/slMODPrivate.h0000644000175000001440000001056710765364440013301 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slMODPrivate.h 1732 2002-11-30 00:41:50Z sjbaker $ */ #include "ul.h" #include #include #include #include #include #ifdef UL_MSVC #include #include #else #include #endif #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif int *dacioGetBuffer () ; void dacioInit( int speed, int stereo ); void dacioFlush(void); void dacioIncomingBufLen(int len); void dacioGlobalVol(int v); void dacioOut(void); void dacioEmpty () ; void dacioSubtract ( int n ) ; int dacioGetLen () ; unsigned char *dacioGetOutBuffer () ; #define MAX_OUTRATE 65536 #define MIN_TEMPO 32 #define DEF_OUTRATE 44100 #define DEF_TEMPO 125 #define DEF_SPEED 6 struct InstHirevInfo { unsigned int w; /* omega: 65536 = 2*pi */ unsigned int wAcc; /* w accumlator */ unsigned char *ptr; unsigned char *end; unsigned char *loopBeg; int x_or; int volL; int volR; int fadeout; int lastL; int lastR; } ; void _MOD_instHirevInit(void); void _MOD_instHirevSetFrameLen(int l); void _MOD_instHirevEraseBuf(void); void _MOD_instHirevFlushBuf(void); void _MOD_instHirevLoop(InstHirevInfo *ihip); /* sample info */ struct SampleInfo { unsigned char *beg; unsigned char *end; int x_or; /* 0x80 (or 0x8000?) */ unsigned char *loopBeg; int c4spd; int vol; int mag; /* magnification */ } ; void _MOD_instOutRate(unsigned int _or); void _MOD_instSelectCh(int ch); void _MOD_instClearPFW(void); void _MOD_instDoPerFrameWorks(int frame); void _MOD_instLoop(void); void _MOD_instInit(void); void _MOD_instNote(int n, int delay); void _MOD_instMono(int n); void _MOD_instVol(int v, int delay); void _MOD_instTuning(int c4spd); void _MOD_instSample(SampleInfo *sip, int delay); void _MOD_instVolSlide(void); void _MOD_instSetVolSlideParams(int d, int mul, int div, int nthFrame, int fine); void _MOD_instSetVolSlideFast(int onOff); void _MOD_instPeriodSlideUp(void); void _MOD_instPeriodSlideDown(void); void _MOD_instSetPeriodSlideParams(int speed, int fine); void _MOD_instSetPeriodAmigaLimit(int onOff); void _MOD_instPortamento(void); void _MOD_instSetPortamentoTo(int to); void _MOD_instSetPortamentoSpeed(int speed); void _MOD_instSetPortamentoDefaultVol(void); void _MOD_instSetPortamentoGlissando(int onOff); void _MOD_instArpeggio(void); void _MOD_instSetArpeggioParams(int plus1, int plus2); void _MOD_instRetrig(void); void _MOD_instSetRetrigParam(int nthFrame); void _MOD_instSampleOffset(int offset); void _MOD_instVibrato(void); void _MOD_instSetVibratoParams(int d, int depth); void _MOD_instSetVibratoWave(int type, int noRetrig); void _MOD_instTremolo(void); void _MOD_instSetTremoloParams(int d, int depth); void _MOD_instSetTremoloWave(int type, int noRetrig); void _MOD_instNoteCut(int frame); void _MOD_instTremor(void); void _MOD_instSetTremorParams(int onTime, int offTime); void _MOD_instNoteOff(int delay); int _MOD_instIsNoteOff(void); void _MOD_instPanPosition(int pos); void _MOD_instEmptyCmd(void); struct Note { unsigned char note ; unsigned char ins ; unsigned char vol ; unsigned char cmd ; unsigned char info ; } ; void _MOD_playNoteSetMono(int m); void _MOD_playNoteSetMasterVol(int mv); void _MOD_playNoteSetGlobalVol(int gv); void _MOD_playNoteSetSample(SampleInfo *sip); void _MOD_playNoteInit(void); void _MOD_playNoteSetOutRate(int _or); void _MOD_playNoteSetTempo(int n); void _MOD_playNoteSetSpeed(int n); void _MOD_playNoteSetNote(int ch, Note *np); void _MOD_playNoteSetPatRepeat(int n); void _MOD_playNote(void); plib-1.8.5/src/sl/slEnvelope.cxx0000644000175000001440000001272310765364440013453 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slEnvelope.cxx 1926 2004-04-06 14:26:03Z sjbaker $ */ #include "sl.h" float slEnvelope::getValue ( float _time ) const { float delta ; int step = getStepDelta ( &_time, &delta ) ; return delta * (_time - time[step]) + value[step] ; } int slEnvelope::getStepDelta ( float *_time, float *delta ) const { float tt ; if ( replay_mode == SL_SAMPLE_LOOP ) { tt = (float) floor ( *_time / time [ nsteps-1 ] ) ; *_time -= tt * time [ nsteps-1 ] ; } tt = *_time ; if ( tt <= time[ 0 ] ) { *delta = 0.0f ; return 0 ; } if ( tt >= time[nsteps-1] ) { *delta = 0.0f ; return nsteps-1 ; } for ( int i = 1 ; i <= nsteps-1 ; i++ ) if ( tt <= time[i] ) { float t1 = time[i-1] ; float v1 = value[i-1] ; float t2 = time[ i ] ; float v2 = value[ i ] ; if ( t1 == t2 ) { *delta = 0.0f ; return i ; } *delta = (v2-v1) / (t2-t1) ; return i-1 ; } *delta = 0.0f ; return nsteps - 1 ; } void slEnvelope::applyToPitch ( Uchar *dst, slPlayer *src, int nframes, int start, int next_env ) { float delta ; float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ; int step = getStepDelta ( &_time, &delta ) ; float _value = delta * (_time - time[step]) + value[step] ; delta /= (float) slScheduler::getCurrent() -> getRate () ; unsigned char tmp [ 512 ] ; float pos = 0 ; float npos = 0 ; unsigned char last = prev_pitchenv; while ( nframes-- ) { npos += _value ; _value += delta ; int offset = (int) ( npos - pos ) ; if ( offset > 512 ) offset = 512 ; if ( offset < 1 ) *(dst++) = last ; else { pos += offset ; src -> read ( offset, tmp, next_env ) ; *(dst++) = last = tmp [ offset-1 ] ; prev_pitchenv = last; } } } void slEnvelope::applyToInvPitch ( Uchar *dst, slPlayer *src, int nframes, int start, int next_env ) { float delta ; float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ; int step = getStepDelta ( &_time, &delta ) ; float _value = delta * (_time - time[step]) + value[step] ; delta /= (float) slScheduler::getCurrent() -> getRate () ; unsigned char tmp [ 512 ] ; float pos = 0 ; float npos = 0 ; unsigned char last = 0x80 ; while ( nframes-- ) { npos += 1.0f / _value ; _value += delta ; int offset = (int) ( npos - pos ) ; if ( offset > 512 ) offset = 512 ; if ( offset < 1 ) *(dst++) = last ; else { pos += offset ; src -> read ( offset, tmp, next_env ) ; *(dst++) = last = tmp [ offset-1 ] ; } } } void slEnvelope::applyToVolume ( Uchar *dst, Uchar *src, int nframes, int start ) { float delta ; float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ; int step = getStepDelta ( &_time, &delta ) ; float _value = delta * (_time - time[step]) + value[step] ; delta /= (float) slScheduler::getCurrent() -> getRate () ; while ( nframes-- ) { register int res = (int)( (float)((int)*(src++)-0x80) * _value ) + 0x80 ; _value += delta ; *(dst++) = ( res > 255 ) ? 255 : ( res < 0 ) ? 0 : res ; } } void slEnvelope::applyToLPFilter ( Uchar *dst, Uchar *src, int nframes, int start ) { float delta ; float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ; int step = getStepDelta ( &_time, &delta ) ; float _value = delta * (_time - time[step]) + value[step] ; register float p_v = previous_value; delta /= (float) slScheduler::getCurrent() -> getRate () ; while ( nframes-- ) { register float c_v = (float) ((int)*(src++) - 0x80); register float f=_value; p_v = p_v*(1.0f - f)+ f*c_v; register int res = (int)(p_v) + 0x80 ; _value += delta ; *(dst++) = ( res > 255 ) ? 255 : ( res < 0 ) ? 0 : res ; } previous_value = p_v; } void slEnvelope::applyToInvVolume ( Uchar *dst, Uchar *src, int nframes, int start ) { float delta ; float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ; int step = getStepDelta ( &_time, &delta ) ; float _value = delta * (_time - time[step]) + value[step] ; delta /= (float) slScheduler::getCurrent() -> getRate () ; delta = - delta ; _value = 1.0f - _value ; while ( nframes-- ) { register int res = (int)( (float)((int)*(src++)-0x80) * _value ) + 0x80 ; _value += delta ; *(dst++) = ( res > 255 ) ? 255 : ( res < 0 ) ? 0 : res ; } } plib-1.8.5/src/sl/smMixer.cxx0000644000175000001440000001574210765364440012767 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: smMixer.cxx 1732 2002-11-30 00:41:50Z sjbaker $ */ #include "sm.h" #ifdef SL_USING_OSS_AUDIO /* ------------------------------------------------------------ */ /* OSSAUDIO - Linux, FreeBSD */ /* ------------------------------------------------------------ */ void smMixer::open ( const char *device ) { fd = ::open ( device, O_WRONLY ) ; if ( fd < 0 ) { perror ( "smMixer: open" ) ; error = SM_TRUE ; } else error = SM_FALSE ; devices = ioctl ( SOUND_MIXER_READ_DEVMASK ) ; } void smMixer::close () { if ( fd >= 0 ) ::close ( fd ) ; } smMixer::smMixer () { open ( SMMIXER_DEFAULT_DEVICE ) ; } smMixer::smMixer ( const char *device ) { open ( device ) ; } smMixer::~smMixer () { close () ; } int smMixer::notWorking () const { return error ; } /* Volume controls are in integer percentages */ int smMixer::getVolume ( int channel ) { return ioctl ( MIXER_READ ( channel ) ) & 0xFF ; } void smMixer::setVolume ( int channel, int volume ) { ioctl ( MIXER_WRITE ( channel ), (( volume & 255 ) << 8 ) | ( volume & 255 ) ) ; } void smMixer::getVolume ( int channel, int *left, int *right ) { int vv = ioctl ( MIXER_READ ( channel ) ) ; if ( left ) *left = vv & 0xFF ; if ( right ) *right = (vv>>8) & 0xFF ; } void smMixer::setVolume ( int channel, int left, int right ) { ioctl ( MIXER_WRITE ( channel ), (( right & 255 ) << 8 ) | ( left & 255 ) ) ; } void smMixer::setTreble ( int treble ) { setVolume ( SOUND_MIXER_TREBLE , treble ) ; } void smMixer::setBass ( int bass ) { setVolume ( SOUND_MIXER_TREBLE , bass ) ; } void smMixer::setMasterVolume ( int volume ) { setVolume ( SOUND_MIXER_VOLUME , volume ) ; } void smMixer::setSynthVolume ( int volume ) { setVolume ( SOUND_MIXER_SYNTH , volume ) ; } void smMixer::setPCMVolume ( int volume ) { setVolume ( SOUND_MIXER_PCM , volume ) ; } void smMixer::setSpeakerVolume( int volume ) { setVolume ( SOUND_MIXER_SPEAKER, volume ) ; } void smMixer::setLineVolume ( int volume ) { setVolume ( SOUND_MIXER_LINE , volume ) ; } void smMixer::setMicVolume ( int volume ) { setVolume ( SOUND_MIXER_MIC , volume ) ; } void smMixer::setCDVolume ( int volume ) { setVolume ( SOUND_MIXER_CD , volume ) ; } void smMixer::setMasterVolume ( int left, int right ) { setVolume ( SOUND_MIXER_VOLUME , left, right ) ; } void smMixer::setSynthVolume ( int left, int right ) { setVolume ( SOUND_MIXER_SYNTH , left, right ) ; } void smMixer::setPCMVolume ( int left, int right ) { setVolume ( SOUND_MIXER_PCM , left, right ) ; } void smMixer::setSpeakerVolume( int left, int right ) { setVolume ( SOUND_MIXER_SPEAKER, left, right ) ; } void smMixer::setLineVolume ( int left, int right ) { setVolume ( SOUND_MIXER_LINE , left, right ) ; } void smMixer::setMicVolume ( int left, int right ) { setVolume ( SOUND_MIXER_MIC , left, right ) ; } void smMixer::setCDVolume ( int left, int right ) { setVolume ( SOUND_MIXER_CD , left, right ) ; } #elif defined(UL_BSD) /* ------------------------------------------------------------ */ /* NetBSD or OpenBSD 2.3 */ /* ------------------------------------------------------------ */ void smMixer::open ( const char *device ) { } void smMixer::close (){} smMixer::smMixer () {} smMixer::smMixer ( const char * ) {} smMixer::~smMixer () {} int smMixer::notWorking () const { return error ; } /* Volume controls are in integer percentages */ int smMixer::getVolume ( int ) { return 50 ; } void smMixer::getVolume ( int, int *left, int *right ) { if ( left ) *left = 50 ; if ( right ) *right = 50 ; } void smMixer::setVolume ( int , int ) {} void smMixer::setVolume ( int , int , int ){} void smMixer::setTreble ( int ) {} void smMixer::setBass ( int ) {} void smMixer::setMasterVolume ( int ) {} void smMixer::setSynthVolume ( int ) {} void smMixer::setPCMVolume ( int ) {} void smMixer::setSpeakerVolume( int ) {} void smMixer::setLineVolume ( int ) {} void smMixer::setMicVolume ( int ) {} void smMixer::setCDVolume ( int ) {} void smMixer::setMasterVolume ( int, int ) {} void smMixer::setSynthVolume ( int, int ) {} void smMixer::setPCMVolume ( int, int ) {} void smMixer::setSpeakerVolume( int, int ) {} void smMixer::setLineVolume ( int, int ) {} void smMixer::setMicVolume ( int, int ) {} void smMixer::setCDVolume ( int, int ) {} #else /* ------------------------------------------------------------ */ /* win32 */ /* ------------------------------------------------------------ */ void smMixer::open ( const char * ) {} void smMixer::close (){} smMixer::smMixer () {} smMixer::smMixer ( const char * ) {} smMixer::~smMixer () {} int smMixer::notWorking () const { return error ; } /* Volume controls are in integer percentages */ int smMixer::getVolume ( int ) { return 50 ; } void smMixer::getVolume ( int, int *left, int *right ) { if ( left ) *left = 50 ; if ( right ) *right = 50 ; } void smMixer::setVolume ( int, int ) {} void smMixer::setVolume ( int, int, int ){} void smMixer::setTreble ( int ) {} void smMixer::setBass ( int ) {} void smMixer::setMasterVolume ( int ) {} void smMixer::setSynthVolume ( int ) {} void smMixer::setPCMVolume ( int ) {} void smMixer::setSpeakerVolume( int ) {} void smMixer::setLineVolume ( int ) {} void smMixer::setMicVolume ( int ) {} void smMixer::setCDVolume ( int ) {} void smMixer::setMasterVolume ( int, int ) {} void smMixer::setSynthVolume ( int, int ) {} void smMixer::setPCMVolume ( int, int ) {} void smMixer::setSpeakerVolume( int, int ) {} void smMixer::setLineVolume ( int, int ) {} void smMixer::setMicVolume ( int, int ) {} void smMixer::setCDVolume ( int, int ) {} #endif plib-1.8.5/src/sl/slMODdacio.cxx0000644000175000001440000000557710765364440013326 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slMODdacio.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "slMODPrivate.h" static int stereo ; static int glob_vol = 0x40 * 0x40 ; /* default g.v = m.v = 64 */ #define VOL_MAX (64*64*128) /* vol max * g.v max * m.v max */ #define VOL_MAX_LOG ( 6 + 6 + 7 ) /* 1 << VOL_MAX_LOG == VOL_MAX */ #define LEV_MAX (128*VOL_MAX) #define MAX_FRAMELEN (MAX_OUTRATE * 60 / (MIN_TEMPO * 24)) static inline unsigned char to8bit ( int x ) { int tmpvar = ( x * glob_vol + LEV_MAX ) >> VOL_MAX_LOG ; return (tmpvar & ~255) ? ~tmpvar >> 16 : tmpvar ; } struct ucharBuffer { unsigned char data [ MAX_FRAMELEN * 4 ] ; unsigned char *ptr ; unsigned char *end ; int size ; public: ucharBuffer () { ptr = data ; size = sizeof ( data ) ; end = data + size ; } void copyFrom ( int *inbufp, int n ) { if ( n == 0 ) return ; if ( stereo ) for (; n > 0; n--) { *ptr++ = to8bit ( *inbufp++ ) ; /* L */ *ptr++ = to8bit ( *inbufp++ ) ; /* R */ } else for (; n > 0; n--) { *ptr++ = to8bit ( *inbufp ) ; inbufp += 2 ; } } int getLen () { return ptr - data ; } unsigned char *getBuffer () { return data ; } void empty () { ptr = data ; } void subtract ( int n ) { /* Delete n bytes from the front of the buffer */ /* WARNING - NOT memcpy OK? */ memmove ( data, data+n, ptr - data - n ) ; ptr -= n ; } } ; struct intBuffer { int data [ MAX_FRAMELEN * 2 ] ; int len ; } ; static intBuffer inbuf ; static ucharBuffer outbuf ; int *dacioGetBuffer () { return inbuf.data ; } void dacioIncomingBufLen ( int len ) { inbuf.len = len ; } void dacioGlobalVol(int v) { glob_vol = v; } int dacioGetLen () { return outbuf.getLen () ; } void dacioOut ( void ) { outbuf.copyFrom ( inbuf.data, inbuf.len ) ; } void dacioEmpty () { outbuf.empty (); } void dacioSubtract ( int n ) { outbuf.subtract(n) ; } unsigned char *dacioGetOutBuffer () { return outbuf.getBuffer() ; } plib-1.8.5/src/sl/Makefile.in0000644000175000001440000004223410765365023012656 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ subdir = src/sl DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLIBRARIES_INSTALL = $(INSTALL_DATA) LIBRARIES = $(lib_LIBRARIES) AR = ar ARFLAGS = cru libplibsl_a_AR = $(AR) $(ARFLAGS) libplibsl_a_LIBADD = am__libplibsl_a_SOURCES_DIST = slDSP.cxx slSample.cxx slEnvelope.cxx \ slPlayer.cxx slMODPlayer.cxx slSamplePlayer.cxx \ slScheduler.cxx slMODdacio.cxx slMODfile.cxx slMODinst.cxx \ slMODnote.cxx slMODPrivate.h slMODfile.h @BUILD_SL_TRUE@am_libplibsl_a_OBJECTS = slDSP.$(OBJEXT) \ @BUILD_SL_TRUE@ slSample.$(OBJEXT) slEnvelope.$(OBJEXT) \ @BUILD_SL_TRUE@ slPlayer.$(OBJEXT) slMODPlayer.$(OBJEXT) \ @BUILD_SL_TRUE@ slSamplePlayer.$(OBJEXT) slScheduler.$(OBJEXT) \ @BUILD_SL_TRUE@ slMODdacio.$(OBJEXT) slMODfile.$(OBJEXT) \ @BUILD_SL_TRUE@ slMODinst.$(OBJEXT) slMODnote.$(OBJEXT) libplibsl_a_OBJECTS = $(am_libplibsl_a_OBJECTS) libplibsm_a_AR = $(AR) $(ARFLAGS) libplibsm_a_LIBADD = am__libplibsm_a_SOURCES_DIST = slPortability.h smMixer.cxx @BUILD_SL_TRUE@am_libplibsm_a_OBJECTS = smMixer.$(OBJEXT) libplibsm_a_OBJECTS = $(am_libplibsm_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libplibsl_a_SOURCES) $(libplibsm_a_SOURCES) DIST_SOURCES = $(am__libplibsl_a_SOURCES_DIST) \ $(am__libplibsm_a_SOURCES_DIST) am__include_HEADERS_DIST = sl.h slPortability.h sm.h includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @BUILD_SL_TRUE@lib_LIBRARIES = libplibsl.a libplibsm.a @BUILD_SL_TRUE@include_HEADERS = sl.h slPortability.h sm.h @BUILD_SL_TRUE@libplibsl_a_SOURCES = \ @BUILD_SL_TRUE@ slDSP.cxx slSample.cxx slEnvelope.cxx \ @BUILD_SL_TRUE@ slPlayer.cxx slMODPlayer.cxx slSamplePlayer.cxx \ @BUILD_SL_TRUE@ slScheduler.cxx slMODdacio.cxx slMODfile.cxx \ @BUILD_SL_TRUE@ slMODinst.cxx slMODnote.cxx slMODPrivate.h slMODfile.h @BUILD_SL_TRUE@libplibsm_a_SOURCES = slPortability.h smMixer.cxx @BUILD_SL_TRUE@INCLUDES = -I$(top_srcdir)/src/util EXTRA_DIST = sl.dsp all: all-am .SUFFIXES: .SUFFIXES: .cxx .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sl/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/sl/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLIBRARIES: $(lib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @$(POST_INSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ p=$(am__strip_dir) \ echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ else :; fi; \ done uninstall-libLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) libplibsl.a: $(libplibsl_a_OBJECTS) $(libplibsl_a_DEPENDENCIES) -rm -f libplibsl.a $(libplibsl_a_AR) libplibsl.a $(libplibsl_a_OBJECTS) $(libplibsl_a_LIBADD) $(RANLIB) libplibsl.a libplibsm.a: $(libplibsm_a_OBJECTS) $(libplibsm_a_DEPENDENCIES) -rm -f libplibsm.a $(libplibsm_a_AR) libplibsm.a $(libplibsm_a_OBJECTS) $(libplibsm_a_LIBADD) $(RANLIB) libplibsm.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slDSP.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slEnvelope.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slMODPlayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slMODdacio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slMODfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slMODinst.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slMODnote.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slPlayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slSample.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slSamplePlayer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slScheduler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smMixer.Po@am__quote@ .cxx.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ rm -f "$(DESTDIR)$(includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-am clean-am: clean-generic clean-libLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-includeHEADERS install-exec-am: install-libLIBRARIES install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(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-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am \ install-includeHEADERS install-info install-info-am \ install-libLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-includeHEADERS uninstall-info-am \ uninstall-libLIBRARIES # 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: plib-1.8.5/src/sl/slMODPlayer.cxx0000644000175000001440000000451310765364440013470 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slMODPlayer.cxx 1568 2002-09-02 06:05:49Z sjbaker $ */ #include "sl.h" #include "slMODPrivate.h" #include "slMODfile.h" int slMODPlayer::preempt ( int delay ) { return slPlayer::preempt ( delay ) ; } void slMODPlayer::init ( const char *fname ) { mf = new MODfile ( fname, slScheduler::getCurrent()->getRate (), SL_FALSE ) ; } slMODPlayer::~slMODPlayer () { delete mf ; } void slMODPlayer::skip ( int /* nframes */ ) { } void slMODPlayer::low_read ( int nframes, Uchar *dst ) { if ( isWaiting() ) start () ; int need_bytes = nframes ; int all_done = 0 ; while ( need_bytes > 0 && !all_done ) { int new_bytes = dacioGetLen () ; /* Compute some more audio */ while ( new_bytes == 0 && !all_done ) { all_done = ! mf -> update () ; new_bytes = dacioGetLen () ; } /* How much did we get? */ if ( new_bytes > need_bytes ) /* oops! Too much */ { memcpy ( dst, dacioGetOutBuffer (), need_bytes ) ; dacioSubtract ( need_bytes ) ; dst += need_bytes ; need_bytes = 0 ; } else { memcpy ( dst, dacioGetOutBuffer (), new_bytes ) ; dacioEmpty () ; dst += new_bytes ; need_bytes -= new_bytes ; } } /* Pad with silence if not enough data */ if ( need_bytes > 0 ) memset ( dst, 128, need_bytes ) ; if ( all_done ) { if ( replay_mode == SL_SAMPLE_ONE_SHOT ) stop () ; else start () ; } } plib-1.8.5/src/sl/slSample.cxx0000644000175000001440000003076410765364440013124 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slSample.cxx 1853 2004-02-08 18:41:15Z stromberg $ */ #include "sl.h" #include void slSample::autoMatch ( const slDSP *dsp ) { if ( dsp == NULL || dsp->notWorking () ) return ; changeRate ( dsp->getRate () ) ; changeBps ( dsp->getBps () ) ; changeStereo ( dsp->getStereo () ) ; } void slSample::adjustVolume ( float vol ) { for ( int i = 0 ; i < length ; i++ ) { int s = (int)(((float) buffer[i] - (float) 0x80) * vol) + 0x80 ; buffer [ i ] = ( s > 255 ) ? 255 : ( s < 0 ) ? 0 : s ; } } void slSample::changeRate ( int r ) { if ( r == rate ) return ; int length2 = (int) ( (float) length * ( (float) r / (float) rate ) ) ; Uchar *buffer2 = new Uchar [ length2 ] ; int samps = length / (getBps() / 8) ; int samps2 = length2 / (getBps() / 8) ; float step = (float) length / (float) length2 ; for ( int i = 0 ; i < samps2 ; i++ ) { float pos = (float) i * step ; int p1 = (int) floor ( pos ) ; int p2 = (int) ceil ( pos ) ; if ( stereo ) { if ( ( p1 & 1 ) != ( i & 1 ) ) { pos++ ; p1++ ; p2++ ; } p2++ ; } float ratio = pos - (float) p1 ; float b1 = (getBps()==8) ? (float) buffer [(p1<0)?0:(p1>=samps)?samps-1:p1] : (float) ((Ushort*)buffer)[(p1<0)?0:(p1>=samps)?samps-1:p1] ; float b2 = (getBps()==8) ? (float) buffer [(p2<0)?0:(p2>=samps)?samps-1:p2] : (float) ((Ushort*)buffer)[(p2<0)?0:(p2>=samps)?samps-1:p2] ; float res = b1 * (1.0f-ratio) + b2 * ratio ; if ( getBps () == 8 ) buffer2 [ i ] = (Uchar) ( (res < 0) ? 0 : (res > 255) ? 255 : res ) ; else ((Ushort *) buffer2 ) [ i ] = (Ushort) ( (res < 0) ? 0 : (res > 65535) ? 65535 : res ) ; } rate = r ; length = length2 ; delete [] buffer ; buffer = buffer2 ; } void slSample::changeToUnsigned () { if ( getBps() == 16 ) { int length2 = length / 2 ; Ushort *buffer2 = (Ushort *) buffer ; for ( int i = 0 ; i < length2 ; i++ ) buffer2 [ i ] = buffer2 [ i ] + 32768 ; } else { for ( int i = 0 ; i < length ; i++ ) buffer [ i ] = (buffer [ i ]>0x80) ? (buffer[i]-0x80) : (0xFF-buffer[i]) ; } } void slSample::changeBps ( int b ) { if ( b == getBps () ) return ; if ( b == 8 && getBps() == 16 ) { length /= 2 ; Uchar *buffer2 = new Uchar [ length ] ; for ( int i = 0 ; i < length ; i++ ) buffer2 [ i ] = ((Ushort *)buffer) [ i ] >> 8 ; delete [] buffer ; buffer = buffer2 ; setBps ( b ) ; } else if ( b == 16 && getBps() == 8 ) { Ushort *buffer2 = new Ushort [ length ] ; for ( int i = 0 ; i < length ; i++ ) buffer2 [ i ] = buffer [ i ] << 8 ; delete [] buffer ; buffer = (Uchar *) buffer2 ; length *= 2 ; setBps ( b ) ; } } void slSample::changeStereo ( int s ) { if ( s == getStereo () ) return ; if ( s && ! getStereo () ) { if ( getBps () == 8 ) { Uchar *buffer2 = new Uchar [ length * 2 ] ; for ( int i = 0 ; i < length ; i++ ) buffer2 [ i*2 ] = buffer2 [ i*2+1 ] = buffer [ i ] ; delete [] buffer ; buffer = buffer2 ; length *= 2 ; setStereo ( SL_TRUE ) ; } else { Ushort *buffer2 = new Ushort [ length ] ; for ( int i = 0 ; i < length / 2 ; i++ ) buffer2 [ i*2 ] = buffer2 [ i*2+1 ] = ((Ushort *) buffer) [ i ] ; delete [] buffer ; buffer = (Uchar *)buffer2 ; length *= 2 ; setStereo ( SL_TRUE ) ; } } else { if ( getBps () == 8 ) { Uchar *buffer2 = new Uchar [ length / 2 ] ; for ( int i = 0 ; i < (length-1)/2 ; i++ ) buffer2 [ i ] = ((int)buffer [ i*2 ] + (int)buffer [ i*2 + 1 ] ) / 2 ; delete [] buffer ; buffer = buffer2 ; length /= 2 ; setStereo ( SL_FALSE ) ; } else { Ushort *buffer2 = new Ushort [ length / 4 ] ; for ( int i = 0 ; i < (length-3) / 4 ; i++ ) buffer2 [ i ] = ((int)((Ushort *)buffer) [ i*2 ] + (int)((Ushort *)buffer) [ i*2 + 1 ] ) / 2 ; delete [] buffer ; buffer = (Uchar *)buffer2 ; length /= 4 ; setStereo ( SL_FALSE ) ; } } } static void swap_Ushort ( Ushort *i ) { *i = ((*i << 8) & 0xFF00) + ((*i >> 8) & 0x00FF) ; } static void swap_int ( int *i ) { *i = ((*i << 24) & 0xFF000000) + ((*i << 8) & 0x00FF0000) + ((*i >> 8) & 0x0000FF00) + ((*i >> 24) & 0x000000FF) ; } int slSample::loadFile ( const char *fname ) { if ( ulStrEqual ( & fname [ strlen ( fname ) - 4 ], ".wav" ) ) return loadWavFile ( fname ) ; if ( ulStrEqual ( & fname [ strlen ( fname ) - 3 ], ".au" ) ) return loadAUFile ( fname ) ; if ( ulStrEqual ( & fname [ strlen ( fname ) - 3 ], ".ub" ) ) return loadRawFile ( fname ) ; ulSetError ( UL_WARNING, "slSample:loadFile: Unknown file type for '%s'.", fname ) ; return SL_FALSE ; } int slSample::loadWavFile ( const char *fname ) { int found_header = SL_FALSE ; int needs_swabbing = SL_FALSE ; delete [] buffer ; buffer = NULL ; length = 0 ; FILE *fd = fopen ( fname, "rb" ) ; if ( fd == NULL ) { ulSetError ( UL_WARNING, "slSample: loadWavFile: Cannot open '%s' for reading.", fname ) ; return SL_FALSE ; } char magic [ 8 ] ; if ( fread ( magic, 4, 1, fd ) == 0 || magic[0] != 'R' || magic[1] != 'I' || magic[2] != 'F' || magic[3] != 'F' ) { ulSetError ( UL_WARNING, "slWavSample: File '%s' has wrong magic number", fname ) ; ulSetError ( UL_WARNING, " - it probably isn't in '.wav' format." ) ; fclose ( fd ) ; return SL_FALSE ; } int leng1 ; if ( fread ( & leng1, sizeof(int), 1, fd ) == 0 ) { ulSetError ( UL_WARNING, "slSample: File '%s' has premature EOF in header", fname ) ; fclose ( fd ) ; return SL_FALSE ; } fread ( magic, 4, 1, fd ) ; if ( magic[0] != 'W' || magic[1] != 'A' || magic[2] != 'V' || magic[3] != 'E' ) { ulSetError ( UL_WARNING, "slSample: File '%s' has no WAVE tag.", fname ) ; fclose ( fd ) ; return SL_FALSE ; } while ( ! feof ( fd ) ) { fread ( magic, 4, 1, fd ) ; if ( magic[0] == 'f' && magic[1] == 'm' && magic[2] == 't' && magic[3] == ' ' ) { found_header = SL_TRUE ; if ( fread ( & leng1, sizeof(int), 1, fd ) == 0 ) { ulSetError ( UL_WARNING, "slSample: File '%s' has premature EOF in header", fname ) ; fclose ( fd ) ; return SL_FALSE ; } if ( leng1 > 65536 ) { needs_swabbing = SL_TRUE ; swap_int ( & leng1 ) ; } Ushort header [ 8 ] ; if ( leng1 != sizeof ( header ) ) ulSetError ( UL_WARNING, "slSample: File '%s' has unexpectedly long (%d byte) header", fname, leng1 ) ; fread ( & header, sizeof(header), 1, fd ) ; for ( int junk = sizeof(header) ; junk < leng1 ; junk++ ) getc ( fd ) ; if ( needs_swabbing ) { swap_Ushort ( & header[0] ) ; swap_Ushort ( & header[1] ) ; swap_int ( (int *) & header[2] ) ; swap_int ( (int *) & header[4] ) ; swap_Ushort ( & header[6] ) ; swap_Ushort ( & header[7] ) ; } if ( header [ 0 ] != 0x0001 ) { ulSetError ( UL_WARNING, "slSample: File '%s' is not WAVE_FORMAT_PCM!", fname ) ; fclose ( fd ) ; return SL_FALSE ; } setStereo ( header[1] > 1 ) ; setRate ( *((int *) (& header[2])) ) ; setBps ( header[7] ) ; } else if ( magic[0] == 'd' && magic[1] == 'a' && magic[2] == 't' && magic[3] == 'a' ) { if ( ! found_header ) { ulSetError ( UL_WARNING, "slSample: File '%s' has no data section", fname ) ; fclose ( fd ) ; return SL_FALSE ; } if ( fread ( & length, sizeof(int), 1, fd ) == 0 ) { ulSetError ( UL_WARNING, "slSample: File '%s' has premature EOF in data", fname ) ; fclose ( fd ) ; return SL_FALSE ; } if ( needs_swabbing ) swap_int ( & length ) ; buffer = new Uchar [ length ] ; fread ( buffer, 1, length, fd ) ; if ( getBps () == 16 ) { changeToUnsigned () ; } fclose ( fd ) ; return SL_TRUE ; } } ulSetError ( UL_WARNING, "slSample: Premature EOF in '%s'.", fname ) ; fclose ( fd ) ; return SL_FALSE ; } int slSample::loadAUFile ( const char *fname ) { delete [] buffer ; buffer = NULL ; length = 0 ; FILE *fd = fopen ( fname, "rb" ) ; if ( fd == NULL ) { ulSetError ( UL_WARNING, "slSample: loadAUFile: Cannot open '%s' for reading.", fname ) ; return SL_FALSE ; } char magic [ 4 ] ; if ( fread ( magic, 4, 1, fd ) == 0 || magic[0] != '.' || magic[1] != 's' || magic[2] != 'n' || magic[3] != 'd' ) { ulSetError ( UL_WARNING, "slSample: File '%s' has wrong magic number", fname ) ; ulSetError ( UL_WARNING, " - it probably isn't in '.au' format." ) ; fclose ( fd ) ; return SL_FALSE ; } int hdr_length ; int dat_length ; int nbytes ; int irate ; int nchans ; if ( fread ( & hdr_length, sizeof(int), 1, fd ) == 0 || fread ( & dat_length, sizeof(int), 1, fd ) == 0 || fread ( & nbytes , sizeof(int), 1, fd ) == 0 || fread ( & irate , sizeof(int), 1, fd ) == 0 || fread ( & nchans , sizeof(int), 1, fd ) == 0 ) { ulSetError ( UL_WARNING, "slSample: File '%s' has premature EOF in header", fname ) ; fclose ( fd ) ; return SL_FALSE ; } if ( hdr_length > 65536 ) { swap_int ( & hdr_length ) ; swap_int ( & dat_length ) ; swap_int ( & nbytes ) ; swap_int ( & irate ) ; swap_int ( & nchans ) ; } bps = nbytes * 8 ; stereo = (nchans>1) ; rate = irate ; if ( nbytes > 2 || nbytes <= 0 || hdr_length > 512 || hdr_length < 24 || irate > 65526 || irate <= 1000 || nchans < 1 || nchans > 2 ) { ulSetError ( UL_WARNING, "slSample: File '%s' has a very strange header", fname ) ; ulSetError ( UL_WARNING, " Header Length = %d", hdr_length ) ; ulSetError ( UL_WARNING, " Data Length = %d", dat_length ) ; ulSetError ( UL_WARNING, " Bytes/sample = %d", nbytes ) ; ulSetError ( UL_WARNING, " Sampling Rate = %dHz",irate ) ; ulSetError ( UL_WARNING, " Num Channels = %d", nchans ) ; fclose ( fd ) ; return SL_FALSE ; } if ( hdr_length > 24 ) { delete [] comment ; comment = new char [ hdr_length - 24 + 1 ] ; fread ( comment, 1, hdr_length - 24, fd ) ; } if ( dat_length > 0 ) { buffer = new Uchar [ dat_length ] ; length = fread ( buffer, 1, dat_length, fd ) ; if ( length != dat_length ) ulSetError ( UL_WARNING, "slAUSample: File '%s' has premature EOF in data.", fname ) ; changeToUnsigned () ; } fclose ( fd ) ; return SL_TRUE ; } int slSample::loadRawFile ( const char *fname ) { delete [] buffer ; buffer = NULL ; length = 0 ; FILE *fd = fopen ( fname, "rb" ) ; if ( fd == NULL ) { ulSetError ( UL_WARNING, "slSample: loadRawFile: Cannot open '%s' for reading.", fname ) ; return SL_FALSE ; } struct stat stat_buf ; if ( fstat ( fileno ( fd ), & stat_buf ) != 0 ) { ulSetError ( UL_WARNING, "slSample: loadRawFile: Cannot get status for '%s'.", fname ) ; fclose ( fd ) ; return SL_FALSE ; } length = stat_buf . st_size ; if ( length > 0 ) { buffer = new Uchar [ length ] ; length = fread ( buffer, 1, length, fd ) ; } bps = 8 ; stereo = SL_FALSE ; rate = 8000 ; /* Guess */ fclose ( fd ) ; return SL_TRUE ; } plib-1.8.5/src/sl/slScheduler.cxx0000644000175000001440000003655710765364440013627 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slScheduler.cxx 1764 2003-05-18 13:45:04Z puggles $ */ #include "sl.h" const char *__slPendingError = NULL ; slScheduler *slScheduler::current = NULL ; void slScheduler::init () { int mi; mixer = NULL ; mixer_buffer = NULL ; /* Note there is a required null element on the end of array */ for ( mi=0; mi <= SL_MAX_MIXERINPUTS; mi++ ) mixer_inputs[mi] = NULL ; current = this ; mixer_gain = 0x100 ; /* When we have to make sound quieter */ if ( notWorking () ) { ulSetError ( UL_WARNING, "slScheduler: soundcard init failed." ) ; setError () ; return ; } if ( getBps() != 8 ) { ulSetError ( UL_WARNING, "slScheduler: Needs a sound card that supports 8 bits per sample." ) ; setError () ; return ; } if ( getStereo() ) { ulSetError ( UL_WARNING, "slScheduler: Needs a sound card that supports monophonic replay." ) ; setError () ; return ; } music = NULL ; for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) player [ i ] = NULL ; amount_left = 0 ; now = 0 ; num_pending_callbacks = 0 ; safety_margin = 1.0 ; initBuffers () ; } void slScheduler::initBuffers () { if ( notWorking () ) return ; delete [] mixer_buffer ; setMaxConcurrent ( 0 ); mixer_buffer_size = getDriverBufferSize () ; int div = 1; if ( getStereo() ) div *= 2 ; if ( getBps() == 16 ) div *= 2 ; seconds_per_buffer = (float)mixer_buffer_size / ( div * getRate() ) ; mixer_buffer = new Uchar [ mixer_buffer_size ] ; memset ( mixer_buffer, 0x80, mixer_buffer_size ) ; setMaxConcurrent ( 3 ); } void slScheduler::setMaxConcurrent ( int mc ) { int mi; for ( mi = 0; mi < SL_MAX_MIXERINPUTS; mi ++ ) if ( mi < mc ) { if ( mixer_inputs[mi] == NULL ) mixer_inputs[mi] = new Uchar [ mixer_buffer_size ] ; } else { if ( mixer_inputs[mi] != NULL ) delete [] mixer_inputs[mi] ; mixer_inputs[mi] = NULL; } } int slScheduler::getMaxConcurrent ( void ) const { int mi, mc = 0; for ( mi = 0; mi < SL_MAX_MIXERINPUTS; mi ++ ) if ( NULL != mixer_inputs[mi] ) mc ++; return mc; } slScheduler::~slScheduler () { delete [] mixer_buffer ; setMaxConcurrent(0); if ( current == this ) current = NULL ; } void slScheduler::realUpdate ( int dump_first ) { if ( notWorking () ) return ; if ( __slPendingError != NULL ) { ulSetError ( UL_FATAL, "%s", __slPendingError ) ; } int i ; while ( ( secondsUsed() <= safety_margin ) && ( secondsRemaining() >= seconds_per_buffer ) ) { slPlayer *psp [ SL_MAX_MIXERINPUTS ] ; int pri [ SL_MAX_MIXERINPUTS ] ; int inputsused = 0 ; int lowest = 0 ; /* makes it safe to reference before assignment below */ /* Decide who we're going to use */ for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ ) { /* Ignore non-existent channels */ if ( player [ i ] == NULL ) continue ; /* Clean up dead sample players */ if ( player [ i ] -> isDone () ) { if ( player [ i ] == music ) music = NULL ; delete player [ i ] ; player [ i ] = NULL ; continue ; } /* Skip paused players, but leave them alone */ if ( player [ i ] -> isPaused () ) continue ; /* This one is viable, make sure we have room */ int mypri = player[i]->getPriority() ; if ( ( inputsused > 0 ) && ( mixer_inputs[inputsused] == NULL ) && ( mypri > pri[lowest] ) ) { /* Not enough room; get rid of someone */ if ( player[lowest] != NULL ) player[lowest] -> preempt ( mixer_buffer_size ) ; psp[lowest] = player[i] ; pri[lowest] = mypri ; int j; for ( j = 0; j < inputsused; j++ ) if ( pri[lowest] < pri[j] ) lowest = j; } else if ( mixer_inputs[inputsused] != NULL ) { /* Ok, we've got room, presumably, for another item */ psp[inputsused] = player[i]; pri[inputsused] = mypri; if ( ( ( inputsused ++ ) == 0 ) || ( pri[lowest] > mypri ) ) lowest = inputsused; } else { /* Oops, something very wrong. Shouldn't get here in normal use. One obvious reason is if user specified zero channels to mix! */ player[i] -> preempt ( mixer_buffer_size ) ; } } /* We've now chosen our sources. Previously we'd go back through and figure out who to report as pre-empted. But we already did that as part of getting our list of sources, so that disappeared. */ /* Now, we actually get the sound samples into the mixer_buffer. All the versions here are fastpaths except the two last ones. Just read the comments on the last one to understand it. */ /* We put a minus sign on the number of inputs if we're attenuating */ switch ( mixer_gain != 0x100 ? -inputsused : inputsused ) { case 0: /* No sound whatsoever, the attenuation is irrelevant */ memset ( mixer_buffer, 0x80, mixer_buffer_size ) ; amount_left = 0 ; if ( mixer_gain < 0x100 ) mixer_gain ++; break ; case 1: /* One sample, so overflow is impossible. No legacy attenuation */ psp[0] -> read ( mixer_buffer_size, mixer_buffer ) ; break ; case 2: { register int l = mixer_buffer_size ; register Uchar *d = mixer_buffer, *a, *b ; register int t, x = l / 100 ; psp[0] -> read ( l, a = mixer_inputs [ 0 ] ) ; psp[1] -> read ( l, b = mixer_inputs [ 1 ] ) ; while ( l-- ) { t = (*a++) - 0x80 + (*b++) ; *d++ = ( t >= 0x100 ? x--, 0xff : ( t <= 0x000 ? x--, 0x00 : t ) ); } if ( x < 0 ) mixer_gain -- ; } break; case 3: { register int l = mixer_buffer_size ; register Uchar *d = mixer_buffer, *a, *b, *c ; register int t, x = l / 100 ; psp[0] -> read ( l, a = mixer_inputs [ 0 ] ) ; psp[1] -> read ( l, b = mixer_inputs [ 1 ] ) ; psp[2] -> read ( l, c = mixer_inputs [ 2 ] ) ; while ( l-- ) *d++ = ( t = (*a++) - 0x100 + (*b++) + (*c++) ), t >= 0x100 ? x--, 0xff : t <= 0x000 ? x--, 0x00 : t; if ( x < 0 ) mixer_gain -- ; } break; default: { /* How much data to get, and where to put it */ int l = mixer_buffer_size ; register Uchar *d = mixer_buffer ; /* We compute one value in here, in the loop below */ register int t ; /* We need to determine the maximum range of values */ int tmax = 0x80, tmin = 0x80; /* A pointer to the element about to be added to "t" */ register Uchar **p ; /* Sound cards use offset binary, so do zero adjustment */ int z = ( (int) 0x8000 / mixer_gain ) - ( inputsused * 0x80 ) ; /* An array of pointers to keep in step with "d" above */ register Uchar * s [ SL_MAX_MIXERINPUTS + 1 ] ; /* First thing is to read individual channels into buffers */ for ( i = 0; i < inputsused; i++ ) psp[i] -> read ( l, s [ i ] = mixer_inputs [ i ] ); /* Put a null on the end of "s" so we don't have to count */ s [ inputsused ] = NULL; /* This while loop is executed for each audio sample */ while ( l-- ) { /* Accumulation to zero, and point to first buffer item */ t = z; p = s; /* Iterate through all buffers to do accumulation */ while ( /* Add this buffer element, advance within buffer */ t += *((*p)++), /* Also advance to the next channel buffer */ *(++p) /* Make the while loop quit when we find NULL */ ) { }; /* Apply gain correction if needed */ if ( mixer_gain != 0x100 ) t = ( t * mixer_gain ) / 0x100 ; /* Store accumulation, but force onscale */ *(d++) = t >= 0x100 ? 0xff : t <= 0x000 ? 0x00 : t ; /* Figure out the maximum signal range */ if ( tmax < t ) tmax = t ; else if ( tmin > t ) tmin = t ; } /* Consider changing the attenuation */ if ( ( ( tmin < 0x00 ) || ( tmax > 0xFF ) ) && ( mixer_gain > 1 ) ) mixer_gain -- ; else if ( ( tmin * ( mixer_gain + 1 ) > 0x80 + 0x10 * mixer_gain ) && ( tmax * ( mixer_gain + 1 ) < 0x80 + 0xE0 * mixer_gain ) && ( mixer_gain < 0x100 ) ) mixer_gain ++ ; // printf ( "Gain=%03x, Range=%04x,%04x\n", mixer_gain, tmin, tmax ); } break; } /* We've created the next buffer of sound data ... now what ? */ if ( dump_first ) { stop () ; dump_first = SL_FALSE ; } play ( mixer_buffer, mixer_buffer_size ) ; now += mixer_buffer_size ; } flushCallBacks () ; } void slScheduler::addCallBack ( slCallBack c, slSample *s, slEvent e, int m ) { if ( notWorking () ) return ; if ( num_pending_callbacks >= SL_MAX_CALLBACKS ) { ulSetError ( UL_WARNING, "slScheduler: Too many pending callback events!" ) ; return ; } slPendingCallBack *p = & ( pending_callback [ num_pending_callbacks++ ] ) ; p -> callback = c ; p -> sample = s ; p -> event = e ; p -> magic = m ; } void slScheduler::flushCallBacks () { if ( notWorking () ) return ; /* Execute all the callbacks that we accumulated in this iteration. This is done at the end of 'update' to reduce the risk of nasty side-effects caused by 'unusual' activities in the application's callback function. */ while ( num_pending_callbacks > 0 ) { slPendingCallBack *p = & ( pending_callback [ --num_pending_callbacks ] ) ; if ( p -> callback ) (*(p->callback))( p->sample, p->event, p->magic ) ; } } void slScheduler::addSampleEnvelope ( slSample *s, int magic, int slot, slEnvelope *e, slEnvelopeType t) { if ( notWorking () ) return ; for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] != NULL && player[i] != music && ( s == NULL || player [ i ] -> getSample () == s ) && ( magic == 0 || player [ i ] -> getMagic () == magic ) ) player [ i ] -> addEnvelope ( slot, e, t ) ; } void slScheduler::resumeSample ( slSample *s, int magic) { if ( notWorking () ) return ; for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] != NULL && player[i] != music && ( s == NULL || player [ i ] -> getSample () == s ) && ( magic == 0 || player [ i ] -> getMagic () == magic ) ) player [ i ] -> resume () ; } void slScheduler::pauseSample ( slSample *s, int magic) { if ( notWorking () ) return ; for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] != NULL && player[i] != music && ( s == NULL || player [ i ] -> getSample () == s ) && ( magic == 0 || player [ i ] -> getMagic () == magic ) ) player [ i ] -> pause () ; } void slScheduler::stopSample ( slSample *s, int magic ) { if ( notWorking () ) return ; for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] != NULL && player[i] != music && ( s == NULL || player [ i ] -> getSample () == s ) && ( magic == 0 || player [ i ] -> getMagic () == magic ) ) player [ i ] -> stop () ; } int slScheduler::loopSample ( slSample *s, int pri, slPreemptMode mode, int magic, slCallBack cb ) { if ( notWorking () ) return -1 ; for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] == NULL ) { player [ i ] = new slSamplePlayer ( s, SL_SAMPLE_LOOP, pri, mode, magic, cb ) ; return i ; } return -1 ; } int slScheduler::playSample ( slSample *s, int pri, slPreemptMode mode, int magic, slCallBack cb) { if ( notWorking () ) return SL_FALSE ; for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] == NULL ) { player [ i ] = new slSamplePlayer ( s, SL_SAMPLE_ONE_SHOT, pri, mode, magic, cb ) ; return SL_TRUE ; } return SL_FALSE ; } void slScheduler::addMusicEnvelope ( int magic, int slot, slEnvelope *e, slEnvelopeType t) { if ( notWorking () ) return ; if ( music != NULL && ( magic == 0 || music -> getMagic () == magic ) ) music -> addEnvelope ( slot, e, t ) ; } void slScheduler::resumeMusic ( int magic) { if ( notWorking () ) return ; if ( music != NULL && ( magic == 0 || music -> getMagic () == magic ) ) music -> resume () ; } void slScheduler::pauseMusic ( int magic) { if ( notWorking () ) return ; if ( music != NULL && ( magic == 0 || music -> getMagic () == magic ) ) music -> pause () ; } void slScheduler::stopMusic ( int magic ) { if ( notWorking () ) return ; if ( music != NULL && ( magic == 0 || music -> getMagic () == magic ) ) { music -> stop () ; for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] == music ) player [ i ] = NULL ; delete music ; music = NULL ; } } int slScheduler::loopMusic ( const char *fname, int pri, slPreemptMode mode, int magic, slCallBack cb ) { if ( notWorking () ) return -1 ; if ( music != NULL ) { ulSetError ( UL_WARNING, "slScheduler: Can't play two music tracks at once." ) ; return -1 ; } for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] == NULL ) { music = new slMODPlayer ( fname, SL_SAMPLE_LOOP, pri, mode, magic, cb ) ; player [ i ] = music ; return i ; } return -1 ; } int slScheduler::playMusic ( const char *fname, int pri, slPreemptMode mode, int magic, slCallBack cb ) { if ( notWorking () ) return SL_FALSE ; if ( music != NULL ) { ulSetError ( UL_WARNING, "slScheduler: Can't play two music tracks at once." ) ; return SL_FALSE ; } for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ ) if ( player [ i ] == NULL ) { music = new slMODPlayer ( fname, SL_SAMPLE_ONE_SHOT, pri, mode, magic, cb ) ; player [ i ] = music ; return SL_TRUE ; } return SL_FALSE ; } plib-1.8.5/src/sl/slPortability.h0000644000175000001440000000450510765364440013624 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slPortability.h 2013 2005-01-16 06:03:31Z sjbaker $ */ #ifndef __SLPORTABILITY_H__ #define __SLPORTABILITY_H__ 1 /* ------------------------------------------------------------- */ /* OS specific includes and defines ... */ /* ------------------------------------------------------------- */ #include "ul.h" #include #include #ifdef UL_MACINTOSH #include #include #ifdef __MWERKS__ #include #endif #endif #ifdef UL_MAC_OSX #include #endif #include #include #include #include #include #if (defined(UL_LINUX) || defined(UL_BSD)) && !defined(__NetBSD__) #define SL_USING_OSS_AUDIO 1 #endif #ifdef SL_USING_OSS_AUDIO # if defined(UL_LINUX) # include # include # elif defined(__FreeBSD__) # include # else /* Tom thinks this file may be under some unixen - but that isn't where the OSS manuals say it should be. If you ever find out the truth, please email me: Steve Baker */ # include # endif #endif #ifdef UL_BSD #ifndef __FreeBSD__ # include #endif #endif /* Tom */ #ifdef UL_IRIX # include #endif #ifdef UL_SOLARIS # include # include #endif #endif plib-1.8.5/src/sl/slPlayer.cxx0000644000175000001440000000717410765364440013136 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slPlayer.cxx 1924 2004-04-06 13:32:26Z sjbaker $ */ #include "sl.h" void slPlayer::addEnvelope ( int i, slEnvelope *_env, slEnvelopeType _type ) { if ( i < 0 || i >= SL_MAX_ENVELOPES ) return ; if ( env [ i ] != NULL ) env [ i ] -> unRef () ; env [ i ] = _env ; if ( _env != NULL ) env [ i ] -> ref () ; env_type [ i ] = _type ; env_start_time [ i ] = slScheduler::getCurrent() -> getTimeNow () ; } int slPlayer::preempt ( int delay ) { switch ( preempt_mode ) { case SL_SAMPLE_CONTINUE: if ( isRunning() ) return SL_FALSE ; /* FALLTHROUGH! */ case SL_SAMPLE_DELAY : break ; case SL_SAMPLE_MUTE : skip ( delay ) ; break ; case SL_SAMPLE_ABORT : stop () ; break ; case SL_SAMPLE_RESTART : reset () ; break ; default : break ; } return SL_TRUE ; } slPlayer::~slPlayer () { } void slPlayer::read ( int nframes, Uchar *dst, int next_env ) { /* WARNING: CO-RECURSIVE! */ /* Find the next envelope */ while ( next_env < SL_MAX_ENVELOPES && env [ next_env ] == NULL ) next_env++ ; /* If there are no fancy envelopes to process then return the raw data. */ if ( next_env >= SL_MAX_ENVELOPES ) /* No fancy envelopes left */ { low_read ( nframes, dst ) ; return ; } /* Envelope processing required... Process the next envelope using data read recursively through the remaining envelopes. */ switch ( env_type [ next_env ] ) { /* For Volume envelopes, SRC and DST can be the same buffer */ case SL_INVERSE_VOLUME_ENVELOPE: read ( nframes, dst, next_env+1 ) ; env[ next_env ]->applyToInvVolume ( dst,dst,nframes,env_start_time[ next_env ] ) ; break ; case SL_VOLUME_ENVELOPE : read ( nframes, dst, next_env+1 ) ; env[ next_env ]->applyToVolume ( dst,dst,nframes,env_start_time[ next_env ] ) ; break ; case SL_INVERSE_PITCH_ENVELOPE : env[ next_env ]->applyToInvPitch ( dst,this,nframes,env_start_time[ next_env ], next_env+1 ) ; break ; case SL_PITCH_ENVELOPE : env[ next_env ]->applyToPitch ( dst,this,nframes,env_start_time[ next_env ], next_env+1 ) ; break ; case SL_INVERSE_FILTER_ENVELOPE: case SL_FILTER_ENVELOPE : read ( nframes, dst, next_env+1 ) ; env [ next_env ] -> applyToLPFilter ( dst, dst, nframes, env_start_time [ next_env ] ) ; break ; case SL_INVERSE_PAN_ENVELOPE : case SL_PAN_ENVELOPE : read ( nframes, dst, next_env+1 ) ; break ; case SL_INVERSE_ECHO_ENVELOPE : case SL_ECHO_ENVELOPE : read ( nframes, dst, next_env+1 ) ; break ; default : break ; } } plib-1.8.5/src/sl/slMODfile.h0000644000175000001440000000417710765364440012606 00000000000000/* PLIB - A Suite of Portable Game Libraries Copyright (C) 1998,2002 Steve Baker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information visit http://plib.sourceforge.net $Id: slMODfile.h 1568 2002-09-02 06:05:49Z sjbaker $ */ typedef unsigned char ModSample [ 30 ] ; typedef unsigned char ModNote [ 4 ] ; struct SampleInfo ; struct Note ; class MODfile { unsigned char *buffer ; unsigned char *p0 ; unsigned char *songName ; int ordNum ; int insNum ; int patNum ; int chNum ; int rstOrd ; unsigned char *ord ; ModSample *smpInfop ; unsigned char *smp0p ; ModNote *pat ; short *note ; unsigned char *fileEnd ; unsigned char *repCounter; SampleInfo *sip ; int firsttime ; int broken ; int play_nextOrd ; int play_loopBeg ; int play_loopCnt ; int play_row0 ; int play_row ; int play_ord0 ; int play_ord ; void makeNoteTable ( void ) ; void tellChSettings ( void ) ; int roundToNote ( int p ) ; void modToS3m ( ModNote *mp, Note *np ) ; void makeSampleInfo ( int smp15 ) ; void parseMod ( unsigned char *pp0, int smp15 ) ; void play_one ( int ppat ) ; unsigned char *read_whole_file ( const char *fname, int *len ) ; public: MODfile ( const char *fname, int speed = 44100, int stereo = 0 ) ; ~MODfile () ; int update () ; } ; plib-1.8.5/Makefile.in0000644000175000001440000004537210765365024011460 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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 = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ ChangeLog INSTALL NEWS config.guess config.sub depcomp \ install-sh missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_FNT_FALSE = @BUILD_FNT_FALSE@ BUILD_FNT_TRUE = @BUILD_FNT_TRUE@ BUILD_JS_FALSE = @BUILD_JS_FALSE@ BUILD_JS_TRUE = @BUILD_JS_TRUE@ BUILD_NET_FALSE = @BUILD_NET_FALSE@ BUILD_NET_TRUE = @BUILD_NET_TRUE@ BUILD_PSL_FALSE = @BUILD_PSL_FALSE@ BUILD_PSL_TRUE = @BUILD_PSL_TRUE@ BUILD_PUAUX_FALSE = @BUILD_PUAUX_FALSE@ BUILD_PUAUX_TRUE = @BUILD_PUAUX_TRUE@ BUILD_PUI_FALSE = @BUILD_PUI_FALSE@ BUILD_PUI_TRUE = @BUILD_PUI_TRUE@ BUILD_PW_FALSE = @BUILD_PW_FALSE@ BUILD_PW_TRUE = @BUILD_PW_TRUE@ BUILD_SG_FALSE = @BUILD_SG_FALSE@ BUILD_SG_TRUE = @BUILD_SG_TRUE@ BUILD_SL_FALSE = @BUILD_SL_FALSE@ BUILD_SL_TRUE = @BUILD_SL_TRUE@ BUILD_SSGAUX_FALSE = @BUILD_SSGAUX_FALSE@ BUILD_SSGAUX_TRUE = @BUILD_SSGAUX_TRUE@ BUILD_SSG_FALSE = @BUILD_SSG_FALSE@ BUILD_SSG_TRUE = @BUILD_SSG_TRUE@ BUILD_UL_FALSE = @BUILD_UL_FALSE@ BUILD_UL_TRUE = @BUILD_UL_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ 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@ 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@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ SUBDIRS = src EXTRA_DIST = KNOWN_BUGS NOTICE README README.GLUT \ README.win32 README.mac TODO-1.6 TODO-2.0 \ TODO_AFTER135 autogen.sh missing \ plib.dsp plib.dsw transferCvs2WebSite all: all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ cd $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu 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; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) uninstall-info-am: # 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -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 $(SHELL) $(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__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__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) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(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 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { 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 installdirs: installdirs-recursive installdirs-am: 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: 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-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ check-am clean clean-generic clean-recursive ctags \ ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \ dist-tarZ dist-zip distcheck distclean distclean-generic \ distclean-recursive distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-info-am # 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: plib-1.8.5/plib.dsw0000644000175000001440000000737310765364452011063 00000000000000Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "fnt"=".\src\fnt\fnt.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "js"=".\src\js\js.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "net"=".\src\net\net.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "plib"=".\plib.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name fnt End Project Dependency Begin Project Dependency Project_Dep_Name js End Project Dependency Begin Project Dependency Project_Dep_Name sg End Project Dependency Begin Project Dependency Project_Dep_Name sl End Project Dependency Begin Project Dependency Project_Dep_Name ssg End Project Dependency Begin Project Dependency Project_Dep_Name psl End Project Dependency Begin Project Dependency Project_Dep_Name pui End Project Dependency Begin Project Dependency Project_Dep_Name ul End Project Dependency Begin Project Dependency Project_Dep_Name ssgAux End Project Dependency Begin Project Dependency Project_Dep_Name net End Project Dependency Begin Project Dependency Project_Dep_Name pw End Project Dependency Begin Project Dependency Project_Dep_Name puAux End Project Dependency }}} ############################################################################### Project: "psl"=".\src\psl\psl.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "puAux"=".\src\puAux\puAux.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "pui"=".\src\pui\pui.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "pw"=".\src\pw\pw.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "sg"=".\src\sg\sg.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "sl"=".\src\sl\sl.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "ssg"=".\src\ssg\ssg.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "ssgAux"=".\src\ssgAux\ssgAux.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "ul"=".\src\util\ul.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### plib-1.8.5/TODO-2.00000644000175000001440000000164010765364452010372 00000000000000[ Put in tasks here that probably won't get done before PLIB 2.0 or change the API in a way that could break existing applications ] PUI section * Remove deprecated puFilePicker widget * Remove deprecated old label and legend places * Remove deprecated PUSTYLE_RADIO * Remove deprecated 'int puValue::getValue ( void )' function (Application developers: Use 'puValue::getIntegerValue' instead) * Remove deprecated 'int puObject::getDefaultValue ( void )' function (Application developers: Use 'puValue::getDefaultIntegerValue' instead) * Line up widget constructors (explicit size vs. max coordinates issue) * Change function parameters taking a 0/1 FALSE/TRUE value from 'int' to 'bool' * In puDeactivateWidget (), invoke the active widget's down callback (Can't be realized prior to 2.0 since it could break existing programs relying on the old behaviour) * Implement puiAUX for complex widgets [ unclear ] plib-1.8.5/transferCvs2WebSite0000644000175000001440000000507010765364452013176 00000000000000# transferCvs2WebSite for plib # # you must already be logged in !! # That means, you must do the following ONCE (once is enough for a lifetime :-)): # cvs -d:pserver:anonymous@cvs1:/cvsroot/plib login # # export doesnt create the "cvs"-directories. Update would. Therefore I use export echo running cd cd /home/groups/p/pl/plib/htdocs echo handling "sg" rm -R sg cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d sg plib/doc/sg >/dev/null 2>&1 echo handling "ssg" rm -R ssg cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d ssg plib/doc/ssg >/dev/null 2>&1 echo handling "sl" rm -R sl cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d sl plib/doc/sl >/dev/null 2>&1 echo handling "js" rm -R js cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d js plib/doc/js >/dev/null 2>&1 echo handling "fnt" rm -R fnt cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d fnt plib/doc/fnt >/dev/null 2>&1 echo handling "pw" rm -R pw cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d pw plib/doc/pw >/dev/null 2>&1 echo handling "psl" rm -R psl cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d psl plib/doc/psl >/dev/null 2>&1 echo handling "puAux" rm -R puAux cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d puAux plib/doc/puAux >/dev/null 2>&1 echo handling "ssgAux" rm -R ssgAux cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d ssgAux plib/doc/ssgAux >/dev/null 2>&1 echo handling "util" rm -R util cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d util plib/doc/util >/dev/null 2>&1 echo handling "pui" rm -R pui cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d pui plib/doc/pui >/dev/null 2>&1 echo handling "net" rm -R net cvs -d:pserver:anonymous@cvs1:/cvsroot/plib export -Dtoday -d net plib/doc/net >/dev/null 2>&1 chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/sg chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/ssg chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/sl chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/js chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/fnt chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/puAux chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/ssgAux chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/util chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/pui chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/psl chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/pw chmod -R u=rwX,g=rwX,o=rX /home/groups/p/pl/plib/htdocs/net echo done. plib-1.8.5/install-sh0000755000175000001440000002202110532024455011371 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2005-05-14.22 # 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. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= dstarg= 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: -c (ignored) -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. --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -c) shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit $?;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t) dstarg=$2 shift shift continue;; -T) no_target_directory=true shift continue;; --version) echo "$0 $scriptversion"; exit $?;; *) # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. test -n "$dir_arg$dstarg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; 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 for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then mkdircmd=: chmodcmd= else mkdircmd=$mkdirprog fi 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 "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # 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: $dstarg: Is a directory" >&2 exit 1 fi dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` shift IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" # mkdir can fail with a `File exist' error in case several # install-sh are creating the directory concurrently. This # is OK. test -d "$pathcomp" || exit fi pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $mkdircmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else dstfile=`basename "$dst"` # 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 trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. $doit $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 "$dsttmp"; } && # Now rename the file to the real destination. { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 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. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit 1 } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" } } fi || { (exit 1); exit 1; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit 0 } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: plib-1.8.5/depcomp0000755000175000001440000003710010532024455010746 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2005-07-09.11 # Copyright (C) 1999, 2000, 2003, 2004, 2005 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, 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. # 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 outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac 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" # 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 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. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## 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). ## - 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 -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## 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. tr ' ' ' ' < "$tmpdepfile" | ## 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. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -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 -eq 0; then : else 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 ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; 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. stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test -f "$tmpdepfile"; then : else stripped=`echo "$stripped" | sed 's,^.*/,,'` tmpdepfile="$stripped.u" fi if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else 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" ;; 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. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mecanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in 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.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #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 $1 != '--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:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. 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 $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac 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. -*|$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" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. 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 $1 != '--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, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; 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-end: "$" # End: plib-1.8.5/TODO-1.60000644000175000001440000000320210765364452010373 00000000000000NEW FEATURES: Structure section * SSG needs RTTI to replace the rapidly vanishing SSG_TYPE bits resource. * I'd like to see the FGFS sky model moved into ssgAux so everyone can use it. We got part of the way towards that - but it was never finished. * I'd like to have a ROAM engine built into ssgAux for terrain rendering. (maybe not *literally* ROAM - but something very like it). SSG section * Support for bump maps, cubic environment maps, etc, etc on hardware that supports it. * Support for multi-texture. * Import some kind of Skin & Bones animation into ssgAux (using the ExPoser code - or something even better). Loader section * MORE file readers and writer. For example, a reader/loader for WWII Fighters would be nice. * No file writers for about 2/3rds of the file formats we support. * I want the PPE material editor's file format built into SSG so we can load and save material lists. * Model formats * VRML * XML version of ssg * WWII (I think thats the name) SG section * function to get the angle between two vectors * plot points on a vector (walking in a straight line) * Expand SG with more intersection and distance-measuring tricks. PUI section * PUI should also be implemented with RTTI as well. * Movable widgets * PUI is still somewhat tied to GLUT...that should go. It'll need a way to get the window dimensions - and at least one built-in font before we can do that. SL section * Re-implement SL on top of OpenAL. * Write players for more modern MOD-like music formats. Examples section * More example programs - more complete demo games and tools. * More documentation for all the new features. plib-1.8.5/README.win320000644000175000001440000000301510765364452011224 00000000000000 PLIB for Windoze. ~~~~~~~~~~~~~~~~~ Let me first say that I (Steve Baker) don't own a copy of Windoze - so I have little or no ability to help Windoze owners with PLIB problems. It's especially important therefore that you direct problems and queries to the PLIB mailing lists. Subscription information is on the PLIB homepage: http://plib.sourceforge.net CygWin: ~~~~~~~ The simplest way to build PLIB for Windoze is to use the CygWin compiler and toolset. Since that environment is pretty close to UNIX/Linux, the ./configure make make install ...mechanism works perfectly. MingW32: ~~~~~~~~ A couple of people have asked about doing a MingW32 port - but as far as I can tell, the "configure/make/make install" approach *should* work. Microsoft Visual C++: ~~~~~~~~~~~~~~~~~~~~~ All you need to do is open the workspace "plib.dsw" in MSVC++, select the "plib" project (using Set Active Project in the Project menu), and build it (using "Rebuild All" in the Build menu). In the examples folder, open the workspace "plib_examples.dsw". Each example has a seperate project in the workspace. Select the one you want and build it. Then you should be able to hit the Go icon on the toolbar and try it out. For your own application, please note that the plib workspace leaves all the necessary includes (*.h) and libraries (*.lib) in the plib root directory (same as workspace). The debug libraries are given a '_d' suffix. Where ever you put those files, make sure #include works so your code is more portable.