mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3671ac2c64 |
No files matched your search
@@ -1,29 +0,0 @@
|
||||
Original source (Freespace 2) by Volition, Inc.; see "credits.tbl"
|
||||
|
||||
Modifications by the FreeSpace Source Code Project (FSSCP)
|
||||
http://fs2source.warpcore.org
|
||||
|
||||
FS2_OPEN STAFF:
|
||||
|
||||
Project leader:
|
||||
Edward "Inquisitor" Gardner
|
||||
|
||||
Programmers:
|
||||
"Bobboau"
|
||||
Dennis "DTP" Pedersen
|
||||
Ian "Goober5000" Warfield
|
||||
Joe "Righteous1" Dowd
|
||||
Mike "penguin" Harris
|
||||
"Mysterial"
|
||||
"PhReAk"
|
||||
Thomas "Random Tiger" Whittaker
|
||||
Will "Unknown PLayer" Rousnel
|
||||
"WMCoolmon"
|
||||
|
||||
Web support:
|
||||
Icefire and the staff at Volitionwatch.com
|
||||
Alex "Thunder" Avery and the staff at Hard Light Productions
|
||||
|
||||
Special thanks to:
|
||||
Volition for making FS2 such a great game
|
||||
Dave Baranec for giving us the code and keeping us sanity checked
|
||||
@@ -1,14 +0,0 @@
|
||||
Volition Copyright (applies to original FreeSpace2 source code
|
||||
developed and released by Volition):
|
||||
|
||||
"Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
|
||||
All source code herein is the property of Volition, Inc. You may not
|
||||
sell or otherwise commercially exploit the source or things you
|
||||
created based on the source."
|
||||
|
||||
|
||||
Modifications by members of the FreeSpace Source Code Project are
|
||||
released under whatever terms the individual authors choose, but the
|
||||
above notice continues to apply to all fs2_open code.
|
||||
|
||||
Binary file not shown.
@@ -1,29 +0,0 @@
|
||||
This is still in pretty rough form.
|
||||
|
||||
|
||||
=== for people building fs2_open:
|
||||
|
||||
Win32-MSVC:
|
||||
Use the Freespace2.dsw workspace and build within the IDE.
|
||||
|
||||
|
||||
Win32-MinGW:
|
||||
make
|
||||
|
||||
|
||||
Linux and other unix variants (NOT YET COMPLETE)
|
||||
./configure [options]
|
||||
make
|
||||
|
||||
|
||||
|
||||
=== for the project maintainers (people who need to
|
||||
=== keep the makefiles up to date) and those building
|
||||
=== from CVS:
|
||||
|
||||
./autogen.sh (should only has to be done once)
|
||||
./configure [options]
|
||||
make
|
||||
|
||||
automake v1.6.1+ and
|
||||
autoconf v2.54+ are required
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
# Makefile.am for fs2_open (top level)
|
||||
#
|
||||
# This file uses GNU Automake to generate makefiles
|
||||
|
||||
SUBDIRS = code
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
FS2OpenSCPReadMe.doc \
|
||||
projects/MSVC_2005/Freespace2.sln \
|
||||
projects/MSVC_2005/Freespace2.vcproj \
|
||||
projects/MSVC_2005/code.vcproj \
|
||||
projects/MSVC_6/Fred2.dsp \
|
||||
projects/MSVC_6/Freespace2.dsp \
|
||||
projects/MSVC_6/Freespace2.dsw \
|
||||
projects/MSVC_6/code.dsp \
|
||||
projects/MSVC_6/libjpeg.dsp \
|
||||
projects/MSVC_6/liblua.dsp \
|
||||
projects/MSVC_6/wxFRED2.dsp \
|
||||
projects/Xcode/English.lproj/InfoPlist.strings \
|
||||
projects/Xcode/FS2_Open.icns \
|
||||
projects/Xcode/FS2_Open.xcodeproj/project.pbxproj \
|
||||
projects/Xcode/Frameworks.tgz \
|
||||
projects/Xcode/Info-debug.plist \
|
||||
projects/Xcode/Info.plist \
|
||||
projects/Xcode/README.Xcode \
|
||||
projects/Xcode/SDLMain.h \
|
||||
projects/Xcode/SDLMain.m
|
||||
|
||||
|
||||
# D_ variants are defaults and should always be used
|
||||
AM_CXXFLAGS = -I./code @D_CFLAGS@
|
||||
AM_LDFLAGS = @D_LDFLAGS@
|
||||
|
||||
EXTRA_PROGRAMS = cfilearchiver cfileextractor cryptstring scramble
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin utilitites
|
||||
##
|
||||
|
||||
# cfilearchiver -- to create VPs
|
||||
cfilearchiver_SOURCES = \
|
||||
code/cfilearchiver/cfilearchiver.cpp
|
||||
|
||||
# cfileextractor -- to extract files from VPs
|
||||
cfileextractor_SOURCES = \
|
||||
code/cfileextractor/cfileextractor.cpp
|
||||
|
||||
# cryptstring -- to encrypt strings that are used as cheat codes
|
||||
cryptstring_SOURCES = \
|
||||
code/cryptstring/cryptstring.cpp
|
||||
|
||||
# scramble -- to encrypt tables
|
||||
scramble_SOURCES = \
|
||||
code/parse/encrypt.cpp \
|
||||
code/scramble/scramble.cpp \
|
||||
code/scramble/scramble.h
|
||||
|
||||
|
||||
# catch all to build utilitites
|
||||
tools: cfilearchiver cfileextractor cryptstring scramble
|
||||
|
||||
|
||||
# cleaning
|
||||
clean-tools:
|
||||
-test -z "$(EXTRA_PROGRAMS)" || rm -f $(EXTRA_PROGRAMS)
|
||||
|
||||
##
|
||||
## End utilitites
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
|
||||
# make sure we get this stuff cleaned up
|
||||
clean-generic: clean-tools
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
This file is required to keep autoconf/automake from complaining.
|
||||
|
||||
See the ChangeLog for what's new.
|
||||
@@ -1,8 +0,0 @@
|
||||
The "projects" directory contains ready projects for:
|
||||
Microsoft Visual C++ 6
|
||||
Microsoft Visual C++ 2005
|
||||
Anjuta 1 (please see README with project before using)
|
||||
|
||||
|
||||
See the ChangeLog to see what's new.
|
||||
See the INSTALL file for instructions on how to build fs2_open.
|
||||
-889
@@ -1,889 +0,0 @@
|
||||
# Configure paths for SDL
|
||||
# Sam Lantinga 9/21/99
|
||||
# stolen from Manish Singh
|
||||
# stolen back from Frank Belew
|
||||
# stolen from Manish Singh
|
||||
# Shamelessly stolen from Owen Taylor
|
||||
|
||||
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_SDL],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries from the sdl-config script
|
||||
dnl
|
||||
AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)],
|
||||
sdl_prefix="$withval", sdl_prefix="")
|
||||
AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
|
||||
sdl_exec_prefix="$withval", sdl_exec_prefix="")
|
||||
AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program],
|
||||
, enable_sdltest=yes)
|
||||
|
||||
if test x$sdl_exec_prefix != x ; then
|
||||
sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix"
|
||||
if test x${SDL_CONFIG+set} != xset ; then
|
||||
SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config
|
||||
fi
|
||||
fi
|
||||
if test x$sdl_prefix != x ; then
|
||||
sdl_args="$sdl_args --prefix=$sdl_prefix"
|
||||
if test x${SDL_CONFIG+set} != xset ; then
|
||||
SDL_CONFIG=$sdl_prefix/bin/sdl-config
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_REQUIRE([AC_CANONICAL_TARGET])
|
||||
PATH="$prefix/bin:$prefix/usr/bin:$PATH"
|
||||
AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH])
|
||||
min_sdl_version=ifelse([$1], ,0.11.0,$1)
|
||||
AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
|
||||
no_sdl=""
|
||||
if test "$SDL_CONFIG" = "no" ; then
|
||||
no_sdl=yes
|
||||
else
|
||||
SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags`
|
||||
SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs`
|
||||
|
||||
sdl_major_version=`$SDL_CONFIG $sdl_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
if test "x$enable_sdltest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
|
||||
LIBS="$LIBS $SDL_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed SDL is sufficiently new. (Also sanity
|
||||
dnl checks the results of sdl-config to some extent
|
||||
dnl
|
||||
rm -f conf.sdltest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "SDL.h"
|
||||
|
||||
char*
|
||||
my_strdup (char *str)
|
||||
{
|
||||
char *new_str;
|
||||
|
||||
if (str)
|
||||
{
|
||||
new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
|
||||
strcpy (new_str, str);
|
||||
}
|
||||
else
|
||||
new_str = NULL;
|
||||
|
||||
return new_str;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int major, minor, micro;
|
||||
char *tmp_version;
|
||||
|
||||
/* This hangs on some systems (?)
|
||||
system ("touch conf.sdltest");
|
||||
*/
|
||||
{ FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); }
|
||||
|
||||
/* HP/UX 9 (%@#!) writes to sscanf strings */
|
||||
tmp_version = my_strdup("$min_sdl_version");
|
||||
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
|
||||
printf("%s, bad version string\n", "$min_sdl_version");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (($sdl_major_version > major) ||
|
||||
(($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
|
||||
(($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
|
||||
printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro);
|
||||
printf("*** best to upgrade to the required version.\n");
|
||||
printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n");
|
||||
printf("*** to point to the correct copy of sdl-config, and remove the file\n");
|
||||
printf("*** config.cache before re-running configure\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
if test "x$no_sdl" = x ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test "$SDL_CONFIG" = "no" ; then
|
||||
echo "*** The sdl-config script installed by SDL could not be found"
|
||||
echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
|
||||
echo "*** your path, or set the SDL_CONFIG environment variable to the"
|
||||
echo "*** full path to sdl-config."
|
||||
else
|
||||
if test -f conf.sdltest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run SDL test program, checking why..."
|
||||
CFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
|
||||
LIBS="$LIBS $SDL_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include "SDL.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{ return 0; }
|
||||
#undef main
|
||||
#define main K_and_R_C_main
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding SDL or finding the wrong"
|
||||
echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means SDL was incorrectly installed"
|
||||
echo "*** or that you have moved SDL since it was installed. In the latter case, you"
|
||||
echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
SDL_CFLAGS=""
|
||||
SDL_LIBS=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
AC_SUBST(SDL_CFLAGS)
|
||||
AC_SUBST(SDL_LIBS)
|
||||
rm -f conf.sdltest
|
||||
])
|
||||
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Macros for wxWindows detection. Typically used in configure.in as:
|
||||
dnl
|
||||
dnl AC_ARG_ENABLE(...)
|
||||
dnl AC_ARG_WITH(...)
|
||||
dnl ...
|
||||
dnl AM_OPTIONS_WXCONFIG
|
||||
dnl ...
|
||||
dnl ...
|
||||
dnl AM_PATH_WXCONFIG(2.3.4, wxWin=1)
|
||||
dnl if test "$wxWin" != 1; then
|
||||
dnl AC_MSG_ERROR([
|
||||
dnl wxWindows must be installed on your system
|
||||
dnl but wx-config script couldn't be found.
|
||||
dnl
|
||||
dnl Please check that wx-config is in path, the directory
|
||||
dnl where wxWindows libraries are installed (returned by
|
||||
dnl 'wx-config --libs' command) is in LD_LIBRARY_PATH or
|
||||
dnl equivalent variable and wxWindows version is 2.3.4 or above.
|
||||
dnl ])
|
||||
dnl fi
|
||||
dnl CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS"
|
||||
dnl CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY"
|
||||
dnl CFLAGS="$CFLAGS $WX_CFLAGS_ONLY"
|
||||
dnl
|
||||
dnl LDFLAGS="$LDFLAGS $WX_LIBS"
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl AM_OPTIONS_WXCONFIG
|
||||
dnl
|
||||
dnl adds support for --wx-prefix, --wx-exec-prefix and --wx-config
|
||||
dnl command line options
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
AC_DEFUN([AM_OPTIONS_WXCONFIG],
|
||||
[
|
||||
AC_ARG_WITH(wx-prefix, [ --with-wx-prefix=PREFIX Prefix where wxWindows is installed (optional)],
|
||||
wx_config_prefix="$withval", wx_config_prefix="")
|
||||
AC_ARG_WITH(wx-exec-prefix,[ --with-wx-exec-prefix=PREFIX Exec prefix where wxWindows is installed (optional)],
|
||||
wx_config_exec_prefix="$withval", wx_config_exec_prefix="")
|
||||
AC_ARG_WITH(wx-config,[ --with-wx-config=CONFIG wx-config script to use (optional)],
|
||||
wx_config_name="$withval", wx_config_name="")
|
||||
])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl AM_PATH_WXCONFIG(VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl
|
||||
dnl Test for wxWindows, and define WX_C*FLAGS, WX_LIBS and WX_LIBS_STATIC
|
||||
dnl (the latter is for static linking against wxWindows). Set WX_CONFIG_NAME
|
||||
dnl environment variable to override the default name of the wx-config script
|
||||
dnl to use. Set WX_CONFIG_PATH to specify the full path to wx-config - in this
|
||||
dnl case the macro won't even waste time on tests for its existence.
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
dnl
|
||||
dnl Get the cflags and libraries from the wx-config script
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_WXCONFIG],
|
||||
[
|
||||
dnl do we have wx-config name: it can be wx-config or wxd-config or ...
|
||||
if test x${WX_CONFIG_NAME+set} != xset ; then
|
||||
WX_CONFIG_NAME=wx-config
|
||||
fi
|
||||
if test "x$wx_config_name" != x ; then
|
||||
WX_CONFIG_NAME="$wx_config_name"
|
||||
fi
|
||||
|
||||
dnl deal with optional prefixes
|
||||
if test x$wx_config_exec_prefix != x ; then
|
||||
wx_config_args="$wx_config_args --exec-prefix=$wx_config_exec_prefix"
|
||||
WX_LOOKUP_PATH="$wx_config_exec_prefix/bin"
|
||||
fi
|
||||
if test x$wx_config_prefix != x ; then
|
||||
wx_config_args="$wx_config_args --prefix=$wx_config_prefix"
|
||||
WX_LOOKUP_PATH="$WX_LOOKUP_PATH:$wx_config_prefix/bin"
|
||||
fi
|
||||
|
||||
dnl don't search the PATH if WX_CONFIG_NAME is absolute filename
|
||||
if test -x "$WX_CONFIG_NAME" ; then
|
||||
AC_MSG_CHECKING(for wx-config)
|
||||
WX_CONFIG_PATH="$WX_CONFIG_NAME"
|
||||
AC_MSG_RESULT($WX_CONFIG_PATH)
|
||||
else
|
||||
AC_PATH_PROG(WX_CONFIG_PATH, $WX_CONFIG_NAME, no, "$WX_LOOKUP_PATH:$PATH")
|
||||
fi
|
||||
|
||||
if test "$WX_CONFIG_PATH" != "no" ; then
|
||||
WX_VERSION=""
|
||||
no_wx=""
|
||||
|
||||
min_wx_version=ifelse([$1], ,2.2.1,$1)
|
||||
AC_MSG_CHECKING(for wxWindows version >= $min_wx_version)
|
||||
|
||||
WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args"
|
||||
|
||||
WX_VERSION=`$WX_CONFIG_WITH_ARGS --version`
|
||||
wx_config_major_version=`echo $WX_VERSION | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
wx_config_minor_version=`echo $WX_VERSION | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
wx_config_micro_version=`echo $WX_VERSION | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
|
||||
wx_requested_major_version=`echo $min_wx_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
wx_requested_minor_version=`echo $min_wx_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
wx_requested_micro_version=`echo $min_wx_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
|
||||
wx_ver_ok=""
|
||||
if test $wx_config_major_version -gt $wx_requested_major_version; then
|
||||
wx_ver_ok=yes
|
||||
else
|
||||
if test $wx_config_major_version -eq $wx_requested_major_version; then
|
||||
if test $wx_config_minor_version -gt $wx_requested_minor_version; then
|
||||
wx_ver_ok=yes
|
||||
else
|
||||
if test $wx_config_minor_version -eq $wx_requested_minor_version; then
|
||||
if test $wx_config_micro_version -ge $wx_requested_micro_version; then
|
||||
wx_ver_ok=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$wx_ver_ok" = x ; then
|
||||
no_wx=yes
|
||||
else
|
||||
WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs`
|
||||
WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs`
|
||||
|
||||
dnl starting with version 2.2.6 wx-config has --cppflags argument
|
||||
wx_has_cppflags=""
|
||||
if test $wx_config_major_version -gt 2; then
|
||||
wx_has_cppflags=yes
|
||||
else
|
||||
if test $wx_config_major_version -eq 2; then
|
||||
if test $wx_config_minor_version -gt 2; then
|
||||
wx_has_cppflags=yes
|
||||
else
|
||||
if test $wx_config_minor_version -eq 2; then
|
||||
if test $wx_config_micro_version -ge 6; then
|
||||
wx_has_cppflags=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$wx_has_cppflags" = x ; then
|
||||
dnl no choice but to define all flags like CFLAGS
|
||||
WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags`
|
||||
WX_CPPFLAGS=$WX_CFLAGS
|
||||
WX_CXXFLAGS=$WX_CFLAGS
|
||||
|
||||
WX_CFLAGS_ONLY=$WX_CFLAGS
|
||||
WX_CXXFLAGS_ONLY=$WX_CFLAGS
|
||||
else
|
||||
dnl we have CPPFLAGS included in CFLAGS included in CXXFLAGS
|
||||
WX_CPPFLAGS=`$WX_CONFIG_WITH_ARGS --cppflags`
|
||||
WX_CXXFLAGS=`$WX_CONFIG_WITH_ARGS --cxxflags`
|
||||
WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags`
|
||||
|
||||
WX_CFLAGS_ONLY=`echo $WX_CFLAGS | sed "s@^$WX_CPPFLAGS *@@"`
|
||||
WX_CXXFLAGS_ONLY=`echo $WX_CXXFLAGS | sed "s@^$WX_CFLAGS *@@"`
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$no_wx" = x ; then
|
||||
AC_MSG_RESULT(yes (version $WX_VERSION))
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
if test "x$WX_VERSION" = x; then
|
||||
dnl no wx-config at all
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(no (version $WX_VERSION is not new enough))
|
||||
fi
|
||||
|
||||
WX_CFLAGS=""
|
||||
WX_CPPFLAGS=""
|
||||
WX_CXXFLAGS=""
|
||||
WX_LIBS=""
|
||||
WX_LIBS_STATIC=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(WX_CPPFLAGS)
|
||||
AC_SUBST(WX_CFLAGS)
|
||||
AC_SUBST(WX_CXXFLAGS)
|
||||
AC_SUBST(WX_CFLAGS_ONLY)
|
||||
AC_SUBST(WX_CXXFLAGS_ONLY)
|
||||
AC_SUBST(WX_LIBS)
|
||||
AC_SUBST(WX_LIBS_STATIC)
|
||||
AC_SUBST(WX_VERSION)
|
||||
])
|
||||
|
||||
# Configure paths for libogg
|
||||
# Jack Moffitt <[email protected]> 10-21-2000
|
||||
# Shamelessly stolen from Owen Taylor and Manish Singh
|
||||
|
||||
dnl XIPH_PATH_OGG([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libogg, and define OGG_CFLAGS and OGG_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_OGG],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(ogg,[ --with-ogg=PFX Prefix where libogg is installed (optional)], ogg_prefix="$withval", ogg_prefix="")
|
||||
AC_ARG_WITH(ogg-libraries,[ --with-ogg-libraries=DIR Directory where libogg library is installed (optional)], ogg_libraries="$withval", ogg_libraries="")
|
||||
AC_ARG_WITH(ogg-includes,[ --with-ogg-includes=DIR Directory where libogg header files are installed (optional)], ogg_includes="$withval", ogg_includes="")
|
||||
AC_ARG_ENABLE(oggtest, [ --disable-oggtest Do not try to compile and run a test Ogg program],, enable_oggtest=yes)
|
||||
|
||||
if test "x$ogg_libraries" != "x" ; then
|
||||
OGG_LIBS="-L$ogg_libraries"
|
||||
elif test "x$ogg_prefix" != "x" ; then
|
||||
OGG_LIBS="-L$ogg_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE" ; then
|
||||
OGG_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
OGG_LIBS="$OGG_LIBS -logg"
|
||||
|
||||
if test "x$ogg_includes" != "x" ; then
|
||||
OGG_CFLAGS="-I$ogg_includes"
|
||||
elif test "x$ogg_prefix" != "x" ; then
|
||||
OGG_CFLAGS="-I$ogg_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OGG_CFLAGS=""
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for Ogg)
|
||||
no_ogg=""
|
||||
|
||||
|
||||
if test "x$enable_oggtest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Ogg is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.oggtest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
system("touch conf.oggtest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_ogg=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_ogg" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.oggtest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Ogg test program, checking why..."
|
||||
CFLAGS="$CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <ogg/ogg.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Ogg or finding the wrong"
|
||||
echo "*** version of Ogg. If it is not finding Ogg, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Ogg was incorrectly installed"
|
||||
echo "*** or that you have moved Ogg since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
OGG_CFLAGS=""
|
||||
OGG_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(OGG_CFLAGS)
|
||||
AC_SUBST(OGG_LIBS)
|
||||
rm -f conf.oggtest
|
||||
])
|
||||
|
||||
# Configure paths for libvorbis
|
||||
# Jack Moffitt <[email protected]> 10-21-2000
|
||||
# Shamelessly stolen from Owen Taylor and Manish Singh
|
||||
# thomasvs added check for vorbis_bitrate_addblock which is new in rc3
|
||||
|
||||
dnl XIPH_PATH_VORBIS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libvorbis, and define VORBIS_CFLAGS and VORBIS_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_VORBIS],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(vorbis,[ --with-vorbis=PFX Prefix where libvorbis is installed (optional)], vorbis_prefix="$withval", vorbis_prefix="")
|
||||
AC_ARG_WITH(vorbis-libraries,[ --with-vorbis-libraries=DIR Directory where libvorbis library is installed (optional)], vorbis_libraries="$withval", vorbis_libraries="")
|
||||
AC_ARG_WITH(vorbis-includes,[ --with-vorbis-includes=DIR Directory where libvorbis header files are installed (optional)], vorbis_includes="$withval", vorbis_includes="")
|
||||
AC_ARG_ENABLE(vorbistest, [ --disable-vorbistest Do not try to compile and run a test Vorbis program],, enable_vorbistest=yes)
|
||||
|
||||
if test "x$vorbis_libraries" != "x" ; then
|
||||
VORBIS_LIBS="-L$vorbis_libraries"
|
||||
elif test "x$vorbis_prefix" != "x" ; then
|
||||
VORBIS_LIBS="-L$vorbis_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
VORBIS_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
VORBIS_LIBS="$VORBIS_LIBS -lvorbis -lm"
|
||||
VORBISFILE_LIBS="-lvorbisfile"
|
||||
VORBISENC_LIBS="-lvorbisenc"
|
||||
|
||||
if test "x$vorbis_includes" != "x" ; then
|
||||
VORBIS_CFLAGS="-I$vorbis_includes"
|
||||
elif test "x$vorbis_prefix" != "x" ; then
|
||||
VORBIS_CFLAGS="-I$vorbis_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
VORBIS_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for Vorbis)
|
||||
no_vorbis=""
|
||||
|
||||
|
||||
if test "x$enable_vorbistest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $VORBIS_CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $VORBIS_LIBS $VORBISENC_LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Vorbis is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.vorbistest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisenc.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
vorbis_block vb;
|
||||
vorbis_dsp_state vd;
|
||||
vorbis_info vi;
|
||||
|
||||
vorbis_info_init (&vi);
|
||||
vorbis_encode_init (&vi, 2, 44100, -1, 128000, -1);
|
||||
vorbis_analysis_init (&vd, &vi);
|
||||
vorbis_block_init (&vd, &vb);
|
||||
/* this function was added in 1.0rc3, so this is what we're testing for */
|
||||
vorbis_bitrate_addblock (&vb);
|
||||
|
||||
system("touch conf.vorbistest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_vorbis=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_vorbis" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.vorbistest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Vorbis test program, checking why..."
|
||||
CFLAGS="$CFLAGS $VORBIS_CFLAGS"
|
||||
LIBS="$LIBS $VORBIS_LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <vorbis/codec.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Vorbis or finding the wrong"
|
||||
echo "*** version of Vorbis. If it is not finding Vorbis, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Vorbis was incorrectly installed"
|
||||
echo "*** or that you have moved Vorbis since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
VORBIS_CFLAGS=""
|
||||
VORBIS_LIBS=""
|
||||
VORBISFILE_LIBS=""
|
||||
VORBISENC_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(VORBIS_CFLAGS)
|
||||
AC_SUBST(VORBIS_LIBS)
|
||||
AC_SUBST(VORBISFILE_LIBS)
|
||||
AC_SUBST(VORBISENC_LIBS)
|
||||
rm -f conf.vorbistest
|
||||
])
|
||||
|
||||
dnl XIPH_PATH_THEORA([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libtheora, and define THEORA_CFLAGS and THEORA_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_THEORA],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(theora,[ --with-theora=PFX Prefix where libtheora is installed (optional)], theora_prefix="$withval", theora_prefix="")
|
||||
AC_ARG_WITH(theora-libraries,[ --with-theora-libraries=DIR Directory where libtheora library is installed (optional)], theora_libraries="$withval", theora_libraries="")
|
||||
AC_ARG_WITH(theora-includes,[ --with-theora-includes=DIR Directory where libtheora header files are installed (optional)], theora_includes="$withval", theora_includes="")
|
||||
AC_ARG_ENABLE(theoratest, [ --disable-theoratest Do not try to compile and run a test Theora program],, enable_theoratest=yes)
|
||||
|
||||
if test "x$theora_libraries" != "x" ; then
|
||||
THEORA_LIBS="-L$theora_libraries"
|
||||
elif test "x$theora_prefix" != "x" ; then
|
||||
THEORA_LIBS="-L$theora_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
THEORA_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
THEORA_LIBS="$THEORA_LIBS -ltheora"
|
||||
|
||||
if test "x$theora_includes" != "x" ; then
|
||||
THEORA_CFLAGS="-I$theora_includes"
|
||||
elif test "x$theora_prefix" != "x" ; then
|
||||
THEORA_CFLAGS="-I$theora_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
THEORA_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for Theora)
|
||||
no_theora=""
|
||||
|
||||
|
||||
if test "x$enable_theoratest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $THEORA_CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $THEORA_LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Theora is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.theoratest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <theora/theora.h>
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
theora_info ti;
|
||||
theora_state ts;
|
||||
|
||||
theora_info_init(&ti);
|
||||
|
||||
system("touch conf.theoratest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_theora=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_theora" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.theoratest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Theora test program, checking why..."
|
||||
CFLAGS="$CFLAGS $THEORA_CFLAGS"
|
||||
LIBS="$LIBS $THEORA_LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <vorbis/codec.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Theora or finding the wrong"
|
||||
echo "*** version of Theora. If it is not finding Theora, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Theora was incorrectly installed"
|
||||
echo "*** or that you have moved Theora since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
THEORA_CFLAGS=""
|
||||
THEORA_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(THEORA_CFLAGS)
|
||||
AC_SUBST(THEORA_LIBS)
|
||||
rm -f conf.theoratest
|
||||
])
|
||||
|
||||
|
||||
dnl AM_PATH_OPENAL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for OpenAL, and define OPENAL_CFLAGS and OPENAL_LIBS
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_OPENAL],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(openal,[ --with-openal=PFX Prefix where OpenAL is installed (optional)], openal_prefix="$withval", openal_prefix="")
|
||||
AC_ARG_WITH(openal-libraries,[ --with-openal-libraries=DIR Directory where OpenAL library is installed (optional)], openal_libraries="$withval", openal_libraries="")
|
||||
AC_ARG_WITH(openal-includes,[ --with-openal-includes=DIR Directory where OpenAL header files are installed (optional)], openal_includes="$withval", openal_includes="")
|
||||
AC_ARG_ENABLE(openaltest, [ --disable-openaltest Do not try to compile and run a test OpenAL program],, enable_openaltest=yes)
|
||||
|
||||
if test "x$openal_libraries" != "x" ; then
|
||||
OPENAL_LIBS="-L$openal_libraries"
|
||||
elif test "x$openal_prefix" != "x" ; then
|
||||
OPENAL_LIBS="-L$openal_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OPENAL_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
OPENAL_LIBS="$OPENAL_LIBS -lopenal"
|
||||
|
||||
if test "x$openal_includes" != "x" ; then
|
||||
OPENAL_CFLAGS="-I$openal_includes"
|
||||
elif test "x$openal_prefix" != "x" ; then
|
||||
OPENAL_CFLAGS="-I$openal_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OPENAL_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for OpenAL)
|
||||
no_openal=""
|
||||
|
||||
|
||||
if test "x$enable_openaltest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $OPENAL_CFLAGS"
|
||||
LIBS="$LIBS $OPENAL_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed OpenAL is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.openaltest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
#ifdef AL_VERSION_1_1
|
||||
alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT");
|
||||
|
||||
system("touch conf.openaltest");
|
||||
return 0;
|
||||
#else
|
||||
printf("\n*** OpenAL version 1.1 or greater is required.\n");
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
],, no_openal=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_openal" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.openaltest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run OpenAL test program, checking why..."
|
||||
CFLAGS="$CFLAGS $OPENAL_CFLAGS"
|
||||
LIBS="$LIBS $OPENAL_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <AL/al.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding OpenAL or finding the wrong"
|
||||
echo "*** version of OpenAL. If it is not finding OpenAL, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means OpenAL was incorrectly installed"
|
||||
echo "*** or that you have moved OpenAL since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
OPENAL_CFLAGS=""
|
||||
OPENAL_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(OPENAL_CFLAGS)
|
||||
AC_SUBST(OPENAL_LIBS)
|
||||
rm -f conf.openaltest
|
||||
])
|
||||
|
||||
dnl AM_PATH_OPENGL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for OpenGL, and define OPENGL_CFLAGS and OPENGL_LIBS
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_OPENGL],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(opengl,[ --with-opengl=PFX Prefix where OpenGL is installed (optional)], opengl_prefix="$withval", opengl_prefix="")
|
||||
AC_ARG_WITH(opengl-libraries,[ --with-opengl-libraries=DIR Directory where OpenGL library is installed (optional)], opengl_libraries="$withval", opengl_libraries="")
|
||||
AC_ARG_WITH(opengl-includes,[ --with-opengl-includes=DIR Directory where OpenGL header files are installed (optional)], opengl_includes="$withval", opengl_includes="")
|
||||
AC_ARG_ENABLE(opengltest, [ --disable-opengltest Do not try to compile and run a test OpenGL program],, enable_opengltest=yes)
|
||||
|
||||
if test "x$opengl_libraries" != "x" ; then
|
||||
OPENGL_LIBS="-L$opengl_libraries"
|
||||
elif test "x$opengl_prefix" != "x" ; then
|
||||
OPENGL_LIBS="-L$opengl_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OPENGL_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
OPENGL_LIBS="$OPENGL_LIBS -lGL -lGLU"
|
||||
|
||||
if test "x$opengl_includes" != "x" ; then
|
||||
OPENGL_CFLAGS="-I$opengl_includes"
|
||||
elif test "x$opengl_prefix" != "x" ; then
|
||||
OPENGL_CFLAGS="-I$opengl_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OPENGL_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
no_opengl=""
|
||||
|
||||
|
||||
if test "x$enable_opengltest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $OPENGL_CFLAGS"
|
||||
LIBS="$LIBS $OPENGL_LIBS"
|
||||
|
||||
AC_CHECK_LIB(GL, glPushMatrix,
|
||||
[AC_CHECK_HEADER(GL/gl.h,
|
||||
[AC_CHECK_LIB(GLU, gluPerspective,
|
||||
[AC_CHECK_HEADER(GL/glu.h, ,
|
||||
dnl NOTE: this is a failure
|
||||
no_opengl=yes
|
||||
)]
|
||||
)]
|
||||
)]
|
||||
)
|
||||
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_opengl" = "x" ; then
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
OPENGL_CFLAGS=""
|
||||
OPENGL_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(OPENGL_CFLAGS)
|
||||
AC_SUBST(OPENGL_LIBS)
|
||||
])
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
PKG_NAME="fs2_open"
|
||||
|
||||
# check the version of a package
|
||||
check_version() {
|
||||
COMMAND=$1
|
||||
MAJOR=$2
|
||||
MINOR=$3
|
||||
MICRO=$4
|
||||
|
||||
($COMMAND --version) </dev/null >/dev/null 2>&1 || return 1
|
||||
|
||||
ver=`$COMMAND --version|head -n 1|sed 's/^.*) //'|sed 's/ (.*)//'`
|
||||
major=`echo $ver | cut -d. -f1 | sed s/[a-zA-Z\-].*//g`
|
||||
minor=`echo $ver | cut -d. -f2 | sed s/[a-zA-Z\-].*//g`
|
||||
micro=`echo $ver | cut -d. -f3 | sed s/[a-zA-Z\-].*//g`
|
||||
test -z "$major" && major=0
|
||||
test -z "$minor" && minor=0
|
||||
test -z "$micro" && micro=0
|
||||
|
||||
fail=0
|
||||
if [ ! "$major" -gt "$MAJOR" ]; then
|
||||
if [ "$major" -lt "$MAJOR" ]; then
|
||||
fail=1
|
||||
elif [ ! "$minor" -gt "$MINOR" ]; then
|
||||
if [ "$minor" -lt "$MINOR" ]; then
|
||||
fail=1
|
||||
elif [ "$micro" -lt "$MICRO" ]; then
|
||||
fail=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
return "$fail"
|
||||
}
|
||||
|
||||
AUTOMAKE=
|
||||
ACLOCAL=
|
||||
DIE=0
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`autoconf' installed to."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
for AM in automake-1.11 automake-1.10 automake-1.9 automake-1.8 automake-1.7 automake-1.6 automake; do
|
||||
(check_version "$AM" 1 6 1) && {
|
||||
AUTOMAKE="$AM"
|
||||
break
|
||||
}
|
||||
done
|
||||
|
||||
if [ -z "$AUTOMAKE" ]; then
|
||||
echo
|
||||
echo "**Error**: You must have \`automake' version 1.6.1 or greater"
|
||||
echo "installed to compile $PKG_NAME. Download the appropriate package"
|
||||
echo "for your distribution, or get the source tarball at"
|
||||
echo "ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
fi
|
||||
|
||||
# if no automake, don't bother testing for aclocal
|
||||
test -z "$AUTOMAKE" || {
|
||||
for ACL in aclocal-1.11 aclocal-1.10 aclocal-1.9 aclocal-1.8 aclocal-1.7 aclocal-1.6 aclocal; do
|
||||
(check_version "$ACL" 1 6 1) && {
|
||||
ACLOCAL="$ACL"
|
||||
break
|
||||
}
|
||||
done
|
||||
|
||||
if [ -z "$ACLOCAL" ]; then
|
||||
echo
|
||||
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
|
||||
echo "installed seems to be outdated. Get a recent package from"
|
||||
echo "ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
fi
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$*"; then
|
||||
echo "**Warning**: I am going to run \`configure' with no arguments."
|
||||
echo "If you wish to pass any to it, please specify them on the"
|
||||
echo \`$0\'" command line."
|
||||
echo
|
||||
fi
|
||||
|
||||
case $CC in
|
||||
xlc )
|
||||
am_opt=--include-deps;;
|
||||
esac
|
||||
|
||||
for coin in `find $srcdir -name configure.ac -print`
|
||||
do
|
||||
dr=`dirname $coin`
|
||||
if test -f $dr/NO-AUTO-GEN; then
|
||||
echo skipping $dr -- flagged as no auto-gen
|
||||
else
|
||||
echo processing $dr
|
||||
macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
|
||||
( cd $dr
|
||||
aclocalinclude="$ACLOCAL_FLAGS"
|
||||
for k in $macrodirs; do
|
||||
if test -d $k; then
|
||||
aclocalinclude="$aclocalinclude -I $k"
|
||||
##else
|
||||
## echo "**Warning**: No such directory \`$k'. Ignored."
|
||||
fi
|
||||
done
|
||||
echo "Running $ACLOCAL $aclocalinclude ..."
|
||||
"$ACLOCAL" $aclocalinclude
|
||||
echo "Running $AUTOMAKE --add-missing --copy --foreign $am_opt ..."
|
||||
"$AUTOMAKE" --add-missing --copy --foreign $am_opt
|
||||
echo "Running autoconf..."
|
||||
autoconf
|
||||
)
|
||||
fi
|
||||
done
|
||||
|
||||
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
|
||||
|
||||
if test x$NOCONFIGURE = x; then
|
||||
echo Running $srcdir/configure $conf_flags "$@" ...
|
||||
$srcdir/configure $conf_flags "$@" \
|
||||
&& echo Now type \`make\' to compile $PKG_NAME.
|
||||
else
|
||||
echo Skipping configure process.
|
||||
fi
|
||||
@@ -1,855 +0,0 @@
|
||||
## code/Makefile.am for fs2_open
|
||||
##
|
||||
## $Id: Makefile.am,v 1.31.2.10 2007-11-22 04:52:12 taylor Exp $
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
freespace2/app_icon.ico \
|
||||
freespace2/freespace.rc \
|
||||
freespace2/freespaceresource.h \
|
||||
freespace2/goal_com.bmp \
|
||||
freespace2/goal_fail.bmp \
|
||||
freespace2/goal_inc.bmp \
|
||||
freespace2/goal_none.bmp \
|
||||
freespace2/goal_ord.bmp \
|
||||
fred2/addvariabledlg.cpp \
|
||||
fred2/addvariabledlg.h \
|
||||
fred2/adjustgriddlg.cpp \
|
||||
fred2/adjustgriddlg.h \
|
||||
fred2/asteroideditordlg.cpp \
|
||||
fred2/asteroideditordlg.h \
|
||||
fred2/bgbitmapdlg.cpp \
|
||||
fred2/bgbitmapdlg.h \
|
||||
fred2/briefingeditordlg.cpp \
|
||||
fred2/briefingeditordlg.h \
|
||||
fred2/campaigneditordlg.cpp \
|
||||
fred2/campaigneditordlg.h \
|
||||
fred2/campaignfilelistbox.cpp \
|
||||
fred2/campaignfilelistbox.h \
|
||||
fred2/campaigntreeview.cpp \
|
||||
fred2/campaigntreeview.h \
|
||||
fred2/campaigntreewnd.cpp \
|
||||
fred2/campaigntreewnd.h \
|
||||
fred2/cmdbrief.cpp \
|
||||
fred2/cmdbrief.h \
|
||||
fred2/createwingdlg.cpp \
|
||||
fred2/createwingdlg.h \
|
||||
fred2/customwingnames.cpp \
|
||||
fred2/customwingnames.h \
|
||||
fred2/debriefingeditordlg.cpp \
|
||||
fred2/debriefingeditordlg.h \
|
||||
fred2/dialog1.cpp \
|
||||
fred2/dialog1.h \
|
||||
fred2/dumpstats.cpp \
|
||||
fred2/dumpstats.h \
|
||||
fred2/editor.h \
|
||||
fred2/eventeditor.cpp \
|
||||
fred2/eventeditor.h \
|
||||
fred2/folderdlg.cpp \
|
||||
fred2/folderdlg.h \
|
||||
fred2/fred.cpp \
|
||||
fred2/fred.h \
|
||||
fred2/fred.rc \
|
||||
fred2/freddoc.cpp \
|
||||
fred2/freddoc.h \
|
||||
fred2/fredrender.cpp \
|
||||
fred2/fredrender.h \
|
||||
fred2/fredstubs.cpp \
|
||||
fred2/fredview.cpp \
|
||||
fred2/fredview.h \
|
||||
fred2/grid.cpp \
|
||||
fred2/grid.h \
|
||||
fred2/ignoreordersdlg.cpp \
|
||||
fred2/ignoreordersdlg.h \
|
||||
fred2/initialships.cpp \
|
||||
fred2/initialships.h \
|
||||
fred2/initialstatus.cpp \
|
||||
fred2/initialstatus.h \
|
||||
fred2/mainfrm.cpp \
|
||||
fred2/mainfrm.h \
|
||||
fred2/makehelp.bat \
|
||||
fred2/management.cpp \
|
||||
fred2/management.h \
|
||||
fred2/messageeditordlg.cpp \
|
||||
fred2/messageeditordlg.h \
|
||||
fred2/missiongoalsdlg.cpp \
|
||||
fred2/missiongoalsdlg.h \
|
||||
fred2/missionnotesdlg.cpp \
|
||||
fred2/missionnotesdlg.h \
|
||||
fred2/missionsave.cpp \
|
||||
fred2/missionsave.h \
|
||||
fred2/modifyvariabledlg.cpp \
|
||||
fred2/modifyvariabledlg.h \
|
||||
fred2/operatorargtypeselect.cpp \
|
||||
fred2/operatorargtypeselect.h \
|
||||
fred2/orienteditor.cpp \
|
||||
fred2/orienteditor.h \
|
||||
fred2/playerstarteditor.cpp \
|
||||
fred2/playerstarteditor.h \
|
||||
fred2/prefsdlg.cpp \
|
||||
fred2/prefsdlg.h \
|
||||
fred2/reinforcementeditordlg.cpp \
|
||||
fred2/reinforcementeditordlg.h \
|
||||
fred2/resource.h \
|
||||
fred2/resource.hm \
|
||||
fred2/setglobalshipflags.cpp \
|
||||
fred2/setglobalshipflags.h \
|
||||
fred2/sexp_tree.cpp \
|
||||
fred2/sexp_tree.h \
|
||||
fred2/shieldsysdlg.cpp \
|
||||
fred2/shieldsysdlg.h \
|
||||
fred2/ship_select.cpp \
|
||||
fred2/ship_select.h \
|
||||
fred2/shipchecklistbox.cpp \
|
||||
fred2/shipchecklistbox.h \
|
||||
fred2/shipclasseditordlg.cpp \
|
||||
fred2/shipclasseditordlg.h \
|
||||
fred2/shipeditordlg.cpp \
|
||||
fred2/shipeditordlg.h \
|
||||
fred2/shipflagsdlg.cpp \
|
||||
fred2/shipflagsdlg.h \
|
||||
fred2/shipgoalsdlg.cpp \
|
||||
fred2/shipgoalsdlg.h \
|
||||
fred2/shipspecialdamage.cpp \
|
||||
fred2/shipspecialdamage.h \
|
||||
fred2/shipspecialhitpoints.cpp \
|
||||
fred2/shipspecialhitpoints.h \
|
||||
fred2/shiptexturesdlg.cpp \
|
||||
fred2/shiptexturesdlg.h \
|
||||
fred2/starfieldeditor.cpp \
|
||||
fred2/starfieldeditor.h \
|
||||
fred2/stdafx.cpp \
|
||||
fred2/stdafx.h \
|
||||
fred2/textviewdlg.cpp \
|
||||
fred2/textviewdlg.h \
|
||||
fred2/voiceactingmanager.cpp \
|
||||
fred2/voiceactingmanager.h \
|
||||
fred2/waypointpathdlg.cpp \
|
||||
fred2/waypointpathdlg.h \
|
||||
fred2/weaponeditordlg.cpp \
|
||||
fred2/weaponeditordlg.h \
|
||||
fred2/wing.cpp \
|
||||
fred2/wing.h \
|
||||
fred2/wing_editor.cpp \
|
||||
fred2/wing_editor.h \
|
||||
fred2/hlp/afxcore.rtf \
|
||||
fred2/hlp/afxhelp.hm \
|
||||
fred2/hlp/afxprint.rtf \
|
||||
fred2/hlp/appexit.bmp \
|
||||
fred2/hlp/bullet.bmp \
|
||||
fred2/hlp/curarw2.bmp \
|
||||
fred2/hlp/curarw4.bmp \
|
||||
fred2/hlp/curhelp.bmp \
|
||||
fred2/hlp/editcopy.bmp \
|
||||
fred2/hlp/editcut.bmp \
|
||||
fred2/hlp/editpast.bmp \
|
||||
fred2/hlp/editundo.bmp \
|
||||
fred2/hlp/filenew.bmp \
|
||||
fred2/hlp/fileopen.bmp \
|
||||
fred2/hlp/fileprnt.bmp \
|
||||
fred2/hlp/filesave.bmp \
|
||||
fred2/hlp/fred.hm \
|
||||
fred2/hlp/fred.hpj \
|
||||
fred2/hlp/help.log \
|
||||
fred2/hlp/hlpsbar.bmp \
|
||||
fred2/hlp/hlptbar.bmp \
|
||||
fred2/hlp/recfirst.bmp \
|
||||
fred2/hlp/reclast.bmp \
|
||||
fred2/hlp/recnext.bmp \
|
||||
fred2/hlp/recprev.bmp \
|
||||
fred2/hlp/scmax.bmp \
|
||||
fred2/hlp/scmenu.bmp \
|
||||
fred2/hlp/scmin.bmp \
|
||||
fred2/res/bitmap1.bmp \
|
||||
fred2/res/black_do.bmp \
|
||||
fred2/res/bmp00001.bmp \
|
||||
fred2/res/chained.bmp \
|
||||
fred2/res/chained_directive.bmp \
|
||||
fred2/res/cursor1.cur \
|
||||
fred2/res/cursor2.cur \
|
||||
fred2/res/data.bmp \
|
||||
fred2/res/fred.ico \
|
||||
fred2/res/fred.rc2 \
|
||||
fred2/res/freddoc.ico \
|
||||
fred2/res/green_do.bmp \
|
||||
fred2/res/root.bmp \
|
||||
fred2/res/root_directive.bmp \
|
||||
fred2/res/toolbar.bmp \
|
||||
fred2/res/toolbar1.bmp \
|
||||
fred2/res/variable.bmp \
|
||||
sound/phrases.xml \
|
||||
sound/gc.exe \
|
||||
wxfred2/res/fred.ico \
|
||||
wxfred2/wxfred.xrc
|
||||
|
||||
|
||||
# D_ variants are defaults and should always be used
|
||||
# FS2_ variants are for game building and wxFRED
|
||||
AM_CXXFLAGS = @D_CFLAGS@ @FS2_CXXFLAGS@
|
||||
AM_LDFLAGS = @D_LDFLAGS@ @FS2_LDFLAGS@
|
||||
|
||||
noinst_LIBRARIES = libcode.a
|
||||
noinst_PROGRAMS = @FS2_BINARY@
|
||||
|
||||
EXTRA_PROGRAMS = fs2_open_r fs2_open_d wxFRED2_r wxFRED2_d fs2_open_INF_r fs2_open_INF_d wxFRED2_INF_r wxFRED2_INF_d
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin CORE library
|
||||
##
|
||||
|
||||
FS2_SOURCES = \
|
||||
ai/ai.cpp \
|
||||
ai/ai.h \
|
||||
ai/aibig.cpp \
|
||||
ai/aibig.h \
|
||||
ai/aicode.cpp \
|
||||
ai/aigoals.cpp \
|
||||
ai/aigoals.h \
|
||||
ai/aiinternal.h \
|
||||
ai/ailocal.h \
|
||||
ai/aiturret.cpp \
|
||||
ai/ai_profiles.cpp \
|
||||
ai/ai_profiles.h \
|
||||
anim/animplay.cpp \
|
||||
anim/animplay.h \
|
||||
anim/packunpack.cpp \
|
||||
anim/packunpack.h \
|
||||
asteroid/asteroid.cpp \
|
||||
asteroid/asteroid.h \
|
||||
autopilot/autopilot.cpp \
|
||||
autopilot/autopilot.h \
|
||||
bmpman/bm_internal.h \
|
||||
bmpman/bmpman.cpp \
|
||||
bmpman/bmpman.h \
|
||||
camera/camera.cpp \
|
||||
camera/camera.h \
|
||||
cfile/cfile.cpp \
|
||||
cfile/cfile.h \
|
||||
cfile/cfilearchive.cpp \
|
||||
cfile/cfilearchive.h \
|
||||
cfile/cfilelist.cpp \
|
||||
cfile/cfilesystem.cpp \
|
||||
cfile/cfilesystem.h \
|
||||
cmdline/cmdline.cpp \
|
||||
cmdline/cmdline.h \
|
||||
cmeasure/cmeasure.cpp \
|
||||
cmeasure/cmeasure.h \
|
||||
controlconfig/controlsconfig.cpp \
|
||||
controlconfig/controlsconfig.h \
|
||||
controlconfig/controlsconfigcommon.cpp \
|
||||
cutscene/cutscenes.cpp \
|
||||
cutscene/cutscenes.h \
|
||||
cutscene/decoder16.cpp \
|
||||
cutscene/decoder8.cpp \
|
||||
cutscene/movie.cpp \
|
||||
cutscene/movie.h \
|
||||
cutscene/mve_audio.cpp \
|
||||
cutscene/mvelib.cpp \
|
||||
cutscene/mvelib.h \
|
||||
cutscene/mveplayer.cpp \
|
||||
cutscene/oggplayer.cpp \
|
||||
cutscene/oggplayer.h \
|
||||
ddsutils/ddsutils.cpp \
|
||||
ddsutils/ddsutils.h \
|
||||
debris/debris.cpp \
|
||||
debris/debris.h \
|
||||
debugconsole/console.cpp \
|
||||
debugconsole/dbugfile.h \
|
||||
debugconsole/timerbar.cpp \
|
||||
debugconsole/timerbar.h \
|
||||
demo/demo.cpp \
|
||||
demo/demo.h \
|
||||
exceptionhandler/exceptionhandler.cpp \
|
||||
exceptionhandler/exceptionhandler.h \
|
||||
external_dll/externalcode.h \
|
||||
external_dll/trackirglobal.cpp \
|
||||
external_dll/trackirglobal.h \
|
||||
fireball/fireballs.cpp \
|
||||
fireball/fireballs.h \
|
||||
fireball/warpineffect.cpp \
|
||||
fs2netd/fs2netd_client.cpp \
|
||||
fs2netd/fs2netd_client.h \
|
||||
fs2netd/tcp_client.cpp \
|
||||
fs2netd/tcp_client.h \
|
||||
fs2netd/tcp_socket.cpp \
|
||||
fs2netd/tcp_socket.h \
|
||||
fs2netd/protocol.h \
|
||||
gamehelp/contexthelp.cpp \
|
||||
gamehelp/contexthelp.h \
|
||||
gamehelp/gameplayhelp.cpp \
|
||||
gamehelp/gameplayhelp.h \
|
||||
gamesequence/gamesequence.cpp \
|
||||
gamesequence/gamesequence.h \
|
||||
gamesnd/eventmusic.cpp \
|
||||
gamesnd/eventmusic.h \
|
||||
gamesnd/gamesnd.cpp \
|
||||
gamesnd/gamesnd.h \
|
||||
globalincs/alphacolors.cpp \
|
||||
globalincs/alphacolors.h \
|
||||
globalincs/crypt.cpp \
|
||||
globalincs/crypt.h \
|
||||
globalincs/def_files.cpp \
|
||||
globalincs/def_files.h \
|
||||
globalincs/fsmemory.cpp \
|
||||
globalincs/fsmemory.h \
|
||||
globalincs/globals.h \
|
||||
globalincs/linklist.h \
|
||||
globalincs/pstypes.h \
|
||||
globalincs/safe_strings.cpp \
|
||||
globalincs/safe_strings.h \
|
||||
globalincs/safe_strings_test.cpp \
|
||||
globalincs/systemvars.cpp \
|
||||
globalincs/systemvars.h \
|
||||
globalincs/version.cpp \
|
||||
globalincs/version.h \
|
||||
graphics/2d.cpp \
|
||||
graphics/2d.h \
|
||||
graphics/font.cpp \
|
||||
graphics/font.h \
|
||||
graphics/generic.cpp \
|
||||
graphics/generic.h \
|
||||
graphics/grbatch.cpp \
|
||||
graphics/grbatch.h \
|
||||
graphics/grinternal.h \
|
||||
graphics/gropengl.cpp \
|
||||
graphics/gropengl.h \
|
||||
graphics/gropenglbmpman.cpp \
|
||||
graphics/gropenglbmpman.h \
|
||||
graphics/gropengldraw.cpp \
|
||||
graphics/gropengldraw.h \
|
||||
graphics/gropenglextension.cpp \
|
||||
graphics/gropenglextension.h \
|
||||
graphics/gropengllight.cpp \
|
||||
graphics/gropengllight.h \
|
||||
graphics/gropenglpostprocessing.cpp \
|
||||
graphics/gropenglpostprocessing.h \
|
||||
graphics/gropenglshader.cpp \
|
||||
graphics/gropenglshader.h \
|
||||
graphics/gropenglstate.cpp \
|
||||
graphics/gropenglstate.h \
|
||||
graphics/gropengltexture.cpp \
|
||||
graphics/gropengltexture.h \
|
||||
graphics/gropengltnl.cpp \
|
||||
graphics/gropengltnl.h \
|
||||
graphics/grstub.cpp \
|
||||
graphics/grstub.h \
|
||||
graphics/line.h \
|
||||
graphics/tmapper.h \
|
||||
hud/hud.cpp \
|
||||
hud/hud.h \
|
||||
hud/hudartillery.cpp \
|
||||
hud/hudartillery.h \
|
||||
hud/hudbrackets.cpp \
|
||||
hud/hudbrackets.h \
|
||||
hud/hudconfig.cpp \
|
||||
hud/hudconfig.h \
|
||||
hud/hudescort.cpp \
|
||||
hud/hudescort.h \
|
||||
hud/hudets.cpp \
|
||||
hud/hudets.h \
|
||||
hud/hudgauges.h \
|
||||
hud/hudlock.cpp \
|
||||
hud/hudlock.h \
|
||||
hud/hudmessage.cpp \
|
||||
hud/hudmessage.h \
|
||||
hud/hudnavigation.cpp \
|
||||
hud/hudnavigation.h \
|
||||
hud/hudobserver.cpp \
|
||||
hud/hudobserver.h \
|
||||
hud/hudparse.cpp \
|
||||
hud/hudparse.h \
|
||||
hud/hudresource.h \
|
||||
hud/hudreticle.cpp \
|
||||
hud/hudreticle.h \
|
||||
hud/hudshield.cpp \
|
||||
hud/hudshield.h \
|
||||
hud/hudsquadmsg.cpp \
|
||||
hud/hudsquadmsg.h \
|
||||
hud/hudtarget.cpp \
|
||||
hud/hudtarget.h \
|
||||
hud/hudtargetbox.cpp \
|
||||
hud/hudtargetbox.h \
|
||||
hud/hudwingmanstatus.cpp \
|
||||
hud/hudwingmanstatus.h \
|
||||
iff_defs/iff_defs.cpp \
|
||||
iff_defs/iff_defs.h \
|
||||
inetfile/cftp.cpp \
|
||||
inetfile/cftp.h \
|
||||
inetfile/chttpget.cpp \
|
||||
inetfile/chttpget.h \
|
||||
inetfile/inetgetfile.cpp \
|
||||
inetfile/inetgetfile.h \
|
||||
io/key.cpp \
|
||||
io/key.h \
|
||||
io/keycontrol.cpp \
|
||||
io/keycontrol.h \
|
||||
io/mouse.cpp \
|
||||
io/mouse.h \
|
||||
io/timer.cpp \
|
||||
io/timer.h \
|
||||
jpgutils/jpgutils.cpp \
|
||||
jpgutils/jpgutils.h \
|
||||
jumpnode/jumpnode.cpp \
|
||||
jumpnode/jumpnode.h \
|
||||
lab/lab.cpp \
|
||||
lab/lab.h \
|
||||
lab/wmcgui.cpp \
|
||||
lab/wmcgui.h \
|
||||
lighting/lighting.cpp \
|
||||
lighting/lighting.h \
|
||||
localization/fhash.cpp \
|
||||
localization/fhash.h \
|
||||
localization/localize.cpp \
|
||||
localization/localize.h \
|
||||
math/fix.cpp \
|
||||
math/fix.h \
|
||||
math/floating.cpp \
|
||||
math/floating.h \
|
||||
math/fvi.cpp \
|
||||
math/fvi.h \
|
||||
math/spline.cpp \
|
||||
math/spline.h \
|
||||
math/staticrand.cpp \
|
||||
math/staticrand.h \
|
||||
math/vecmat.cpp \
|
||||
math/vecmat.h \
|
||||
menuui/barracks.cpp \
|
||||
menuui/barracks.h \
|
||||
menuui/credits.cpp \
|
||||
menuui/credits.h \
|
||||
menuui/fishtank.cpp \
|
||||
menuui/fishtank.h \
|
||||
menuui/mainhallmenu.cpp \
|
||||
menuui/mainhallmenu.h \
|
||||
menuui/mainhalltemp.cpp \
|
||||
menuui/mainhalltemp.h \
|
||||
menuui/optionsmenu.cpp \
|
||||
menuui/optionsmenu.h \
|
||||
menuui/optionsmenumulti.cpp \
|
||||
menuui/optionsmenumulti.h \
|
||||
menuui/playermenu.cpp \
|
||||
menuui/playermenu.h \
|
||||
menuui/readyroom.cpp \
|
||||
menuui/readyroom.h \
|
||||
menuui/snazzyui.cpp \
|
||||
menuui/snazzyui.h \
|
||||
menuui/techmenu.cpp \
|
||||
menuui/techmenu.h \
|
||||
menuui/trainingmenu.cpp \
|
||||
menuui/trainingmenu.h \
|
||||
mission/missionbriefcommon.cpp \
|
||||
mission/missionbriefcommon.h \
|
||||
mission/missioncampaign.cpp \
|
||||
mission/missioncampaign.h \
|
||||
mission/missiongoals.cpp \
|
||||
mission/missiongoals.h \
|
||||
mission/missiongrid.cpp \
|
||||
mission/missiongrid.h \
|
||||
mission/missionhotkey.cpp \
|
||||
mission/missionhotkey.h \
|
||||
mission/missionload.cpp \
|
||||
mission/missionload.h \
|
||||
mission/missionlog.cpp \
|
||||
mission/missionlog.h \
|
||||
mission/missionmessage.cpp \
|
||||
mission/missionmessage.h \
|
||||
mission/missionparse.cpp \
|
||||
mission/missionparse.h \
|
||||
mission/missiontraining.cpp \
|
||||
mission/missiontraining.h \
|
||||
missionui/chatbox.cpp \
|
||||
missionui/chatbox.h \
|
||||
missionui/fictionviewer.cpp \
|
||||
missionui/fictionviewer.h \
|
||||
missionui/missionbrief.cpp \
|
||||
missionui/missionbrief.h \
|
||||
missionui/missioncmdbrief.cpp \
|
||||
missionui/missioncmdbrief.h \
|
||||
missionui/missiondebrief.cpp \
|
||||
missionui/missiondebrief.h \
|
||||
missionui/missionloopbrief.cpp \
|
||||
missionui/missionloopbrief.h \
|
||||
missionui/missionpause.cpp \
|
||||
missionui/missionpause.h \
|
||||
missionui/missionrecommend.cpp \
|
||||
missionui/missionrecommend.h \
|
||||
missionui/missionscreencommon.cpp \
|
||||
missionui/missionscreencommon.h \
|
||||
missionui/missionshipchoice.cpp \
|
||||
missionui/missionshipchoice.h \
|
||||
missionui/missionstats.cpp \
|
||||
missionui/missionstats.h \
|
||||
missionui/missionweaponchoice.cpp \
|
||||
missionui/missionweaponchoice.h \
|
||||
missionui/redalert.cpp \
|
||||
missionui/redalert.h \
|
||||
model/model.h \
|
||||
model/modelanim.cpp \
|
||||
model/modelanim.h \
|
||||
model/modelcollide.cpp \
|
||||
model/modelinterp.cpp \
|
||||
model/modelsinc.h \
|
||||
model/modeloctant.cpp \
|
||||
model/modelread.cpp \
|
||||
nebula/neb.cpp \
|
||||
nebula/neb.h \
|
||||
nebula/neblightning.cpp \
|
||||
nebula/neblightning.h \
|
||||
network/chat_api.cpp \
|
||||
network/chat_api.h \
|
||||
network/multi.cpp \
|
||||
network/multi.h \
|
||||
network/multilag.cpp \
|
||||
network/multilag.h \
|
||||
network/multimsgs.cpp \
|
||||
network/multimsgs.h \
|
||||
network/multiteamselect.cpp \
|
||||
network/multiteamselect.h \
|
||||
network/multiui.cpp \
|
||||
network/multiui.h \
|
||||
network/multiutil.cpp \
|
||||
network/multiutil.h \
|
||||
network/multi_campaign.cpp \
|
||||
network/multi_campaign.h \
|
||||
network/multi_data.cpp \
|
||||
network/multi_data.h \
|
||||
network/multi_dogfight.cpp \
|
||||
network/multi_dogfight.h \
|
||||
network/multi_endgame.cpp \
|
||||
network/multi_endgame.h \
|
||||
network/multi_ingame.cpp \
|
||||
network/multi_ingame.h \
|
||||
network/multi_kick.cpp \
|
||||
network/multi_kick.h \
|
||||
network/multi_log.cpp \
|
||||
network/multi_log.h \
|
||||
network/multi_obj.cpp \
|
||||
network/multi_obj.h \
|
||||
network/multi_observer.cpp \
|
||||
network/multi_observer.h \
|
||||
network/multi_oo.h \
|
||||
network/multi_options.cpp \
|
||||
network/multi_options.h \
|
||||
network/multi_pause.cpp \
|
||||
network/multi_pause.h \
|
||||
network/multi_pinfo.cpp \
|
||||
network/multi_pinfo.h \
|
||||
network/multi_ping.cpp \
|
||||
network/multi_ping.h \
|
||||
network/multi_pmsg.cpp \
|
||||
network/multi_pmsg.h \
|
||||
network/multi_pxo.cpp \
|
||||
network/multi_pxo.h \
|
||||
network/multi_rate.cpp \
|
||||
network/multi_rate.h \
|
||||
network/multi_respawn.cpp \
|
||||
network/multi_respawn.h \
|
||||
network/multi_sexp.cpp \
|
||||
network/multi_sexp.h \
|
||||
network/multi_team.cpp \
|
||||
network/multi_team.h \
|
||||
network/multi_update.h \
|
||||
network/multi_voice.cpp \
|
||||
network/multi_voice.h \
|
||||
network/multi_xfer.cpp \
|
||||
network/multi_xfer.h \
|
||||
network/psnet.cpp \
|
||||
network/psnet.h \
|
||||
network/psnet2.cpp \
|
||||
network/psnet2.h \
|
||||
network/stand_gui.cpp \
|
||||
network/stand_gui-unix.cpp \
|
||||
network/stand_gui.h \
|
||||
object/collidedebrisship.cpp \
|
||||
object/collidedebrisweapon.cpp \
|
||||
object/collideshipship.cpp \
|
||||
object/collideshipweapon.cpp \
|
||||
object/collideweaponweapon.cpp \
|
||||
object/deadobjectdock.cpp \
|
||||
object/deadobjectdock.h \
|
||||
object/objcollide.cpp \
|
||||
object/objcollide.h \
|
||||
object/objectdock.cpp \
|
||||
object/objectdock.h \
|
||||
object/object.cpp \
|
||||
object/object.h \
|
||||
object/objectshield.cpp \
|
||||
object/objectshield.h \
|
||||
object/objectsnd.cpp \
|
||||
object/objectsnd.h \
|
||||
object/objectsort.cpp \
|
||||
object/parseobjectdock.cpp \
|
||||
object/parseobjectdock.h \
|
||||
object/waypoint.cpp \
|
||||
object/waypoint.h \
|
||||
observer/observer.cpp \
|
||||
observer/observer.h \
|
||||
palman/palman.cpp \
|
||||
palman/palman.h \
|
||||
parse/encrypt.cpp \
|
||||
parse/encrypt.h \
|
||||
parse/lua.cpp \
|
||||
parse/lua.h \
|
||||
parse/parselo.cpp \
|
||||
parse/parselo.h \
|
||||
parse/scripting.cpp \
|
||||
parse/scripting.h \
|
||||
parse/sexp.cpp \
|
||||
parse/sexp.h \
|
||||
particle/particle.cpp \
|
||||
particle/particle.h \
|
||||
pcxutils/pcxutils.cpp \
|
||||
pcxutils/pcxutils.h \
|
||||
pngutils/pngutils.cpp \
|
||||
pngutils/pngutils.h \
|
||||
physics/physics.cpp \
|
||||
physics/physics.h \
|
||||
playerman/managepilot.cpp \
|
||||
playerman/managepilot.h \
|
||||
playerman/player.h \
|
||||
playerman/playercontrol.cpp \
|
||||
popup/popup.cpp \
|
||||
popup/popup.h \
|
||||
popup/popupdead.cpp \
|
||||
popup/popupdead.h \
|
||||
radar/radar.cpp \
|
||||
radar/radar.h \
|
||||
radar/radarorb.cpp \
|
||||
radar/radarorb.h \
|
||||
radar/radarsetup.cpp \
|
||||
radar/radarsetup.h \
|
||||
render/3d.h \
|
||||
render/3dclipper.cpp \
|
||||
render/3ddraw.cpp \
|
||||
render/3dinternal.h \
|
||||
render/3dlaser.cpp \
|
||||
render/3dmath.cpp \
|
||||
render/3dsetup.cpp \
|
||||
ship/afterburner.cpp \
|
||||
ship/afterburner.h \
|
||||
ship/awacs.cpp \
|
||||
ship/awacs.h \
|
||||
ship/shield.cpp \
|
||||
ship/ship.cpp \
|
||||
ship/ship.h \
|
||||
ship/shipcontrails.cpp \
|
||||
ship/shipcontrails.h \
|
||||
ship/shipfx.cpp \
|
||||
ship/shipfx.h \
|
||||
ship/shiphit.cpp \
|
||||
ship/shiphit.h \
|
||||
ship/subsysdamage.h \
|
||||
sound/audiostr.cpp \
|
||||
sound/audiostr.h \
|
||||
sound/acm.cpp \
|
||||
sound/acm.h \
|
||||
sound/ds.cpp \
|
||||
sound/ds.h \
|
||||
sound/ds3d.cpp \
|
||||
sound/ds3d.h \
|
||||
sound/dscap.cpp \
|
||||
sound/dscap.h \
|
||||
sound/fsspeech.cpp \
|
||||
sound/fsspeech.h \
|
||||
sound/openal.cpp \
|
||||
sound/openal.h \
|
||||
sound/rtvoice.cpp \
|
||||
sound/rtvoice.h \
|
||||
sound/sound.cpp \
|
||||
sound/sound.h \
|
||||
sound/speech.cpp \
|
||||
sound/speech.h \
|
||||
sound/voicerec.cpp \
|
||||
sound/voicerec.h \
|
||||
sound/ogg/ogg.cpp \
|
||||
sound/ogg/ogg.h \
|
||||
species_defs/species_defs.cpp \
|
||||
species_defs/species_defs.h \
|
||||
starfield/nebula.cpp \
|
||||
starfield/nebula.h \
|
||||
starfield/starfield.cpp \
|
||||
starfield/starfield.h \
|
||||
starfield/supernova.cpp \
|
||||
starfield/supernova.h \
|
||||
stats/medals.cpp \
|
||||
stats/medals.h \
|
||||
stats/scoring.cpp \
|
||||
stats/scoring.h \
|
||||
stats/stats.cpp \
|
||||
stats/stats.h \
|
||||
tgautils/tgautils.cpp \
|
||||
tgautils/tgautils.h \
|
||||
ui/button.cpp \
|
||||
ui/checkbox.cpp \
|
||||
ui/gadget.cpp \
|
||||
ui/icon.cpp \
|
||||
ui/inputbox.cpp \
|
||||
ui/keytrap.cpp \
|
||||
ui/listbox.cpp \
|
||||
ui/radio.cpp \
|
||||
ui/scroll.cpp \
|
||||
ui/slider.cpp \
|
||||
ui/slider2.cpp \
|
||||
ui/ui.h \
|
||||
ui/uidefs.h \
|
||||
ui/uidraw.cpp \
|
||||
ui/uimouse.cpp \
|
||||
ui/window.cpp \
|
||||
weapon/beam.cpp \
|
||||
weapon/beam.h \
|
||||
weapon/corkscrew.cpp \
|
||||
weapon/corkscrew.h \
|
||||
weapon/emp.cpp \
|
||||
weapon/emp.h \
|
||||
weapon/flak.cpp \
|
||||
weapon/flak.h \
|
||||
weapon/muzzleflash.cpp \
|
||||
weapon/muzzleflash.h \
|
||||
weapon/shockwave.cpp \
|
||||
weapon/shockwave.h \
|
||||
weapon/swarm.cpp \
|
||||
weapon/swarm.h \
|
||||
weapon/trails.cpp \
|
||||
weapon/trails.h \
|
||||
weapon/weapons.cpp \
|
||||
weapon/weapon.h
|
||||
|
||||
## conditional includes follow:
|
||||
|
||||
## joystic support sources
|
||||
if FS2_OS_WIN32
|
||||
JOY_SOURCES = \
|
||||
io/joy.cpp \
|
||||
io/joy.h \
|
||||
io/joy_ff.cpp \
|
||||
io/joy_ff.h \
|
||||
io/sw_error.hpp \
|
||||
io/sw_force.h \
|
||||
io/sw_guid.hpp \
|
||||
io/swff_lib.cpp
|
||||
endif
|
||||
|
||||
if FS2_OS_UNIX
|
||||
JOY_SOURCES = \
|
||||
io/joy.h \
|
||||
io/joy_ff.h \
|
||||
io/joy-unix.cpp
|
||||
endif
|
||||
|
||||
## Win32-specific sources
|
||||
if FS2_OS_WIN32
|
||||
WIN32_SOURCES = \
|
||||
directx/vasync.h \
|
||||
directx/vd3dtypes.h \
|
||||
directx/vddraw.h \
|
||||
directx/vdinput.h \
|
||||
directx/vdplay.h \
|
||||
directx/vdplobby.h \
|
||||
directx/vdsetup.h \
|
||||
directx/vdvp.h \
|
||||
globalincs/windebug.cpp \
|
||||
graphics/gl/GLAUX.H \
|
||||
graphics/gl/GLU.H \
|
||||
graphics/gl/Gl.h \
|
||||
graphics/gl/Glext.h \
|
||||
graphics/gl/wglext.h \
|
||||
osapi/monopub.h \
|
||||
osapi/osapi.cpp \
|
||||
osapi/osapi.h \
|
||||
osapi/osregistry.cpp \
|
||||
osapi/osregistry.h \
|
||||
osapi/outwnd.cpp \
|
||||
osapi/outwnd.h
|
||||
endif
|
||||
|
||||
## Unix-specific sources
|
||||
if FS2_OS_UNIX
|
||||
UNIX_SOURCES = \
|
||||
osapi/osapi_unix.cpp \
|
||||
osapi/osapi.h \
|
||||
osapi/osregistry_unix.cpp \
|
||||
osapi/osregistry.h \
|
||||
osapi/outwnd_unix.cpp \
|
||||
osapi/outwnd.h \
|
||||
windows_stub/stubs.cpp \
|
||||
windows_stub/config.h
|
||||
endif
|
||||
|
||||
|
||||
## libcode.a
|
||||
libcode_a_SOURCES = ${FS2_SOURCES} ${JOY_SOURCES} ${WIN32_SOURCES} \
|
||||
${UNIX_SOURCES}
|
||||
|
||||
##
|
||||
## End CODE library
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin MAIN fs2 binary
|
||||
##
|
||||
|
||||
FS2OPEN_SOURCES = \
|
||||
freespace2/freespace.cpp \
|
||||
freespace2/freespace.h \
|
||||
freespace2/levelpaging.cpp \
|
||||
freespace2/levelpaging.h
|
||||
|
||||
fs2_open_d_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_r_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_INF_d_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_INF_r_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_d_LDADD = libcode.a
|
||||
fs2_open_r_LDADD = libcode.a
|
||||
fs2_open_INF_d_LDADD = libcode.a
|
||||
fs2_open_INF_r_LDADD = libcode.a
|
||||
|
||||
##
|
||||
## End MAIN binary
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin wxFRED2 binary
|
||||
##
|
||||
|
||||
wxFRED_SOURCES = \
|
||||
wxfred2/wxfred2.cpp \
|
||||
wxfred2/wxfred2.h \
|
||||
wxfred2/fredframe.cpp \
|
||||
wxfred2/fredframe.h \
|
||||
wxfred2/wxfred_xrc.cpp \
|
||||
wxfred2/wxfred_xrc.h
|
||||
|
||||
wxFRED2_d_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_r_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_INF_d_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_INF_r_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_d_LDADD = libcode.a
|
||||
wxFRED2_r_LDADD = libcode.a
|
||||
wxFRED2_INF_d_LDADD = libcode.a
|
||||
wxFRED2_INF_r_LDADD = libcode.a
|
||||
|
||||
##
|
||||
## End wxFRED2 binary
|
||||
##
|
||||
###############################################################################
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
// The code in here is just for bookeeping, allocating
|
||||
// ai slots and linking them to ships.
|
||||
// See AiCode.cpp for the actual AI code.
|
||||
|
||||
#include "ai/ai.h"
|
||||
#include "object/object.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
|
||||
|
||||
int Total_goal_ship_names = 0;
|
||||
char Goal_ship_names[MAX_GOAL_SHIP_NAMES][NAME_LENGTH];
|
||||
ai_info Ai_info[MAX_AI_INFO];
|
||||
ai_info *Player_ai;
|
||||
|
||||
// Return index of free AI slot.
|
||||
// Return -1 if no free slot.
|
||||
int ai_get_slot(int shipnum)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_AI_INFO ; i++)
|
||||
if (Ai_info[i].shipnum == -1) {
|
||||
Ai_info[i].shipnum = shipnum;
|
||||
return i;
|
||||
}
|
||||
|
||||
Warning( LOCATION, "Couldn't get AI slot" );
|
||||
Int3();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Releases an AI slot to be used by someone else.
|
||||
// Only modifies in Ai_info struct. Does not modify hook in ship.
|
||||
void ai_free_slot(int ai_index)
|
||||
{
|
||||
Assert( (ai_index >= 0) && (ai_index < MAX_AI_INFO) );
|
||||
|
||||
Ai_info[ai_index].shipnum = -1;
|
||||
}
|
||||
|
||||
int get_wingnum(int objnum)
|
||||
{
|
||||
int shipnum, ai_index;
|
||||
|
||||
shipnum = Objects[objnum].instance;
|
||||
|
||||
ai_index = Ships[shipnum].ai_index;
|
||||
|
||||
return Ai_info[ai_index].wing;
|
||||
}
|
||||
|
||||
void set_wingnum(int objnum, int wingnum)
|
||||
{
|
||||
int shipnum, ai_index;
|
||||
|
||||
Assert(Objects[objnum].type == OBJ_SHIP);
|
||||
|
||||
shipnum = Objects[objnum].instance;
|
||||
|
||||
Assert((shipnum >= 0) && (shipnum < MAX_SHIPS));
|
||||
|
||||
ai_index = Ships[shipnum].ai_index;
|
||||
|
||||
Assert( (ai_index >= 0) && (ai_index < MAX_AI_INFO) );
|
||||
|
||||
Ai_info[ai_index].wing = wingnum;
|
||||
}
|
||||
|
||||
char *ai_get_goal_ship_name(char *name, int *index)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < Total_goal_ship_names; i++)
|
||||
if (!stricmp(name, Goal_ship_names[i])) {
|
||||
*index = i;
|
||||
return Goal_ship_names[i];
|
||||
}
|
||||
|
||||
Assert(Total_goal_ship_names < MAX_GOAL_SHIP_NAMES);
|
||||
Assertion(strlen(name) < NAME_LENGTH - 1, "Ship name %s is too long. Needs to be 31 characters or less.", name);
|
||||
i = Total_goal_ship_names++;
|
||||
strcpy_s(Goal_ship_names[i], name);
|
||||
*index = i;
|
||||
return Goal_ship_names[i];
|
||||
}
|
||||
-710
@@ -1,710 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _AI_H
|
||||
#define _AI_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "ai/ai_profiles.h"
|
||||
#include "physics/physics.h"
|
||||
|
||||
struct ship_weapon;
|
||||
struct ship_subsys;
|
||||
struct object;
|
||||
struct ship_info;
|
||||
|
||||
#define AI_DEFAULT_CLASS 3 // default AI class for new ships (Fred)
|
||||
|
||||
#define AIF_FORMATION_WING (1 << 0) // Fly in formation as part of wing.
|
||||
#define AIF_AWAITING_REPAIR (1 << 1) // Awaiting a repair ship.
|
||||
#define AIF_BEING_REPAIRED (1 << 2) // Currently docked with repair ship.
|
||||
#define AIF_REPAIRING (1 << 3) // Repairing a ship (or going to repair a ship)
|
||||
#define AIF_SEEK_LOCK (1 << 4) // set if should focus on gaining aspect lock, not hitting with lasers
|
||||
#define AIF_FORMATION_OBJECT (1 << 5) // Fly in formation off a specific object.
|
||||
#define AIF_TEMPORARY_IGNORE (1 << 6) // Means current ignore_objnum is only temporary, not an order from the player.
|
||||
#define AIF_USE_EXIT_PATH (1 << 7) // Used by path code, to flag path as an exit path
|
||||
#define AIF_USE_STATIC_PATH (1 << 8) // Used by path code, use fixed path, don't try to recreate
|
||||
#define AIF_TARGET_COLLISION (1 << 9) // Collided with aip->target_objnum last frame. Avoid that ship for half a second or so.
|
||||
#define AIF_UNLOAD_SECONDARIES (1 << 10) // Fire secondaries as fast as possible!
|
||||
#define AIF_ON_SUBSYS_PATH (1 << 11) // Current path leads to a subsystem
|
||||
#define AIF_AVOID_SHOCKWAVE_SHIP (1 << 12) // Avoid an existing shockwave from a ship.
|
||||
#define AIF_AVOID_SHOCKWAVE_WEAPON (1 << 13) // Avoid an expected shockwave from a weapon. shockwave_object field contains object index.
|
||||
#define AIF_AVOID_SHOCKWAVE_STARTED (1 << 14) // Already started avoiding shockwave, don't keep deciding whether to avoid.
|
||||
#define AIF_ATTACK_SLOWLY (1 << 15) // Move slowly while attacking.
|
||||
#define AIF_REPAIR_OBSTRUCTED (1 << 16) // Ship wants to be repaired, but path is obstructed.
|
||||
#define AIF_KAMIKAZE (1 << 17) // Crash into target
|
||||
#define AIF_NO_DYNAMIC (1 << 18) // Not allowed to get dynamic goals
|
||||
#define AIF_AVOIDING_SMALL_SHIP (1 << 19) // Avoiding a player ship.
|
||||
#define AIF_AVOIDING_BIG_SHIP (1 << 20) // Avoiding a large ship.
|
||||
#define AIF_BIG_SHIP_COLLIDE_RECOVER_1 (1 << 21) // Collided into a big ship. Recovering by flying away.
|
||||
#define AIF_BIG_SHIP_COLLIDE_RECOVER_2 (1 << 22) // Collided into a big ship. Fly towards big ship sphere perimeter.
|
||||
#define AIF_STEALTH_PURSUIT (1 << 23) // Ai is trying to fight stealth ship
|
||||
|
||||
// Goober5000
|
||||
#define AIF_UNLOAD_PRIMARIES (1 << 24) // Fire primaries as fast as possible!
|
||||
#define AIF_TRYING_UNSUCCESSFULLY_TO_WARP (1 << 25) // Trying to warp, but can't warp at the moment
|
||||
|
||||
#define AIF_AVOID_SHOCKWAVE (AIF_AVOID_SHOCKWAVE_SHIP | AIF_AVOID_SHOCKWAVE_WEAPON)
|
||||
#define AIF_FORMATION (AIF_FORMATION_WING | AIF_FORMATION_OBJECT)
|
||||
|
||||
// dock_orient_and_approach() modes.
|
||||
#define DOA_APPROACH 1 // Approach the current point on the path (aip->path_cur)
|
||||
#define DOA_DOCK 2 // Dock with goal object.
|
||||
#define DOA_UNDOCK_1 3 // Begin undocking with goal object. Just move away.
|
||||
#define DOA_UNDOCK_2 4 // Secondary undocking. Move away.
|
||||
#define DOA_UNDOCK_3 5 // Tertiary undocking. Move away and orient away.
|
||||
#define DOA_DOCK_STAY 6 // Rigidly maintain position in dock bay.
|
||||
|
||||
// Type values for ai_dock_with_object() dock_type parameter.
|
||||
#define AIDO_DOCK 1 // Set goal of docking with object.
|
||||
#define AIDO_DOCK_NOW 2 // Immediately move into dock position. For ships that start mission docked.
|
||||
#define AIDO_UNDOCK 3 // Set goal of undocking with object.
|
||||
|
||||
// Submodes for seeking safety.
|
||||
#define AISS_1 41 // Pick a spot to fly to.
|
||||
#define AISS_2 42 // Flying to spot.
|
||||
#define AISS_3 43 // Gotten near spot, fly about there.
|
||||
#define AISS_1a 44 // Pick a new nearby spot because we are endangered, then go to AISS_2
|
||||
|
||||
#define MAX_AI_GOALS 5
|
||||
|
||||
// types of ai goals -- tyese types will help us to determination on which goals should
|
||||
// have priority over others (i.e. when a player issues a goal to a wing, then a seperate
|
||||
// goal to a ship in that wing). We would probably use this type in conjunction with
|
||||
// goal priority to establish which goal to follow
|
||||
#define AIG_TYPE_EVENT_SHIP 1 // from mission event direct to ship
|
||||
#define AIG_TYPE_EVENT_WING 2 // from mission event direct to wing
|
||||
#define AIG_TYPE_PLAYER_SHIP 3 // from player direct to ship
|
||||
#define AIG_TYPE_PLAYER_WING 4 // from player direct to wing
|
||||
#define AIG_TYPE_DYNAMIC 5 // created on the fly
|
||||
|
||||
// flags for AI_GOALS
|
||||
#define AIGF_DOCKER_INDEX_VALID (1<<0) // when set, index field for docker is valid
|
||||
#define AIGF_DOCKEE_INDEX_VALID (1<<1) // when set, index field for dockee is valid
|
||||
#define AIGF_GOAL_ON_HOLD (1<<2) // when set, this goal cannot currently be satisfied, although it could be in the future
|
||||
#define AIGF_SUBSYS_NEEDS_FIXUP (1<<3) // when set, the subsystem index (for a destroy subsystem goal) is invalid and must be gotten from the subsys name stored in docker.name field!!
|
||||
#define AIGF_GOAL_OVERRIDE (1<<4) // paired with AIG_TYPE_DYNAMIC to mean this goal overrides any other goal
|
||||
#define AIGF_PURGE (1<<5) // purge this goal next time we process
|
||||
#define AIGF_GOALS_PURGED (1<<6) // this goal has already caused other goals to get purged
|
||||
#define AIGF_DOCK_SOUND_PLAYED (1<<7) // Goober5000 - replacement for AL's hack ;)
|
||||
|
||||
#define AIGF_DOCK_INDEXES_VALID (AIGF_DOCKER_INDEX_VALID|AIGF_DOCKEE_INDEX_VALID)
|
||||
|
||||
// Flags to ai_turn_towards_vector().
|
||||
#define AITTV_FAST (1<<0) // Turn fast, not slowed down based on skill level.
|
||||
#define AITTV_VIA_SEXP (1<<1) // Goober5000 - via sexp
|
||||
#define AITTV_IGNORE_BANK (1<<2) // Goober5000 - ignore bank when turning
|
||||
|
||||
#define KAMIKAZE_HULL_ON_DEATH -1000.0f // Hull strength ship gets set to if it crash-dies.
|
||||
|
||||
// flags for possible ai overrides
|
||||
#define AIORF_FULL (1<<0) // Full sexp control
|
||||
#define AIORF_ROLL (1<<1) // Sexp forced roll maneuver
|
||||
#define AIORF_PITCH (1<<2) // Sexp forced pitch change
|
||||
#define AIORF_HEADING (1<<3) // Sexp forced heading change
|
||||
#define AIORF_FULL_LAT (1<<4) // full control over up/side/forward movement
|
||||
#define AIORF_UP (1<<5) // vertical movement
|
||||
#define AIORF_SIDEWAYS (1<<6) // horizontal movement
|
||||
#define AIORF_FORWARD (1<<7) // forward movement
|
||||
|
||||
// structure for AI goals
|
||||
typedef struct ai_goal {
|
||||
int signature; // Unique identifier. All goals ever created (per mission) have a unique signature.
|
||||
int ai_mode; // one of the AIM_* modes for this goal
|
||||
int ai_submode; // maybe need a submode
|
||||
int type; // one of the AIG_TYPE_* values above
|
||||
int flags; // one of the AIGF_* values above
|
||||
fix time; // time at which this goal was issued.
|
||||
int priority; // how important is this goal -- number 0 - 100
|
||||
char *ship_name; // name of the ship that this goal acts upon
|
||||
int ship_name_index; // index of ship_name in Goal_ship_names[][]
|
||||
int wp_index; // index into waypoints list of waypoints that this ship might fly.
|
||||
int weapon_signature; // signature of weapon this ship might be chasing. Paired with above value to get target.
|
||||
|
||||
// unions for docking stuff.
|
||||
// (AIGF_DOCKER_INDEX_VALID and AIGF_DOCKEE_INDEX_VALID tell us to use indexes; otherwise we use names)
|
||||
// these are the dockpoints used on the docker and dockee ships, not the ships themselves
|
||||
union {
|
||||
char *name;
|
||||
int index;
|
||||
} docker;
|
||||
|
||||
union {
|
||||
char *name;
|
||||
int index;
|
||||
} dockee;
|
||||
|
||||
} ai_goal;
|
||||
|
||||
#define MAX_GOAL_SHIP_NAMES 100
|
||||
|
||||
#define AIM_CHASE 0
|
||||
#define AIM_EVADE 1
|
||||
#define AIM_GET_BEHIND 2
|
||||
#define AIM_STAY_NEAR 3 // Stay near another ship.
|
||||
#define AIM_STILL 4 // Sit still. Don't move. Hold your breath. Don't blink.
|
||||
#define AIM_GUARD 5 // Guard an object
|
||||
#define AIM_AVOID 6 // Avoid an object
|
||||
#define AIM_WAYPOINTS 7 // Fly waypoints
|
||||
#define AIM_DOCK 8 // Dock with ship.
|
||||
#define AIM_NONE 9 // Uh, do nothing.
|
||||
#define AIM_BIGSHIP 10 // Like a capital ship, doesn't focus on one ship.
|
||||
#define AIM_PATH 11 // Follow path on ship
|
||||
#define AIM_BE_REARMED 12 // Allow self to be rearmed
|
||||
#define AIM_SAFETY 13 // Seek safety at periphery of battle
|
||||
#define AIM_EVADE_WEAPON 14 // Evade a weapon.
|
||||
#define AIM_STRAFE 15 // attack a big ship by strafing it
|
||||
#define AIM_PLAY_DEAD 16 // Play dead. Get it? Don't move, fire, etc.
|
||||
#define AIM_BAY_EMERGE 17 // Emerging from a fighter bay, following path to do so
|
||||
#define AIM_BAY_DEPART 18 // Departing to a fighter bay, following path to do so
|
||||
#define AIM_SENTRYGUN 19 // AI mode for sentry guns only (floating turrets)
|
||||
#define AIM_WARP_OUT 20 // Commence warp out sequence. Point in legal direction. Then call John's code.
|
||||
#define AIM_FLY_TO_SHIP 21 // [Kazan] Fly to a ship, doesn't matter if it's hostile or friendly -- for Autopilot usage
|
||||
|
||||
#define MAX_AI_BEHAVIORS 22 // Number of AIM_xxxx types
|
||||
|
||||
#define MAX_WAYPOINTS_PER_LIST 20
|
||||
#define MAX_ENEMY_DISTANCE 2500.0f // maximum distance from which a ship will pursue an enemy.
|
||||
|
||||
#define AI_GOAL_NONE -1
|
||||
|
||||
#define AI_ACTIVE_GOAL_DYNAMIC 999
|
||||
|
||||
typedef struct ai_class {
|
||||
char name[NAME_LENGTH];
|
||||
float ai_accuracy[NUM_SKILL_LEVELS];
|
||||
float ai_evasion[NUM_SKILL_LEVELS];
|
||||
float ai_courage[NUM_SKILL_LEVELS];
|
||||
float ai_patience[NUM_SKILL_LEVELS];
|
||||
|
||||
//SUSHI: These were originally in AI_Profiles, adding the option to override in AI.tbl
|
||||
//INT_MIN and FLT_MIN represent the "not set" state for which defaults are used instead.
|
||||
float ai_cmeasure_fire_chance[NUM_SKILL_LEVELS];
|
||||
float ai_in_range_time[NUM_SKILL_LEVELS];
|
||||
float ai_link_ammo_levels_maybe[NUM_SKILL_LEVELS];
|
||||
float ai_link_ammo_levels_always[NUM_SKILL_LEVELS];
|
||||
float ai_primary_ammo_burst_mult[NUM_SKILL_LEVELS];
|
||||
float ai_link_energy_levels_maybe[NUM_SKILL_LEVELS];
|
||||
float ai_link_energy_levels_always[NUM_SKILL_LEVELS];
|
||||
fix ai_predict_position_delay[NUM_SKILL_LEVELS];
|
||||
float ai_shield_manage_delay[NUM_SKILL_LEVELS];
|
||||
float ai_ship_fire_delay_scale_friendly[NUM_SKILL_LEVELS];
|
||||
float ai_ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS];
|
||||
float ai_ship_fire_secondary_delay_scale_friendly[NUM_SKILL_LEVELS];
|
||||
float ai_ship_fire_secondary_delay_scale_hostile[NUM_SKILL_LEVELS];
|
||||
float ai_turn_time_scale[NUM_SKILL_LEVELS];
|
||||
float ai_glide_attack_percent[NUM_SKILL_LEVELS];
|
||||
float ai_circle_strafe_percent[NUM_SKILL_LEVELS];
|
||||
float ai_glide_strafe_percent[NUM_SKILL_LEVELS];
|
||||
float ai_random_sidethrust_percent[NUM_SKILL_LEVELS];
|
||||
float ai_stalemate_time_thresh[NUM_SKILL_LEVELS];
|
||||
float ai_stalemate_dist_thresh[NUM_SKILL_LEVELS];
|
||||
int ai_chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
|
||||
float ai_max_aim_update_delay[NUM_SKILL_LEVELS];
|
||||
float ai_turret_max_aim_update_delay[NUM_SKILL_LEVELS];
|
||||
int ai_profile_flags; //Holds the state of flags that are set
|
||||
int ai_profile_flags_set; //Holds which flags are set and which are just left alone
|
||||
int ai_profile_flags2;
|
||||
int ai_profile_flags2_set;
|
||||
|
||||
//SUSHI: These are optional overrides to an AI class to prevent the automatic scaling based on AI class index
|
||||
int ai_aburn_use_factor[NUM_SKILL_LEVELS];
|
||||
float ai_shockwave_evade_chance[NUM_SKILL_LEVELS];
|
||||
float ai_get_away_chance[NUM_SKILL_LEVELS];
|
||||
float ai_secondary_range_mult[NUM_SKILL_LEVELS];
|
||||
bool ai_class_autoscale; //Defaults to true, but can be turned off in order to disable extra scaling of some AI behaviors
|
||||
//based on AI class index
|
||||
} ai_class;
|
||||
|
||||
// Submode definitions.
|
||||
// Note: These need to be renamed to be of the form: AIS_mode_xxxx
|
||||
#define SM_CONTINUOUS_TURN 1 // takes parm: vector_id {0..3 = right, -right, up, -up}
|
||||
#define SM_ATTACK 2
|
||||
#define SM_EVADE_SQUIGGLE 3
|
||||
#define SM_EVADE_BRAKE 4
|
||||
#define SM_EVADE 5
|
||||
#define SM_SUPER_ATTACK 6
|
||||
#define SM_AVOID 7
|
||||
#define SM_GET_BEHIND 8
|
||||
#define SM_GET_AWAY 9
|
||||
#define SM_EVADE_WEAPON 10 // Evade incoming weapon
|
||||
#define SM_FLY_AWAY 11 // Fly away from target_objnum
|
||||
#define SM_ATTACK_FOREVER 12 // Engine subsystem destroyed, so attack, never evading, avoiding, etc.
|
||||
#define SM_STEALTH_FIND 13 // Stealth ship is "targeted", but not visible, so try to find based on predicted pos
|
||||
#define SM_STEALTH_SWEEP 14 // General sweep, looking for stealth after not visible for some time.
|
||||
#define SM_BIG_APPROACH 15 // Big ship approaches another
|
||||
#define SM_BIG_CIRCLE 16 // Big ship flies circle around other big ship to get good angle to go parallel
|
||||
#define SM_BIG_PARALLEL 17 // Big ship flies parallel to another
|
||||
|
||||
//SUSHI: Attack submodes (besides those implicitly listed above)
|
||||
#define AIS_CHASE_GLIDEATTACK 18 // Ship uses glide to move in a constant direction while pointing and shooting at target
|
||||
#define AIS_CHASE_CIRCLESTRAFE 19 // Attempt a circle-strafe on the target
|
||||
|
||||
// Submodes for docking behavior
|
||||
#define AIS_DOCK_0 21
|
||||
#define AIS_DOCK_1 22
|
||||
#define AIS_DOCK_2 23
|
||||
#define AIS_DOCK_3 24
|
||||
//#define AIS_DOCK_3A 25
|
||||
#define AIS_DOCK_4 26 // Only for rearm/repair.
|
||||
#define AIS_DOCK_4A 27 // Only for not rearm/repair. MK, 7/15/97
|
||||
#define AIS_UNDOCK_0 30
|
||||
#define AIS_UNDOCK_1 31
|
||||
#define AIS_UNDOCK_2 32
|
||||
#define AIS_UNDOCK_3 33
|
||||
#define AIS_UNDOCK_4 34
|
||||
|
||||
// Submodes for Guard behavior
|
||||
#define AIS_GUARD_PATROL 101
|
||||
#define AIS_GUARD_ATTACK 102
|
||||
#define AIS_GUARD_2 103
|
||||
#define AIS_GUARD_STATIC 104 // maintain current relative position to guard object, if possible
|
||||
|
||||
// Submodes for strafing big ships behavior (AIM_STRAFE)
|
||||
#define AIS_STRAFE_ATTACK 201 // fly towards target and attack
|
||||
#define AIS_STRAFE_AVOID 202 // fly evasive vector to avoid incoming fire
|
||||
#define AIS_STRAFE_RETREAT1 203 // fly away from attack point
|
||||
#define AIS_STRAFE_RETREAT2 204
|
||||
#define AIS_STRAFE_POSITION 205 // re-position to resume strafing attack
|
||||
#define AIS_STRAFE_GLIDE_ATTACK 206 // SUSHI: Glide strafe atack
|
||||
|
||||
#define WPF_REPEAT (1 << 0)
|
||||
#define WPF_BACKTRACK (1 << 1)
|
||||
|
||||
#define PD_FORWARD 1
|
||||
#define PD_BACKWARD -1
|
||||
|
||||
#define MIN_TRACKABLE_ASPECT_DOT 0.992f // dot of fvec and vec_to_enemy to progress towards aspect lock
|
||||
|
||||
// Submodes for warping out.
|
||||
#define AIS_WARP_1 300 // Make sure there is no obstruction to warping out.
|
||||
#define AIS_WARP_2 301
|
||||
#define AIS_WARP_3 302
|
||||
#define AIS_WARP_4 303
|
||||
#define AIS_WARP_5 304
|
||||
#define AIS_DEPART_TO_BAY 305
|
||||
|
||||
// A node on a path.
|
||||
// Contains global location of point.
|
||||
// Contains hooks back to original path information.
|
||||
// This hook is used to extract information on the point such as whether it is
|
||||
// protected by turrets.
|
||||
typedef struct pnode {
|
||||
vec3d pos;
|
||||
int path_num; // path number from polymodel, ie in polymodel, paths[path_num]
|
||||
int path_index; // index in original model path of point, ie in model_path, use verts[path_index]
|
||||
} pnode;
|
||||
|
||||
#define MAX_PATH_POINTS 1000
|
||||
extern pnode Path_points[MAX_PATH_POINTS];
|
||||
extern pnode *Ppfp; // Free pointer in path points.
|
||||
|
||||
// Goober5000 (based on the "you can only remember 7 things in short-term memory" assumption)
|
||||
#define MAX_IGNORE_NEW_OBJECTS 7
|
||||
|
||||
typedef struct ai_info {
|
||||
int ai_flags; // Special flags for AI behavior.
|
||||
int shipnum; // Ship using this slot, -1 means none.
|
||||
int type; //
|
||||
int wing; // Member of what wing? -1 means none.
|
||||
|
||||
int behavior; // AI behavior; vestigial field from early development of FS1
|
||||
int mode;
|
||||
int previous_mode;
|
||||
int mode_time; // timestamp at which current mode elapses.
|
||||
int target_objnum; // object index of current target.
|
||||
int target_signature; // Signature of current target.
|
||||
int previous_target_objnum; // On 5/19/97, only used for player.
|
||||
|
||||
int stealth_last_cheat_visible_stamp; // when within 100m, always update pos and velocity, with error increasing for increasing time from last legal visible
|
||||
int stealth_last_visible_stamp;
|
||||
float stealth_sweep_box_size;
|
||||
vec3d stealth_last_pos;
|
||||
vec3d stealth_velocity;
|
||||
|
||||
float previous_dot_to_enemy; // dot(fvec, vec_to_enemy) last frame
|
||||
float target_time; // Amount of time continuously targeting this ship.
|
||||
|
||||
int enemy_wing; // When picking an enemy wing, only allow to be in enemy_wing, unless == -1, in which case don't care.
|
||||
int attacker_objnum;
|
||||
|
||||
int goal_objnum; // mode specific goal. In DOCK, ship to dock with.
|
||||
int goal_signature;
|
||||
|
||||
int guard_objnum; // Ship to guard.
|
||||
int guard_signature; // Signature of ship to guard.
|
||||
int guard_wingnum; // Wing to guard. guard_objnum set to leader.
|
||||
|
||||
int ignore_objnum; // ship to be ignored, based on player order. UNUSED_OBJNUM if none. -(wing_num+1) if ignoring wing.
|
||||
int ignore_signature; // signature of ship to be ignored
|
||||
|
||||
// Goober5000
|
||||
int ignore_new_objnums[MAX_IGNORE_NEW_OBJECTS];
|
||||
int ignore_new_signatures[MAX_IGNORE_NEW_OBJECTS];
|
||||
|
||||
int ai_class; // Class. Might be override of default.
|
||||
|
||||
// Probably become obsolete, to be replaced by path_start, path_cur, etc.
|
||||
int wp_list; // waypoint list index
|
||||
int wp_index; // waypoint index in list
|
||||
int wp_flags; // waypoint flags, see WPF_xxxx
|
||||
int wp_dir; // 1 or -1, amount to add to get to next waypoint index.
|
||||
int waypoint_speed_cap; // -1 no cap, otherwise cap - changed to int by Goober5000
|
||||
|
||||
// Path following information
|
||||
int path_start; // Index into global array, start of path.
|
||||
int path_cur; // Index into global array, current location in path.
|
||||
int path_length; // Number of links in this path.
|
||||
int path_dir; // PD_FORWARD, PD_BACKWARD
|
||||
int path_flags; // loop, backtrack, whatever else.
|
||||
int path_objnum; // Object of interest. It's model contains the path.
|
||||
int path_goal_obj_hash; // Hash value of goal object when global path created.
|
||||
fix path_next_create_time; // Next time at which we'll create a global path.
|
||||
vec3d path_create_pos; // Object's position at time of global path creation.
|
||||
matrix path_create_orient; // Object's orientation at time of global path creation.
|
||||
int mp_index; // Model path index. Index in polymodel:model_paths
|
||||
fix path_next_check_time; // Last time checked to see if would collide with model.
|
||||
int path_goal_dist; // minimum distance to first path point to consider path reached
|
||||
int path_subsystem_next_check; // timestamp to next check if subsystem is still visible
|
||||
|
||||
int submode;
|
||||
int previous_submode; // previous submode, get it?
|
||||
float best_dot_to_enemy; // best dot product to enemy in last BEST_DOT_TIME seconds
|
||||
float best_dot_from_enemy; // best dot product for enemy to player in last BEST_DOT_TIME seconds
|
||||
fix best_dot_to_time; // time at which best dot occurred
|
||||
fix best_dot_from_time; // time at which best dot occurred
|
||||
fix submode_start_time; // time at which we entered the current submode
|
||||
int submode_parm0; // parameter specific to current submode
|
||||
int submode_parm1; // SUSHI: Another optional parameter
|
||||
fix next_predict_pos_time; // Next time to predict position.
|
||||
|
||||
//SUSHI: like last_predicted_enemy_pos, but for aiming (which currently ignores predicted position)
|
||||
//Unlike the predicted position stuff, also takes into account velocity
|
||||
//Only used against small ships
|
||||
fix next_aim_pos_time;
|
||||
vec3d last_aim_enemy_pos;
|
||||
vec3d last_aim_enemy_vel;
|
||||
|
||||
ai_goal goals[MAX_AI_GOALS];
|
||||
int active_goal; // index of active goal, -1 if none, AI_ACTIVE_GOAL_DYNAMIC if dynamic (runtime-created) goal
|
||||
int goal_check_time; // timer used for processing goals for this ai object
|
||||
|
||||
vec3d last_predicted_enemy_pos; // Where he thought enemy was last time.
|
||||
float time_enemy_in_range; // Amount of time enemy continuously in "sight", near crosshair.
|
||||
float time_enemy_near; // SUSHI: amount of time enemy continuously "near" the player
|
||||
fix last_attack_time; // Missiontime of last time this ship attacked its enemy.
|
||||
fix last_hit_time; // Missiontime of last time this ship was hit by anyone.
|
||||
int last_hit_quadrant; // Shield section of last hit.
|
||||
fix last_hit_target_time; // Missiontime of last time this ship successfully hit target.
|
||||
int hitter_objnum; // Object index of ship that hit this ship last time.
|
||||
int hitter_signature; // Signature of hitter. Prevents stupidity if hitter gets killed.
|
||||
fix resume_goal_time; // Time at which to resume interrupted goal, if nothing else intervenes.
|
||||
float prev_accel; // Acceleration last frame.
|
||||
float prev_dot_to_goal; // dot of fvec to goal last frame, used to see if making progress towards goal.
|
||||
vec3d goal_point; // Used in AIM_SAFETY, AIM_STILL and in circling.
|
||||
vec3d prev_goal_point; // Previous location of goal point, used at least for evading.
|
||||
|
||||
//Values copied from the AI class
|
||||
float ai_accuracy, ai_evasion, ai_courage, ai_patience;
|
||||
int ai_aburn_use_factor;
|
||||
float ai_shockwave_evade_chance;
|
||||
float ai_get_away_chance;
|
||||
float ai_secondary_range_mult;
|
||||
bool ai_class_autoscale;
|
||||
|
||||
//SUSHI: These were originally in AI_Profiles, adding the option to override in AI.tbl
|
||||
float ai_cmeasure_fire_chance;
|
||||
float ai_in_range_time;
|
||||
float ai_link_ammo_levels_maybe;
|
||||
float ai_link_ammo_levels_always;
|
||||
float ai_primary_ammo_burst_mult;
|
||||
float ai_link_energy_levels_maybe;
|
||||
float ai_link_energy_levels_always;
|
||||
fix ai_predict_position_delay;
|
||||
float ai_shield_manage_delay;
|
||||
float ai_ship_fire_delay_scale_friendly;
|
||||
float ai_ship_fire_delay_scale_hostile;
|
||||
float ai_ship_fire_secondary_delay_scale_friendly;
|
||||
float ai_ship_fire_secondary_delay_scale_hostile;
|
||||
float ai_turn_time_scale;
|
||||
float ai_glide_attack_percent;
|
||||
float ai_circle_strafe_percent;
|
||||
float ai_glide_strafe_percent;
|
||||
float ai_random_sidethrust_percent;
|
||||
float ai_stalemate_time_thresh;
|
||||
float ai_stalemate_dist_thresh;
|
||||
int ai_chance_to_use_missiles_on_plr;
|
||||
float ai_max_aim_update_delay;
|
||||
float ai_turret_max_aim_update_delay;
|
||||
int ai_profile_flags; //Holds AI_Profiles flags (possibly overriden by AI class) that actually apply to AI
|
||||
int ai_profile_flags2;
|
||||
|
||||
|
||||
union {
|
||||
float lead_scale; // Amount to lead current opponent by.
|
||||
float stay_near_distance; // Distance to stay within for AIM_STAY_NEAR mode.
|
||||
};
|
||||
|
||||
ship_subsys* targeted_subsys; // Targeted subobject on current target. NULL if none;
|
||||
ship_subsys* last_subsys_target; // last known subsystem target
|
||||
int targeted_subsys_parent; // Parent objnum of subobject, not necessarily targeted
|
||||
|
||||
float aspect_locked_time; // Time towards acquiring lock for current_target
|
||||
|
||||
// ship_subsys *targeted_subobject; // subsystem to attack
|
||||
// int attack_subsystem_parent; // objnum of the object containing the attack_subsystem
|
||||
|
||||
// Goober5000
|
||||
int support_ship_objnum; // objnum of support ship docking with us, or (if we're a support ship) object we're docking to
|
||||
int support_ship_signature; // signature of the same
|
||||
|
||||
int danger_weapon_objnum; // Closest objnum of weapon fired at this ship.
|
||||
int danger_weapon_signature; // Signature of object danger_weapon_objnum.
|
||||
|
||||
vec3d guard_vec; // vector to object being guarded, only used in AIS_GUARD_STATIC submode
|
||||
int nearest_locked_object; // Nearest locked object.
|
||||
float nearest_locked_distance; // Distance to nearest locked object.
|
||||
|
||||
float current_target_distance; // Distance of current target from player
|
||||
int current_target_is_locked; // Flag to indicate whether the current target is locked for missile fire
|
||||
int current_target_dist_trend; // Tracks whether distance to target is increasing or decreasing
|
||||
int current_target_speed_trend; // Tracks whether speed of target is increasing or decreasing
|
||||
|
||||
float last_dist; // last frame's distance between player and target
|
||||
float last_speed; // last frame's target speed
|
||||
int last_secondary_index; // needed for secondary weapon change check
|
||||
int last_target;
|
||||
|
||||
int rearm_first_missile; // flag to show that reloading of missilies hasn't begun yet
|
||||
int rearm_first_ballistic_primary; // flag to show that reloading of ballistic primaries hasn't begun yet
|
||||
int rearm_release_delay; // timestamp used to delay separation of ships after rearm complete
|
||||
|
||||
fix afterburner_stop_time; // Missiontime to turn off afterburner
|
||||
int last_objsig_hit; // The object number signature of the ship last hit by this ship
|
||||
int ignore_expire_timestamp; // Timestamp at which temporary ignore (AIF_TEMPORARY_IGNORE) expires.
|
||||
int warp_out_timestamp; // Timestamp at which this ship is to warp out.
|
||||
int next_rearm_request_timestamp; // Timestamp at which ship might next request rearm.
|
||||
int primary_select_timestamp; // When to next select a primary weapon.
|
||||
int secondary_select_timestamp; // When to next select a secondary weapon.
|
||||
|
||||
int scan_for_enemy_timestamp; // When to next look for enemy fighters if sitting still while pounding
|
||||
// on a bigship. SCAN_FIGHTERS_INTERVAL is defined in AiBig.h
|
||||
int choose_enemy_timestamp; // Time at which it is next legal to choose a new enemy (does not apply
|
||||
// to special situations, like getting hit by a weapon)
|
||||
int force_warp_time; // time at which to give up avoiding a ship and just warp out
|
||||
|
||||
int shockwave_object; // Object index of missile that will generate a shockwave. We will try to avoid.
|
||||
|
||||
int shield_manage_timestamp; // Time at which to next manage shield.
|
||||
int self_destruct_timestamp; // Time at which to self-destruct, probably due to being disabled.
|
||||
int ok_to_target_timestamp; // Time at which this ship can dynamically target.
|
||||
|
||||
float kamikaze_damage; // some damage value used to produce a shockwave from a kamikaze ship
|
||||
vec3d big_attack_point; // Global point this ship is attacking on a big ship.
|
||||
vec3d big_attack_surface_normal; // Surface normal at ship at big_attack_point;
|
||||
int pick_big_attack_point_timestamp; // timestamp at which to pick a new point to attack on a big ship.
|
||||
|
||||
// Note: These three avoid_XX terms are shared between the code that avoids small (only player now) and large ships
|
||||
// The bits in ai_flags determine which is occurring. AIF_AVOID_SMALL_SHIP, AIF_AVOID_BIG_SHIP
|
||||
int avoid_ship_num; // object index of small ship to avoid
|
||||
vec3d avoid_goal_point; // point to aim at when avoiding a ship
|
||||
fix avoid_check_timestamp; // timestamp at which to next check for having to avoid ship
|
||||
|
||||
vec3d big_collision_normal; // Global normal of collision with big ship. Helps find direction to fly away from big ship. Set for each collision.
|
||||
vec3d big_recover_pos_1; // Global point to fly towards when recovering from collision with a big ship, stage 1.
|
||||
vec3d big_recover_pos_2; // Global point to fly towards when recovering from collision with a big ship, stage 2.
|
||||
int big_recover_timestamp; // timestamp at which it's OK to re-enter stage 1.
|
||||
|
||||
int abort_rearm_timestamp; // time at which this rearm should be aborted in a multiplayer game.
|
||||
|
||||
// artillery targeting info
|
||||
int artillery_objnum; // object currently being targeted for artillery lock/attack
|
||||
int artillery_sig; // artillery object signature
|
||||
float artillery_lock_time; // how long we've been locked onto this guy
|
||||
vec3d artillery_lock_pos; // base position of the lock point on (in model's frame of reference)
|
||||
float lethality; // measure of how dangerous ship is to enemy BIG|HUGE ships (likelyhood of targeting)
|
||||
|
||||
int ai_override_flags; // flags for marking ai overrides from sexp or lua systems
|
||||
control_info ai_override_ci; // ai override control info
|
||||
int ai_override_timestamp; // mark for when to end the current override
|
||||
} ai_info;
|
||||
|
||||
#define MAX_AI_INFO MAX_SHIPS
|
||||
|
||||
// SUBSYS_PATH_DIST is used as the distance that a subsystem path should terminate from the actual
|
||||
// subsystem. We don't want to rely on the model path points for this, since we may need to be
|
||||
// changed.
|
||||
#define SUBSYS_PATH_DIST 500.0f
|
||||
|
||||
// Friendly damage defines
|
||||
#define MAX_BURST_DAMAGE 20 // max damage that can be done in BURST_DURATION
|
||||
#define BURST_DURATION 500 // decay time over which Player->damage_this_burst falls from MAX_BURST_DAMAGE to 0
|
||||
|
||||
extern int Mission_all_attack; // !0 means all teams attack all teams.
|
||||
extern int Total_goal_ship_names;
|
||||
extern char Goal_ship_names[MAX_GOAL_SHIP_NAMES][NAME_LENGTH];
|
||||
|
||||
extern void update_ai_info_for_hit(int hitter_obj, int hit_obj);
|
||||
extern void ai_frame_all(void);
|
||||
|
||||
extern int find_guard_obj(void);
|
||||
|
||||
extern ai_info Ai_info[];
|
||||
extern ai_info *Player_ai;
|
||||
|
||||
extern ai_class *Ai_classes;
|
||||
extern char** Ai_class_names;
|
||||
|
||||
extern int Num_ai_classes;
|
||||
extern int Ai_firing_enabled;
|
||||
|
||||
extern char *Skill_level_names(int skill_level, int translate = 1);
|
||||
extern int Ai_goal_signature;
|
||||
|
||||
// need access to following data in AiBig.cpp
|
||||
extern object *Pl_objp;
|
||||
extern object *En_objp;
|
||||
extern float AI_frametime;
|
||||
|
||||
|
||||
// Return index of free AI slot.
|
||||
// Return 0 if no free slot.
|
||||
int ai_get_slot(int shipnum);
|
||||
|
||||
// Releases an AI slot to be used by someone else.
|
||||
void ai_free_slot(int ai_index);
|
||||
|
||||
// call to init one ai object.. you can pass all sorts of
|
||||
// stuff by adding new paramters.
|
||||
void ai_object_init(object * obj, int ai_index);
|
||||
|
||||
// Called once a frame
|
||||
void ai_process( object * obj, int ai_index, float frametime );
|
||||
|
||||
int get_wingnum(int objnum);
|
||||
|
||||
void set_wingnum(int objnum, int wingnum);
|
||||
char *ai_get_goal_ship_name(char *name, int *index);
|
||||
|
||||
extern void init_ai_system(void);
|
||||
extern void ai_attack_object(object *attacker, object *attacked, ship_subsys *ssp);
|
||||
extern void ai_evade_object(object *evader, object *evaded);
|
||||
extern void ai_ignore_object(object *ignorer, object *ignored, int ignore_new);
|
||||
extern void ai_ignore_wing(object *ignorer, int wingnum, int priority);
|
||||
extern void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type);
|
||||
extern void ai_stay_still(object *still_objp, vec3d *view_pos);
|
||||
extern void ai_set_default_behavior(object *obj, int classnum);
|
||||
extern void ai_do_default_behavior(object *obj);
|
||||
extern void ai_start_waypoints(object *objp, int waypoint_list_index, int wp_flags);
|
||||
extern void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal);
|
||||
extern void ai_ship_destroy(int shipnum, int method);
|
||||
extern void ai_turn_towards_vector(vec3d *dest, object *objp, float frametime, float turn_time, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec = NULL, int sexp_flags = 0);
|
||||
extern void init_ai_object(int objnum);
|
||||
extern void ai_init(void); // Call this one to parse ai.tbl.
|
||||
extern void ai_level_init(void); // Call before each level to reset AI
|
||||
|
||||
extern int ai_set_attack_subsystem(object *objp, int subnum);
|
||||
extern int ai_issue_rearm_request(object *requester_objp); // Object requests rearm/repair.
|
||||
extern int ai_abort_rearm_request(object *requester_objp); // Object aborts rearm/repair.
|
||||
extern void ai_do_repair_frame(object *objp, ai_info *aip, float frametime); // Repair a ship object, player or AI.
|
||||
extern void ai_update_danger_weapon(int objnum, int weapon_objnum);
|
||||
|
||||
// called externally from MissionParse.cpp to position ships in wings upon arrival into the
|
||||
// mission.
|
||||
extern void get_absolute_wing_pos( vec3d *result_pos, object *leader_objp, int wing_index, int formation_object_flag);
|
||||
extern void get_absolute_wing_pos_autopilot( vec3d *result_pos, object *leader_objp, int wing_index, int formation_object_flag);
|
||||
|
||||
// Interface from goals code to AI. Set ship to guard. *objp guards *other_objp
|
||||
extern void ai_set_guard_object(object *objp, object *other_objp);
|
||||
extern void ai_set_evade_object(object *objp, object *other_objp);
|
||||
extern void ai_set_guard_wing(object *objp, int wingnum);
|
||||
extern void ai_warp_out(object *objp, vec3d *vp);
|
||||
extern void ai_attack_wing(object *attacker, int wingnum);
|
||||
extern void ai_deathroll_start(object *ship_obj);
|
||||
extern void ai_fly_in_formation(int wing_num); // Force wing to fly in formation.
|
||||
extern void ai_disband_formation(int wing_num); // Force wing to disband formation flying.
|
||||
extern int set_target_objnum(ai_info *aip, int objnum);
|
||||
extern void ai_form_on_wing(object *objp, object *goal_objp);
|
||||
extern void ai_do_stay_near(object *objp, object *other_obj, float dist);
|
||||
extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
|
||||
extern void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int dockee_index );
|
||||
extern void ai_add_rearm_goal( object *requester_objp, object *support_objp );
|
||||
extern void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_path=0);
|
||||
extern int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 );
|
||||
|
||||
// Goober5000
|
||||
extern void ai_do_safety(object *objp);
|
||||
|
||||
// used to get path info for fighter bay emerging and departing
|
||||
int ai_acquire_emerge_path(object *pl_objp, int parent_objnum, int path_mask, vec3d *pos, vec3d *fvec);
|
||||
int ai_acquire_depart_path(object *pl_objp, int parent_objnum, int path_mask);
|
||||
|
||||
// used by AiBig.cpp
|
||||
extern void ai_set_positions(object *pl_objp, object *en_objp, ai_info *aip, vec3d *player_pos, vec3d *enemy_pos);
|
||||
extern void accelerate_ship(ai_info *aip, float accel);
|
||||
extern void turn_away_from_point(object *objp, vec3d *point, float bank_override);
|
||||
extern float ai_endangered_by_weapon(ai_info *aip);
|
||||
extern void update_aspect_lock_information(ai_info *aip, vec3d *vec_to_enemy, float dist_to_enemy, float enemy_radius);
|
||||
extern void ai_chase_ct();
|
||||
extern void ai_find_path(object *pl_objp, int objnum, int path_num, int exit_flag, int subsys_path=0);
|
||||
extern float ai_path();
|
||||
extern void evade_weapon();
|
||||
extern int might_collide_with_ship(object *obj1, object *obj2, float dot_to_enemy, float dist_to_enemy, float duration);
|
||||
extern int ai_fire_primary_weapon(object *objp); //changed to return weather it fired-Bobboau
|
||||
extern int ai_fire_secondary_weapon(object *objp, int priority1 = -1, int priority2 = -1);
|
||||
extern float ai_get_weapon_dist(ship_weapon *swp);
|
||||
extern void turn_towards_point(object *objp, vec3d *point, vec3d *slide_vec, float bank_override);
|
||||
extern int ai_maybe_fire_afterburner(object *objp, ai_info *aip);
|
||||
extern void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, ai_info *aip);
|
||||
|
||||
extern int is_instructor(object *objp);
|
||||
extern int find_enemy(int objnum, float range, int max_attackers);
|
||||
|
||||
float ai_get_weapon_speed(ship_weapon *swp);
|
||||
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, vec3d *gun_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
|
||||
|
||||
// function to change rearm status for ai ships (called from sexpression code)
|
||||
extern void ai_set_rearm_status( int team, int new_status );
|
||||
extern void ai_good_secondary_time( int team, int weapon_index, int num_weapons, char *shipname );
|
||||
|
||||
extern void ai_do_objects_docked_stuff(object *docker, int docker_point, object *dockee, int dockee_point, bool update_clients = true);
|
||||
extern void ai_do_objects_undocked_stuff( object *docker, object *dockee );
|
||||
extern void ai_do_objects_repairing_stuff( object *repaired_obj, object *repair_obj, int how );
|
||||
|
||||
extern int find_danger_weapon(object *sobjp, float dtime, float *atime, float dot_threshhold);
|
||||
|
||||
void ai_set_mode_warp_out(object *objp, ai_info *aip);
|
||||
|
||||
// prototyped by Goober5000
|
||||
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers);
|
||||
|
||||
// moved to header file by Goober5000
|
||||
void ai_announce_ship_dying(object *dying_objp);
|
||||
|
||||
// added by kazan
|
||||
void ai_start_fly_to_ship(object *objp, int shipnum);
|
||||
void ai_fly_to_ship();
|
||||
|
||||
//Moved declaration here for player ship -WMC
|
||||
void process_subobjects(int objnum);
|
||||
|
||||
//SUSHI: Setting ai_info stuff from both ai class and ai profile
|
||||
void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t *profile);
|
||||
|
||||
//SUSHI: Updating AI aim
|
||||
void ai_update_aim(ai_info *aip, object* En_Objp);
|
||||
|
||||
//SUSHI: Random evasive sidethrust
|
||||
void do_random_sidethrust(ai_info *aip, ship_info *sip);
|
||||
|
||||
#endif
|
||||
@@ -1,458 +0,0 @@
|
||||
/*
|
||||
* Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/def_files.h"
|
||||
#include "ai/ai_profiles.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "localization/localize.h"
|
||||
|
||||
|
||||
// global stuff
|
||||
int Num_ai_profiles;
|
||||
int Default_ai_profile;
|
||||
ai_profile_t Ai_profiles[MAX_AI_PROFILES];
|
||||
|
||||
// local to this file
|
||||
static int Ai_profiles_initted = 0;
|
||||
static char Default_profile_name[NAME_LENGTH];
|
||||
|
||||
|
||||
// utility
|
||||
void set_flag(ai_profile_t *profile, char *name, int flag, int type)
|
||||
{
|
||||
if (optional_string(name))
|
||||
{
|
||||
bool val;
|
||||
stuff_boolean(&val);
|
||||
|
||||
if (type == AIP_FLAG) {
|
||||
if (val)
|
||||
profile->flags |= flag;
|
||||
else
|
||||
profile->flags &= ~flag;
|
||||
} else {
|
||||
if (val)
|
||||
profile->flags2 |= flag;
|
||||
else
|
||||
profile->flags2 &= ~flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void parse_ai_profiles_tbl(char *filename)
|
||||
{
|
||||
int i, rval;
|
||||
char profile_name[NAME_LENGTH];
|
||||
ai_profile_t dummy_profile;
|
||||
char *saved_Mp = NULL;
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default ai_profiles.tbl>", rval));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("ai_profiles.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
// start parsing
|
||||
required_string("#AI Profiles");
|
||||
|
||||
// new default?
|
||||
if (optional_string("$Default Profile:"))
|
||||
stuff_string(Default_profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// begin reading data
|
||||
while (required_string_either("#End","$Profile Name:"))
|
||||
{
|
||||
ai_profile_t *profile = &dummy_profile;
|
||||
ai_profile_t *previous_profile = NULL;
|
||||
bool no_create = false;
|
||||
|
||||
// get the name
|
||||
required_string("$Profile Name:");
|
||||
stuff_string(profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// see if it exists
|
||||
for (i = 0; i < Num_ai_profiles; i++)
|
||||
{
|
||||
if (!stricmp(Ai_profiles[i].profile_name, profile_name))
|
||||
{
|
||||
previous_profile = &Ai_profiles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// modular table stuff
|
||||
if (optional_string("+nocreate"))
|
||||
{
|
||||
no_create = true;
|
||||
|
||||
// use the previous one if possible,
|
||||
// otherwise continue to use the dummy one
|
||||
if (previous_profile != NULL)
|
||||
profile = previous_profile;
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't create multiple profiles with the same name
|
||||
if (previous_profile != NULL)
|
||||
{
|
||||
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we're under the limit
|
||||
if (Num_ai_profiles >= MAX_AI_PROFILES)
|
||||
{
|
||||
Warning(LOCATION, "Too many profiles in ai_profiles.tbl! Max is %d.\n", MAX_AI_PROFILES-1); // -1 because one is built-in
|
||||
skip_to_string("#End", NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
profile = &Ai_profiles[Num_ai_profiles];
|
||||
Num_ai_profiles++;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize profile if we're not building from a previously parsed one
|
||||
if (!no_create)
|
||||
{
|
||||
// base profile, so zero it out
|
||||
if (profile == &Ai_profiles[0])
|
||||
{
|
||||
memset(profile, 0, sizeof(ai_profile_t));
|
||||
}
|
||||
// brand new profile, so set it to the base defaults
|
||||
else
|
||||
{
|
||||
memcpy(profile, &Ai_profiles[0], sizeof(ai_profile_t));
|
||||
}
|
||||
}
|
||||
|
||||
// set the name
|
||||
strcpy_s(profile->profile_name, profile_name);
|
||||
|
||||
|
||||
// fill in any and all settings; they're all optional and can be in any order
|
||||
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
|
||||
{
|
||||
if (optional_string("$Player Afterburner Recharge Scale:"))
|
||||
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Beam Friendly Fire Damage:"))
|
||||
parse_float_list(profile->beam_friendly_damage_cap, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Countermeasure Life Scale:"))
|
||||
parse_float_list(profile->cmeasure_life_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Countermeasure Firing Chance:"))
|
||||
parse_float_list(profile->cmeasure_fire_chance, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI In Range Time:"))
|
||||
parse_float_list(profile->in_range_time, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Always Links Ammo Weapons:"))
|
||||
parse_float_list(profile->link_ammo_levels_always, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Maybe Links Ammo Weapons:"))
|
||||
parse_float_list(profile->link_ammo_levels_maybe, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Primary Ammo Burst Multiplier:"))
|
||||
parse_float_list(profile->primary_ammo_burst_mult, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Always Links Energy Weapons:"))
|
||||
parse_float_list(profile->link_energy_levels_always, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Maybe Links Energy Weapons:"))
|
||||
parse_float_list(profile->link_energy_levels_maybe, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Missles Locked on Player:"))
|
||||
parse_int_list(profile->max_allowed_player_homers, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Player Attackers:"))
|
||||
parse_int_list(profile->max_attackers, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Incoming Asteroids:"))
|
||||
parse_int_list(profile->max_incoming_asteroids, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Damage Factor:") || optional_string("$AI Damage Reduction to Player Hull:"))
|
||||
parse_float_list(profile->player_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Subsys Damage Factor:") || optional_string("$AI Damage Reduction to Player Subsys:"))
|
||||
parse_float_list(profile->subsys_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
// represented in fractions of F1_0
|
||||
if (optional_string("$Predict Position Delay:"))
|
||||
{
|
||||
int iLoop;
|
||||
float temp_list[NUM_SKILL_LEVELS];
|
||||
|
||||
parse_float_list(temp_list, NUM_SKILL_LEVELS);
|
||||
|
||||
for (iLoop = 0; iLoop < NUM_SKILL_LEVELS; iLoop++)
|
||||
profile->predict_position_delay[iLoop] = fl2f(temp_list[iLoop]);
|
||||
}
|
||||
|
||||
if (optional_string("$Player Shield Recharge Scale:"))
|
||||
parse_float_list(profile->shield_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Shield Manage Delay:") || optional_string("$AI Shield Manage Delays:"))
|
||||
parse_float_list(profile->shield_manage_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Friendly AI Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_delay_scale_friendly, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Hostile AI Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_delay_scale_hostile, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Friendly AI Secondary Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_secondary_delay_scale_friendly, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Hostile AI Secondary Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_secondary_delay_scale_hostile, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Subsys Damage Factor:") || optional_string("$AI Damage Reduction to Player Subsys:"))
|
||||
parse_float_list(profile->subsys_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Turn Time Scale:"))
|
||||
parse_float_list(profile->turn_time_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Glide Attack Percent:")) {
|
||||
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.0f) {
|
||||
profile->glide_attack_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Glide Attack Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_attack_percent[i]);
|
||||
}
|
||||
profile->glide_attack_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Circle Strafe Percent:")) {
|
||||
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.0f) {
|
||||
profile->circle_strafe_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Circle Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->circle_strafe_percent[i]);
|
||||
}
|
||||
profile->circle_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Glide Strafe Percent:")) {
|
||||
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.0f) {
|
||||
profile->glide_strafe_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Glide Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_strafe_percent[i]);
|
||||
}
|
||||
profile->glide_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Random Sidethrust Percent:")) {
|
||||
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
|
||||
profile->random_sidethrust_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Random Sidethrust Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->random_sidethrust_percent[i]);
|
||||
}
|
||||
profile->random_sidethrust_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Stalemate Time Threshold:"))
|
||||
parse_float_list(profile->stalemate_time_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Stalemate Distance Threshold:"))
|
||||
parse_float_list(profile->stalemate_dist_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Weapon Recharge Scale:"))
|
||||
parse_float_list(profile->weapon_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Target Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_target, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Player Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_player, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Required For Kill Scale:"))
|
||||
parse_float_list(profile->kill_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Required For Assist Scale:"))
|
||||
parse_float_list(profile->assist_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Awarded For Capship Assist:"))
|
||||
parse_float_list(profile->assist_award_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Repair Penalty:"))
|
||||
parse_int_list(profile->repair_penalty, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Delay Before Allowing Bombs to Be Shot Down:"))
|
||||
parse_float_list(profile->delay_bomb_arm_timer, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Chance AI Has to Fire Missiles at Player:"))
|
||||
parse_int_list(profile->chance_to_use_missiles_on_plr, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Aim Update Delay:"))
|
||||
parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Turret Max Aim Update Delay:"))
|
||||
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart shield management:", AIPF_SMART_SHIELD_MANAGEMENT, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart afterburner management:", AIPF_SMART_AFTERBURNER_MANAGEMENT, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow rapid secondary dumbfire:", AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$huge turret weapons ignore bombs:", AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$don't insert random turret fire delay:", AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$shockwaves damage small ship subsystems:", AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$navigation subsystem governs warpout capability:", AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$include beams for kills and assists:", AIPF_INCLUDE_BEAMS_IN_STAT_CALCS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$score kills based on damage caused:", AIPF_KILL_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$score assists based on damage caused:", AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix linked primary weapon decision bug:", AIPF_FIX_LINKED_PRIMARY_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$prevent turrets targeting too distant bombs:", AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart subsystem targeting for turrets:", AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AIPF_FIX_HEAT_SEEKER_STEALTH_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$multi allow empty primaries:", AIPF_MULTI_ALLOW_EMPTY_PRIMARIES, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$multi allow empty secondaries:", AIPF_MULTI_ALLOW_EMPTY_SECONDARIES, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow turrets target weapons freely:", AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use only single fov for turrets:", AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$force beam turrets to use normal fov:", AIPF_FORCE_BEAM_TURRET_FOV, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix ai class bug:", AIPF_FIX_AI_CLASS_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$perform less checks for death screams:", AIPF2_PERFORM_LESS_SCREAM_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$advanced turret fov edge checks:", AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$require turrets to have target in fov:", AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if ( saved_Mp && (saved_Mp == Mp) )
|
||||
Mp++;
|
||||
|
||||
// find next valid option
|
||||
skip_to_start_of_string_either("$", "#");
|
||||
saved_Mp = Mp;
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
extern void fs2netd_add_table_validation(char *tblname);
|
||||
fs2netd_add_table_validation(filename);
|
||||
|
||||
// close localization
|
||||
lcl_ext_close();
|
||||
}
|
||||
|
||||
void ai_profiles_init()
|
||||
{
|
||||
int temp;
|
||||
|
||||
if (Ai_profiles_initted)
|
||||
return;
|
||||
|
||||
Num_ai_profiles = 0;
|
||||
Default_ai_profile = 0;
|
||||
Default_profile_name[0] = '\0';
|
||||
|
||||
// init retail entry first
|
||||
parse_ai_profiles_tbl(NULL);
|
||||
|
||||
// now parse the supplied table (if any)
|
||||
if (cf_exists_full("ai_profiles.tbl", CF_TYPE_TABLES))
|
||||
parse_ai_profiles_tbl("ai_profiles.tbl");
|
||||
|
||||
// parse any modular tables
|
||||
parse_modular_table("*-aip.tbm", parse_ai_profiles_tbl);
|
||||
|
||||
// set default if specified
|
||||
temp = ai_profile_lookup(Default_profile_name);
|
||||
if (temp >= 0)
|
||||
Default_ai_profile = temp;
|
||||
|
||||
Ai_profiles_initted = 1;
|
||||
}
|
||||
|
||||
int ai_profile_lookup(char *name)
|
||||
{
|
||||
for (int i = 0; i < Num_ai_profiles; i++)
|
||||
if (!stricmp(name, Ai_profiles[i].profile_name))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _AI_PROFILES_H_
|
||||
#define _AI_PROFILES_H_
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
|
||||
// flag int defines
|
||||
#define AIP_FLAG 1
|
||||
#define AIP_FLAG2 2
|
||||
|
||||
// flags
|
||||
#define AIPF_SMART_SHIELD_MANAGEMENT (1 << 0)
|
||||
#define AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS (1 << 1)
|
||||
#define AIPF_SMART_PRIMARY_WEAPON_SELECTION (1 << 2)
|
||||
#define AIPF_SMART_SECONDARY_WEAPON_SELECTION (1 << 3)
|
||||
#define AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE (1 << 4)
|
||||
#define AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS (1 << 5)
|
||||
#define AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY (1 << 6)
|
||||
#define AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY (1 << 7)
|
||||
#define AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS (1 << 8)
|
||||
#define AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP (1 << 9)
|
||||
#define AIPF_NO_MIN_DOCK_SPEED_CAP (1 << 10)
|
||||
#define AIPF_DISABLE_LINKED_FIRE_PENALTY (1 << 11)
|
||||
#define AIPF_DISABLE_WEAPON_DAMAGE_SCALING (1 << 12)
|
||||
#define AIPF_USE_ADDITIVE_WEAPON_VELOCITY (1 << 13)
|
||||
#define AIPF_USE_NEWTONIAN_DAMPENING (1 << 14)
|
||||
#define AIPF_INCLUDE_BEAMS_IN_STAT_CALCS (1 << 15)
|
||||
#define AIPF_KILL_SCORING_SCALES_WITH_DAMAGE (1 << 16)
|
||||
#define AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE (1 << 17)
|
||||
#define AIPF_ALLOW_MULTI_EVENT_SCORING (1 << 18)
|
||||
#define AIPF_SMART_AFTERBURNER_MANAGEMENT (1 << 19)
|
||||
#define AIPF_FIX_LINKED_PRIMARY_BUG (1 << 20)
|
||||
#define AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE (1 << 21)
|
||||
#define AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS (1 << 22)
|
||||
#define AIPF_FIX_HEAT_SEEKER_STEALTH_BUG (1 << 23)
|
||||
#define AIPF_MULTI_ALLOW_EMPTY_PRIMARIES (1 << 24)
|
||||
#define AIPF_MULTI_ALLOW_EMPTY_SECONDARIES (1 << 25)
|
||||
#define AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY (1 << 26)
|
||||
#define AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS (1 << 27)
|
||||
#define AIPF_ALLOW_VERTICAL_DODGE (1 << 28) //Allows AI ships to evade weapons vertically as well as horizontally
|
||||
#define AIPF_FORCE_BEAM_TURRET_FOV (1 << 29)
|
||||
#define AIPF_FIX_AI_CLASS_BUG (1 << 30)
|
||||
|
||||
// flags2
|
||||
#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0)
|
||||
#define AIPF2_NO_SPECIAL_PLAYER_AVOID (1 << 1)
|
||||
#define AIPF2_PERFORM_LESS_SCREAM_CHECKS (1 << 2)
|
||||
#define AIPF2_ALL_SHIPS_MANAGE_SHIELDS (1 << 3)
|
||||
#define AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS (1 << 4)
|
||||
#define AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV (1 << 5)
|
||||
|
||||
|
||||
#define MAX_AI_PROFILES 5
|
||||
|
||||
typedef struct ai_profile_t {
|
||||
|
||||
char profile_name[NAME_LENGTH];
|
||||
|
||||
int flags;
|
||||
int flags2;
|
||||
|
||||
// difficulty-related values
|
||||
int max_incoming_asteroids[NUM_SKILL_LEVELS]; // max number of asteroids thrown at friendlies
|
||||
int max_allowed_player_homers[NUM_SKILL_LEVELS]; // max number of simultaneous homing weapons on player
|
||||
int max_attackers[NUM_SKILL_LEVELS]; // max number of ships that can attack a ship
|
||||
fix predict_position_delay[NUM_SKILL_LEVELS]; // how long until AI predicts a ship position
|
||||
float in_range_time[NUM_SKILL_LEVELS]; // seconds to add to time it takes to get enemy in range (only for player's enemies)
|
||||
float shield_manage_delay[NUM_SKILL_LEVELS]; // how long before AI manages shields (note that the player's team always uses the average skill's delay)
|
||||
|
||||
// AI ships link primaries if energy levels greater than these percents
|
||||
float link_energy_levels_always[NUM_SKILL_LEVELS]; // always link
|
||||
float link_energy_levels_maybe[NUM_SKILL_LEVELS]; // link if hull strength low
|
||||
|
||||
// AI ships link primaries if ammunition levels greater than these percents
|
||||
float link_ammo_levels_always[NUM_SKILL_LEVELS]; // always link
|
||||
float link_ammo_levels_maybe[NUM_SKILL_LEVELS]; // link if hull strength low
|
||||
float primary_ammo_burst_mult[NUM_SKILL_LEVELS]; // SUSHI: Multiplier adjusting burst frequency for ballistic primary weapons
|
||||
|
||||
// difficulty-related scales
|
||||
float cmeasure_life_scale[NUM_SKILL_LEVELS]; // life of countermeasures
|
||||
float cmeasure_fire_chance[NUM_SKILL_LEVELS]; // chance a countermeasure will be fired based on skill level (also scaled by ai_class)
|
||||
float weapon_energy_scale[NUM_SKILL_LEVELS]; // weapon energy available
|
||||
float shield_energy_scale[NUM_SKILL_LEVELS]; // shield energy available
|
||||
float afterburner_recharge_scale[NUM_SKILL_LEVELS]; // speed of afterburner recharge
|
||||
float player_damage_scale[NUM_SKILL_LEVELS]; // damage applied to the player
|
||||
|
||||
float subsys_damage_scale[NUM_SKILL_LEVELS]; // damage applied to a player subsystem
|
||||
float beam_friendly_damage_cap[NUM_SKILL_LEVELS]; // damage cap values for friendly beam fire
|
||||
float turn_time_scale[NUM_SKILL_LEVELS]; // speed at which enemy ships turn
|
||||
float glide_attack_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "glide attack" move
|
||||
float circle_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "circle strafe" move
|
||||
float glide_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use glide when strafing capships
|
||||
float random_sidethrust_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to randomly use sidethrust while dogfihthing
|
||||
float stalemate_time_thresh[NUM_SKILL_LEVELS]; // SUSHI: The amount of time required for the AI to detect (and try to break) dogfight stalemate
|
||||
float stalemate_dist_thresh[NUM_SKILL_LEVELS]; // SUSHI: The maximum distance the AI and target must be within for a stalemate
|
||||
float max_aim_update_delay[NUM_SKILL_LEVELS]; // SUSHI: The maximum delay before the AI updates their aim against small ships
|
||||
float turret_max_aim_update_delay[NUM_SKILL_LEVELS]; // SUSHI: As above, but for turrets updating their aim
|
||||
|
||||
// Multiplicative delay factors for increasing skill levels.
|
||||
float ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS];
|
||||
float ship_fire_delay_scale_friendly[NUM_SKILL_LEVELS];
|
||||
|
||||
// Multiplicative secondary delay factors for increasing skill levels.
|
||||
float ship_fire_secondary_delay_scale_hostile[NUM_SKILL_LEVELS];
|
||||
float ship_fire_secondary_delay_scale_friendly[NUM_SKILL_LEVELS];
|
||||
|
||||
// Maximum turrets of one ship allowed to shoot the same target
|
||||
int max_turret_ownage_target[NUM_SKILL_LEVELS];
|
||||
int max_turret_ownage_player[NUM_SKILL_LEVELS];
|
||||
|
||||
// percentage of damage caused required for a kill/assist
|
||||
float kill_percentage_scale[NUM_SKILL_LEVELS];
|
||||
float assist_percentage_scale[NUM_SKILL_LEVELS];
|
||||
|
||||
// percentage of the capships score given to other team mates on a kill
|
||||
float assist_award_percentage_scale[NUM_SKILL_LEVELS];
|
||||
|
||||
// the number of points subtracted from score for a rearm started on a player
|
||||
int repair_penalty[NUM_SKILL_LEVELS];
|
||||
|
||||
float delay_bomb_arm_timer[NUM_SKILL_LEVELS];
|
||||
|
||||
// the chance (x/7) that ship is allowed to fire missiles at player ship.
|
||||
int chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
|
||||
|
||||
|
||||
} ai_profile_t;
|
||||
|
||||
|
||||
extern int Num_ai_profiles;
|
||||
extern int Default_ai_profile;
|
||||
extern ai_profile_t Ai_profiles[MAX_AI_PROFILES];
|
||||
|
||||
|
||||
void ai_profiles_init();
|
||||
|
||||
int ai_profile_lookup(char *name);
|
||||
|
||||
#endif
|
||||
-1791
File diff suppressed because it is too large.
Load diff
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __AIBIG_H__
|
||||
#define __AIBIG_H__
|
||||
|
||||
struct object;
|
||||
struct ai_info;
|
||||
struct vec3d;
|
||||
struct ship_subsys;
|
||||
|
||||
void ai_big_ship(object *objp);
|
||||
void ai_big_chase();
|
||||
void ai_big_subsys_path_cleanup(ai_info *aip);
|
||||
|
||||
// strafe functions
|
||||
void ai_big_strafe();
|
||||
int ai_big_maybe_enter_strafe_mode(object *objp, int weapon_objnum, int consider_target_only=0);
|
||||
void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp);
|
||||
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov=1.0f);
|
||||
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
-15724
File diff suppressed because it is too large.
Load diff
-2437
File diff suppressed because it is too large.
Load diff
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _AIGOALS_H
|
||||
#define _AIGOALS_H
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct wing;
|
||||
struct ai_info;
|
||||
struct ai_goal;
|
||||
|
||||
// macros for goals which get set via sexpressions in the mission code
|
||||
|
||||
// IMPORTANT! If you add a new AI_GOAL_x define, be sure to update the functions
|
||||
// ai_update_goal_references() and query_referenced_in_ai_goals() or else risk breaking
|
||||
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
|
||||
// to worry about doing this. Also add it to list in Fred\Management.cpp, and let Hoffoss know!
|
||||
// WMC - Oh and add them to Ai_goal_names plz. TY! :)
|
||||
#define AI_GOAL_CHASE (1<<1) // 0x00000002
|
||||
#define AI_GOAL_DOCK (1<<2) // 0x00000004 // used for undocking as well
|
||||
#define AI_GOAL_WAYPOINTS (1<<3) // 0x00000008
|
||||
#define AI_GOAL_WAYPOINTS_ONCE (1<<4) // 0x00000010
|
||||
#define AI_GOAL_WARP (1<<5) // 0x00000020
|
||||
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6) // 0x00000040
|
||||
#define AI_GOAL_FORM_ON_WING (1<<7) // 0x00000080
|
||||
#define AI_GOAL_UNDOCK (1<<8) // 0x00000100
|
||||
#define AI_GOAL_CHASE_WING (1<<9) // 0x00000200
|
||||
#define AI_GOAL_GUARD (1<<10) // 0x00000400
|
||||
#define AI_GOAL_DISABLE_SHIP (1<<11) // 0x00000800
|
||||
#define AI_GOAL_DISARM_SHIP (1<<12) // 0x00001000
|
||||
#define AI_GOAL_CHASE_ANY (1<<13) // 0x00002000
|
||||
#define AI_GOAL_IGNORE (1<<14) // 0x00004000
|
||||
#define AI_GOAL_GUARD_WING (1<<15) // 0x00008000
|
||||
#define AI_GOAL_EVADE_SHIP (1<<16) // 0x00010000
|
||||
|
||||
// the next goals are for support ships only
|
||||
#define AI_GOAL_STAY_NEAR_SHIP (1<<17) // 0x00020000
|
||||
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18) // 0x00040000
|
||||
#define AI_GOAL_REARM_REPAIR (1<<19) // 0x00080000
|
||||
|
||||
// resume regular goals
|
||||
#define AI_GOAL_STAY_STILL (1<<20) // 0x00100000
|
||||
#define AI_GOAL_PLAY_DEAD (1<<21) // 0x00200000
|
||||
#define AI_GOAL_CHASE_WEAPON (1<<22) // 0x00400000
|
||||
|
||||
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
|
||||
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
|
||||
|
||||
// now the masks for ship types
|
||||
|
||||
// Goober5000: added AI_GOAL_STAY_NEAR_SHIP and AI_GOAL_KEEP_SAFE_DISTANCE as valid for fighters
|
||||
//WMC - Don't need these anymore. Whee!
|
||||
/*
|
||||
#define AI_GOAL_ACCEPT_FIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_DESTROY_SUBSYSTEM | AI_GOAL_CHASE_WING | AI_GOAL_GUARD | AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP | AI_GOAL_CHASE_ANY | AI_GOAL_IGNORE | AI_GOAL_IGNORE_NEW | AI_GOAL_GUARD_WING | AI_GOAL_EVADE_SHIP | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE )
|
||||
#define AI_GOAL_ACCEPT_BOMBER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_STEALTH ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_TRANSPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_CHASE_WING | AI_GOAL_DOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_UNDOCK | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD| AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_FREIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_TRANSPORT | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CRUISER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FREIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CORVETTE ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_GAS_MINER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_AWACS ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CAPITAL ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER & ~(AI_GOAL_DOCK | AI_GOAL_UNDOCK) | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_SUPERCAP ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CAPITAL | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_SUPPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_DOCK | AI_GOAL_UNDOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD)
|
||||
#define AI_GOAL_ACCEPT_ESCAPEPOD ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_TRANSPORT| AI_GOAL_STAY_NEAR_SHIP )
|
||||
*/
|
||||
|
||||
#define MAX_AI_DOCK_NAMES 25
|
||||
|
||||
typedef flag_def_list ai_goal_list;
|
||||
|
||||
extern ai_goal_list Ai_goal_names[];
|
||||
extern int Num_ai_goals;
|
||||
|
||||
extern int Num_ai_dock_names;
|
||||
extern char Ai_dock_names[MAX_AI_DOCK_NAMES][NAME_LENGTH];
|
||||
|
||||
extern char *Ai_goal_text(int goal);
|
||||
|
||||
// extern function definitions
|
||||
extern void ai_post_process_mission();
|
||||
extern void ai_maybe_add_form_goal( wing *wingp );
|
||||
extern void ai_process_mission_orders( int objnum, ai_info *aip );
|
||||
|
||||
extern int ai_goal_num(ai_goal *goals);
|
||||
|
||||
// adds goals to ships/wing through sexpressions
|
||||
extern void ai_add_ship_goal_scripting(int mode, int submode, int priority, char *shipname, ai_info *aip);
|
||||
extern void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip );
|
||||
extern void ai_add_wing_goal_sexp( int sexp, int type, int wingnum );
|
||||
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp );
|
||||
|
||||
extern int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp );
|
||||
extern void ai_remove_wing_goal_sexp(int sexp, int wingnum);
|
||||
|
||||
// adds goals to ships/sings through player orders
|
||||
extern void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip );
|
||||
extern void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum );
|
||||
|
||||
extern void ai_remove_ship_goal( ai_info *aip, int index );
|
||||
extern void ai_clear_ship_goals( ai_info *aip );
|
||||
extern void ai_clear_wing_goals( int wingnum );
|
||||
|
||||
extern void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip );
|
||||
|
||||
extern void ai_mission_goal_complete( ai_info *aip );
|
||||
extern void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp );
|
||||
|
||||
extern void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name);
|
||||
extern int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name);
|
||||
extern char *ai_add_dock_name(char *str);
|
||||
|
||||
extern int ai_query_goal_valid( int ship, int ai_goal );
|
||||
|
||||
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
|
||||
extern void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate = 1 );
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AIINTERNAL_H
|
||||
#define _AIINTERNAL_H
|
||||
|
||||
//Returns true if the specified object is a stealth ship, false if not
|
||||
bool is_object_stealth_ship(object* objp);
|
||||
|
||||
//Number of live turrets on the object attacking
|
||||
int num_turrets_attacking(object *turret_parent, int target_objnum);
|
||||
|
||||
//Determine whether an object is targetable within a nebula (checks for stealth)
|
||||
int object_is_targetable(object *target, ship *viewer);
|
||||
|
||||
//Returns the number of enemy fighters within threshold of pos.
|
||||
int num_nearby_fighters(int enemy_team_mask, vec3d *pos, float threshold);
|
||||
|
||||
//Returns true if OK for *aip to fire its current weapon at its current target.
|
||||
int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip);
|
||||
|
||||
//Does all the stuff needed to aim and fire a turret.
|
||||
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum);
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AILOCAL_H
|
||||
#define _AILOCAL_H
|
||||
|
||||
// -- Don't put anything in here --
|
||||
// Put it in ai.h!
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __ANIMPLAY_H__
|
||||
#define __ANIMPLAY_H__
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
struct anim;
|
||||
struct anim_info;
|
||||
struct anim_instance;
|
||||
|
||||
// structure passed in when playing an anim. Talk about overkill..
|
||||
typedef struct {
|
||||
anim *anim_info;
|
||||
int x;
|
||||
int y;
|
||||
int base_w;
|
||||
int base_h;
|
||||
int start_at;
|
||||
int stop_at;
|
||||
int screen_id;
|
||||
vec3d *world_pos;
|
||||
float radius;
|
||||
int framerate_independent;
|
||||
void *color;
|
||||
int skip_frames;
|
||||
int looped;
|
||||
int ping_pong;
|
||||
} anim_play_struct;
|
||||
|
||||
enum
|
||||
{
|
||||
PAGE_FROM_MEM = 0,
|
||||
PAGE_FROM_DISK = 1,
|
||||
PAGE_FROM_DISK_FORCED = 2
|
||||
};
|
||||
|
||||
extern int Anim_paused;
|
||||
|
||||
void anim_init();
|
||||
void anim_level_init();
|
||||
void anim_level_close();
|
||||
void anim_render_all(int screen_id, float frametime);
|
||||
void anim_render_one(int screen_id, anim_instance *ani, float frametime);
|
||||
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int max_x = -1, int max_y = -1);
|
||||
anim_instance *anim_play(anim_play_struct *aps);
|
||||
void anim_ignore_next_frametime();
|
||||
int anim_stop_playing(anim_instance* anim_instance);
|
||||
int anim_show_next_frame(anim_instance *instance, float frametime);
|
||||
void anim_release_all_instances(int screen_id = 0);
|
||||
void anim_release_render_instance(anim_instance* instance);
|
||||
anim *anim_load(char *name, int cf_dir_type = CF_TYPE_ANY, int file_mapped = PAGE_FROM_MEM);
|
||||
int anim_free(anim *ptr);
|
||||
int anim_playing(anim_instance *ai);
|
||||
int anim_write_frames_out(char *filename);
|
||||
void anim_display_info(char *filename);
|
||||
void anim_read_header(anim *ptr, CFILE *fp);
|
||||
void anim_reverse_direction(anim_instance *ai); // called automatically for ping-ponging, and can also be called externally
|
||||
void anim_pause(anim_instance *ai);
|
||||
void anim_unpause(anim_instance *ai);
|
||||
|
||||
int anim_instance_is_streamed(anim_instance *ai);
|
||||
unsigned char anim_instance_get_byte(anim_instance *ai, int offset);
|
||||
|
||||
#endif /* __ANIMPLAY_H__ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __PACKUNPACK_H__
|
||||
#define __PACKUNPACK_H__
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct CFILE;
|
||||
|
||||
#define ANI_STREAM_CACHE_SIZE 4096
|
||||
|
||||
#define PACKER_CODE 0xEE // Use'd by PACKING_METHOD_RLE
|
||||
#define PACKING_METHOD_RLE 0 // Hoffoss's RLE format
|
||||
#define PACKING_METHOD_RLE_KEY 1 // Hoffoss's key frame RLE format
|
||||
#define PACKING_METHOD_STD_RLE 2 // Standard RLE format (high bit is count)
|
||||
#define PACKING_METHOD_STD_RLE_KEY 3 // Standard RLE format key frame
|
||||
|
||||
#define STD_RLE_CODE 0x80
|
||||
|
||||
typedef struct key_frame {
|
||||
int frame_num; // which frame number this key frame is
|
||||
int offset; // offset from the start of data block
|
||||
} key_frame;
|
||||
|
||||
#define ANF_MEM_MAPPED (1<<0) // animation is memory-mapped file
|
||||
#define ANF_STREAMED (1<<1)
|
||||
#define ANF_XPARENT (1<<2) // animation has transparency
|
||||
#define ANF_ALL_KEYFRAMES (1<<3) // all the frames are keyframes (this is necessary if we want to play the file backwards)
|
||||
|
||||
typedef struct anim {
|
||||
anim *next;
|
||||
char name[MAX_PATH_LEN];
|
||||
ubyte packer_code;
|
||||
int width;
|
||||
int height;
|
||||
int total_frames;
|
||||
int instance_count; // number of instances that are currently playing
|
||||
int ref_count; // number of times this anim has been loaded
|
||||
float time; // playback time in seconds
|
||||
int num_keys;
|
||||
key_frame *keys;
|
||||
ubyte palette[768];
|
||||
ubyte palette_translation[256];
|
||||
ubyte *data; // points to compressed data
|
||||
CFILE* cfile_ptr;
|
||||
int version;
|
||||
int fps;
|
||||
ubyte xparent_r; // red component for the transparent color in source image
|
||||
ubyte xparent_g; // green component for the transparent color in source image
|
||||
ubyte xparent_b; // blue component for the transparent color in source image
|
||||
int flags;
|
||||
uint screen_sig;
|
||||
int file_offset; // file offset to start of frame data
|
||||
int cache_file_offset;
|
||||
ubyte *cache;
|
||||
} anim;
|
||||
|
||||
// the direction to play the anim (forwards or backwards)
|
||||
#define ANIM_DIRECT_FORWARD 0
|
||||
#define ANIM_DIRECT_REVERSE 1
|
||||
|
||||
typedef struct anim_instance {
|
||||
anim_instance *next, *prev;
|
||||
int x,y; // coordinates anim is played at (top left corner of anim)
|
||||
int base_w, base_h; // coordinate scale this anim is played in.
|
||||
vec3d *world_pos; // world (x,y,z) position of explosion
|
||||
float radius; // radius of image, needed for scaling
|
||||
int frame_num; // current frame, or last frame if between frames (first frame is 0)
|
||||
int last_frame_num;// last frame rendered
|
||||
anim *parent; // pointer to anim structure, which holds compressed data
|
||||
ubyte *data; // pointer to next frame's compressed data
|
||||
ubyte *frame; // uncompressed frame
|
||||
float time_elapsed; // how long the anim has played for (in seconds)
|
||||
int start_at; // frame anim playing should start
|
||||
int stop_at; // frame anim playing should stop
|
||||
int framerate_independent; // animation should play back in same amount of time, regardless
|
||||
int skip_frames; // should anim skip frames during framerate independent playback
|
||||
int looped; // should anim keep playing over and over...
|
||||
int stop_now; // flag to indicate time to stop the animation
|
||||
int last_bitmap; // id of last bitmap that was rendered out from animation
|
||||
int screen_id; // 0 means all screens should render, otherwise screen specific
|
||||
void *aa_color; // anti-aliased bitmap color
|
||||
int xlate_pal;
|
||||
int direction; // playing forwards or backwards ?
|
||||
int ping_pong; // should be played ping-pong style
|
||||
int paused; // pause the anim
|
||||
int file_offset; // current offset into frame (like data, put offset into file)
|
||||
int loop_count; // starts at 0, and is incremented each time it loops
|
||||
} anim_instance;
|
||||
|
||||
int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type);
|
||||
int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type);
|
||||
|
||||
ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp);
|
||||
int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp);
|
||||
|
||||
void anim_init();
|
||||
anim_instance *init_anim_instance(anim *ptr, int bpp);
|
||||
void free_anim_instance(anim_instance *inst);
|
||||
int anim_get_next_frame(anim_instance *inst);
|
||||
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp);
|
||||
void anim_set_palette(anim *a);
|
||||
void anim_check_for_palette_change(anim_instance *inst);
|
||||
|
||||
|
||||
#endif /* __PACKUNPACK_H__ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __ASTEROID_H__
|
||||
#define __ASTEROID_H__
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/globals.h" // for NAME_LENGTH
|
||||
|
||||
|
||||
struct object;
|
||||
struct polymodel;
|
||||
struct collision_info_struct;
|
||||
|
||||
#define MAX_ASTEROIDS 512
|
||||
|
||||
#define NUM_DEBRIS_SIZES 3
|
||||
#define NUM_DEBRIS_POFS 3 // Number of POFs per debris size
|
||||
|
||||
#define ASTEROID_TYPE_SMALL 0
|
||||
#define ASTEROID_TYPE_MEDIUM 1
|
||||
#define ASTEROID_TYPE_LARGE 2
|
||||
|
||||
// This is for the asteroid types plus DEBRIS_X_Y
|
||||
// (X is each species and Y is SMALL, MEDIUM, and LARGE)
|
||||
// 20060826 - made dynamic -- taylor
|
||||
//#define MAX_DEBRIS_TYPES ((MAX_SPECIES + 1) * NUM_DEBRIS_SIZES)
|
||||
|
||||
// these should always be equal for the benefit of generic asteroids (c.f. asteroid_page_in)
|
||||
#define MAX_ACTIVE_DEBRIS_TYPES NUM_DEBRIS_SIZES
|
||||
|
||||
// Goober5000 - currently same as MAX_SHIP_DETAIL_LEVELS (put here to avoid an #include)
|
||||
#define MAX_ASTEROID_DETAIL_LEVELS 5
|
||||
|
||||
|
||||
// Data structure to track the active asteroids
|
||||
typedef struct asteroid_obj {
|
||||
asteroid_obj *next, *prev;
|
||||
int flags, objnum;
|
||||
} asteroid_obj;
|
||||
extern asteroid_obj Asteroid_obj_list;
|
||||
|
||||
|
||||
typedef struct asteroid_info {
|
||||
char name[NAME_LENGTH]; // name for the asteroid
|
||||
char pof_files[NUM_DEBRIS_POFS][MAX_FILENAME_LEN]; // POF files to load/associate with ship
|
||||
int num_detail_levels; // number of detail levels for this ship
|
||||
int detail_distance[MAX_ASTEROID_DETAIL_LEVELS]; // distance to change detail levels at
|
||||
float max_speed; // cap on speed for asteroid
|
||||
int damage_type_idx; //Damage type of the asteroid
|
||||
float inner_rad; // radius within which maximum area effect damage is applied
|
||||
float outer_rad; // radius at which no area effect damage is applied
|
||||
float damage; // maximum damage applied from area effect explosion
|
||||
float blast; // maximum blast impulse from area effect explosion
|
||||
float initial_asteroid_strength; // starting strength of asteroid
|
||||
polymodel *modelp[NUM_DEBRIS_POFS];
|
||||
int model_num[NUM_DEBRIS_POFS];
|
||||
|
||||
asteroid_info( )
|
||||
: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx( -1 ),
|
||||
inner_rad( 0 ), outer_rad( 0 ), damage( 0 ), blast( 0 ),
|
||||
initial_asteroid_strength( 0 )
|
||||
{
|
||||
name[ 0 ] = NULL;
|
||||
memset( pof_files, 0, sizeof( pof_files ) );
|
||||
memset( detail_distance, 0, sizeof( detail_distance ) );
|
||||
memset( modelp, 0, sizeof( modelp ) );
|
||||
memset( model_num, 0, sizeof( model_num ) );
|
||||
}
|
||||
} asteroid_info;
|
||||
|
||||
|
||||
#define AF_USED (1<<0) // Set means used.
|
||||
|
||||
typedef struct asteroid {
|
||||
int flags;
|
||||
int objnum;
|
||||
int asteroid_type; // 0..MAX_DEBRIS_TYPES
|
||||
int asteroid_subtype; // Index in asteroid_info for modelnum and modelp
|
||||
int check_for_wrap; // timestamp to check for asteroid wrapping around field
|
||||
int check_for_collide; // timestamp to check for asteroid colliding with escort ships
|
||||
int final_death_time; // timestamp to swap in new models after explosion starts
|
||||
int collide_objnum; // set to objnum that asteroid will be impacting soon
|
||||
int collide_objsig; // object signature corresponding to collide_objnum
|
||||
vec3d death_hit_pos; // hit pos that caused death
|
||||
int target_objnum; // Yes, hah! Asteroids can have targets. See asteroid_aim_at_target().
|
||||
} asteroid;
|
||||
|
||||
|
||||
// TYPEDEF FOR DEBRIS TYPE
|
||||
typedef enum {
|
||||
DG_ASTEROID,
|
||||
DG_SHIP
|
||||
} debris_genre_t;
|
||||
|
||||
// TYPEDEF FOR FIELD TYPE
|
||||
typedef enum {
|
||||
FT_ACTIVE,
|
||||
FT_PASSIVE
|
||||
} field_type_t;
|
||||
|
||||
typedef struct asteroid_field {
|
||||
vec3d min_bound; // Minimum range of field.
|
||||
vec3d max_bound; // Maximum range of field.
|
||||
int has_inner_bound;
|
||||
vec3d inner_min_bound;
|
||||
vec3d inner_max_bound;
|
||||
vec3d vel; // Average asteroid moves at this velocity.
|
||||
float speed; // Average speed of field
|
||||
int num_initial_asteroids; // Number of asteroids at creation.
|
||||
field_type_t field_type; // active throws and wraps, passive does not
|
||||
debris_genre_t debris_genre; // type of debris (ship or asteroid) [generic type]
|
||||
int field_debris_type[MAX_ACTIVE_DEBRIS_TYPES]; // one of the debris type defines above
|
||||
} asteroid_field;
|
||||
|
||||
extern SCP_vector< asteroid_info > Asteroid_info;
|
||||
extern asteroid Asteroids[MAX_ASTEROIDS];
|
||||
extern asteroid_field Asteroid_field;
|
||||
|
||||
extern int Num_asteroids;
|
||||
extern int Asteroids_enabled;
|
||||
|
||||
void asteroid_init();
|
||||
void asteroid_level_init();
|
||||
void asteroid_level_close();
|
||||
void asteroid_create_all();
|
||||
void asteroid_render( object *asteroid_objp );
|
||||
void asteroid_delete( object *asteroid_objp );
|
||||
void asteroid_process_pre( object *asteroid_objp, float frame_time);
|
||||
void asteroid_process_post( object *asteroid_objp, float frame_time);
|
||||
int asteroid_check_collision( object *asteroid_objp, object * other_obj, vec3d * hitpos, collision_info_struct *asteroid_hit_info=NULL );
|
||||
void asteroid_hit( object *asteroid_objp, object *other_objp, vec3d *hitpos, float damage );
|
||||
int asteroid_count();
|
||||
int asteroid_collide_objnum(object *asteroid_objp);
|
||||
float asteroid_time_to_impact(object *asteroid_objp);
|
||||
void asteroid_show_brackets();
|
||||
void asteroid_target_closest_danger();
|
||||
int asteroid_get_random_in_cone(vec3d *pos, vec3d *dir, float ang, int danger = 0);
|
||||
|
||||
// need to extern for multiplayer
|
||||
void asteroid_sub_create(object *parent_objp, int asteroid_type, vec3d *relvec);
|
||||
|
||||
void asteroid_frame();
|
||||
|
||||
#endif // __ASTEROID_H__
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,151 +0,0 @@
|
||||
// Autopilot.h
|
||||
// Derek Meek
|
||||
// 4-30-2004
|
||||
|
||||
|
||||
|
||||
#if !defined(_AUTOPILOT_H_)
|
||||
#define _AUTOPILOT_H_
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "object/object.h"
|
||||
#include <map>
|
||||
|
||||
// milliseconds between updates
|
||||
#define NPS_TICKRATE 125
|
||||
|
||||
#define MAX_NAVPOINTS 8
|
||||
|
||||
#define NP_WAYPOINT 0x0001 // Nav Point is bound to the poistion of a single node of a waypoint path
|
||||
#define NP_SHIP 0x0002 // Nav Point is bound to the poisiton of a certain ship
|
||||
#define NP_HIDDEN 0x0004 // Nav Point doesn't show on map and isn't selectable
|
||||
#define NP_NOACCESS 0x0008 // Nav Point isn't selectable
|
||||
#define NP_VISITED 0x0100 // Whether we've been within 1,000 meters of this waypoint
|
||||
|
||||
#define NP_NOSELECT ( NP_HIDDEN | NP_NOACCESS )
|
||||
#define NP_VALIDTYPE ( NP_WAYPOINT | NP_SHIP )
|
||||
|
||||
struct NavPoint
|
||||
{
|
||||
char NavName[32];
|
||||
int flags;
|
||||
|
||||
void *target_obj;
|
||||
int waypoint_num; //only used when flags & NP_WAYPOINT
|
||||
|
||||
vec3d *GetPosition();
|
||||
char* GetInteralName();
|
||||
};
|
||||
|
||||
|
||||
#define NP_MSG_FAIL_NOSEL 0
|
||||
#define NP_MSG_FAIL_GLIDING 1
|
||||
#define NP_MSG_FAIL_TOCLOSE 2
|
||||
#define NP_MSG_FAIL_HOSTILES 3
|
||||
#define NP_MSG_MISC_LINKED 4
|
||||
#define NP_MSG_FAIL_HAZARD 5
|
||||
#define NP_MSG_FAIL_SUPPORT_PRESENT 6
|
||||
#define NP_MSG_FAIL_SUPPORT_WORKING 7
|
||||
#define NP_NUM_MESSAGES 8
|
||||
|
||||
struct NavMessage
|
||||
{
|
||||
char message[256];
|
||||
char filename[256]; // can be ""
|
||||
};
|
||||
|
||||
extern bool AutoPilotEngaged;
|
||||
extern int CurrentNav;
|
||||
extern NavPoint Navs[MAX_NAVPOINTS];
|
||||
extern NavMessage NavMsgs[NP_NUM_MESSAGES];
|
||||
extern int LockAPConv;
|
||||
extern std::map<int,int> autopilot_wings;
|
||||
|
||||
// Cycles through the NavPoint List
|
||||
bool Sel_NextNav();
|
||||
|
||||
|
||||
// Tell us if autopilot is allowed
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within AutopilotMinEnemyDistance meters
|
||||
// * No asteroids within AutopilotMinAsteroidDistance meters
|
||||
// * Destination > 1,000 meters away
|
||||
// * Support ship not present or is actively leaving
|
||||
bool CanAutopilot(vec3d targetPos, bool send_msg=false);
|
||||
|
||||
// Check if autopilot is allowed at player's current position
|
||||
// See CanAutopilot(vec3d, bool) for more information
|
||||
inline bool CanAutopilot(bool send_msg=false) { return CanAutopilot(Player_obj->pos, send_msg); }
|
||||
|
||||
// Engages autopilot
|
||||
// This does:
|
||||
// * Checks if Autopilot is allowed. See CanAutopilot() for conditions.
|
||||
// * Control switched from player to AI
|
||||
// * Time compression to 32x
|
||||
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
// Returns false if autopilot cannot be started. True otherwise.
|
||||
bool StartAutopilot();
|
||||
|
||||
// Disengages autopilot
|
||||
// this does:
|
||||
// * Time compression to 1x
|
||||
// * Delete AI nav goal
|
||||
// * Control switched from AI to player
|
||||
void EndAutoPilot();
|
||||
|
||||
|
||||
// Checks for changes every NPS_TICKRATE milliseconds
|
||||
// Checks:
|
||||
// * if we've gotten close enough to a nav point for it to be counted as "Visited"
|
||||
// * If we're current AutoNavigating it checks if we need to autodisengage
|
||||
void NavSystem_Do();
|
||||
|
||||
|
||||
// Inits the Nav System
|
||||
void NavSystem_Init();
|
||||
|
||||
// parse autopilot.tbl
|
||||
void parse_autopilot_table(char *filename);
|
||||
|
||||
// Finds a Nav point by name
|
||||
int FindNav(char *Nav);
|
||||
|
||||
// Set A Nav point to "ZERO"
|
||||
void ZeroNav(int i);
|
||||
|
||||
// Removes a Nav
|
||||
bool DelNavPoint(char *Nav);
|
||||
bool DelNavPoint(int nav);
|
||||
|
||||
// adds a Nav
|
||||
bool AddNav_Ship(char *Nav, char *TargetName, int flags);
|
||||
bool AddNav_Waypoint(char *Nav, char *WP_Path, int node, int flags);
|
||||
|
||||
//Change Flags
|
||||
bool Nav_Alt_Flags(char *Nav, int flags);
|
||||
|
||||
// Sexp Accessors
|
||||
bool Nav_Set_Flag(char *Nav, int flag);
|
||||
bool Nav_UnSet_Flag(char *Nav, int flag);
|
||||
|
||||
bool Nav_Set_Hidden(char *Nav);
|
||||
bool Nav_Set_NoAccess(char *Nav);
|
||||
bool Nav_Set_Visited(char *Nav);
|
||||
|
||||
bool Nav_UnSet_Hidden(char *Nav);
|
||||
bool Nav_UnSet_NoAccess(char *Nav);
|
||||
bool Nav_UnSet_Visited(char *Nav);
|
||||
|
||||
// Useful functions
|
||||
unsigned int DistanceTo(char *nav);
|
||||
unsigned int DistanceTo(int nav);
|
||||
|
||||
bool IsVisited(char *nav);
|
||||
bool IsVisited(int nav);
|
||||
|
||||
void send_autopilot_msg(char *msg, char *snd=NULL);
|
||||
void send_autopilot_msgID(int msgid);
|
||||
#endif
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef __BM_INTERNAL_H__
|
||||
#define __BM_INTERNAL_H__
|
||||
|
||||
|
||||
// extra check to make sure this stuff doesn't end up in normal files
|
||||
// don't use any of this unless BMPMAN_INTERNAL is defined
|
||||
#ifdef BMPMAN_INTERNAL
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
|
||||
|
||||
// no-type ( used in: bm_bitmaps[i].type )
|
||||
#define BM_TYPE_NONE 0
|
||||
// in-memory type ( used in: bm_bitmaps[i].type )
|
||||
#define BM_TYPE_USER 1
|
||||
// file-type types ( used in: bm_bitmaps[i].type )
|
||||
#define BM_TYPE_PCX 2
|
||||
#define BM_TYPE_TGA 3 // 16 or 32 bit targa
|
||||
#define BM_TYPE_DDS 4 // generic identifier for DDS
|
||||
#define BM_TYPE_PNG 5 // PNG
|
||||
#define BM_TYPE_JPG 6 // 32 bit jpeg
|
||||
#define BM_TYPE_ANI 7 // in-house ANI format
|
||||
#define BM_TYPE_EFF 8 // specifies any type of animated image, the EFF itself is just text
|
||||
// c-type types ( used in: bm_bitmaps[i].c_type )
|
||||
#define BM_TYPE_DXT1 9 // 24 bit with switchable alpha (compressed)
|
||||
#define BM_TYPE_DXT3 10 // 32 bit with 4 bit alpha (compressed)
|
||||
#define BM_TYPE_DXT5 11 // 32 bit with 8 bit alpha (compressed)
|
||||
#define BM_TYPE_CUBEMAP_DDS 12 // generic DDS cubemap (uncompressed cubemap surface)
|
||||
#define BM_TYPE_CUBEMAP_DXT1 13 // 24-bit cubemap (compressed cubemap surface)
|
||||
#define BM_TYPE_CUBEMAP_DXT3 14 // 32-bit cubemap (compressed cubemap surface)
|
||||
#define BM_TYPE_CUBEMAP_DXT5 15 // 32-bit cubemap (compressed cubemap surface)
|
||||
// special types ( used in: bm_bitmaps[i].type )
|
||||
#define BM_TYPE_RENDER_TARGET_STATIC 16 // 24/32 bit setup internally as a static render target
|
||||
#define BM_TYPE_RENDER_TARGET_DYNAMIC 17 // 24/32 bit setup internally as a dynamic render target
|
||||
|
||||
|
||||
/// Moved from cpp file ///////////////////
|
||||
// Consider these 'protected' structures and functions that should only be used by special bitmap functions
|
||||
typedef union bm_extra_info {
|
||||
struct {
|
||||
// Stuff needed for animations
|
||||
int first_frame; // used for animations -- points to index of first frame
|
||||
int num_frames; // used for animation -- number of frames in the animation
|
||||
ubyte fps; // used for animation -- frames per second
|
||||
int keyframe; // used for animation -- keyframe info
|
||||
|
||||
struct {
|
||||
// stuff for static animations
|
||||
ubyte type; // type for individual images
|
||||
char filename[MAX_FILENAME_LEN]; // filename for individual images
|
||||
} eff;
|
||||
} ani;
|
||||
|
||||
struct {
|
||||
// Stuff needed for user bitmaps
|
||||
void *data; // For user bitmaps, this is where the data comes from
|
||||
ubyte bpp; // For user bitmaps, this is what format the data is
|
||||
ubyte flags; // Flags passed to bm_create
|
||||
} user;
|
||||
} bm_extra_info;
|
||||
|
||||
|
||||
typedef struct bitmap_entry {
|
||||
// identification
|
||||
char filename[MAX_FILENAME_LEN]; // filename for this bitmap
|
||||
|
||||
uint signature; // a unique signature identifying the data
|
||||
uint palette_checksum; // checksum used to be sure bitmap is in current palette
|
||||
int handle; // Handle = id*MAX_BITMAPS + bitmapnum
|
||||
int last_used; // When this bitmap was last used
|
||||
|
||||
ubyte type; // PCX, USER, ANI, etc
|
||||
ubyte comp_type; // What sort of compressed type, BM_TYPE_NONE if not compressed
|
||||
signed char ref_count; // Number of locks on bitmap. Can't unload unless ref_count is 0.
|
||||
|
||||
int dir_type; // which directory this was loaded from (to skip other locations with same name)
|
||||
|
||||
// compressed bitmap stuff (.dds) - RT please take a look at this and tell me if we really need it
|
||||
int mem_taken; // How much memory does this bitmap use? - UnknownPlayer
|
||||
int num_mipmaps; // number of mipmap levels, we need to read all of them
|
||||
|
||||
// Stuff to keep track of usage
|
||||
ubyte preloaded; // If set, then this was loaded from the lst file
|
||||
int preload_count; // how many times this gets used in game, for unlocking
|
||||
ubyte used_flags; // What flags it was accessed thru
|
||||
int load_count;
|
||||
|
||||
// Bitmap info
|
||||
bitmap bm;
|
||||
|
||||
// Data for animations and user bitmaps
|
||||
bm_extra_info info;
|
||||
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
// bookeeping
|
||||
ubyte used_last_frame; // If set, then it was used last frame
|
||||
ubyte used_this_frame; // If set, then it was used this frame
|
||||
int data_size; // How much data this bitmap uses
|
||||
int used_count; // How many times it was accessed
|
||||
#endif
|
||||
} bitmap_entry;
|
||||
|
||||
extern bitmap_entry bm_bitmaps[MAX_BITMAPS];
|
||||
|
||||
|
||||
// image specific lock functions
|
||||
void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_pcx( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
|
||||
|
||||
#endif // BMPMAN_INTERNAL
|
||||
|
||||
#endif // __BM_INTERNAL_H__
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,290 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _BMPMAN_H
|
||||
#define _BMPMAN_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define BMPMAN_NDEBUG
|
||||
#endif
|
||||
|
||||
|
||||
// this is causing problems - let's UP IT -- Kazan
|
||||
// bumped from 3500 to 4500 2004/09/21 - taylor
|
||||
// bumped to 4750 2005/02/03 - taylor
|
||||
//#define MAX_BITMAPS 3500 // How many bitmaps the game can handle
|
||||
#define MAX_BITMAPS 4750 // How many bitmaps the game can handle
|
||||
// NOTE: MAX_BITMAPS shouldn't need to be bumped again. With the fixed bm_release() and it's
|
||||
// proper use even the largest missions should stay under this number. With the largest retail
|
||||
// missions and wasteful content we should still have about 20% of the slots free. If it still
|
||||
// goes over then it's something the artists need to fix. For instance the Terran Mara fighter,
|
||||
// with -spec and -glow and using the Shinepack, needs 117 bitmap slots alone. 111 of those is
|
||||
// just for the glowmaps. This number can be greatly reduced if the number of ani frames for
|
||||
// another LOD than LOD0 has fewer or no ani frames. A 37 frame glow ani for LOD2 is little
|
||||
// more than a waste of resources. Future reports of texture corruption should be initially
|
||||
// approached with content as the cause and not code. If anything we could/should reduce
|
||||
// MAX_BITMAPS in the future. Where it's at now should accomidate even the largest mods.
|
||||
// -- Taylor
|
||||
|
||||
|
||||
#define BMP_AABITMAP (1<<0) // antialiased bitmap
|
||||
#define BMP_TEX_XPARENT (1<<1) // transparent texture
|
||||
#define BMP_TEX_OTHER (1<<2) // so we can identify all "normal" textures
|
||||
#define BMP_TEX_DXT1 (1<<3) // dxt1 compressed 8r8g8b1a (24bit)
|
||||
#define BMP_TEX_DXT3 (1<<4) // dxt3 compressed 8r8g8b4a (32bit)
|
||||
#define BMP_TEX_DXT5 (1<<5) // dxt5 compressed 8r8g8b8a (32bit)
|
||||
#define BMP_TEX_CUBEMAP (1<<6) // a texture made for cubic environment map
|
||||
// ***** NOTE: bitmap.flags is an 8-bit value, no more BMP_TEX_* flags can be added unless the type is changed!! ******
|
||||
|
||||
//compressed texture types
|
||||
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 )
|
||||
|
||||
//non compressed textures
|
||||
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER )
|
||||
|
||||
// any texture type
|
||||
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP )
|
||||
|
||||
#define BMP_FLAG_RENDER_TARGET_STATIC (1<<0)
|
||||
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1)
|
||||
#define BMP_FLAG_CUBEMAP (1<<2)
|
||||
|
||||
typedef struct bitmap {
|
||||
short w, h; // Width and height
|
||||
short rowsize; // What you need to add to go to next row
|
||||
ubyte bpp; // How many bits per pixel it is. (7,8,15,16,24,32) (what is requested)
|
||||
ubyte true_bpp; // How many bits per pixel the image actually is.
|
||||
ubyte flags; // See the BMP_???? defines for values (this isn't for the BMP_FLAG_* stuff)
|
||||
ptr_u data; // Pointer to data, or maybe offset into VRAM.
|
||||
ubyte *palette; // If bpp==8, this is pointer to palette. If the BMP_NO_PALETTE_MAP flag
|
||||
// is not set, this palette just points to the screen palette. (gr_palette)
|
||||
} bitmap;
|
||||
|
||||
|
||||
extern int Bm_paging;
|
||||
|
||||
void bm_init();
|
||||
|
||||
void bm_close();
|
||||
|
||||
int bm_get_cache_slot( int bitmap_id, int separate_ani_frames );
|
||||
|
||||
int bm_get_next_handle();
|
||||
|
||||
void *bm_malloc(int n, int size);
|
||||
|
||||
void bm_update_memory_used(int n, int size);
|
||||
|
||||
// how many bytes of textures are used.
|
||||
extern int bm_texture_ram;
|
||||
|
||||
// This loads a bitmap so we can draw with it later.
|
||||
// It returns a negative number if it couldn't load
|
||||
// the bitmap. On success, it returns the bitmap
|
||||
// number.
|
||||
int bm_load(char * filename);
|
||||
|
||||
// special load function. basically allows you to load a bitmap which already exists (by filename).
|
||||
// this is useful because in some cases we need to have a bitmap which is locked in screen format
|
||||
// _and_ texture format, such as pilot pics and squad logos
|
||||
int bm_load_duplicate(char *filename);
|
||||
|
||||
// Creates a bitmap that exists in RAM somewhere, instead
|
||||
// of coming from a disk file. You pass in a pointer to a
|
||||
// block of data. The data can be in the following formats:
|
||||
// 8 bpp (mapped into game palette)
|
||||
// 32 bpp
|
||||
// On success, it returns the bitmap number. You cannot
|
||||
// free that RAM until bm_release is called on that bitmap.
|
||||
// See example at bottom of this file
|
||||
int bm_create( int bpp, int w, int h, void *data = NULL, int flags = 0);
|
||||
|
||||
// Frees up a bitmap's data, but bitmap number 'n' can
|
||||
// still be used, it will just have to be paged in next
|
||||
// time it is locked.
|
||||
int bm_unload( int n, int clear_render_targets = 0 );
|
||||
|
||||
// like bm_unload() except that it's safe to use to free data without worrying about
|
||||
// load_count so it's safe to use in relation to bm_release() and in gr_*_texture functions
|
||||
int bm_unload_fast( int n, int clear_render_targets = 0 );
|
||||
|
||||
// Frees up a bitmap's data, and it's slot, so bitmap
|
||||
// number 'n' cannot be used anymore, and bm_load or
|
||||
// bm_create might reuse the slot.
|
||||
int bm_release( int n, int clear_render_targets = 0 );
|
||||
|
||||
// This loads a bitmap sequence so we can draw with it later.
|
||||
// It returns a negative number if it couldn't load
|
||||
// the bitmap. On success, it returns the bitmap
|
||||
// number of the first frame and nframes is set.
|
||||
extern int bm_load_animation( char * filename, int * nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY );
|
||||
|
||||
//Loads either animation (bm_load_animation) or still image (bm_load)
|
||||
extern int bm_load_either(char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
|
||||
|
||||
// This locks down a bitmap and returns a pointer to a bitmap
|
||||
// that can be accessed until you call bm_unlock. Only lock
|
||||
// a bitmap when you need it! This will convert it into the
|
||||
// appropriate format also.
|
||||
extern bitmap * bm_lock( int bitmapnum, ubyte bpp, ubyte flags );
|
||||
|
||||
// The signature is a field that gets filled in with
|
||||
// a unique signature for each bitmap. The signature for each bitmap
|
||||
// will also change when the bitmap's data changes.
|
||||
extern uint bm_get_signature( int bitmapnum);
|
||||
|
||||
//gets the image type
|
||||
ubyte bm_get_type(int handle);
|
||||
|
||||
// Unlocks a bitmap
|
||||
extern void bm_unlock( int bitmapnum );
|
||||
|
||||
//WMC - Returns 0 if invalid, nonzero if valid
|
||||
extern int bm_is_valid(int handle);
|
||||
|
||||
// Gets info. w,h,or flags,nframes or fps can be NULL if you don't care.
|
||||
//WMC - Returns -1 on failure, handle or first frame handle on success.
|
||||
int bm_get_info( int bitmapnum, int *w=NULL, int * h=NULL, ubyte * flags=NULL, int *nframes=NULL, int *fps=NULL );
|
||||
|
||||
// get filename
|
||||
extern void bm_get_filename(int bitmapnum, char *filename);
|
||||
|
||||
// resyncs all the bitmap palette
|
||||
extern void bm_update();
|
||||
|
||||
// call to load all data for all bitmaps that have been requested to be loaded
|
||||
extern void bm_gfx_load_all();
|
||||
extern void bm_unload_all();
|
||||
|
||||
// call to get the palette for a bitmap
|
||||
void bm_get_palette(int n, ubyte *pal, char *name);
|
||||
|
||||
// Hacked function to get a pixel from a bitmap.
|
||||
// Only works good in 8bpp mode.
|
||||
void bm_gfx_get_pixel( int bitmap, float u, float v, ubyte *r, ubyte *g, ubyte *b );
|
||||
|
||||
// Returns number of bytes of bitmaps locked this frame
|
||||
// ntotal = number of bytes of bitmaps locked this frame
|
||||
// nnew = number of bytes of bitmaps locked this frame that weren't locked last frame
|
||||
void bm_get_frame_usage(int *ntotal, int *nnew);
|
||||
|
||||
/*
|
||||
* Example on using bm_create
|
||||
*
|
||||
{
|
||||
static int test_inited = 0;
|
||||
static int test_bmp;
|
||||
static uint test_bmp_data[128*64];
|
||||
|
||||
if ( !test_inited ) {
|
||||
test_inited = 1;
|
||||
// Create the new bitmap and fill in its data.
|
||||
// When you're done with it completely, call
|
||||
// bm_release to free up the bitmap handle
|
||||
test_bmp = bm_create( 32, 128, 64, test_bmp_data );
|
||||
int i,j;
|
||||
for (i=0; i<64; i++ ) {
|
||||
for (j=0; j<64; j++ ) {
|
||||
uint r=i*4;
|
||||
test_bmp_data[j+i*128] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bm_unload(test_bmp); // this pages out the data, so that the
|
||||
// next bm_lock will convert the new data to the
|
||||
// correct bpp
|
||||
|
||||
// put in new data
|
||||
int x,y;
|
||||
gr_reset_clip();
|
||||
for (y=0; y<64; y++)
|
||||
for (x=0; x<128; x++ )
|
||||
test_bmp_data[y*128+x] = 15;
|
||||
|
||||
// Draw the bitmap to upper left corner
|
||||
gr_set_bitmap(test_bmp);
|
||||
gr_bitmap( 0,0 );
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//============================================================================
|
||||
// Paging stuff
|
||||
//============================================================================
|
||||
|
||||
void bm_page_in_start();
|
||||
void bm_page_in_stop();
|
||||
|
||||
// Paging code in a library should call these functions
|
||||
// in its page in function.
|
||||
|
||||
// Marks a texture as being used for this level
|
||||
// If num_frames is passed, assume this is an animation
|
||||
void bm_page_in_texture( int bitmapnum, int num_frames = 0 );
|
||||
|
||||
// marks a texture as being a transparent textyre used for this level
|
||||
// Marks a texture as being used for this level
|
||||
// If num_frames is passed, assume this is an animation
|
||||
void bm_page_in_xparent_texture( int bitmapnum, int num_frames=1 );
|
||||
|
||||
// Marks an aabitmap as being used for this level
|
||||
// If num_frames is passed, assume this is an animation
|
||||
void bm_page_in_aabitmap( int bitmapnum, int num_frames=1 );
|
||||
|
||||
// unload a texture that was paged in
|
||||
int bm_page_out( int handle );
|
||||
|
||||
//
|
||||
// Mode: 0 = High memory
|
||||
// 1 = Low memory ( every other frame of ani's)
|
||||
// 2 = Debug low memory ( only use first frame of each ani )
|
||||
void bm_set_low_mem( int mode );
|
||||
|
||||
char *bm_get_filename(int handle);
|
||||
|
||||
void BM_SELECT_SCREEN_FORMAT();
|
||||
void BM_SELECT_TEX_FORMAT();
|
||||
void BM_SELECT_ALPHA_TEX_FORMAT();
|
||||
|
||||
// set the rgba components of a pixel, any of the parameters can be NULL
|
||||
extern void (*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
extern void (*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_argb_d3d_16_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_argb_d3d_32_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_argb_d3d_16_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
void bm_set_components_argb_d3d_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
// get the rgba components of a pixel, any of the parameters can be NULL
|
||||
void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
extern int GLOWMAP; //this holds a reference to a map that is a fully lit version of its index -Bobboau
|
||||
extern int SPECMAP; //this holds a reference to a map that is for specular mapping -Bobboau
|
||||
extern int ENVMAP; //this holds a reference to a map that is for environment mapping -Bobboau
|
||||
extern int NORMMAP; // normal mapping
|
||||
extern int HEIGHTMAP; // height map for normal mapping
|
||||
|
||||
int bm_is_compressed(int num);
|
||||
int bm_get_tcache_type(int num);
|
||||
int bm_get_size(int num);
|
||||
int bm_get_num_mipmaps(int num);
|
||||
int bm_has_alpha_channel(int handle);
|
||||
|
||||
void bm_print_bitmaps();
|
||||
|
||||
int bm_make_render_target( int width, int height, int flags );
|
||||
int bm_is_render_target(int bitmap_id);
|
||||
int bm_set_render_target(int handle, int face = -1);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,184 +0,0 @@
|
||||
|
||||
#ifndef _CAMERA_H
|
||||
#define _CAMERA_H
|
||||
|
||||
#include "graphics/2d.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/globals.h"
|
||||
#include "physics/physics.h" //for avd
|
||||
#include "object/object.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#define CAM_STATIONARY_FOV (1<<0)
|
||||
#define CAM_STATIONARY_ORI (1<<1)
|
||||
#define CAM_STATIONARY_POS (1<<2)
|
||||
#define CAM_DEFAULT_FLAGS 0
|
||||
|
||||
class camera
|
||||
{
|
||||
friend class avd_camera;
|
||||
protected:
|
||||
char name[NAME_LENGTH];
|
||||
int sig;
|
||||
int flags;
|
||||
|
||||
object_h object_host;
|
||||
int object_host_submodel;
|
||||
|
||||
object_h object_target;
|
||||
int object_target_submodel;
|
||||
|
||||
void (*func_custom_position)(camera *cam, vec3d *pos);
|
||||
void (*func_custom_orientation)(camera *cam, matrix *ori);
|
||||
|
||||
avd_movement fov;
|
||||
|
||||
avd_movement pos_x;
|
||||
avd_movement pos_y;
|
||||
avd_movement pos_z;
|
||||
|
||||
//avd_movement ori_p;
|
||||
//avd_movement ori_b;
|
||||
//avd_movement ori_h;
|
||||
//avd_movement ori_progress;
|
||||
//matrix ori_initial;
|
||||
//matrix ori_final;
|
||||
avd_movement ori[9];
|
||||
|
||||
//Cache stuff
|
||||
float c_fov;
|
||||
vec3d c_pos;
|
||||
matrix c_ori;
|
||||
public:
|
||||
camera(char *in_name=NULL, int in_signature=-1);
|
||||
~camera();
|
||||
void clear();
|
||||
void reset();
|
||||
|
||||
//Set
|
||||
void set_name(char *in_name);
|
||||
|
||||
void set_object_host(object *objp, int n_object_host_submodel = -1);
|
||||
void set_object_target(object *objp, int n_object_target_submodel = -1);
|
||||
|
||||
void set_custom_position_function(void (*n_func_custom_position)(camera *cam, vec3d *pos));
|
||||
void set_custom_orientation_function(void (*n_func_custom_orientation)(camera *cam, matrix *ori));
|
||||
|
||||
void set_fov(float in_fov, float in_fov_time = 0.0f, float in_fov_acceleration_time = 0.0f, float in_deceleration_time = 0.0f);
|
||||
|
||||
void set_position(vec3d *in_position = NULL, float in_translation_time = 0.0f, float in_translation_acceleration_time = 0.0f, float in_translation_deceleration_time = 0.0f, float in_end_velocity = 0.0f);
|
||||
void set_translation_velocity(vec3d *in_velocity, float in_acceleration_time = 0.0f);
|
||||
|
||||
void set_rotation(matrix *in_orientation = NULL, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation(angles *in_angles, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation_facing(vec3d *in_target, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time = 0.0f);
|
||||
|
||||
//Get
|
||||
char *get_name() {return name;}
|
||||
int get_signature() {return sig;}
|
||||
object *get_object_host();
|
||||
int get_object_host_submodel();
|
||||
object *get_object_target();
|
||||
int get_object_target_submodel();
|
||||
float get_fov();
|
||||
void get_info(vec3d *position, matrix *orientation);
|
||||
|
||||
//Is
|
||||
bool is_empty(){return sig < 0;}
|
||||
|
||||
//Do
|
||||
void do_frame(float in_frametime);
|
||||
};
|
||||
|
||||
class warp_camera
|
||||
{
|
||||
private:
|
||||
float c_time;
|
||||
float c_damping;
|
||||
|
||||
vec3d c_vel;
|
||||
vec3d c_desired_vel;
|
||||
|
||||
vec3d c_pos;
|
||||
matrix c_ori;
|
||||
public:
|
||||
warp_camera();
|
||||
warp_camera(object *objp);
|
||||
void reset();
|
||||
|
||||
void set_position(vec3d *in_pos);
|
||||
void set_rotation(matrix *in_ori);
|
||||
void set_velocity(vec3d *in_vel, bool instantaneous);
|
||||
|
||||
void do_frame(float in_frametime);
|
||||
|
||||
void get_info(vec3d *position, matrix *orientation);
|
||||
};
|
||||
|
||||
extern warp_camera Warp_camera;
|
||||
|
||||
class subtitle
|
||||
{
|
||||
private:
|
||||
void clone(const subtitle &sub);
|
||||
|
||||
SCP_vector<std::string> text_lines;
|
||||
struct { int x; int y; } text_pos;
|
||||
|
||||
float display_time;
|
||||
float fade_time;
|
||||
color text_color;
|
||||
int text_fontnum;
|
||||
|
||||
//Done with set
|
||||
char imageanim[MAX_FILENAME_LEN];
|
||||
int image_id;
|
||||
struct { int x; int y; int w; int h; } image_pos;
|
||||
|
||||
//Time this has been displayed
|
||||
float time_displayed;
|
||||
|
||||
//When to end it
|
||||
float time_displayed_end;
|
||||
|
||||
bool post_shaded;
|
||||
public:
|
||||
subtitle(int in_x_pos, int in_y_pos, char* in_text = NULL, char* in_imageanim = NULL,
|
||||
float in_display_time = 0, float in_fade_time = 0.0f, color *in_text_color = NULL, int in_text_fontnum = -1,
|
||||
bool center_x = false, bool center_y = false, int in_width = 0, int in_height = 0, bool post_shaded=false);
|
||||
~subtitle();
|
||||
|
||||
subtitle(const subtitle &sub) { clone(sub); }
|
||||
const subtitle &operator=(const subtitle &sub);
|
||||
|
||||
void do_frame(float frametime);
|
||||
bool is_post_shaded( ) { return post_shaded; }
|
||||
};
|
||||
|
||||
//Some global stuff
|
||||
extern SCP_vector<subtitle> Subtitles;
|
||||
extern float VIEWER_ZOOM_DEFAULT;
|
||||
extern float Sexp_fov;
|
||||
|
||||
//Helpful functions
|
||||
void cam_init();
|
||||
void cam_close();
|
||||
void cam_do_frame(float frametime);
|
||||
camid cam_create(char *n_name=NULL, vec3d *n_pos=NULL, matrix *n_ori=NULL, object *n_object=NULL, int n_submodel_parent=-1);
|
||||
camid cam_create(char *n_name, vec3d *n_pos, vec3d *n_norm, object *n_object=NULL, int n_submodel_parent=-1);
|
||||
void cam_delete(camid cid);
|
||||
bool cam_set_camera(camid cid);
|
||||
void cam_reset_camera();
|
||||
camid cam_lookup(char *name);
|
||||
camid cam_get_camera(uint index);
|
||||
camid cam_get_current();
|
||||
uint cam_get_num();
|
||||
|
||||
void subtitles_init();
|
||||
void subtitles_close();
|
||||
void subtitles_do_frame(float frametime);
|
||||
void subtitles_do_frame_post_shaded(float frametime);
|
||||
|
||||
#endif // _CAMERA_H
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,326 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __CFILE_H__
|
||||
#define __CFILE_H__
|
||||
|
||||
|
||||
#include <time.h>
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#define CF_EOF (-1)
|
||||
|
||||
#define CF_SEEK_SET (0)
|
||||
#define CF_SEEK_CUR (1)
|
||||
#define CF_SEEK_END (2)
|
||||
|
||||
typedef struct CFILE {
|
||||
int id; // Index into cfile.cpp specific structure
|
||||
int version; // version of this file
|
||||
} CFILE;
|
||||
|
||||
// extra info that can be returned when getting a file listing
|
||||
typedef struct {
|
||||
time_t write_time;
|
||||
} file_list_info;
|
||||
|
||||
|
||||
#define CF_MAX_FILENAME_LENGTH 32 // Includes null terminater, so real length is 31
|
||||
#define CF_MAX_PATHNAME_LENGTH 256 // Includes null terminater, so real length is 255
|
||||
|
||||
#define CF_TYPE_ANY -1 // Used to check in any directory
|
||||
|
||||
#define CF_TYPE_INVALID 0
|
||||
#define CF_TYPE_ROOT 1 // Root must be 1!!
|
||||
#define CF_TYPE_DATA 2
|
||||
#define CF_TYPE_MAPS 3
|
||||
#define CF_TYPE_TEXT 4
|
||||
#define CF_TYPE_MODELS 5
|
||||
#define CF_TYPE_TABLES 6
|
||||
#define CF_TYPE_SOUNDS 7
|
||||
#define CF_TYPE_SOUNDS_8B22K 8
|
||||
#define CF_TYPE_SOUNDS_16B11K 9
|
||||
#define CF_TYPE_VOICE 10
|
||||
#define CF_TYPE_VOICE_BRIEFINGS 11
|
||||
#define CF_TYPE_VOICE_CMD_BRIEF 12
|
||||
#define CF_TYPE_VOICE_DEBRIEFINGS 13
|
||||
#define CF_TYPE_VOICE_PERSONAS 14
|
||||
#define CF_TYPE_VOICE_SPECIAL 15
|
||||
#define CF_TYPE_VOICE_TRAINING 16
|
||||
#define CF_TYPE_MUSIC 17
|
||||
#define CF_TYPE_MOVIES 18
|
||||
#define CF_TYPE_INTERFACE 19
|
||||
#define CF_TYPE_FONT 20
|
||||
#define CF_TYPE_EFFECTS 21
|
||||
#define CF_TYPE_HUD 22
|
||||
#define CF_TYPE_PLAYERS 23
|
||||
#define CF_TYPE_PLAYER_IMAGES 24
|
||||
#define CF_TYPE_SQUAD_IMAGES 25
|
||||
#define CF_TYPE_SINGLE_PLAYERS 26
|
||||
#define CF_TYPE_MULTI_PLAYERS 27
|
||||
#define CF_TYPE_CACHE 28
|
||||
#define CF_TYPE_MULTI_CACHE 29
|
||||
#define CF_TYPE_MISSIONS 30
|
||||
#define CF_TYPE_CONFIG 31
|
||||
#define CF_TYPE_DEMOS 32
|
||||
#define CF_TYPE_CBANIMS 33
|
||||
#define CF_TYPE_INTEL_ANIMS 34
|
||||
#define CF_TYPE_SCRIPTS 35
|
||||
#define CF_TYPE_FICTION 36
|
||||
|
||||
#define CF_MAX_PATH_TYPES 37 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
|
||||
|
||||
// TRUE if type is specified and valid
|
||||
#define CF_TYPE_SPECIFIED(path_type) (((path_type)>CF_TYPE_INVALID) && ((path_type)<CF_MAX_PATH_TYPES))
|
||||
|
||||
// #define's for the type parameter in cfopen.
|
||||
#define CFILE_NORMAL 0 // open file normally
|
||||
#define CFILE_MEMORY_MAPPED (1<<0) // open file as a memory-mapped file
|
||||
|
||||
#define CF_SORT_NONE 0
|
||||
#define CF_SORT_NAME 1
|
||||
#define CF_SORT_TIME 2
|
||||
#define CF_SORT_REVERSE 3
|
||||
|
||||
#define cfread_fix(file) (fix)cfread_int(file)
|
||||
#define cfwrite_fix(i,file) cfwrite_int(i,file)
|
||||
|
||||
// callback function used for get_file_list() to filter files to be added to list. Return 1
|
||||
// to add file to list, or 0 to not add it.
|
||||
extern int (*Get_file_list_filter)(char *filename);
|
||||
|
||||
// cfile directory. valid after cfile_init() returns successfully
|
||||
#define CFILE_ROOT_DIRECTORY_LEN 256
|
||||
extern char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
#ifdef SCP_UNIX
|
||||
extern char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
#endif
|
||||
|
||||
//================= LOW-LEVEL FUNCTIONS ==================
|
||||
// Call this once at the beginning of the program
|
||||
int cfile_init(char *exe_dir,char *cdrom_dir=NULL);
|
||||
|
||||
// Call this if pack files got added or removed or the
|
||||
// cdrom changed. This will refresh the list of filenames
|
||||
// stored in packfiles and on the cdrom.
|
||||
void cfile_refresh();
|
||||
|
||||
// add an extension to a filename if it doesn't already have it
|
||||
char *cf_add_ext(char *filename, char *ext);
|
||||
|
||||
// return CF_TYPE (directory location type) of a CFILE you called cfopen() successfully on.
|
||||
int cf_get_dir_type(CFILE *cfile);
|
||||
|
||||
// Opens the file. If no path is given, use the extension to look into the
|
||||
// default path. If mode is NULL, delete the file.
|
||||
CFILE *cfopen(char *filename, char *mode, int type = CFILE_NORMAL, int dir_type = CF_TYPE_ANY, bool localize = false);
|
||||
|
||||
// like cfopen(), but it accepts a fully qualified path only (ie, the result of a cf_find_file_location() call)
|
||||
// NOTE: only supports reading files!!
|
||||
CFILE *cfopen_special(char *file_path, char *mode, const int size, const int offset, int dir_type = CF_TYPE_ANY);
|
||||
|
||||
// Flush the open file buffer
|
||||
int cflush(CFILE *cfile);
|
||||
|
||||
// version number of opened file. Will be 0 unless you put something else here after you
|
||||
// open a file. Once set, you can use minimum version numbers with the read functions.
|
||||
void cf_set_version( CFILE * cfile, int version );
|
||||
|
||||
// Deletes a file. Returns 0 on error, 1 if successful
|
||||
int cf_delete(char *filename, int dir_type);
|
||||
|
||||
// Same as _access function to read a file's access bits
|
||||
int cf_access(char *filename, int dir_type, int mode);
|
||||
|
||||
// Returns 1 if the file exists, 0 if not.
|
||||
// Checks only the file system.
|
||||
int cf_exists(char *filename, int dir_type);
|
||||
|
||||
// Goober5000
|
||||
// Returns 1 if the file exists, 0 if not.
|
||||
// Checks both the file system and the VPs.
|
||||
int cf_exists_full(char *filename, int dir_type);
|
||||
// check num_ext worth of ext_list extensions
|
||||
int cf_exists_full_ext(char *filename, int dir_type, const int num_ext, const char **ext_list);
|
||||
|
||||
// ctmpfile() opens a temporary file stream. File is deleted automatically when closed
|
||||
CFILE *ctmpfile();
|
||||
|
||||
// Closes the file
|
||||
int cfclose(CFILE *cfile);
|
||||
|
||||
//Checks if the given handle is valid
|
||||
int cf_is_valid(CFILE *cfile);
|
||||
|
||||
// Returns size of file...
|
||||
int cfilelength(CFILE *fp);
|
||||
|
||||
// Reads data
|
||||
int cfread(void *buf, int elsize, int nelem, CFILE *fp);
|
||||
|
||||
// cfwrite() writes to the file
|
||||
int cfwrite(void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
|
||||
// Reads/writes RLE compressed data.
|
||||
int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
int cfwrite_compressed(void *param_buf, int param_elsize, int param_nelem, CFILE *cfile);
|
||||
|
||||
// Moves the file pointer
|
||||
int cfseek(CFILE *fp, int offset, int where);
|
||||
|
||||
// Returns current position of file.
|
||||
int cftell(CFILE *fp);
|
||||
|
||||
// cfputc() writes a character to a file
|
||||
int cfputc(int c, CFILE *cfile);
|
||||
|
||||
// cfputs() writes a string to a file
|
||||
int cfputs(char *str, CFILE *cfile);
|
||||
|
||||
// cfgetc() reads a character to a file
|
||||
int cfgetc(CFILE *cfile);
|
||||
|
||||
// cfgets() reads a string from a file
|
||||
char *cfgets(char *buf, int n, CFILE *cfile);
|
||||
|
||||
// cfeof() Tests for end-of-file on a stream
|
||||
int cfeof(CFILE *cfile);
|
||||
|
||||
// Return the data pointer associated with the CFILE structure (for memory mapped files)
|
||||
void *cf_returndata(CFILE *cfile);
|
||||
|
||||
// get the 2 byte checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_short(char *filename, ushort *chksum, int max_size = -1, int cf_type = CF_TYPE_ANY );
|
||||
|
||||
// get the 2 byte checksum of the passed file - return 0 if operation failed, 1 if succeeded
|
||||
// NOTE : preserves current file position
|
||||
int cf_chksum_short(CFILE *file, ushort *chksum, int max_size = -1);
|
||||
|
||||
// get the 32 bit CRC checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_long(char *filename, uint *chksum, int max_size = -1, int cf_type = CF_TYPE_ANY );
|
||||
|
||||
// get the 32 bit CRC checksum of the passed file - return 0 if operation failed, 1 if succeeded
|
||||
// NOTE : preserves current file position
|
||||
int cf_chksum_long(CFILE *file, uint *chksum, int max_size = -1);
|
||||
|
||||
int cf_chksum_pack(char *filename, uint *chk_long, bool full = false);
|
||||
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
ushort cf_add_chksum_short(ushort seed, ubyte *buffer, int size);
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
uint cf_add_chksum_long(uint seed, ubyte *buffer, int size);
|
||||
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
//================= HIGH LEVEL FUNCTIONS ==================
|
||||
int cfexist(char *filename); // Returns true if file exists on disk (1) or in hog (2).
|
||||
|
||||
// rename a file, utilizing the extension to determine where file is.
|
||||
#define CF_RENAME_SUCCESS 0 // successfully renamed the file
|
||||
#define CF_RENAME_FAIL_ACCESS 1 // new name could not be created
|
||||
#define CF_RENAME_FAIL_EXIST 2 // old name does not exist
|
||||
int cf_rename(char *old_name, char *name, int type = CF_TYPE_ANY );
|
||||
|
||||
// changes the attributes of a file
|
||||
void cf_attrib(char *name, int set, int clear, int type);
|
||||
|
||||
// flush (delete all files in) the passed directory (by type), return the # of files deleted
|
||||
// NOTE : WILL NOT DELETE READ-ONLY FILES
|
||||
int cfile_flush_dir(int type);
|
||||
|
||||
// functions for reading from cfile
|
||||
// These are all high level, built up from
|
||||
// cfread.
|
||||
int cfgetc(CFILE *fp);
|
||||
char *cfgets(char *buf, size_t n, CFILE *fp);
|
||||
char cfread_char(CFILE *file, int ver = 0, char deflt = 0);
|
||||
ubyte cfread_ubyte(CFILE *file, int ver = 0, ubyte deflt = 0);
|
||||
short cfread_short(CFILE *file, int ver = 0, short deflt = 0);
|
||||
ushort cfread_ushort(CFILE *file, int ver = 0, ushort deflt = 0);
|
||||
int cfread_int(CFILE *file, int ver = 0, int deflt = 0);
|
||||
uint cfread_uint(CFILE *file, int ver = 0, uint deflt = 0);
|
||||
float cfread_float(CFILE *file, int ver = 0, float deflt = 0.0f);
|
||||
void cfread_vector(vec3d *vec, CFILE *file, int ver = 0, vec3d *deflt = NULL);
|
||||
void cfread_angles(angles *ang, CFILE *file, int ver = 0, angles *deflt = NULL);
|
||||
|
||||
// Reads variable length, null-termined string. Will only read up
|
||||
// to n characters.
|
||||
void cfread_string(char *buf,int n, CFILE *file);
|
||||
// Read a fixed length that is null-terminatedm, and has the length
|
||||
// stored in file
|
||||
void cfread_string_len(char *buf,int n, CFILE *file);
|
||||
|
||||
// functions for writing cfiles
|
||||
int cfwrite_char(char c, CFILE *file);
|
||||
int cfwrite_float(float f, CFILE *file);
|
||||
int cfwrite_int(int i, CFILE *file);
|
||||
int cfwrite_uint(uint i, CFILE *file);
|
||||
int cfwrite_short(short s, CFILE *file);
|
||||
int cfwrite_ushort(ushort s, CFILE *file);
|
||||
int cfwrite_ubyte(ubyte u, CFILE *file);
|
||||
int cfwrite_vector(vec3d *vec, CFILE *file);
|
||||
int cfwrite_angles(angles *ang, CFILE *file);
|
||||
|
||||
// writes variable length, null-termined string.
|
||||
int cfwrite_string(char *buf, CFILE *file);
|
||||
|
||||
// write a fixed length that is null-terminatedm, and has the length
|
||||
// stored in file
|
||||
int cfwrite_string_len(char *buf, CFILE *file);
|
||||
|
||||
int cf_get_file_list( int max, char **list, int type, char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int type, char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
void cf_sort_filenames( int n, char **list, int sort, file_list_info *info = NULL );
|
||||
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files.
|
||||
// Input: filespace - Filename & extension
|
||||
// pathtype - See CF_TYPE_ defines in CFILE.H
|
||||
// max_out - Maximum string size to be stuffed into pack_filename
|
||||
// Output: pack_filename - Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns 0.
|
||||
int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize = false);
|
||||
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files. Searches all locations in order for first filename using ext filter list.
|
||||
// Input: filename - Filename & extension
|
||||
// ext_num - number of extensions to look for
|
||||
// ext_list - extension filter list
|
||||
// pathtype - See CF_TYPE_ defines in CFILE.H
|
||||
// max_out - Maximum string length that should be stuffed into pack_filename
|
||||
// Output: pack_filename - Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns -1, else returns offset into ext_list.
|
||||
// (NOTE: This function is exponentially slow, so don't use it unless truely needed!!)
|
||||
int cf_find_file_location_ext(char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out = 0, char *pack_filename = NULL, int *size = NULL, int *offset = NULL, bool localize = false);
|
||||
|
||||
// Functions to change directories
|
||||
int cfile_chdir(char *dir);
|
||||
|
||||
#ifdef _WIN32
|
||||
int cfile_chdrive(int DriveNum, int flag);
|
||||
#endif
|
||||
|
||||
// push current directory on a 'stack' (so we can restore it) and change the directory
|
||||
int cfile_push_chdir(int type);
|
||||
|
||||
// restore directory on top of the stack
|
||||
int cfile_pop_dir();
|
||||
|
||||
|
||||
#endif /* __CFILE_H__ */
|
||||
@@ -1,253 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define _CFILE_INTERNAL
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#include <winbase.h> /* needed for memory mapping of file functions */
|
||||
#endif
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "cfile/cfilearchive.h"
|
||||
#include "luaconf.h"
|
||||
|
||||
|
||||
#define CHECK_POSITION
|
||||
|
||||
// Called once to setup the low-level reading code.
|
||||
|
||||
void cf_init_lowlevel_read_code( CFILE * cfile, int lib_offset, int size, int pos )
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
cb->lib_offset = lib_offset;
|
||||
cb->raw_position = pos;
|
||||
cb->size = size;
|
||||
|
||||
if ( cb->fp ) {
|
||||
if ( cb->lib_offset ) {
|
||||
fseek( cb->fp, cb->lib_offset, SEEK_SET );
|
||||
}
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
int raw_position;
|
||||
raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// cfeof() Tests for end-of-file on a stream
|
||||
//
|
||||
// returns a nonzero value after the first read operation that attempts to read
|
||||
// past the end of the file. It returns 0 if the current position is not end of file.
|
||||
// There is no error return.
|
||||
|
||||
int cfeof(CFILE *cfile)
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
int result;
|
||||
|
||||
result = 0;
|
||||
|
||||
// cfeof() not supported for memory-mapped files
|
||||
Assert( !cb->data );
|
||||
|
||||
Assert(cb->fp != NULL);
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
int raw_position;
|
||||
raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
#endif
|
||||
|
||||
if (cb->raw_position >= cb->size ) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// cftell() returns offset into file
|
||||
//
|
||||
// returns: success ==> offset into the file
|
||||
// error ==> -1
|
||||
//
|
||||
int cftell( CFILE * cfile )
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
// Doesn't work for memory mapped files
|
||||
Assert( !cb->data );
|
||||
|
||||
Assert(cb->fp != NULL);
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
int raw_position;
|
||||
raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
#endif
|
||||
|
||||
return cb->raw_position;
|
||||
}
|
||||
|
||||
|
||||
// cfseek() moves the file pointer
|
||||
//
|
||||
// returns: success ==> 0
|
||||
// error ==> non-zero
|
||||
//
|
||||
int cfseek( CFILE *cfile, int offset, int where )
|
||||
{
|
||||
|
||||
Assert(cfile != NULL);
|
||||
Cfile_block *cb;
|
||||
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
|
||||
cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
|
||||
// TODO: seek to offset in memory mapped file
|
||||
Assert( !cb->data );
|
||||
Assert( cb->fp != NULL );
|
||||
|
||||
int goal_position;
|
||||
|
||||
switch( where ) {
|
||||
case CF_SEEK_SET:
|
||||
goal_position = offset+cb->lib_offset;
|
||||
break;
|
||||
case CF_SEEK_CUR:
|
||||
{
|
||||
goal_position = cb->raw_position+offset+cb->lib_offset;
|
||||
}
|
||||
break;
|
||||
case CF_SEEK_END:
|
||||
goal_position = cb->size+offset+cb->lib_offset;
|
||||
break;
|
||||
default:
|
||||
Int3();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int result = fseek(cb->fp, goal_position, SEEK_SET );
|
||||
cb->raw_position = goal_position - cb->lib_offset;
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
int tmp_offset;
|
||||
tmp_offset = (int)ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// cfread() reads from a file
|
||||
//
|
||||
// returns: returns the number of full elements read
|
||||
//
|
||||
//
|
||||
int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
{
|
||||
if(!cf_is_valid(cfile))
|
||||
return 0;
|
||||
|
||||
int size = elsize*nelem;
|
||||
|
||||
if(buf == NULL || size <= 0)
|
||||
return 0;
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
// cfread() not supported for memory-mapped files
|
||||
if(cb->data != NULL)
|
||||
{
|
||||
Warning(LOCATION, "Writing is not supported for mem-mapped files");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (cb->raw_position+size) > cb->size ) {
|
||||
size = cb->size - cb->raw_position;
|
||||
if ( size < 1 ) {
|
||||
return 0;
|
||||
}
|
||||
//mprintf(( "CFILE: EOF encountered in file\n" ));
|
||||
}
|
||||
|
||||
int bytes_read = fread( buf, 1, size, cb->fp );
|
||||
if ( bytes_read > 0 ) {
|
||||
cb->raw_position += bytes_read;
|
||||
}
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
int tmp_offset;
|
||||
tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
#endif
|
||||
|
||||
return bytes_read / elsize;
|
||||
|
||||
}
|
||||
|
||||
int cfread_lua_number(double *buf, CFILE *cfile)
|
||||
{
|
||||
if(!cf_is_valid(cfile))
|
||||
return 0;
|
||||
|
||||
if(buf == NULL)
|
||||
return 0;
|
||||
|
||||
Cfile_block *cb = &Cfile_block_list[cfile->id];
|
||||
|
||||
// cfread() not supported for memory-mapped files
|
||||
if(cb->data != NULL)
|
||||
{
|
||||
Warning(LOCATION, "Writing is not supported for mem-mapped files");
|
||||
return 0;
|
||||
}
|
||||
|
||||
long orig_pos = ftell(cb->fp);
|
||||
int items_read = fscanf(cb->fp, LUA_NUMBER_SCAN, buf);
|
||||
cb->raw_position += ftell(cb->fp)-orig_pos;
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
int tmp_offset;
|
||||
tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
#endif
|
||||
|
||||
return items_read;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _CFILEARCHIVE_H
|
||||
#define _CFILEARCHIVE_H
|
||||
|
||||
#ifndef _CFILE_INTERNAL
|
||||
#error This file should only be included internally in CFILE!!
|
||||
#endif
|
||||
|
||||
// The following Cfile_block data is private to cfile.cpp
|
||||
// DO NOT MOVE the Cfile_block* information to cfile.h / do not extern this data
|
||||
//
|
||||
#define CFILE_BLOCK_UNUSED 0
|
||||
#define CFILE_BLOCK_USED 1
|
||||
|
||||
typedef struct Cfile_block {
|
||||
int type; // CFILE_BLOCK_UNUSED, CFILE_BLOCK_USED
|
||||
int dir_type; // directory location
|
||||
FILE *fp; // File pointer if opening an individual file
|
||||
void *data; // Pointer for memory-mapped file access. NULL if not mem-mapped.
|
||||
#ifdef _WIN32
|
||||
HANDLE hInFile; // Handle from CreateFile()
|
||||
HANDLE hMapFile; // Handle from CreateFileMapping()
|
||||
#else
|
||||
// int fd; // file descriptor
|
||||
size_t data_length; // length of data for mmap
|
||||
#endif
|
||||
int lib_offset;
|
||||
int raw_position;
|
||||
int size; // for packed files
|
||||
|
||||
} Cfile_block;
|
||||
|
||||
#define MAX_CFILE_BLOCKS 64
|
||||
extern Cfile_block Cfile_block_list[MAX_CFILE_BLOCKS];
|
||||
extern CFILE Cfile_list[MAX_CFILE_BLOCKS];
|
||||
|
||||
// Called once to setup the low-level reading code.
|
||||
void cf_init_lowlevel_read_code( CFILE * cfile, int lib_offset, int size, int pos );
|
||||
|
||||
#endif
|
||||
@@ -1,473 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#include <winbase.h> /* needed for memory mapping of file functions */
|
||||
#endif
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
// Sorts a list of filenames using the specified sorting method (CF_SORT_*).
|
||||
// n = number of filenames in list to sort
|
||||
// list = list of filenames to be sorted
|
||||
// sort = sorting method to use (one of the CF_SORT_* defines)
|
||||
// info = extra info for each file. Only required if sorting by time, however if you
|
||||
// have extra file info, you should pass it as well to get it sorted too (so an
|
||||
// index into list is the same index for info for that file
|
||||
void cf_sort_filenames( int n, char **list, int sort, file_list_info *info )
|
||||
{
|
||||
int i, j, incr;
|
||||
char *t;
|
||||
file_list_info tt;
|
||||
|
||||
if (sort == CF_SORT_NAME) {
|
||||
incr = n / 2;
|
||||
while (incr > 0) {
|
||||
for (i=incr; i<n; i++) {
|
||||
j = i - incr;
|
||||
while (j >= 0) {
|
||||
if (stricmp(list[j], list[j + incr]) > 0) {
|
||||
t = list[j];
|
||||
list[j] = list[j + incr];
|
||||
list[j + incr] = t;
|
||||
|
||||
if (info) {
|
||||
tt = info[j];
|
||||
info[j] = info[j + incr];
|
||||
info[j + incr] = tt;
|
||||
}
|
||||
|
||||
j -= incr;
|
||||
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
incr /= 2;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else if (sort == CF_SORT_TIME) {
|
||||
Assert(info);
|
||||
incr = n / 2;
|
||||
while (incr > 0) {
|
||||
for (i=incr; i<n; i++) {
|
||||
j = i - incr;
|
||||
while (j >= 0) {
|
||||
if (info[j].write_time < info[j + incr].write_time) {
|
||||
t = list[j];
|
||||
list[j] = list[j + incr];
|
||||
list[j + incr] = t;
|
||||
|
||||
tt = info[j];
|
||||
info[j] = info[j + incr];
|
||||
info[j + incr] = tt;
|
||||
j -= incr;
|
||||
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
incr /= 2;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else if (sort == CF_SORT_REVERSE) {
|
||||
incr = n / 2;
|
||||
char buffer[MAX_FILENAME_LEN];
|
||||
file_list_info tt_tmp;
|
||||
|
||||
for (i = 0; i < incr; i++) {
|
||||
t = list[n - 1 - i];
|
||||
|
||||
if (list[i] != t) {
|
||||
strcpy_s(buffer, list[i]);
|
||||
strcpy(list[i], t);
|
||||
strcpy(t, buffer);
|
||||
|
||||
if (info) {
|
||||
tt = info[n - 1 - i];
|
||||
tt_tmp = info[i];
|
||||
info[i] = tt;
|
||||
tt = tt_tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nprintf(("Error", "Unknown sorting method %d passed to cf_sort_filenames()\n", sort));
|
||||
}
|
||||
|
||||
|
||||
#if (0) // these aren't used anywhere now
|
||||
|
||||
// cf_compress - Do Run Length Compression on a block of data. Targa format.
|
||||
//
|
||||
// Usage:
|
||||
// out Buffer to write it out to
|
||||
// in Buffer to compress
|
||||
// bytecount Number of bytes input
|
||||
int cf_compress(char *out, char *in, int bytecount )
|
||||
{
|
||||
int pixcount; // number of pixels in the current packet
|
||||
char *inputpixel=NULL; // current input pixel position
|
||||
char *matchpixel=NULL; // pixel value to match for a run
|
||||
char *flagbyte=NULL; // location of last flag byte to set
|
||||
int rlcount; // current count in r.l. string
|
||||
int rlthresh; // minimum valid run length
|
||||
char *copyloc; // location to begin copying at
|
||||
|
||||
// set the threshold -- the minimum valid run length
|
||||
rlthresh = 2; // Require a 2 pixel span before rle'ing
|
||||
|
||||
// set the first pixel up
|
||||
|
||||
flagbyte = out; // place to put next flag if run
|
||||
inputpixel = in;
|
||||
pixcount = 1;
|
||||
rlcount = 0;
|
||||
copyloc = (char *)0;
|
||||
|
||||
// loop till data processing complete
|
||||
do {
|
||||
|
||||
// if we have accumulated a 128-byte packet, process it
|
||||
if ( pixcount == 129 ) {
|
||||
*flagbyte = 127;
|
||||
|
||||
// set the run flag if this is a run
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
*flagbyte |= 0x80;
|
||||
pixcount = 2;
|
||||
}
|
||||
|
||||
// copy the data into place
|
||||
++flagbyte;
|
||||
memmove( flagbyte, copyloc, pixcount-1 );
|
||||
flagbyte += pixcount-1;
|
||||
pixcount = 1;
|
||||
|
||||
// set up for next packet
|
||||
continue;
|
||||
}
|
||||
|
||||
// if zeroth byte, handle as special case
|
||||
if ( pixcount == 1 ) {
|
||||
rlcount = 0;
|
||||
copyloc = inputpixel; /* point to 1st guy in packet */
|
||||
matchpixel = inputpixel; /* set pointer to pix to match */
|
||||
pixcount = 2;
|
||||
inputpixel += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// assembling a packet -- look at next pixel
|
||||
|
||||
// current pixel == match pixel?
|
||||
if ( *inputpixel == *matchpixel ) {
|
||||
|
||||
// establishing a run of enough length to
|
||||
// save space by doing it
|
||||
// -- write the non-run length packet
|
||||
// -- start run-length packet
|
||||
|
||||
if ( ++rlcount == rlthresh ) {
|
||||
|
||||
// close a non-run packet
|
||||
|
||||
if ( pixcount > (rlcount+1) ) {
|
||||
// write out length and do not set run flag
|
||||
|
||||
*flagbyte++ = (char)(pixcount - 2 - rlthresh);
|
||||
|
||||
memmove(flagbyte, copyloc, (pixcount-1-rlcount) );
|
||||
flagbyte += (pixcount-1-rlcount);
|
||||
|
||||
copyloc = inputpixel;
|
||||
pixcount = rlcount + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// no match -- either break a run or continue without one
|
||||
// if a run exists break it:
|
||||
// write the bytes in the string (1+1)
|
||||
// start the next string
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
|
||||
*flagbyte++ = (char)(0x80 | rlcount);
|
||||
memmove(flagbyte, copyloc, 1 );
|
||||
flagbyte += 1;
|
||||
pixcount = 1;
|
||||
continue;
|
||||
} else {
|
||||
|
||||
// not a match and currently not a run
|
||||
// - save the current pixel
|
||||
// - reset the run-length flag
|
||||
rlcount = 0;
|
||||
matchpixel = inputpixel;
|
||||
}
|
||||
}
|
||||
pixcount++;
|
||||
inputpixel += 1;
|
||||
} while ( inputpixel < (in + bytecount));
|
||||
|
||||
// quit this buffer without loosing any data
|
||||
if ( --pixcount >= 1 ) {
|
||||
*flagbyte = (char)(pixcount - 1);
|
||||
if ( rlcount >= rlthresh ) {
|
||||
*flagbyte |= 0x80;
|
||||
pixcount = 1;
|
||||
}
|
||||
|
||||
// copy the data into place
|
||||
++flagbyte;
|
||||
memmove(flagbyte, copyloc, pixcount );
|
||||
flagbyte += pixcount;
|
||||
}
|
||||
return(flagbyte-out);
|
||||
}
|
||||
|
||||
|
||||
// cf_decompress - Do Decompression on a run-length encoded block of data. Targa format.
|
||||
//
|
||||
// Usage:
|
||||
// out Buffer to write it out to
|
||||
// in Buffer to compress
|
||||
// bytecount Number of bytes input
|
||||
int cf_decompress(char *out, char *in )
|
||||
{
|
||||
int count;
|
||||
|
||||
char *param_out = out;
|
||||
|
||||
while(1) {
|
||||
|
||||
count = int(*in++);
|
||||
int run_span = count & 0x80;
|
||||
|
||||
count &= (~0x80);
|
||||
|
||||
if ( count > 0 ) {
|
||||
if ( run_span ) {
|
||||
// RLE'd data
|
||||
ubyte c = *in++;
|
||||
|
||||
memset( out, c, count );
|
||||
out += count;
|
||||
} else {
|
||||
memmove( out, in, count );
|
||||
in += count;
|
||||
out += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out - param_out;
|
||||
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
|
||||
// cfread() reads from a file and decompresses it
|
||||
//
|
||||
// returns: returns the number of full elements read
|
||||
//
|
||||
//
|
||||
int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
{
|
||||
char *out = (char *)buf;
|
||||
|
||||
while(1) {
|
||||
|
||||
ubyte count;
|
||||
|
||||
if ( cfread( &count, 1, 1, cfile ) != 1 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
int run_span = count & 0x80;
|
||||
count &= (~0x80);
|
||||
count++;
|
||||
|
||||
if ( count > 0 ) {
|
||||
if ( run_span ) {
|
||||
// RLE'd data
|
||||
ubyte c;
|
||||
if ( cfread( &c, 1, 1, cfile ) != 1 ) {
|
||||
break;
|
||||
}
|
||||
memset( out, c, count );
|
||||
} else {
|
||||
if ( cfread( out, 1, count, cfile ) != count ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
out += count;
|
||||
if ( out >= (char *)buf + (elsize*nelem)) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (out - (char *)buf)/elsize;
|
||||
}
|
||||
|
||||
int cfwrite_compressed(void *param_buf, int param_elsize, int param_nelem, CFILE *cfile)
|
||||
{
|
||||
char *in = (char *)param_buf;
|
||||
int bytecount = (param_elsize * param_nelem );
|
||||
|
||||
int pixcount; // number of pixels in the current packet
|
||||
char *inputpixel=NULL; // current input pixel position
|
||||
char *matchpixel=NULL; // pixel value to match for a run
|
||||
int rlcount; // current count in r.l. string
|
||||
int rlthresh; // minimum valid run length
|
||||
char *copyloc; // location to begin copying at
|
||||
|
||||
// set the threshold -- the minimum valid run length
|
||||
rlthresh = 2; // Require a 2 pixel span before rle'ing
|
||||
|
||||
// set the first pixel up
|
||||
|
||||
inputpixel = in;
|
||||
pixcount = 1;
|
||||
rlcount = 0;
|
||||
copyloc = (char *)0;
|
||||
|
||||
// loop till data processing complete
|
||||
do {
|
||||
|
||||
// if we have accumulated a 128-byte packet, process it
|
||||
if ( pixcount == 129 ) {
|
||||
ubyte code = 127;
|
||||
|
||||
// set the run flag if this is a run
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
code |= 0x80;
|
||||
pixcount = 2;
|
||||
}
|
||||
|
||||
cfwrite( &code, 1, 1, cfile );
|
||||
|
||||
// copy the data into place
|
||||
cfwrite( copyloc, 1, pixcount-1, cfile );
|
||||
pixcount = 1;
|
||||
|
||||
// set up for next packet
|
||||
continue;
|
||||
}
|
||||
|
||||
// if zeroth byte, handle as special case
|
||||
if ( pixcount == 1 ) {
|
||||
rlcount = 0;
|
||||
copyloc = inputpixel; /* point to 1st guy in packet */
|
||||
matchpixel = inputpixel; /* set pointer to pix to match */
|
||||
pixcount = 2;
|
||||
inputpixel += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// assembling a packet -- look at next pixel
|
||||
|
||||
// current pixel == match pixel?
|
||||
if ( *inputpixel == *matchpixel ) {
|
||||
|
||||
// establishing a run of enough length to
|
||||
// save space by doing it
|
||||
// -- write the non-run length packet
|
||||
// -- start run-length packet
|
||||
|
||||
if ( ++rlcount == rlthresh ) {
|
||||
|
||||
// close a non-run packet
|
||||
|
||||
if ( pixcount > (rlcount+1) ) {
|
||||
// write out length and do not set run flag
|
||||
|
||||
ubyte code = (ubyte)(pixcount - 2 - rlthresh);
|
||||
cfwrite( &code, 1, 1, cfile );
|
||||
|
||||
cfwrite( copyloc, 1, (pixcount-1-rlcount), cfile );
|
||||
copyloc = inputpixel;
|
||||
pixcount = rlcount + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// no match -- either break a run or continue without one
|
||||
// if a run exists break it:
|
||||
// write the bytes in the string (1+1)
|
||||
// start the next string
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
|
||||
ubyte code = (ubyte)(0x80 | rlcount);
|
||||
cfwrite( &code, 1, 1, cfile );
|
||||
cfwrite( copyloc, 1, 1, cfile );
|
||||
pixcount = 1;
|
||||
continue;
|
||||
} else {
|
||||
|
||||
// not a match and currently not a run
|
||||
// - save the current pixel
|
||||
// - reset the run-length flag
|
||||
rlcount = 0;
|
||||
matchpixel = inputpixel;
|
||||
}
|
||||
}
|
||||
pixcount++;
|
||||
inputpixel += 1;
|
||||
} while ( inputpixel < (in + bytecount));
|
||||
|
||||
// quit this buffer without loosing any data
|
||||
if ( --pixcount >= 1 ) {
|
||||
ubyte code = ubyte(pixcount - 1);
|
||||
|
||||
// set the run flag if this is a run
|
||||
|
||||
if ( rlcount >= rlthresh ) {
|
||||
code |= 0x80;
|
||||
pixcount = 1;
|
||||
}
|
||||
|
||||
cfwrite( &code, 1, 1, cfile );
|
||||
|
||||
// copy the data into place
|
||||
cfwrite( copyloc, 1, pixcount, cfile );
|
||||
}
|
||||
|
||||
return param_nelem;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _CFILESYSTEM_H
|
||||
#define _CFILESYSTEM_H
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
// Builds a list of all the files
|
||||
void cf_build_secondary_filelist( char *cdrom_path );
|
||||
void cf_free_secondary_filelist();
|
||||
|
||||
// Internal stuff
|
||||
typedef struct cf_pathtype {
|
||||
int index; // To verify that the CF_TYPE define is correctly indexed into this array
|
||||
char *path; // Path relative to FreeSpace root, has ending backslash.
|
||||
char *extensions; // Extensions used in this pathtype, separated by spaces
|
||||
int parent_index; // Index of this directory's parent. Used for creating directories when writing.
|
||||
} cf_pathtype;
|
||||
|
||||
// During cfile_init, verify that Pathtypes[n].index == n for each item
|
||||
extern cf_pathtype Pathtypes[CF_MAX_PATH_TYPES];
|
||||
|
||||
// Returns the default storage path for files given a
|
||||
// particular pathtype. In other words, the path to
|
||||
// the unpacked, non-cd'd, stored on hard drive path.
|
||||
// If filename isn't null it will also tack the filename
|
||||
// on the end, creating a completely valid filename.
|
||||
// Input: pathtype - CF_TYPE_??
|
||||
// path_max - Maximum characters in the path
|
||||
// filename - optional, if set, tacks the filename onto end of path.
|
||||
// Output: path - Fully qualified pathname.
|
||||
//Returns 0 if result would be too long (invalid result)
|
||||
int cf_create_default_path_string( char *path, uint path_max, int pathtype, char *filename=NULL, bool localize = false);
|
||||
|
||||
|
||||
#endif //_CFILESYSTEM_H
|
||||
@@ -1,432 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <conio.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
static int data_error;
|
||||
static int no_dir;
|
||||
|
||||
// right out of pstypes.h but we don't want to use the INTEL_INT macro here
|
||||
// since it would require SDL which isn't used on WIN32 platforms
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define INT_SWAP(x) ( \
|
||||
(x << 24) | \
|
||||
(((ulong)x) >> 24) | \
|
||||
((x & 0x0000ff00) << 8) | \
|
||||
((x & 0x00ff0000) >> 8) \
|
||||
)
|
||||
#else
|
||||
#define INT_SWAP(x) (x)
|
||||
#endif
|
||||
|
||||
|
||||
size_t fswrite_int(int *wint, FILE *stream)
|
||||
{
|
||||
int tmp = *wint;
|
||||
tmp = INT_SWAP(tmp);
|
||||
|
||||
return fwrite(&tmp, 1, sizeof(int), stream);
|
||||
}
|
||||
|
||||
unsigned int Total_size=16; // Start with size of header
|
||||
unsigned int Num_files =0;
|
||||
FILE *fp_out = NULL;
|
||||
FILE *fp_out_hdr = NULL;
|
||||
|
||||
typedef struct vp_header {
|
||||
char id[4];
|
||||
int version;
|
||||
int index_offset;
|
||||
int num_files;
|
||||
} vp_header;
|
||||
|
||||
//vp_header Vp_header;
|
||||
|
||||
char archive_dat[1024];
|
||||
char archive_hdr[1024];
|
||||
|
||||
#define BLOCK_SIZE (1024*1024)
|
||||
#define VERSION_NUMBER 2;
|
||||
|
||||
char tmp_data[BLOCK_SIZE]; // 1 MB
|
||||
|
||||
void write_header()
|
||||
{
|
||||
int ver = VERSION_NUMBER;
|
||||
|
||||
fseek(fp_out, 0, SEEK_SET);
|
||||
fwrite("VPVP", 1, 4, fp_out);
|
||||
fswrite_int(&ver, fp_out);
|
||||
fswrite_int((int*)&Total_size, fp_out);
|
||||
fswrite_int((int*)&Num_files, fp_out);
|
||||
}
|
||||
|
||||
int write_index(char *hf, char *df)
|
||||
{
|
||||
FILE *h = NULL, *d = NULL;
|
||||
unsigned int i;
|
||||
|
||||
h = fopen(hf, "rb");
|
||||
d = fopen(df, "a+b");
|
||||
|
||||
if ( (h == NULL) || (d == NULL) )
|
||||
{
|
||||
if ( h )
|
||||
fclose( h );
|
||||
if ( d )
|
||||
fclose( d );
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < Num_files; i++) {
|
||||
fread(tmp_data, 32+4+4+4, 1, h);
|
||||
fwrite(tmp_data, 32+4+4+4, 1, d);
|
||||
}
|
||||
|
||||
fclose(h);
|
||||
fclose(d);
|
||||
|
||||
unlink(hf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pack_file( char *filespec, char *filename, int filesize, _fs_time_t time_write )
|
||||
{
|
||||
char path[1024];
|
||||
|
||||
if ( strstr( filename, ".vp" )) {
|
||||
// Don't pack yourself!!
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strstr( filename, ".hdr" )) {
|
||||
// Don't pack yourself!!
|
||||
return;
|
||||
}
|
||||
|
||||
if ( filesize == 0 ) {
|
||||
// Don't pack 0 length files, screws up directory structure!
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strlen(filename) > 31 ) {
|
||||
printf( "Filename '%s' too long! Skipping...\n", filename );
|
||||
return;
|
||||
}
|
||||
|
||||
memset( path, 0, sizeof(path) );
|
||||
strcpy( path, filename );
|
||||
|
||||
fswrite_int( (int*)&Total_size, fp_out_hdr );
|
||||
fswrite_int( &filesize, fp_out_hdr );
|
||||
fwrite( &path, 1, 32, fp_out_hdr );
|
||||
fswrite_int( (int*)&time_write, fp_out_hdr );
|
||||
|
||||
Total_size += filesize;
|
||||
Num_files++;
|
||||
|
||||
printf( "Packing %s%s%s...", filespec, DIR_SEPARATOR_STR, filename );
|
||||
|
||||
sprintf( path, "%s%s%s", filespec, DIR_SEPARATOR_STR, filename );
|
||||
|
||||
|
||||
FILE *fp = fopen( path, "rb" );
|
||||
|
||||
if ( fp == NULL ) {
|
||||
printf( "Error opening '%s'\n", path );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int nbytes, nbytes_read=0;
|
||||
|
||||
do {
|
||||
nbytes = fread( tmp_data, 1, BLOCK_SIZE, fp );
|
||||
if ( nbytes > 0 ) {
|
||||
fwrite( tmp_data, 1, nbytes, fp_out );
|
||||
nbytes_read += nbytes;
|
||||
|
||||
}
|
||||
} while( nbytes > 0 );
|
||||
|
||||
fclose(fp);
|
||||
|
||||
printf( " %d bytes\n", nbytes_read );
|
||||
}
|
||||
|
||||
// This function adds a directory marker to the header file
|
||||
void add_directory( char * dirname)
|
||||
{
|
||||
char path[256];
|
||||
char *pathptr = path;
|
||||
char *tmpptr;
|
||||
int i = 0;
|
||||
|
||||
strcpy(path, dirname);
|
||||
|
||||
fswrite_int( (int*)&Total_size, fp_out_hdr);
|
||||
fswrite_int( &i, fp_out_hdr);
|
||||
|
||||
// strip out any directories that this dir is a subdir of
|
||||
while ( (tmpptr = strchr(pathptr, DIR_SEPARATOR_CHAR)) != NULL ) {
|
||||
pathptr = tmpptr+1;
|
||||
}
|
||||
|
||||
fwrite(pathptr, 1, 32, fp_out_hdr);
|
||||
fswrite_int( &i, fp_out_hdr); // timestamp = 0
|
||||
|
||||
Num_files++;
|
||||
}
|
||||
|
||||
void pack_directory( char * filespec)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int find_handle;
|
||||
_finddata_t find;
|
||||
#endif
|
||||
char tmp[512];
|
||||
char tmp1[512];
|
||||
char *ts;
|
||||
|
||||
// strip trailing slash
|
||||
ts = filespec + (strlen(filespec) - 1);
|
||||
while ( (*ts == DIR_SEPARATOR_CHAR) && (ts > filespec) )
|
||||
*ts = '\0';
|
||||
|
||||
strcpy( tmp1, filespec );
|
||||
|
||||
add_directory(filespec);
|
||||
strcat( tmp1, DIR_SEPARATOR_STR"*.*" );
|
||||
|
||||
printf( "In dir '%s'\n", tmp1 );
|
||||
|
||||
#ifdef _WIN32
|
||||
find_handle = _findfirst( tmp1, &find );
|
||||
if( find_handle != -1 ) {
|
||||
if ( find.attrib & _A_SUBDIR ) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "\\" );
|
||||
strcat( tmp, find.name );
|
||||
pack_directory(tmp);
|
||||
}
|
||||
} else {
|
||||
pack_file( filespec, find.name, find.size, find.time_write );
|
||||
}
|
||||
|
||||
while( !_findnext( find_handle, &find ) ) {
|
||||
if ( find.attrib & _A_SUBDIR ) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "\\" );
|
||||
strcat( tmp, find.name );
|
||||
pack_directory(tmp);
|
||||
|
||||
}
|
||||
} else {
|
||||
pack_file( filespec, find.name, find.size, find.time_write );
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
DIR *dirp;
|
||||
struct dirent *dir;
|
||||
|
||||
dirp = opendir (filespec);
|
||||
if ( dirp ) {
|
||||
while ((dir = readdir(dirp)) != NULL) {
|
||||
|
||||
char fn[MAX_PATH];
|
||||
snprintf(fn, MAX_PATH-1, "%s/%s", filespec, dir->d_name);
|
||||
fn[MAX_PATH-1] = 0;
|
||||
|
||||
struct stat buf;
|
||||
if (stat(fn, &buf) == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (strcmp(dir->d_name, ".") == 0) || (strcmp(dir->d_name, "..") == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (strcmp(dir->d_name, ".svn") == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISDIR(buf.st_mode)) {
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "/" );
|
||||
strcat( tmp, dir->d_name );
|
||||
pack_directory(tmp);
|
||||
} else {
|
||||
pack_file( filespec, dir->d_name, buf.st_size, buf.st_mtime );
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
} else {
|
||||
printf("Error: Source directory does not exist!\n");
|
||||
no_dir = 1;
|
||||
}
|
||||
#endif
|
||||
add_directory("..");
|
||||
}
|
||||
|
||||
int verify_directory( char *filespec )
|
||||
{
|
||||
char *ts;
|
||||
char *dd;
|
||||
|
||||
// strip trailing '/'
|
||||
ts = filespec+(strlen(filespec)-1);
|
||||
while ( (*ts == DIR_SEPARATOR_CHAR) && (ts > filespec) )
|
||||
*ts = '\0';
|
||||
|
||||
// make sure last directory is named "data", ignoring case
|
||||
dd = filespec + (strlen(filespec) - 4);
|
||||
if ( stricmp( dd, "data" ) )
|
||||
data_error = 1;
|
||||
|
||||
return data_error;
|
||||
}
|
||||
|
||||
void print_instructions()
|
||||
{
|
||||
printf( "Creates a vp archive out of a FreeSpace data tree.\n\n" );
|
||||
printf( "Usage: cfilearchiver archive_name src_dir\n");
|
||||
printf( "Example: cfilearchiver freespace /tmp/freespace/data\n\n");
|
||||
printf( "Directory structure options:\n" );
|
||||
printf( " Effects (.ani .pcx .neb .tga)\n" );
|
||||
printf( " Fonts (.vf)\n" );
|
||||
printf( " Hud (.ani .pcx .tga\n" );
|
||||
printf( " Interface (.pcx .ani .tga)\n" );
|
||||
printf( " Maps (.pcx .ani .tga)\n" );
|
||||
printf( " Missions (.ntl .ssv), FS1(.fsm .fsc), FS2(.fs2 .fc2)\n" );
|
||||
printf( " Models (.pof)\n" );
|
||||
printf( " Music (.wav)\n" );
|
||||
printf( " Sounds/8b22k (.wav)\n" );
|
||||
printf( " Sounds/16b11k (.wav)\n" );
|
||||
printf( " Tables (.tbl)\n" );
|
||||
printf( " Voice/Briefing (.wav)\n" );
|
||||
printf( " Voice/Command briefings (.wav)\n" );
|
||||
printf( " Voice/Debriefing (.wav)\n" );
|
||||
printf( " Voice/Personas (.wav)\n" );
|
||||
printf( " Voice/Special (.wav)\n" );
|
||||
printf( " Voice/Training (.wav)\n" );
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redfine main() which is something
|
||||
// that we don't want since we don't actually link against SDL, this solves the problem...
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[] )
|
||||
{
|
||||
char archive[1024];
|
||||
char *p;
|
||||
|
||||
if ( argc < 3 ) {
|
||||
#ifdef _WIN32
|
||||
printf( "Usage: %s archive_name src_dir\n", argv[0] );
|
||||
printf( "Example: %s freespace c:\\freespace\\data\n", argv[0] );
|
||||
printf( "Creates an archive named freespace out of the\nfreespace data tree\n" );
|
||||
printf( "Press any key to exit...\n" );
|
||||
getch();
|
||||
return 1;
|
||||
#else
|
||||
print_instructions();
|
||||
#endif
|
||||
}
|
||||
|
||||
strcpy( archive, argv[1] );
|
||||
p = strchr( archive, '.' );
|
||||
if (p) *p = 0; // remove extension
|
||||
|
||||
strcpy( archive_dat, archive );
|
||||
strcat( archive_dat, ".vp" );
|
||||
|
||||
strcpy( archive_hdr, archive );
|
||||
strcat( archive_hdr, ".hdr" );
|
||||
|
||||
fp_out = fopen( archive_dat, "wb" );
|
||||
if ( !fp_out ) {
|
||||
printf( "Couldn't open '%s'!\n", archive_dat );
|
||||
#ifdef _WIN32
|
||||
printf( "Press any key to exit...\n" );
|
||||
getch();
|
||||
return 1;
|
||||
#else
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
fp_out_hdr = fopen( archive_hdr, "wb" );
|
||||
if ( !fp_out_hdr ) {
|
||||
printf( "Couldn't open '%s'!\n", archive_hdr );
|
||||
#ifdef _WIN32
|
||||
printf( "Press any key to exit...\n" );
|
||||
getch();
|
||||
return 1;
|
||||
#else
|
||||
exit(2);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( verify_directory( argv[2] ) != 0 ) {
|
||||
printf("Warning! Last directory must be named \"data\" (not case sensitive)\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
write_header();
|
||||
|
||||
pack_directory( argv[2] );
|
||||
|
||||
// in case the directory doesn't exist
|
||||
if ( no_dir )
|
||||
exit(4);
|
||||
|
||||
write_header();
|
||||
|
||||
fclose(fp_out);
|
||||
fclose(fp_out_hdr);
|
||||
|
||||
printf( "Data files written, appending index...\n" );
|
||||
|
||||
if (!write_index(archive_hdr, archive_dat)) {
|
||||
printf("Error appending index!\n");
|
||||
#ifdef _WIN32
|
||||
printf("Press any key to exit...\n");
|
||||
getch();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "%d total KB.\n", Total_size/1024 );
|
||||
return 0;
|
||||
}
|
||||
@@ -1,497 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Taylor Richards
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GLOBAL FUNCTIONS AND VARIABLES
|
||||
//
|
||||
|
||||
// right out of pstypes.h but we don't want to use the INTEL_INT macro here
|
||||
// since it would require SDL which isn't used on WIN32 platforms
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define INT_SWAP(x) ( \
|
||||
(x << 24) | \
|
||||
(((ulong)x) >> 24) | \
|
||||
((x & 0x0000ff00) << 8) | \
|
||||
((x & 0x00ff0000) >> 8) \
|
||||
)
|
||||
#else
|
||||
#define INT_SWAP(x) (x)
|
||||
#endif
|
||||
|
||||
FILE *fp_in = NULL;
|
||||
FILE *fp_out = NULL;
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 255
|
||||
#endif
|
||||
|
||||
char out_dir[MAX_PATH];
|
||||
|
||||
#define BLOCK_SIZE (1024*1024)
|
||||
|
||||
char tmp_data[BLOCK_SIZE]; // 1 MB
|
||||
|
||||
static int have_index = 0;
|
||||
static int have_header = 0;
|
||||
|
||||
#define ERR_NO_FP_IN 0
|
||||
#define ERR_NO_FP_OUT 1
|
||||
#define ERR_INVALID_VP 2
|
||||
#define ERR_NO_INDEX 3
|
||||
#define ERR_NO_HEADER 4
|
||||
#define ERR_PATH_TOO_LONG 5
|
||||
|
||||
typedef struct vp_header {
|
||||
char id[4]; // 'VPVP'
|
||||
int version;
|
||||
int index_offset; // offset where the file index starts, also a total file data size count
|
||||
int num_files; // number of files, including each step in the directory structure
|
||||
} vp_header;
|
||||
|
||||
vp_header VP_Header;
|
||||
|
||||
typedef struct vp_fileinfo {
|
||||
// stuff that is actually written to the VP
|
||||
int offset; // offset of where this file is in the VP
|
||||
int file_size; // size of file
|
||||
char file_name[CF_MAX_FILENAME_LENGTH]; // filename
|
||||
_fs_time_t write_time; // date/time in _fs_time_t type (a 32-bit version of time_t)
|
||||
|
||||
// not in the VP
|
||||
char file_path[CF_MAX_PATHNAME_LENGTH]; // file path, generated here and not actually in the VP on a per file basis
|
||||
|
||||
vp_fileinfo() {
|
||||
offset = 0;
|
||||
file_size = 0;
|
||||
file_name[0] = '\0';
|
||||
file_path[0] = '\0';
|
||||
write_time = 0;
|
||||
}
|
||||
|
||||
~vp_fileinfo() {}
|
||||
} vp_fileinfo;
|
||||
|
||||
std::vector<vp_fileinfo> VP_FileInfo;
|
||||
|
||||
// just like strlwr() but without actually including it here
|
||||
void lowercase(char *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
while (*s) {
|
||||
*s = tolower(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The useful stuff...
|
||||
//
|
||||
|
||||
void print_error(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case ERR_NO_FP_IN:
|
||||
printf("ERROR: The input file (fp_in) is NULL! Exiting...\n");
|
||||
break;
|
||||
case ERR_NO_FP_OUT:
|
||||
printf("ERROR: The output file (fp_out) is NULL! Exiting...\n");
|
||||
break;
|
||||
case ERR_INVALID_VP:
|
||||
printf("ERROR: The specified VP file is invalid! Exiting...\n");
|
||||
break;
|
||||
case ERR_NO_INDEX:
|
||||
printf("ERROR: No file index is available! Exiting...\n");
|
||||
break;
|
||||
case ERR_NO_HEADER:
|
||||
printf("ERROR: No file header is available! Exiting...\n");
|
||||
break;
|
||||
case ERR_PATH_TOO_LONG:
|
||||
printf("ERROR: Path to output directory is too long! Exiting...\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void read_header()
|
||||
{
|
||||
fseek(fp_in, 0, SEEK_SET);
|
||||
fread(&VP_Header.id, 1, 4, fp_in);
|
||||
fread(&VP_Header.version, 1, sizeof(int), fp_in);
|
||||
fread(&VP_Header.index_offset, 1, sizeof(int), fp_in);
|
||||
fread(&VP_Header.num_files, 1, sizeof(int), fp_in);
|
||||
|
||||
VP_Header.version = INT_SWAP(VP_Header.version);
|
||||
VP_Header.index_offset = INT_SWAP(VP_Header.index_offset);
|
||||
VP_Header.num_files = INT_SWAP(VP_Header.num_files);
|
||||
|
||||
// check for a valid id (VPVP)
|
||||
if ( (VP_Header.id[0] != 'V') && (VP_Header.id[1] != 'P') && (VP_Header.id[2] != 'V') && (VP_Header.id[3] != 'P') )
|
||||
print_error(ERR_INVALID_VP);
|
||||
|
||||
// the index_offset needs to be greater than the size of vp_header at the very least and there should be at least one file
|
||||
if ( !(VP_Header.index_offset > (int)sizeof(vp_header)) || !(VP_Header.num_files > 1) )
|
||||
print_error(ERR_INVALID_VP);
|
||||
|
||||
|
||||
have_header = 1;
|
||||
}
|
||||
|
||||
void read_index(int lc = 0)
|
||||
{
|
||||
if (fp_in == NULL)
|
||||
print_error(ERR_NO_FP_IN);
|
||||
else if (!have_header)
|
||||
print_error(ERR_NO_HEADER);
|
||||
|
||||
int i;
|
||||
char path[CF_MAX_PATHNAME_LENGTH];
|
||||
|
||||
fseek(fp_in, VP_Header.index_offset, SEEK_SET);
|
||||
|
||||
memset(path, 0, CF_MAX_PATHNAME_LENGTH);
|
||||
|
||||
for ( i = 0; i < VP_Header.num_files; i++) {
|
||||
vp_fileinfo vpinfo;
|
||||
|
||||
fread(&vpinfo.offset, 1, sizeof(int), fp_in);
|
||||
fread(&vpinfo.file_size, 1, sizeof(int), fp_in);
|
||||
fread(&vpinfo.file_name, 1, CF_MAX_FILENAME_LENGTH, fp_in);
|
||||
fread(&vpinfo.write_time, 1, sizeof(_fs_time_t), fp_in);
|
||||
|
||||
vpinfo.offset = INT_SWAP(vpinfo.offset);
|
||||
vpinfo.file_size = INT_SWAP(vpinfo.file_size);
|
||||
vpinfo.write_time = INT_SWAP(vpinfo.write_time);
|
||||
|
||||
// check if it's a directory and if so then create a path to use for files
|
||||
if (vpinfo.file_size == 0) {
|
||||
// if we get a ".." then drop down in the path
|
||||
if (!strcmp(vpinfo.file_name, "..")) {
|
||||
char *s = strrchr(path, DIR_SEPARATOR_CHAR);
|
||||
|
||||
if (s)
|
||||
*s = '\0';
|
||||
|
||||
// skip, we don't want to add the ".." to the path
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't add the very first directory separator character, easier to clean later
|
||||
if (path[0] != 0)
|
||||
strcat( path, DIR_SEPARATOR_STR );
|
||||
|
||||
// always make directory names lower case for ease of use
|
||||
lowercase( vpinfo.file_name );
|
||||
|
||||
strcat( path, vpinfo.file_name );
|
||||
} // it's a file then
|
||||
else {
|
||||
// lowercase the filename if wanted
|
||||
if (lc == 1)
|
||||
lowercase( vpinfo.file_name );
|
||||
|
||||
strcpy( vpinfo.file_path, path );
|
||||
VP_FileInfo.push_back(vpinfo);
|
||||
}
|
||||
}
|
||||
|
||||
have_index = 1;
|
||||
}
|
||||
|
||||
void extract_all_files(char *file)
|
||||
{
|
||||
if (fp_in == NULL)
|
||||
print_error(ERR_NO_FP_IN);
|
||||
else if (!have_header)
|
||||
print_error(ERR_NO_HEADER);
|
||||
else if (!have_index)
|
||||
print_error(ERR_NO_INDEX);
|
||||
|
||||
int status, m_error, nbytes, nbytes_remaining;
|
||||
char path[CF_MAX_PATHNAME_LENGTH+CF_MAX_FILENAME_LENGTH+1]; // path length + filename length + extra NULL
|
||||
char path2[CF_MAX_PATHNAME_LENGTH+CF_MAX_FILENAME_LENGTH+1]; // path length + filename length + extra NULL
|
||||
char *c;
|
||||
ubyte have_outdir = 0;
|
||||
|
||||
int out_len = strlen(out_dir);
|
||||
|
||||
if (out_len > 0)
|
||||
have_outdir = 1;
|
||||
|
||||
printf("VP file extractor - version 0.6\n");
|
||||
printf("\n");
|
||||
|
||||
if (have_outdir) {
|
||||
printf("Output directory: \"%s\"\n", out_dir);
|
||||
}
|
||||
|
||||
printf("Extracting: %s...\n", file);
|
||||
|
||||
for (uint i = 0; i < VP_FileInfo.size(); i++) {
|
||||
// save the file path to a temp location and recursively make the needed directories
|
||||
if (have_outdir) {
|
||||
if ( (out_len + 1 + strlen(path)) > MAX_PATH-1 )
|
||||
print_error(ERR_PATH_TOO_LONG);
|
||||
|
||||
sprintf(path, "%s%s%s%s", out_dir, DIR_SEPARATOR_STR, VP_FileInfo[i].file_path, DIR_SEPARATOR_STR);
|
||||
} else {
|
||||
sprintf(path, "%s%s", VP_FileInfo[i].file_path, DIR_SEPARATOR_STR);
|
||||
}
|
||||
|
||||
c = &path[0];
|
||||
|
||||
while (c++) {
|
||||
c = strchr(c, DIR_SEPARATOR_CHAR);
|
||||
|
||||
if (c) {
|
||||
*c = '\0'; // NULL at DIR_SEP char
|
||||
|
||||
#ifdef _WIN32
|
||||
status = _mkdir(path);
|
||||
#else
|
||||
status = mkdir(path, 0777);
|
||||
#endif
|
||||
|
||||
m_error = errno;
|
||||
|
||||
if (status && (m_error != EEXIST) ) {
|
||||
printf("Cannot mkdir %s: %s\n", VP_FileInfo[i].file_path, strerror(m_error));
|
||||
continue;
|
||||
}
|
||||
|
||||
*c = DIR_SEPARATOR_CHAR; // replace DIR_SEP char
|
||||
}
|
||||
}
|
||||
|
||||
memset( path, 0, CF_MAX_PATHNAME_LENGTH+CF_MAX_FILENAME_LENGTH+1);
|
||||
|
||||
// start writing out the file
|
||||
fseek(fp_in, VP_FileInfo[i].offset, SEEK_SET);
|
||||
|
||||
sprintf(path, "%s%s%s", VP_FileInfo[i].file_path, DIR_SEPARATOR_STR, VP_FileInfo[i].file_name);
|
||||
|
||||
// this is cheap, I know.
|
||||
if (have_outdir) {
|
||||
if ( (out_len + 1 + strlen(path)) > MAX_PATH-1 )
|
||||
print_error(ERR_PATH_TOO_LONG);
|
||||
|
||||
sprintf(path2, "%s%s%s", out_dir, DIR_SEPARATOR_STR, path);
|
||||
} else {
|
||||
strcpy(path2, path);
|
||||
}
|
||||
|
||||
fp_out = fopen(path2, "wb");
|
||||
|
||||
printf(" %s ... ", path);
|
||||
|
||||
if (fp_out == NULL) {
|
||||
printf("can't create file!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
nbytes_remaining = VP_FileInfo[i].file_size;
|
||||
|
||||
while ( nbytes_remaining > 0 ) {
|
||||
nbytes = fread( tmp_data, 1, MIN(BLOCK_SIZE, nbytes_remaining), fp_in );
|
||||
|
||||
if (nbytes > 0) {
|
||||
fwrite( tmp_data, 1, nbytes, fp_out );
|
||||
nbytes_remaining -= nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
printf("done!\n");
|
||||
|
||||
fclose(fp_out);
|
||||
fp_out = NULL;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// TODO: the formatting of this is a bit loco but I don't care enough to make it better...
|
||||
void list_all_files(char *file)
|
||||
{
|
||||
char out_time[20];
|
||||
float one_k = 1024.0f;
|
||||
float one_m = 1048576.0f;
|
||||
char m;
|
||||
float div_by;
|
||||
time_t plat_time;
|
||||
|
||||
// if we don't have an index then bail
|
||||
if (!have_index)
|
||||
print_error(ERR_NO_INDEX);
|
||||
|
||||
|
||||
printf("VP file extractor - version 0.6\n");
|
||||
printf("\n");
|
||||
printf("%s:\n", file);
|
||||
printf("\n");
|
||||
|
||||
printf(" Name Size Offset Date/Time Path\n");
|
||||
printf("-------------------------------------------------------------------------------\n");
|
||||
for (uint i = 0; i < VP_FileInfo.size(); i++) {
|
||||
plat_time = VP_FileInfo[i].write_time; // gets rid of some platform strangeness this way
|
||||
strftime(out_time, 32, "%F %H:%M", localtime(&plat_time)); // YYYY-mm-dd HH:mm (ISO 8601 date format, 24-hr time)
|
||||
|
||||
if (VP_FileInfo[i].file_size > (int)one_m) {
|
||||
m = 'M';
|
||||
div_by = one_m;
|
||||
} else {
|
||||
m = 'K';
|
||||
div_by = one_k;
|
||||
}
|
||||
|
||||
int len = strlen( VP_FileInfo[i].file_name );
|
||||
printf("%s %*.1f%c %10i %18s %3s%s\n", VP_FileInfo[i].file_name, 33 - len, (float)VP_FileInfo[i].file_size/div_by, m, VP_FileInfo[i].offset, out_time, DIR_SEPARATOR_STR, VP_FileInfo[i].file_path);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
// we use the vector size here since VP_Header.num_files would include each entry
|
||||
// in the directory tree as well as individual files and that artificially inflates
|
||||
// the number of files that we show or would extract
|
||||
printf("Total files: %i\n", (int)VP_FileInfo.size());
|
||||
|
||||
// yeah, I'm just that cheap
|
||||
if (VP_Header.index_offset > (int)one_m) {
|
||||
m = 'M';
|
||||
div_by = one_m;
|
||||
} else {
|
||||
m = 'K';
|
||||
div_by = one_k;
|
||||
}
|
||||
|
||||
printf("Total size: %.1f%c\n", (float)VP_Header.index_offset/div_by, m);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void help()
|
||||
{
|
||||
printf("VP file extractor - version 0.6\n");
|
||||
printf("\n");
|
||||
printf("Usage: cfileextractor [-x | -l] [-L] [-o <dir>] <vp_filename>\n");
|
||||
printf("\n");
|
||||
printf(" Commands (only one at the time):\n");
|
||||
printf(" -x | --extract Extract all files into current directory.\n");
|
||||
printf(" -l | --list List all files in VP archive.\n");
|
||||
printf(" -h | --help Show this help text.\n");
|
||||
printf("\n");
|
||||
printf(" Options:\n");
|
||||
printf(" -L | --lowercase Force all filenames to be lower case.\n");
|
||||
printf(" -o <dir> Extract files to <dir> instead of current directory.\n");
|
||||
printf(" NOTE: No spaces allowed, enclose path in \" \" if needed.\n");
|
||||
printf("\n");
|
||||
printf(" (No command specified will list all files in the VP archive.)\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redfine main() which is something
|
||||
// that we don't want since we don't actually link against SDL, this solves the problem...
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int extract = 0, lc = 0, list = 0;
|
||||
|
||||
if (argc < 2) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// the last option should always be the VP file that we want
|
||||
fp_in = fopen(argv[argc-1], "rb");
|
||||
|
||||
if (fp_in == NULL)
|
||||
print_error(ERR_NO_FP_IN);
|
||||
|
||||
// if the header is invalid then read_header() should exit us out
|
||||
read_header();
|
||||
|
||||
memset(out_dir, 0, MAX_PATH);
|
||||
|
||||
// TODO: add filter based extraction
|
||||
for (int i = 1; i < argc-1; i++) {
|
||||
if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--extract")) {
|
||||
if (list) {
|
||||
help();
|
||||
exit(0);
|
||||
}
|
||||
extract = 1;
|
||||
} else if (!strcmp(argv[i], "-L") || !strcmp(argv[i], "--lowercase")) {
|
||||
lc = 1;
|
||||
} else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--list")) {
|
||||
if (extract) {
|
||||
help();
|
||||
exit(0);
|
||||
}
|
||||
list = 1;
|
||||
} else if ( !strcmp(argv[i], "-o") && (i+1 < argc) && (argv[i+1][0] != '-') ) {
|
||||
strncpy(out_dir, argv[i+1], MAX_PATH-1);
|
||||
i++; // have to increment "i" past the output directory
|
||||
} else {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// read the file index, make all filenames lowercase if wanted
|
||||
read_index( lc );
|
||||
|
||||
if (extract) {
|
||||
extract_all_files( argv[argc-1] );
|
||||
return 0;
|
||||
} else if (list) {
|
||||
list_all_files( argv[argc-1] );
|
||||
return 0;
|
||||
} else {
|
||||
// if only -L is specified or no command is specified then just list files
|
||||
list_all_files( argv[argc-1] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FS_CMDLINE_HEADER_FILE
|
||||
#define FS_CMDLINE_HEADER_FILE
|
||||
|
||||
|
||||
int parse_cmdline(char *cmdline);
|
||||
|
||||
int fred2_parse_cmdline(int argc, char *argv[]);
|
||||
// COMMAND LINE SETTINGS
|
||||
// This section is for reference by all the *_init() functions. For example, the multiplayer init function
|
||||
// could check to see if (int Cmdline_multi_stream_chat_to_file) has been set by the command line parser.
|
||||
//
|
||||
// Add any extern definitions here and put the actual variables inside of cmdline.cpp for ease of use
|
||||
// Also, check to make sure anything you add doesn't break Fred or TestCode
|
||||
|
||||
|
||||
// RETAIL OPTIONS ----------------------------------------------
|
||||
extern char *Cmdline_connect_addr;
|
||||
extern char *Cmdline_game_name;
|
||||
extern char *Cmdline_game_password;
|
||||
extern char *Cmdline_rank_above;
|
||||
extern char *Cmdline_rank_below;
|
||||
extern int Cmdline_cd_check;
|
||||
extern int Cmdline_client_dodamage;
|
||||
extern int Cmdline_closed_game;
|
||||
extern int Cmdline_freespace_no_music;
|
||||
extern int Cmdline_freespace_no_sound;
|
||||
extern int Cmdline_gimme_all_medals;
|
||||
extern int Cmdline_mouse_coords;
|
||||
extern int Cmdline_multi_log;
|
||||
extern int Cmdline_multi_stream_chat_to_file;
|
||||
extern int Cmdline_network_port;
|
||||
extern int Cmdline_restricted_game;
|
||||
extern int Cmdline_server_firing;
|
||||
extern int Cmdline_spew_pof_info;
|
||||
extern int Cmdline_start_netgame;
|
||||
extern int Cmdline_timeout;
|
||||
extern int Cmdline_use_last_pilot;
|
||||
extern int Cmdline_window;
|
||||
extern int Cmdline_fullscreen_window;
|
||||
extern char *Cmdline_res;
|
||||
|
||||
|
||||
// FSO OPTIONS -------------------------------------------------
|
||||
|
||||
// Graphics related
|
||||
extern double specular_exponent_value;
|
||||
extern float Cmdline_clip_dist;
|
||||
extern float Cmdline_fov;
|
||||
extern float Cmdline_ogl_spec;
|
||||
extern float static_light_factor;
|
||||
extern float static_point_factor;
|
||||
extern float static_tube_factor;
|
||||
extern int Cmdline_ambient_factor;
|
||||
extern int Cmdline_cell;
|
||||
extern int Cmdline_env;
|
||||
extern int Cmdline_mipmap;
|
||||
extern int Cmdline_missile_lighting;
|
||||
extern int Cmdline_glow;
|
||||
extern int Cmdline_nomotiondebris;
|
||||
extern int Cmdline_noscalevid; // disables fit-to-window for movies - taylor
|
||||
extern int Cmdline_spec;
|
||||
extern int Cmdline_normal;
|
||||
extern int Cmdline_height;
|
||||
extern int Cmdline_enable_3d_shockwave;
|
||||
extern int Cmdline_postprocess;
|
||||
extern int Cmdline_bloom_intensity;
|
||||
|
||||
// Game Speed related
|
||||
extern int Cmdline_cache_bitmaps;
|
||||
extern int Cmdline_img2dds;
|
||||
extern int Cmdline_NoFPSCap;
|
||||
extern int Cmdline_no_vsync;
|
||||
|
||||
// HUD related
|
||||
extern int Cmdline_ballistic_gauge;
|
||||
extern int Cmdline_dualscanlines;
|
||||
extern int Cmdline_orb_radar;
|
||||
extern int Cmdline_rearm_timer;
|
||||
extern int Cmdline_targetinfo;
|
||||
|
||||
// Gameplay related
|
||||
extern int Cmdline_3dwarp;
|
||||
extern int Cmdline_ship_choice_3d;
|
||||
extern int Cmdline_weapon_choice_3d;
|
||||
extern int Cmdline_warp_flash;
|
||||
extern int Cmdline_autopilot_interruptable;
|
||||
|
||||
// Audio related
|
||||
extern int Cmdline_query_speech;
|
||||
extern int Cmdline_snd_preload;
|
||||
extern int Cmdline_voice_recognition;
|
||||
|
||||
// MOD related
|
||||
extern char *Cmdline_mod; // DTP for mod support
|
||||
// Multiplayer/Network related
|
||||
extern char *Cmdline_almission; // DTP for autoload mission (for multi only)
|
||||
extern int Cmdline_ingamejoin;
|
||||
extern int Cmdline_mpnoreturn;
|
||||
extern char *Cmdline_spew_mission_crcs;
|
||||
extern char *Cmdline_spew_table_crcs;
|
||||
extern int Cmdline_objupd;
|
||||
|
||||
// Troubleshooting
|
||||
extern int Cmdline_d3d_lesstmem;
|
||||
extern int Cmdline_load_all_weapons;
|
||||
extern int Cmdline_nohtl;
|
||||
extern int Cmdline_noibx;
|
||||
extern int Cmdline_nomovies; // WMC Toggles movie playing support
|
||||
extern int Cmdline_no_set_gamma;
|
||||
extern int Cmdline_novbo;
|
||||
extern int Cmdline_safeloading;
|
||||
extern int Cmdline_no_fbo;
|
||||
extern int Cmdline_noglsl;
|
||||
extern int Cmdline_ati_color_swap;
|
||||
extern int Cmdline_no_3d_sound;
|
||||
extern int Cmdline_no_glsl_model_rendering;
|
||||
|
||||
// Developer/Testing related
|
||||
extern char *Cmdline_start_mission;
|
||||
extern int Cmdline_dis_collisions;
|
||||
extern int Cmdline_dis_weapons;
|
||||
extern int Cmdline_noparseerrors;
|
||||
extern int Cmdline_nowarn;
|
||||
extern int Cmdline_extra_warn;
|
||||
extern int Cmdline_show_mem_usage;
|
||||
extern int Cmdline_show_pos;
|
||||
extern int Cmdline_show_stats;
|
||||
extern int Cmdline_timerbar;
|
||||
extern int Cmdline_save_render_targets;
|
||||
extern int Cmdline_debug_window;
|
||||
extern int Cmdline_verify_vps;
|
||||
#ifdef SCP_UNIX
|
||||
extern int Cmdline_no_grab;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//extern char FreeSpace_Directory[]; // allievating a cfilesystem problem caused by fred -- Kazan
|
||||
#endif
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "cmeasure/cmeasure.h"
|
||||
//#include "freespace2/freespace.h"
|
||||
//#include "model/model.h"
|
||||
#include "ship/ship.h"
|
||||
#include "math/staticrand.h"
|
||||
#include "object/object.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "hud/hud.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "network/multimsgs.h"
|
||||
#include "mission/missionparse.h"
|
||||
|
||||
|
||||
//cmeasure_info Cmeasure_info[MAX_CMEASURE_TYPES];
|
||||
//cmeasure Cmeasures[MAX_CMEASURES];
|
||||
|
||||
//int Num_cmeasure_types = 0;
|
||||
//int Num_cmeasures = 0;
|
||||
//int Cmeasure_inited = 0;
|
||||
int Cmeasures_homing_check = 0;
|
||||
int Countermeasures_enabled = 1; // Debug, set to 0 means no one can fire countermeasures.
|
||||
|
||||
// This will get called at the start of each level.
|
||||
//Not anymore - WMC
|
||||
/*
|
||||
void cmeasure_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !Cmeasure_inited )
|
||||
Cmeasure_inited = 1;
|
||||
|
||||
// Reset everything between levels
|
||||
Num_cmeasures = 0;
|
||||
|
||||
for (i=0; i<MAX_CMEASURES; i++ ) {
|
||||
Cmeasures[i].subtype = CMEASURE_UNUSED;
|
||||
}
|
||||
|
||||
}*/
|
||||
/*
|
||||
void cmeasure_render(object * objp)
|
||||
{
|
||||
// JAS TODO: Replace with proper fireball
|
||||
cmeasure *cmp;
|
||||
cmeasure_info *cmip;
|
||||
|
||||
cmp = &Cmeasures[objp->instance];
|
||||
cmip = &Cmeasure_info[cmp->subtype];
|
||||
|
||||
if ( cmp->subtype == CMEASURE_UNUSED ) {
|
||||
Int3(); // Hey, what are we doing in here?
|
||||
return;
|
||||
}
|
||||
|
||||
if ( cmip->model_num > -1 ) {
|
||||
model_clear_instance(cmip->model_num);
|
||||
model_render(cmip->model_num, &objp->orient, &objp->pos, MR_NO_LIGHTING );
|
||||
} else {
|
||||
mprintf(( "Not rendering countermeasure because model_num is negative\n" ));
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
void cmeasure_delete( object * objp )
|
||||
{
|
||||
int num;
|
||||
|
||||
num = objp->instance;
|
||||
|
||||
// Assert( Cmeasures[num].objnum == OBJ_INDEX(objp));
|
||||
|
||||
Cmeasures[num].subtype = CMEASURE_UNUSED;
|
||||
Num_cmeasures--;
|
||||
Assert( Num_cmeasures >= 0 );
|
||||
}*/
|
||||
|
||||
// broke cmeasure_move into two functions -- process_pre and process_post (as was done with
|
||||
// all *_move functions). Nothing to do for process_pre
|
||||
/*
|
||||
void cmeasure_process_pre( object *objp, float frame_time)
|
||||
{
|
||||
}*/
|
||||
/*
|
||||
void cmeasure_process_post(object * objp, float frame_time)
|
||||
{
|
||||
int num;
|
||||
num = objp->instance;
|
||||
|
||||
// Assert( Cmeasures[num].objnum == objnum );
|
||||
cmeasure *cmp = &Cmeasures[num];
|
||||
|
||||
if ( cmp->lifeleft >= 0.0f) {
|
||||
cmp->lifeleft -= frame_time;
|
||||
if ( cmp->lifeleft < 0.0f ) {
|
||||
objp->flags |= OF_SHOULD_BE_DEAD;
|
||||
// demo_do_flag_dead(OBJ_INDEX(objp));
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
// creates one countermeasure. A ship fires 1 of these per launch. rand_val is used
|
||||
// in multiplayer. If -1, then create a random number. If non-negative, use this
|
||||
// number for static_rand functions
|
||||
/*
|
||||
int cmeasure_create( object * source_obj, vec3d * pos, int cm_type, int rand_val )
|
||||
{
|
||||
int n, objnum, parent_objnum, arand;
|
||||
object * obj;
|
||||
ship *shipp;
|
||||
cmeasure *cmp;
|
||||
cmeasure_info *cmeasurep;
|
||||
|
||||
Cmeasures_homing_check = 2; // Tell homing code to scan everything for two frames. If only one frame, get sync problems due to objects being created at end of frame!
|
||||
|
||||
parent_objnum = OBJ_INDEX(source_obj);
|
||||
|
||||
Assert( source_obj->type == OBJ_SHIP );
|
||||
Assert( source_obj->instance >= 0 && source_obj->instance < MAX_SHIPS );
|
||||
|
||||
shipp = &Ships[source_obj->instance];
|
||||
|
||||
if ( Num_cmeasures >= MAX_CMEASURES)
|
||||
return -1;
|
||||
|
||||
for (n=0; n<MAX_CMEASURES; n++ )
|
||||
if ( Cmeasures[n].subtype == CMEASURE_UNUSED)
|
||||
break;
|
||||
if ( n == MAX_CMEASURES)
|
||||
return -1;
|
||||
|
||||
nprintf(("Network", "Cmeasure created by %s\n", Ships[source_obj->instance].ship_name));
|
||||
|
||||
cmp = &Cmeasures[n];
|
||||
cmeasurep = &Cmeasure_info[cm_type];
|
||||
|
||||
if ( pos == NULL )
|
||||
pos = &source_obj->pos;
|
||||
|
||||
objnum = obj_create( OBJ_CMEASURE, parent_objnum, n, &source_obj->orient, pos, 1.0f, OF_RENDERS | OF_PHYSICS );
|
||||
|
||||
Assert( objnum >= 0 && objnum < MAX_OBJECTS );
|
||||
|
||||
// Create Debris piece n!
|
||||
if ( rand_val == -1 )
|
||||
arand = myrand(); // use a random number to get lifeleft, and random vector for displacement from ship
|
||||
else
|
||||
arand = rand_val;
|
||||
|
||||
cmp->lifeleft = static_randf(arand) * (cmeasurep->life_max - cmeasurep->life_min) / cmeasurep->life_min;
|
||||
if (source_obj->flags & OF_PLAYER_SHIP){
|
||||
cmp->lifeleft *= The_mission.ai_profile->cmeasure_life_scale[Game_skill_level];
|
||||
}
|
||||
cmp->lifeleft = cmeasurep->life_min + cmp->lifeleft * (cmeasurep->life_max - cmeasurep->life_min);
|
||||
|
||||
// cmp->objnum = objnum;
|
||||
cmp->team = shipp->team;
|
||||
cmp->subtype = cm_type;
|
||||
cmp->objnum = objnum;
|
||||
cmp->source_objnum = parent_objnum;
|
||||
cmp->source_sig = Objects[objnum].signature;
|
||||
|
||||
cmp->flags = 0;
|
||||
|
||||
nprintf(("Jim", "Frame %i: Launching countermeasure #%i\n", Framecount, Objects[objnum].signature));
|
||||
|
||||
obj = &Objects[objnum];
|
||||
|
||||
Num_cmeasures++;
|
||||
|
||||
//Set countermeasure velocity
|
||||
vec3d vel, rand_vec;
|
||||
|
||||
//Get cmeasure rear velocity in world
|
||||
vm_vec_scale_add(&vel, &source_obj->phys_info.vel, &source_obj->orient.vec.fvec, -25.0f);
|
||||
|
||||
//Get random velocity vector
|
||||
static_randvec(arand+1, &rand_vec);
|
||||
|
||||
//Add it to the rear velocity
|
||||
vm_vec_scale_add2(&vel, &rand_vec, 2.0f);
|
||||
|
||||
obj->phys_info.vel = vel;
|
||||
|
||||
vm_vec_zero(&obj->phys_info.rotvel);
|
||||
vm_vec_zero(&obj->phys_info.max_vel);
|
||||
vm_vec_zero(&obj->phys_info.max_rotvel);
|
||||
|
||||
// blow out his reverse thrusters. Or drag, same thing.
|
||||
obj->phys_info.rotdamp = 10000.0f;
|
||||
obj->phys_info.side_slip_time_const = 10000.0f;
|
||||
|
||||
obj->phys_info.max_vel.xyz.z = -25.0f;
|
||||
vm_vec_copy_scale(&obj->phys_info.desired_vel, &obj->orient.vec.fvec, obj->phys_info.max_vel.xyz.z );
|
||||
|
||||
return arand; // need to return this value for multiplayer purposes
|
||||
}*/
|
||||
|
||||
//Used to set a countermeasure velocity after being launched from a ship as a countermeasure
|
||||
//ie not as a primary or secondary.
|
||||
void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
|
||||
{
|
||||
vec3d vel, rand_vec;
|
||||
|
||||
//Get cmeasure rear velocity in world
|
||||
vm_vec_scale_add(&vel, &parent_objp->phys_info.vel, &parent_objp->orient.vec.fvec, -25.0f);
|
||||
|
||||
//Get random velocity vector
|
||||
static_randvec(arand+1, &rand_vec);
|
||||
|
||||
//Add it to the rear velocity
|
||||
vm_vec_scale_add2(&vel, &rand_vec, 2.0f);
|
||||
|
||||
objp->phys_info.vel = vel;
|
||||
|
||||
//Zero out this stuff so it isn't moving
|
||||
vm_vec_zero(&objp->phys_info.rotvel);
|
||||
vm_vec_zero(&objp->phys_info.max_vel);
|
||||
vm_vec_zero(&objp->phys_info.max_rotvel);
|
||||
|
||||
//Idunnit. -WMC
|
||||
//objp->phys_info.flags |= PF_CONST_VEL;
|
||||
|
||||
//WMC - I don't think this stuff is needed with the flag I set
|
||||
//WMC - Or maybe it is.
|
||||
|
||||
// blow out his reverse thrusters. Or drag, same thing.
|
||||
objp->phys_info.rotdamp = 10000.0f;
|
||||
objp->phys_info.side_slip_time_const = 10000.0f;
|
||||
|
||||
objp->phys_info.max_vel.xyz.z = -25.0f;
|
||||
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z );
|
||||
}
|
||||
|
||||
void cmeasure_select_next(ship *shipp)
|
||||
{
|
||||
Assert(shipp != NULL);
|
||||
int i, new_index;
|
||||
|
||||
for (i = 1; i < Num_weapon_types; i++)
|
||||
{
|
||||
new_index = (shipp->current_cmeasure + i) % Num_weapon_types;
|
||||
|
||||
if(Weapon_info[new_index].wi_flags & WIF_CMEASURE)
|
||||
{
|
||||
shipp->current_cmeasure = new_index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//snd_play( &Snds[SND_CMEASURE_CYCLE] );
|
||||
|
||||
mprintf(("Countermeasure type set to %i in frame %i\n", shipp->current_cmeasure, Framecount));
|
||||
}
|
||||
|
||||
// If this is a player countermeasure, let the player know he evaded a missile
|
||||
void cmeasure_maybe_alert_success(object *objp)
|
||||
{
|
||||
//Is this a countermeasure, and does it have a parent
|
||||
if ( objp->type != OBJ_WEAPON || objp->parent < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_CMEASURE);
|
||||
|
||||
if ( objp->parent == OBJ_INDEX(Player_obj) ) {
|
||||
hud_start_text_flash(XSTR("Evaded", 1430), 800);
|
||||
snd_play(&Snds[SND_MISSILE_EVADED_POPUP]);
|
||||
} else if ( Objects[objp->parent].flags & OF_PLAYER_SHIP ) {
|
||||
send_countermeasure_success_packet( objp->parent );
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _CMEASURE_H
|
||||
#define _CMEASURE_H
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
|
||||
struct object;
|
||||
//struct vec3d;
|
||||
|
||||
//#define MAX_CMEASURES 64
|
||||
|
||||
// Goes in cmeasure.subtype
|
||||
//#define CMEASURE_UNUSED -1
|
||||
|
||||
//#define MAX_CMEASURE_TYPES 3
|
||||
|
||||
#define CMEASURE_WAIT 333 // delay in milliseconds between countermeasure firing.
|
||||
|
||||
//#define CMF_DUD_HEAT 0x01 // If set, this cmeasure is a dud to heat seekers. Set at create time.
|
||||
//#define CMF_DUD_ASPECT 0x02 // If set, this cmeasure is a dud to aspect seekers. Set at create time.
|
||||
|
||||
//#define CMF_DUD (CMF_DUD_HEAT | CMF_DUD_ASPECT)
|
||||
|
||||
// Maximum distance at which a countermeasure can be tracked
|
||||
// If this value is too large, missiles will always be tracking countermeasures.
|
||||
#define MAX_CMEASURE_TRACK_DIST 300.0f
|
||||
/*
|
||||
typedef struct cmeasure_info {
|
||||
char cmeasure_name[NAME_LENGTH];
|
||||
//float max_speed; // launch speed, relative to ship
|
||||
float fire_wait; // time between launches
|
||||
float life_min, life_max; // lifetime will be in range min..max.
|
||||
int launch_sound; // Sound played when launched.
|
||||
char pof_name[NAME_LENGTH];
|
||||
int model_num; // What this renders as
|
||||
} cmeasure_info;
|
||||
|
||||
typedef struct cmeasure {
|
||||
int flags; // You know, flag type things.
|
||||
int subtype; // See CMEASURE_??? defines
|
||||
int objnum;
|
||||
int source_objnum; // What object this came from
|
||||
int source_sig; // Signature of the source object
|
||||
int team; // Team of the ship where the cmeasure came from
|
||||
float lifeleft; // When 0 or less object dies
|
||||
} cmeasure;
|
||||
*/
|
||||
//extern cmeasure_info Cmeasure_info[MAX_CMEASURE_TYPES];
|
||||
//extern cmeasure Cmeasures[MAX_CMEASURES];
|
||||
//extern int Num_cmeasure_types;
|
||||
//extern int Num_cmeasures;
|
||||
extern int Cmeasures_homing_check;
|
||||
extern int Countermeasures_enabled;
|
||||
|
||||
//extern void cmeasure_init();
|
||||
//extern void cmeasure_render( object * obj );
|
||||
//extern void cmeasure_delete( object * obj );
|
||||
//extern void cmeasure_process_pre( object * obj, float frame_time);
|
||||
//extern void cmeasure_process_post( object * obj, float frame_time);
|
||||
//extern int cmeasure_create( object * source_obj, vec3d *pos, int cm_type, int rand_val = -1 );
|
||||
extern void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand);
|
||||
extern void cmeasure_select_next(object *objp);
|
||||
extern void cmeasure_maybe_alert_success(object *objp);
|
||||
|
||||
extern float Skill_level_cmeasure_life_scale[NUM_SKILL_LEVELS];
|
||||
|
||||
#endif // _CMEASURE_H
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef CONTROLS_CONFIG_H
|
||||
#define CONTROLS_CONFIG_H
|
||||
|
||||
#define CONTROL_CONFIG_XSTR 507
|
||||
|
||||
#define JOY_X_AXIS 0
|
||||
#define JOY_Y_AXIS 1
|
||||
#define JOY_Z_AXIS 2
|
||||
#define JOY_RX_AXIS 3
|
||||
#define JOY_RY_AXIS 4
|
||||
#define JOY_RZ_AXIS 5
|
||||
|
||||
#define NUM_JOY_AXIS_ACTIONS 5
|
||||
|
||||
#define JOY_HEADING_AXIS 0
|
||||
#define JOY_PITCH_AXIS 1
|
||||
#define JOY_BANK_AXIS 2
|
||||
#define JOY_ABS_THROTTLE_AXIS 3
|
||||
#define JOY_REL_THROTTLE_AXIS 4
|
||||
|
||||
// --------------------------------------------------
|
||||
// different types of controls that can be assigned
|
||||
// --------------------------------------------------
|
||||
|
||||
#define CC_TYPE_TRIGGER 0
|
||||
#define CC_TYPE_CONTINUOUS 1
|
||||
|
||||
typedef struct config_item {
|
||||
short key_default; // default key bound to action
|
||||
short joy_default; // default joystick button bound to action
|
||||
char tab; // what tab (category) it belongs in
|
||||
bool hasXSTR; // whether we should translate this with an XSTR
|
||||
char *text; // describes the action in the config screen
|
||||
char type; // manner control should be checked in
|
||||
short key_id; // actual key bound to action
|
||||
short joy_id; // joystick button bound to action
|
||||
int used; // has control been used yet in mission? If so, this is the timestamp
|
||||
} config_item;
|
||||
|
||||
// --------------------------------------------------
|
||||
// Keyboard #defines for the actions
|
||||
// This is the value of the id field in config_item
|
||||
// --------------------------------------------------
|
||||
|
||||
// targeting a ship
|
||||
|
||||
#define TARGET_NEXT 0
|
||||
#define TARGET_PREV 1
|
||||
#define TARGET_NEXT_CLOSEST_HOSTILE 2
|
||||
#define TARGET_PREV_CLOSEST_HOSTILE 3
|
||||
#define TOGGLE_AUTO_TARGETING 4
|
||||
#define TARGET_NEXT_CLOSEST_FRIENDLY 5
|
||||
#define TARGET_PREV_CLOSEST_FRIENDLY 6
|
||||
#define TARGET_SHIP_IN_RETICLE 7
|
||||
#define TARGET_CLOSEST_SHIP_ATTACKING_TARGET 8
|
||||
#define TARGET_LAST_TRANMISSION_SENDER 9
|
||||
#define STOP_TARGETING_SHIP 10
|
||||
|
||||
// targeting a ship's subsystem
|
||||
#define TARGET_SUBOBJECT_IN_RETICLE 11
|
||||
#define TARGET_NEXT_SUBOBJECT 12
|
||||
#define TARGET_PREV_SUBOBJECT 13
|
||||
#define STOP_TARGETING_SUBSYSTEM 14
|
||||
|
||||
// speed matching
|
||||
#define MATCH_TARGET_SPEED 15
|
||||
#define TOGGLE_AUTO_MATCH_TARGET_SPEED 16
|
||||
|
||||
// weapons
|
||||
#define FIRE_PRIMARY 17
|
||||
#define FIRE_SECONDARY 18
|
||||
#define CYCLE_NEXT_PRIMARY 19
|
||||
#define CYCLE_PREV_PRIMARY 20
|
||||
#define CYCLE_SECONDARY 21
|
||||
#define CYCLE_NUM_MISSLES 22
|
||||
#define LAUNCH_COUNTERMEASURE 23
|
||||
|
||||
// controls
|
||||
#define FORWARD_THRUST 24
|
||||
#define REVERSE_THRUST 25
|
||||
#define BANK_LEFT 26
|
||||
#define BANK_RIGHT 27
|
||||
#define PITCH_FORWARD 28
|
||||
#define PITCH_BACK 29
|
||||
#define YAW_LEFT 30
|
||||
#define YAW_RIGHT 31
|
||||
|
||||
// throttle control
|
||||
#define ZERO_THROTTLE 32
|
||||
#define MAX_THROTTLE 33
|
||||
#define ONE_THIRD_THROTTLE 34
|
||||
#define TWO_THIRDS_THROTTLE 35
|
||||
#define PLUS_5_PERCENT_THROTTLE 36
|
||||
#define MINUS_5_PERCENT_THROTTLE 37
|
||||
|
||||
// squadmate messaging keys
|
||||
#define ATTACK_MESSAGE 38
|
||||
#define DISARM_MESSAGE 39
|
||||
#define DISABLE_MESSAGE 40
|
||||
#define ATTACK_SUBSYSTEM_MESSAGE 41
|
||||
#define CAPTURE_MESSAGE 42
|
||||
#define ENGAGE_MESSAGE 43
|
||||
#define FORM_MESSAGE 44
|
||||
#define IGNORE_MESSAGE 45
|
||||
#define PROTECT_MESSAGE 46
|
||||
#define COVER_MESSAGE 47
|
||||
#define WARP_MESSAGE 48
|
||||
#define REARM_MESSAGE 49
|
||||
|
||||
#define TARGET_CLOSEST_SHIP_ATTACKING_SELF 50
|
||||
|
||||
// Views
|
||||
#define VIEW_CHASE 51
|
||||
#define VIEW_EXTERNAL 52
|
||||
#define VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK 53
|
||||
#define VIEW_SLEW 54
|
||||
#define VIEW_OTHER_SHIP 55
|
||||
#define VIEW_DIST_INCREASE 56
|
||||
#define VIEW_DIST_DECREASE 57
|
||||
#define VIEW_CENTER 58
|
||||
#define PADLOCK_UP 59
|
||||
#define PADLOCK_DOWN 60
|
||||
#define PADLOCK_LEFT 61
|
||||
#define PADLOCK_RIGHT 62
|
||||
|
||||
|
||||
#define RADAR_RANGE_CYCLE 63
|
||||
#define SQUADMSG_MENU 64
|
||||
#define SHOW_GOALS 65
|
||||
#define END_MISSION 66
|
||||
#define TARGET_TARGETS_TARGET 67
|
||||
#define AFTERBURNER 68
|
||||
|
||||
#define INCREASE_WEAPON 69
|
||||
#define DECREASE_WEAPON 70
|
||||
#define INCREASE_SHIELD 71
|
||||
#define DECREASE_SHIELD 72
|
||||
#define INCREASE_ENGINE 73
|
||||
#define DECREASE_ENGINE 74
|
||||
#define ETS_EQUALIZE 75
|
||||
#define SHIELD_EQUALIZE 76
|
||||
#define SHIELD_XFER_TOP 77
|
||||
#define SHIELD_XFER_BOTTOM 78
|
||||
#define SHIELD_XFER_LEFT 79
|
||||
#define SHIELD_XFER_RIGHT 80
|
||||
|
||||
#define XFER_SHIELD 81
|
||||
#define XFER_LASER 82
|
||||
//#define SHOW_DAMAGE_POPUP 83 // AL: this binding should be removing next time the controls are reorganized
|
||||
|
||||
#define GLIDE_WHEN_PRESSED 83
|
||||
//Backslash -- this was a convenient place for Glide When Pressed, since Show Damage Popup isn't used
|
||||
#define BANK_WHEN_PRESSED 84
|
||||
#define SHOW_NAVMAP 85
|
||||
#define ADD_REMOVE_ESCORT 86
|
||||
#define ESCORT_CLEAR 87
|
||||
#define TARGET_NEXT_ESCORT_SHIP 88
|
||||
|
||||
#define TARGET_CLOSEST_REPAIR_SHIP 89
|
||||
#define TARGET_NEXT_UNINSPECTED_CARGO 90
|
||||
#define TARGET_PREV_UNINSPECTED_CARGO 91
|
||||
#define TARGET_NEWEST_SHIP 92
|
||||
#define TARGET_NEXT_LIVE_TURRET 93
|
||||
#define TARGET_PREV_LIVE_TURRET 94
|
||||
|
||||
#define TARGET_NEXT_BOMB 95
|
||||
#define TARGET_PREV_BOMB 96
|
||||
|
||||
// multiplayer messaging keys
|
||||
#define MULTI_MESSAGE_ALL 97
|
||||
#define MULTI_MESSAGE_FRIENDLY 98
|
||||
#define MULTI_MESSAGE_HOSTILE 99
|
||||
#define MULTI_MESSAGE_TARGET 100
|
||||
|
||||
// multiplayer misc keys
|
||||
#define MULTI_OBSERVER_ZOOM_TO 101
|
||||
|
||||
#define TIME_SPEED_UP 102
|
||||
#define TIME_SLOW_DOWN 103
|
||||
|
||||
#define TOGGLE_HUD_CONTRAST 104
|
||||
|
||||
#define MULTI_TOGGLE_NETINFO 105
|
||||
|
||||
#define MULTI_SELF_DESTRUCT 106
|
||||
|
||||
#define TOGGLE_HUD 107
|
||||
#define RIGHT_SLIDE_THRUST 108
|
||||
#define LEFT_SLIDE_THRUST 109
|
||||
#define UP_SLIDE_THRUST 110
|
||||
#define DOWN_SLIDE_THRUST 111
|
||||
#define HUD_TARGETBOX_TOGGLE_WIREFRAME 112
|
||||
#define VIEW_TOPDOWN 113
|
||||
#define VIEW_TRACK_TARGET 114
|
||||
|
||||
//AutoPilot - Kazan
|
||||
#define AUTO_PILOT_TOGGLE 115
|
||||
#define NAV_CYCLE 116
|
||||
|
||||
//Gliding
|
||||
#define TOGGLE_GLIDING 117
|
||||
|
||||
// this should be the total number of control action defines above (or last define + 1)
|
||||
#define CCFG_MAX 118
|
||||
|
||||
extern int Failed_key_index;
|
||||
extern int Invert_heading;
|
||||
extern int Invert_pitch;
|
||||
extern int Invert_roll;
|
||||
extern int Invert_thrust;
|
||||
extern int Disable_axis2;
|
||||
extern int Disable_axis3;
|
||||
|
||||
extern int Axis_map_to[];
|
||||
extern int Invert_axis[];
|
||||
extern int Invert_axis_defaults[];
|
||||
|
||||
extern config_item Control_config[]; // stores the keyboard configuration
|
||||
extern char **Scan_code_text;
|
||||
extern char **Joy_button_text;
|
||||
|
||||
// initialize common control config stuff - call at game startup after localization has been initialized
|
||||
void control_config_common_init();
|
||||
|
||||
void control_config_init();
|
||||
void control_config_do_frame(float frametime);
|
||||
void control_config_close();
|
||||
|
||||
void control_config_cancel_exit();
|
||||
|
||||
void control_config_reset_defaults();
|
||||
int translate_key_to_index(char *key);
|
||||
char *translate_key(char *key);
|
||||
char *textify_scancode(int code);
|
||||
float check_control_timef(int id);
|
||||
int check_control(int id, int key = -1);
|
||||
void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr);
|
||||
void control_used(int id);
|
||||
void control_config_clear();
|
||||
void clear_key_binding(short key);
|
||||
void control_check_indicate();
|
||||
void control_config_clear_used_status();
|
||||
|
||||
#endif
|
||||
@@ -1,519 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "controlconfig/controlsconfig.h"
|
||||
#include "io/key.h"
|
||||
#include "io/joy.h"
|
||||
#include "localization/localize.h"
|
||||
|
||||
|
||||
#define TARGET_TAB 0
|
||||
#define SHIP_TAB 1
|
||||
#define WEAPON_TAB 2
|
||||
#define COMPUTER_TAB 3
|
||||
|
||||
int Failed_key_index;
|
||||
|
||||
// assume control keys are used as modifiers until we find out
|
||||
int Shift_is_modifier;
|
||||
int Ctrl_is_modifier;
|
||||
int Alt_is_modifier;
|
||||
|
||||
int Axis_enabled[JOY_NUM_AXES] = { 1, 1, 1, 0, 0, 0 };
|
||||
int Axis_enabled_defaults[JOY_NUM_AXES] = { 1, 1, 1, 0, 0, 0 };
|
||||
int Invert_axis[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
|
||||
int Invert_axis_defaults[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
// arrays which hold the key mappings. The array index represents a key-independent action.
|
||||
//
|
||||
//XSTR:OFF
|
||||
config_item Control_config[CCFG_MAX + 1] = {
|
||||
// targeting a ship
|
||||
{ KEY_T, -1, TARGET_TAB, true, "Target Next Ship" },
|
||||
{ KEY_SHIFTED | KEY_T, -1, TARGET_TAB, true, "Target Previous Ship" },
|
||||
{ KEY_H, 2, TARGET_TAB, true, "Target Next Closest Hostile Ship" },
|
||||
{ KEY_SHIFTED | KEY_H, -1, TARGET_TAB, true, "Target Previous Closest Hostile Ship" },
|
||||
{ KEY_ALTED | KEY_H, -1, TARGET_TAB, true, "Toggle Auto Targeting" },
|
||||
{ KEY_F, -1, TARGET_TAB, true, "Target Next Closest Friendly Ship" },
|
||||
{ KEY_SHIFTED | KEY_F, -1, TARGET_TAB, true, "Target Previous Closest Friendly Ship" },
|
||||
{ KEY_Y, 4, TARGET_TAB, true, "Target Ship in Reticle" },
|
||||
{ KEY_G, -1, TARGET_TAB, true, "Target Target's Nearest Attacker" },
|
||||
{ KEY_ALTED | KEY_Y, -1, TARGET_TAB, true, "Target Last Ship to Send Transmission" },
|
||||
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, true, "Turn Off Targeting" },
|
||||
|
||||
// targeting a ship's subsystem
|
||||
{ KEY_V, -1, TARGET_TAB, true, "Target Subsystem in Reticle" },
|
||||
{ KEY_S, -1, TARGET_TAB, true, "Target Next Subsystem" },
|
||||
{ KEY_SHIFTED | KEY_S, -1, TARGET_TAB, true, "Target Previous Subsystem" },
|
||||
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, true, "Turn Off Targeting of Subsystems" },
|
||||
|
||||
// matching speed
|
||||
{ KEY_M, -1, COMPUTER_TAB, true, "Match Target Speed" },
|
||||
{ KEY_ALTED | KEY_M, -1, COMPUTER_TAB, true, "Toggle Auto Speed Matching" },
|
||||
|
||||
// weapons
|
||||
{ KEY_LCTRL, 0, WEAPON_TAB, true, "Fire Primary Weapon", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_SPACEBAR, 1, WEAPON_TAB, true, "Fire Secondary Weapon", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PERIOD, -1, WEAPON_TAB, true, "Cycle Forward Primary Weapon" },
|
||||
{ KEY_COMMA, -1, WEAPON_TAB, true, "Cycle Backward Primary Weapon" },
|
||||
{ KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Bank" },
|
||||
{ KEY_SHIFTED | KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Firing Rate" },
|
||||
{ KEY_X, 3, WEAPON_TAB, true, "Launch Countermeasure" },
|
||||
|
||||
// controls
|
||||
{ KEY_A, -1, SHIP_TAB, true, "Forward Thrust", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_Z, -1, SHIP_TAB, true, "Reverse Thrust", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PAD7, -1, SHIP_TAB, true, "Bank Left", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PAD9, -1, SHIP_TAB, true, "Bank Right", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PAD8, -1, SHIP_TAB, true, "Pitch Forward", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PAD2, -1, SHIP_TAB, true, "Pitch Backward", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PAD4, -1, SHIP_TAB, true, "Turn Left", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PAD6, -1, SHIP_TAB, true, "Turn Right", CC_TYPE_CONTINUOUS },
|
||||
|
||||
// throttle controls
|
||||
{ KEY_BACKSP, -1, SHIP_TAB, true, "Set Throttle to Zero" },
|
||||
{ KEY_SLASH, -1, SHIP_TAB, true, "Set Throttle to Max" },
|
||||
{ KEY_LBRACKET, -1, SHIP_TAB, true, "Set Throttle to One-Third" },
|
||||
{ KEY_RBRACKET, -1, SHIP_TAB, true, "Set Throttle to Two-Thirds" },
|
||||
{ KEY_EQUAL, -1, SHIP_TAB, true, "Increase Throttle 5 Percent" },
|
||||
{ KEY_MINUS, -1, SHIP_TAB, true, "Decrease Throttle 5 Percent" },
|
||||
|
||||
// squadmate messaging
|
||||
{ KEY_SHIFTED | KEY_A, -1, COMPUTER_TAB, true, "Attack My Target" },
|
||||
{ KEY_SHIFTED | KEY_Z, -1, COMPUTER_TAB, true, "Disarm My Target" },
|
||||
{ KEY_SHIFTED | KEY_D, -1, COMPUTER_TAB, true, "Disable My Target" },
|
||||
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, true, "Attack My Subsystem" },
|
||||
{ KEY_SHIFTED | KEY_X, -1, COMPUTER_TAB, true, "Capture My Target" },
|
||||
{ KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Engage Enemy" },
|
||||
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, true, "Form on My Wing" },
|
||||
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, true, "Ignore My Target" },
|
||||
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, true, "Protect My Target" },
|
||||
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, true, "Cover Me" },
|
||||
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, true, "Return to Base" },
|
||||
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, true, "Rearm Me" },
|
||||
|
||||
{ KEY_R, 6, TARGET_TAB, true, "Target Closest Attacking Ship" },
|
||||
|
||||
// Views
|
||||
{ KEY_PADMULTIPLY, -1, COMPUTER_TAB, true, "Chase View" },
|
||||
{ KEY_PADPERIOD, -1, COMPUTER_TAB, true, "External View"},
|
||||
{ KEY_PADENTER, -1, COMPUTER_TAB, true, "Toggle External Camera Lock"},
|
||||
{ KEY_PAD0, -1, COMPUTER_TAB, true, "Free Look View", CC_TYPE_CONTINUOUS }, // Not in use anymore (Swifty)
|
||||
{ KEY_PADDIVIDE, -1, COMPUTER_TAB, true, "Current Target View" },
|
||||
{ KEY_PADPLUS, -1, COMPUTER_TAB, true, "Increase View Distance", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PADMINUS, -1, COMPUTER_TAB, true, "Decrease View Distance", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_PAD5, -1, COMPUTER_TAB, true, "Center View", CC_TYPE_CONTINUOUS },
|
||||
{ -1, 33, COMPUTER_TAB, true, "View Up", CC_TYPE_CONTINUOUS },
|
||||
{ -1, 32, COMPUTER_TAB, true, "View Rear", CC_TYPE_CONTINUOUS },
|
||||
{ -1, 34, COMPUTER_TAB, true, "View Left", CC_TYPE_CONTINUOUS },
|
||||
{ -1, 35, COMPUTER_TAB, true, "View Right", CC_TYPE_CONTINUOUS },
|
||||
|
||||
{ KEY_RAPOSTRO, -1, COMPUTER_TAB, true, "Cycle Radar Range" },
|
||||
{ KEY_C, -1, COMPUTER_TAB, true, "Communications Menu" },
|
||||
{ -1, -1, -1, true, "Show Objectives" },
|
||||
{ KEY_ALTED | KEY_J, -1, COMPUTER_TAB, true, "Enter Subspace (End Mission)" },
|
||||
{ KEY_J, -1, TARGET_TAB, true, "Target Target's Target" },
|
||||
{ KEY_TAB, 5, SHIP_TAB, true, "Afterburner", CC_TYPE_CONTINUOUS },
|
||||
|
||||
{ KEY_INSERT, -1, COMPUTER_TAB, true, "Increase Weapon Energy" },
|
||||
{ KEY_DELETE, -1, COMPUTER_TAB, true, "Decrease Weapon Energy" },
|
||||
{ KEY_HOME, -1, COMPUTER_TAB, true, "Increase Shield Energy" },
|
||||
{ KEY_END, -1, COMPUTER_TAB, true, "Decrease Shield Energy" },
|
||||
{ KEY_PAGEUP, -1, COMPUTER_TAB, true, "Increase Engine Energy" },
|
||||
{ KEY_PAGEDOWN, -1, COMPUTER_TAB, true, "Decrease Engine Energy" },
|
||||
{ KEY_ALTED | KEY_D, -1, COMPUTER_TAB, true, "Equalize Energy Settings" },
|
||||
|
||||
{ KEY_Q, 7, COMPUTER_TAB, true, "Equalize Shields" },
|
||||
{ KEY_UP, -1, COMPUTER_TAB, true, "Augment Forward Shield" },
|
||||
{ KEY_DOWN, -1, COMPUTER_TAB, true, "Augment Rear Shield" },
|
||||
{ KEY_LEFT, -1, COMPUTER_TAB, true, "Augment Left Shield" },
|
||||
{ KEY_RIGHT, -1, COMPUTER_TAB, true, "Augment Right Shield" },
|
||||
{ KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Laser->Shield" },
|
||||
{ KEY_SHIFTED | KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Shield->Laser" },
|
||||
// { -1, -1, -1, true, "Show Damage Popup Window" },
|
||||
|
||||
{ -1, -1, SHIP_TAB, false, "Glide When Pressed", CC_TYPE_CONTINUOUS },
|
||||
//Backslash -- this was a convenient place for Glide When Pressed, as Show Damage Popup isn't used
|
||||
{ -1, -1, SHIP_TAB, true, "Bank When Pressed", CC_TYPE_CONTINUOUS },
|
||||
{ -1, -1, -1, true, "Show Nav Map" },
|
||||
{ KEY_ALTED | KEY_E, -1, COMPUTER_TAB, true, "Add or Remove Escort" },
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Clear Escort List" },
|
||||
{ KEY_E, -1, TARGET_TAB, true, "Target Next Escort Ship" },
|
||||
{ KEY_ALTED | KEY_R, -1, TARGET_TAB, true, "Target Closest Repair Ship" },
|
||||
|
||||
{ KEY_U, -1, TARGET_TAB, true, "Target Next Uninspected Cargo" },
|
||||
{ KEY_SHIFTED | KEY_U, -1, TARGET_TAB, true, "Target Previous Uninspected Cargo" },
|
||||
{ KEY_N, -1, TARGET_TAB, true, "Target Newest Ship in Area" },
|
||||
{ KEY_K, -1, TARGET_TAB, true, "Target Next Live Turret" },
|
||||
{ KEY_SHIFTED | KEY_K, -1, TARGET_TAB, true, "Target Previous Live Turret" },
|
||||
|
||||
{ KEY_B, -1, TARGET_TAB, true, "Target Next Hostile Bomb or Bomber" },
|
||||
{ KEY_SHIFTED | KEY_B, -1, TARGET_TAB, true, "Target Previous Hostile Bomb or Bomber" },
|
||||
|
||||
// multiplayer messaging keys
|
||||
{ KEY_1, -1, COMPUTER_TAB, true, "(Multiplayer) Message All", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_2, -1, COMPUTER_TAB, true, "(Multiplayer) Message Friendly", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_3, -1, COMPUTER_TAB, true, "(Multiplayer) Message Hostile", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_4, -1, COMPUTER_TAB, true, "(Multiplayer) Message Target", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, true, "(Multiplayer) Observer Zoom to Target"},
|
||||
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, true, "Increase Time Compression" },
|
||||
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, true, "Decrease Time Compression" },
|
||||
{ KEY_L, -1, COMPUTER_TAB, true, "Toggle High HUD Contrast" },
|
||||
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, true, "(Multiplayer) Toggle Network Info"},
|
||||
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, true, "(Multiplayer) Self Destruct"},
|
||||
|
||||
// Misc
|
||||
{ KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, true, "Toggle HUD"},
|
||||
{ KEY_SHIFTED | KEY_3, -1, SHIP_TAB, true, "Right Thrust", CC_TYPE_CONTINUOUS},
|
||||
{ KEY_SHIFTED | KEY_1, -1, SHIP_TAB, true, "Left Thrust", CC_TYPE_CONTINUOUS},
|
||||
{ KEY_SHIFTED | KEY_PADPLUS, -1, SHIP_TAB, true, "Up Thrust", CC_TYPE_CONTINUOUS},
|
||||
{ KEY_SHIFTED | KEY_PADENTER, -1, SHIP_TAB, true, "Down Thrust", CC_TYPE_CONTINUOUS},
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, true, "Toggle HUD Wireframe Target View"},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Top-Down View"},
|
||||
{ -1, -1, COMPUTER_TAB, false, "Target Padlock View"}, // (Swifty) Toggle for VM_TRACK
|
||||
// Auto Navigation Systen
|
||||
{ KEY_ALTED | KEY_A, -1, COMPUTER_TAB, false, "Toggle Auto Pilot"},
|
||||
{ KEY_ALTED | KEY_N, -1, COMPUTER_TAB, false, "Cycle Nav Points"},
|
||||
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, false, "Toggle Gliding"},
|
||||
{ -1, -1, -1, false, "" }
|
||||
};
|
||||
|
||||
char *Scan_code_text_german[] = {
|
||||
"", "Esc", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0", "Akzent '", "\xE1", "R\x81""cktaste", "Tab",
|
||||
"Q", "W", "E", "R", "T", "Z", "U", "I",
|
||||
"O", "P", "\x9A", "+", "Eingabe", "Strg Links", "A", "S",
|
||||
|
||||
"D", "F", "G", "H", "J", "K", "L", "\x99",
|
||||
"\xAE", "`", "Shift", "#", "Y", "X", "C", "V",
|
||||
"B", "N", "M", ",", ".", "-", "Shift", "Num *",
|
||||
"Alt", "Leertaste", "Hochstell", "F1", "F2", "F3", "F4", "F5",
|
||||
|
||||
"F6", "F7", "F8", "F9", "F10", "Pause", "Rollen", "Num 7",
|
||||
"Num 8", "Num 9", "Num -", "Num 4", "Num 5", "Num 6", "Num +", "Num 1",
|
||||
"Num 2", "Num 3", "Num 0", "Num ,", "", "", "", "F11",
|
||||
"F12", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "Num Eingabe", "Strg Rechts", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "Num /", "", "Druck",
|
||||
"Alt", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "Num Lock", "", "Pos 1",
|
||||
"Pfeil Hoch", "Bild Hoch", "", "Pfeil Links", "", "Pfeil Rechts", "", "Ende",
|
||||
"Pfeil Runter", "Bild Runter", "Einfg", "Entf", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
};
|
||||
|
||||
char *Joy_button_text_german[] = {
|
||||
"Knopf 1", "Knopf 2", "Knopf 3", "Knopf 4", "Knopf 5", "Knopf 6",
|
||||
"Knopf 7", "Knopf 8", "Knopf 9", "Knopf 10", "Knopf 11", "Knopf 12",
|
||||
"Knopf 13", "Knopf 14", "Knopf 15", "Knopf 16", "Knopf 17", "Knopf 18",
|
||||
"Knopf 19", "Knopf 20", "Knopf 21", "Knopf 22", "Knopf 23", "Knopf 24",
|
||||
"Knopf 25", "Knopf 26", "Knopf 27", "Knopf 28", "Knopf 29", "Knopf 30",
|
||||
"Knopf 31", "Knopf 32", "Hut Hinten", "Hut Vorne", "Hut Links", "Hut Rechts"
|
||||
};
|
||||
|
||||
char *Scan_code_text_french[] = {
|
||||
"", "\x90""chap", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0", "-", "=", "Fl\x82""che Ret.", "Tab",
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I",
|
||||
"O", "P", "[", "]", "Entr\x82""e", "Ctrl Gauche", "A", "S",
|
||||
|
||||
"D", "F", "G", "H", "J", "K", "L", ";",
|
||||
"'", "`", "Maj.", "\\", "Z", "X", "C", "V",
|
||||
"B", "N", "M", ",", ".", "/", "Maj.", "Pav\x82 *",
|
||||
"Alt", "Espace", "Verr. Maj.", "F1", "F2", "F3", "F4", "F5",
|
||||
|
||||
"F6", "F7", "F8", "F9", "F10", "Pause", "Arret defil", "Pav\x82 7",
|
||||
"Pav\x82 8", "Pav\x82 9", "Pav\x82 -", "Pav\x82 4", "Pav\x82 5", "Pav\x82 6", "Pav\x82 +", "Pav\x82 1",
|
||||
"Pav\x82 2", "Pav\x82 3", "Pav\x82 0", "Pav\x82 .", "", "", "", "F11",
|
||||
"F12", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "Pav\x82 Entr", "Ctrl Droite", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "Pav\x82 /", "", "Impr \x82""cran",
|
||||
"Alt", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "Verr num", "", "Orig.",
|
||||
"Fl\x82""che Haut", "Page Haut", "", "Fl\x82""che Gauche", "", "Fl\x82""che Droite", "", "Fin",
|
||||
"Fl\x82""che Bas", "Page Bas", "Inser", "Suppr", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
};
|
||||
|
||||
char *Joy_button_text_french[] = {
|
||||
"Bouton 1", "Bouton 2", "Bouton 3", "Bouton 4", "Bouton 5", "Bouton 6",
|
||||
"Bouton 7", "Bouton 8", "Bouton 9", "Bouton 10", "Bouton 11", "Bouton 12",
|
||||
"Bouton 13", "Bouton 14", "Bouton 15", "Bouton 16", "Bouton 17", "Bouton 18",
|
||||
"Bouton 19", "Bouton 20", "Bouton 21", "Bouton 22", "Bouton 23", "Bouton 24",
|
||||
"Bouton 25", "Bouton 26", "Bouton 27", "Bouton 28", "Bouton 29", "Bouton 30",
|
||||
"Bouton 31", "Bouton 32", "Chapeau Arrière", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
|
||||
};
|
||||
|
||||
// This is the text that is displayed on the screen for the keys a player selects
|
||||
char *Scan_code_text_english[] = {
|
||||
"", "Esc", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0", "-", "=", "Backspace", "Tab",
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I",
|
||||
"O", "P", "[", "]", "Enter", "Left Ctrl", "A", "S",
|
||||
|
||||
"D", "F", "G", "H", "J", "K", "L", ";",
|
||||
"'", "`", "Shift", "\\", "Z", "X", "C", "V",
|
||||
"B", "N", "M", ",", ".", "/", "Shift", "Pad *",
|
||||
"Alt", "Spacebar", "Caps Lock", "F1", "F2", "F3", "F4", "F5",
|
||||
|
||||
"F6", "F7", "F8", "F9", "F10", "Pause", "Scroll Lock", "Pad 7",
|
||||
"Pad 8", "Pad 9", "Pad -", "Pad 4", "Pad 5", "Pad 6", "Pad +", "Pad 1",
|
||||
"Pad 2", "Pad 3", "Pad 0", "Pad .", "", "", "", "F11",
|
||||
"F12", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "Pad Enter", "Right Ctrl", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "Pad /", "", "Print Scrn",
|
||||
"Alt", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "Num Lock", "", "Home",
|
||||
"Up Arrow", "Page Up", "", "Left Arrow", "", "Right Arrow", "", "End",
|
||||
"Down Arrow", "Page Down", "Insert", "Delete", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
};
|
||||
|
||||
char *Joy_button_text_english[] = {
|
||||
"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6",
|
||||
"Button 7", "Button 8", "Button 9", "Button 10", "Button 11", "Button 12",
|
||||
"Button 13", "Button 14", "Button 15", "Button 16", "Button 17", "Button 18",
|
||||
"Button 19", "Button 20", "Button 21", "Button 22", "Button 23", "Button 24",
|
||||
"Button 25", "Button 26", "Button 27", "Button 28", "Button 29", "Button 30",
|
||||
"Button 31", "Button 32", "Hat Back", "Hat Forward", "Hat Left", "Hat Right"
|
||||
};
|
||||
|
||||
char **Scan_code_text = Scan_code_text_english;
|
||||
char **Joy_button_text = Joy_button_text_english;
|
||||
|
||||
void set_modifier_status()
|
||||
{
|
||||
int i;
|
||||
|
||||
Alt_is_modifier = 0;
|
||||
Shift_is_modifier = 0;
|
||||
Ctrl_is_modifier = 0;
|
||||
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (Control_config[i].key_id < 0)
|
||||
continue;
|
||||
|
||||
if (Control_config[i].key_id & KEY_ALTED)
|
||||
Alt_is_modifier = 1;
|
||||
|
||||
if (Control_config[i].key_id & KEY_SHIFTED)
|
||||
Shift_is_modifier = 1;
|
||||
|
||||
if (Control_config[i].key_id & KEY_CTRLED) {
|
||||
Assert(0); // get Alan
|
||||
Ctrl_is_modifier = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int translate_key_to_index(char *key)
|
||||
{
|
||||
int i, index = -1, alt = 0, shift = 0, max_scan_codes;
|
||||
|
||||
if (Lcl_gr) {
|
||||
max_scan_codes = sizeof(Scan_code_text_german) / sizeof(char *);
|
||||
} else if (Lcl_fr) {
|
||||
max_scan_codes = sizeof(Scan_code_text_french) / sizeof(char *);
|
||||
} else {
|
||||
max_scan_codes = sizeof(Scan_code_text_english) / sizeof(char *);
|
||||
}
|
||||
|
||||
// look for modifiers
|
||||
Assert(key);
|
||||
if (!strnicmp(key, "Alt", 3)) {
|
||||
alt = 1;
|
||||
key += 3;
|
||||
if (*key)
|
||||
key++;
|
||||
}
|
||||
|
||||
char *translated_shift;
|
||||
|
||||
if(Lcl_gr){
|
||||
translated_shift = "Shift";
|
||||
} else if(Lcl_fr){
|
||||
translated_shift = "Maj.";
|
||||
} else {
|
||||
translated_shift = "Shift";
|
||||
}
|
||||
|
||||
if (!strnicmp(key, translated_shift, 5)) {
|
||||
shift = 1;
|
||||
key += 5;
|
||||
if (*key)
|
||||
key++;
|
||||
}
|
||||
|
||||
// look up index for default key
|
||||
if (*key) {
|
||||
for (i=0; i<max_scan_codes; i++)
|
||||
if (!stricmp(key, Scan_code_text_english[i])) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == max_scan_codes)
|
||||
return -1;
|
||||
|
||||
if (shift)
|
||||
index |= KEY_SHIFTED;
|
||||
if (alt)
|
||||
index |= KEY_ALTED;
|
||||
|
||||
// convert scancode to Control_config index
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (Control_config[i].key_default == index) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == CCFG_MAX)
|
||||
return -1;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Given the system default key 'key', return the current key that is bound to the function
|
||||
// Both are 'key' and the return value are descriptive strings that can be displayed
|
||||
// directly to the user. If 'key' isn't a real key or not normally bound to anything,
|
||||
// or there is no key current bound to the function, NULL is returned.
|
||||
char *translate_key(char *key)
|
||||
{
|
||||
int index = -1, code = -1;
|
||||
|
||||
index = translate_key_to_index(key);
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
|
||||
code = Control_config[index].key_id;
|
||||
Failed_key_index = index;
|
||||
if (code < 0) {
|
||||
code = Control_config[index].joy_id;
|
||||
if (code >= 0)
|
||||
return Joy_button_text[code];
|
||||
}
|
||||
|
||||
return textify_scancode(code);
|
||||
}
|
||||
|
||||
char *textify_scancode(int code)
|
||||
{
|
||||
static char text[40];
|
||||
|
||||
if (code < 0)
|
||||
return "None";
|
||||
|
||||
int keycode = code & KEY_MASK;
|
||||
|
||||
*text = 0;
|
||||
if (code & KEY_ALTED && !(keycode == KEY_LALT || keycode == KEY_RALT)) {
|
||||
if(Lcl_gr){
|
||||
strcat_s(text, "Alt-");
|
||||
} else if(Lcl_fr){
|
||||
strcat_s(text, "Alt-");
|
||||
} else {
|
||||
strcat_s(text, "Alt-");
|
||||
}
|
||||
}
|
||||
|
||||
if (code & KEY_SHIFTED && !(keycode == KEY_LSHIFT || keycode == KEY_RSHIFT)) {
|
||||
if(Lcl_gr){
|
||||
strcat_s(text, "Shift-");
|
||||
} else if(Lcl_fr){
|
||||
strcat_s(text, "Maj.-");
|
||||
} else {
|
||||
strcat_s(text, "Shift-");
|
||||
}
|
||||
}
|
||||
|
||||
strcat_s(text, Scan_code_text[keycode]);
|
||||
return text;
|
||||
}
|
||||
//XSTR:ON
|
||||
|
||||
// initialize common control config stuff - call at game startup after localization has been initialized
|
||||
void control_config_common_init()
|
||||
{
|
||||
if(Lcl_gr){
|
||||
Scan_code_text = Scan_code_text_german;
|
||||
Joy_button_text = Joy_button_text_german;
|
||||
|
||||
// swap init bindings for y and z keys
|
||||
Control_config[TARGET_SHIP_IN_RETICLE].key_default = KEY_Z;
|
||||
Control_config[TARGET_LAST_TRANMISSION_SENDER].key_default = KEY_ALTED | KEY_Z;
|
||||
Control_config[REVERSE_THRUST].key_default = KEY_Y;
|
||||
Control_config[DISARM_MESSAGE].key_default = KEY_SHIFTED | KEY_Y;
|
||||
} else if(Lcl_fr){
|
||||
Scan_code_text = Scan_code_text_french;
|
||||
Joy_button_text = Joy_button_text_french;
|
||||
} else {
|
||||
Scan_code_text = Scan_code_text_english;
|
||||
Joy_button_text = Joy_button_text_english;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "globalincs/crypt.h"
|
||||
|
||||
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redfine main() which is something
|
||||
// that we don't want since we don't actually link against SDL, this solves the problem...
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *crypt_string;
|
||||
|
||||
if ( argc == 1 ) {
|
||||
printf("Usage: cryptstring <string1> <string2> ...\n");
|
||||
printf("Output will be <crypt1> <crypt2>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for ( i = 1; i < argc; i++ ) {
|
||||
char *s;
|
||||
|
||||
s = argv[i];
|
||||
// if the length of the string is greater than the number of crypted symbols we
|
||||
// return, then pass only the maximum length
|
||||
if ( strlen(s) > CRYPT_STRING_LENGTH )
|
||||
s += (strlen(s) - CRYPT_STRING_LENGTH);
|
||||
|
||||
crypt_string = jcrypt(s);
|
||||
printf("%s\n", crypt_string);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *jcrypt (char *plainstring)
|
||||
{
|
||||
int i,t,len;
|
||||
static char cryptstring[CRYPT_STRING_LENGTH + 1];
|
||||
|
||||
len=strlen (plainstring);
|
||||
if (len > CRYPT_STRING_LENGTH)
|
||||
len = CRYPT_STRING_LENGTH;
|
||||
|
||||
for (i = 0;i < len; i++) {
|
||||
cryptstring[i]=0;
|
||||
|
||||
for (t = 0; t < len; t++) {
|
||||
cryptstring[i]^=(plainstring[t] ^ plainstring[i%(t+1)]);
|
||||
cryptstring[i]%=90;
|
||||
cryptstring[i]+=33;
|
||||
}
|
||||
}
|
||||
|
||||
cryptstring[i]=0;
|
||||
return ((char *)cryptstring);
|
||||
}
|
||||
@@ -1,681 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "cutscene/cutscenes.h"
|
||||
#include "ui/ui.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "gamesequence/gamesequence.h"
|
||||
#include "freespace2/freespace.h"
|
||||
#include "io/key.h"
|
||||
#include "movie.h"
|
||||
#include "popup/popup.h"
|
||||
#include "menuui/mainhallmenu.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "localization/localize.h"
|
||||
#include "parse/parselo.h"
|
||||
|
||||
|
||||
extern int Cmdline_nomovies;
|
||||
|
||||
|
||||
char *Cutscene_bitmap_name[GR_NUM_RESOLUTIONS] = {
|
||||
"ViewFootage",
|
||||
"2_ViewFootage"
|
||||
};
|
||||
char *Cutscene_mask_name[GR_NUM_RESOLUTIONS] = {
|
||||
"ViewFootage-m",
|
||||
"2_ViewFootage-m"
|
||||
};
|
||||
|
||||
int Cutscenes_viewable;
|
||||
int Description_index;
|
||||
SCP_vector<cutscene_info> Cutscenes;
|
||||
|
||||
//extern int All_movies_enabled; // If set, all movies may be viewed. Keyed off cheat code.
|
||||
void cutscene_close()
|
||||
{
|
||||
for(size_t i = 0; i < Cutscenes.size(); i++)
|
||||
{
|
||||
if(Cutscenes[i].description)
|
||||
{
|
||||
vm_free(Cutscenes[i].description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialization stuff for cutscenes
|
||||
void cutscene_init()
|
||||
{
|
||||
atexit(cutscene_close);
|
||||
char buf[MULTITEXT_LENGTH];
|
||||
int rval;
|
||||
cutscene_info cutinfo;
|
||||
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "cutscenes.tbl", rval));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("cutscenes.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse in all the cutscenes
|
||||
Cutscenes.clear();
|
||||
skip_to_string("#Cutscenes");
|
||||
ignore_white_space();
|
||||
|
||||
while ( required_string_either("#End", "$Filename:") )
|
||||
{
|
||||
memset(&cutinfo, 0, sizeof(cutscene_info));
|
||||
|
||||
required_string("$Filename:");
|
||||
stuff_string( cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN );
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string( cutinfo.name, F_NAME, NAME_LENGTH );
|
||||
|
||||
required_string("$Description:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
cutinfo.description = vm_strdup(buf);
|
||||
|
||||
required_string("$cd:");
|
||||
stuff_int( &cutinfo.cd );
|
||||
|
||||
Cutscenes.push_back(cutinfo);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
Cutscenes_viewable = INTRO_CUTSCENE_FLAG;
|
||||
|
||||
// close localization
|
||||
lcl_ext_close();
|
||||
}
|
||||
|
||||
// function to return 0 based index of which CD a particular movie is on
|
||||
// returns -1 on failure.
|
||||
int cutscenes_get_cd_num( char *filename )
|
||||
{
|
||||
#if defined(OEM_BUILD)
|
||||
return 0; // only 1 cd for OEM
|
||||
#else
|
||||
|
||||
for (size_t i = 0; i < Cutscenes.size(); i++ ) {
|
||||
if ( !stricmp(Cutscenes[i].filename, filename) ) {
|
||||
return (Cutscenes[i].cd - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
#endif // defined(OEM_BUILD)
|
||||
}
|
||||
|
||||
// marks a cutscene as viewable
|
||||
void cutscene_mark_viewable(char *filename)
|
||||
{
|
||||
char cut_file[MAX_FILENAME_LEN];
|
||||
char file[MAX_FILENAME_LEN];
|
||||
|
||||
Assert(filename!=NULL);
|
||||
|
||||
// strip off extension
|
||||
strcpy_s( file, filename );
|
||||
char *p = strchr( file, '.' );
|
||||
if ( p ) {
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
// change to lower case
|
||||
strlwr(file);
|
||||
|
||||
for (size_t i = 0; i < Cutscenes.size(); i++ ) {
|
||||
// change the cutscene file name to lower case
|
||||
strcpy_s(cut_file, Cutscenes[i].filename);
|
||||
strlwr(cut_file);
|
||||
|
||||
// see if the stripped filename matches the cutscene filename
|
||||
if ( strstr(cut_file, file) != NULL ) {
|
||||
Cutscenes_viewable |= (1<<i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define NUM_BUTTONS 8
|
||||
|
||||
#define TECH_DATABASE_BUTTON 0
|
||||
#define SIMULATOR_BUTTON 1
|
||||
#define CUTSCENES_BUTTON 2
|
||||
#define CREDITS_BUTTON 3
|
||||
|
||||
#define SCROLL_UP_BUTTON 4
|
||||
#define SCROLL_DOWN_BUTTON 5
|
||||
#define PLAY_BUTTON 6
|
||||
#define EXIT_BUTTON 7
|
||||
|
||||
static SCP_vector<int> Cutscene_list;
|
||||
//static int Stats_scroll_offset; // not used - taylor
|
||||
static int Selected_line = 0; // line that is currently selected for binding
|
||||
static int Scroll_offset;
|
||||
static int Background_bitmap;
|
||||
static UI_BUTTON List_region;
|
||||
static UI_WINDOW Ui_window;
|
||||
|
||||
static ui_button_info Buttons[GR_NUM_RESOLUTIONS][NUM_BUTTONS] = {
|
||||
{ // GR_640
|
||||
ui_button_info("TDB_00", 7, 3, 37, 7, 0), // tech database 1
|
||||
ui_button_info("TDB_01", 7, 18, 37, 23, 1), // tech database 2
|
||||
ui_button_info("TDB_02", 7, 34, 37, 38, 2), // tech database 3
|
||||
ui_button_info("TDB_03", 7, 49, 37, 54, 3), // tech database 4
|
||||
|
||||
ui_button_info("VFB_04", 6, 318, -1, -1, 4), // scroll up
|
||||
ui_button_info("VFB_05", 36, 318, -1, -1, 5), // scroll down
|
||||
ui_button_info("VFB_06", 578, 319, 587, 366, 6), // play
|
||||
ui_button_info("VFB_07", 574, 431, 587, 413, 7), // exit
|
||||
},
|
||||
{ // GR_1024
|
||||
ui_button_info("2_TDB_00", 12, 5, 59, 12, 0), // tech database 1
|
||||
ui_button_info("2_TDB_01", 12, 31, 59, 37, 1), // tech database 2
|
||||
ui_button_info("2_TDB_02", 12, 56, 59, 62, 2), // tech database 3
|
||||
ui_button_info("2_TDB_03", 12, 81, 59, 88, 3), // tech database 4
|
||||
|
||||
ui_button_info("2_VFB_04", 9, 509, -1, -1, 4), // scroll up
|
||||
ui_button_info("2_VFB_05", 58, 509, -1, -1, 5), // scroll down
|
||||
ui_button_info("2_VFB_06", 925, 511, 940, 586, 6), // play
|
||||
ui_button_info("2_VFB_07", 918, 689, 940, 661, 7), // exit
|
||||
}
|
||||
};
|
||||
|
||||
// text
|
||||
#define NUM_CUTSCENE_TEXT 6
|
||||
UI_XSTR Cutscene_text[GR_NUM_RESOLUTIONS][NUM_CUTSCENE_TEXT] = {
|
||||
{ // GR_640
|
||||
{"Technical Database", 1055, 37, 7, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][TECH_DATABASE_BUTTON].button },
|
||||
{"Mission Simulator", 1056, 37, 23, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][SIMULATOR_BUTTON].button },
|
||||
{"Cutscenes", 1057, 37, 38, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][CUTSCENES_BUTTON].button },
|
||||
{"Credits", 1058, 37, 54, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][CREDITS_BUTTON].button },
|
||||
|
||||
{"Play", 1335, 587, 366, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][PLAY_BUTTON].button },
|
||||
{"Exit", 1419, 587, 413, UI_XSTR_COLOR_PINK, -1, &Buttons[0][EXIT_BUTTON].button },
|
||||
},
|
||||
{ // GR_1024
|
||||
{"Technical Database", 1055, 59, 12, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][TECH_DATABASE_BUTTON].button },
|
||||
{"Mission Simulator", 1056, 59, 37, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][SIMULATOR_BUTTON].button },
|
||||
{"Cutscenes", 1057, 59, 62, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][CUTSCENES_BUTTON].button },
|
||||
{"Credits", 1058, 59, 88, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][CREDITS_BUTTON].button },
|
||||
|
||||
{"Play", 1335, 940, 586, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][PLAY_BUTTON].button },
|
||||
{"Exit", 1419, 940, 661, UI_XSTR_COLOR_PINK, -1, &Buttons[1][EXIT_BUTTON].button },
|
||||
}
|
||||
};
|
||||
|
||||
int Cutscene_list_coords[GR_NUM_RESOLUTIONS][4] = {
|
||||
{ // GR_640
|
||||
9, 117, 621, 198
|
||||
},
|
||||
{ // GR_1024
|
||||
14, 188, 994, 316
|
||||
}
|
||||
};
|
||||
|
||||
int Cutscene_desc_coords[GR_NUM_RESOLUTIONS][4] = {
|
||||
{ // GR_640
|
||||
9, 378, 484, 73
|
||||
},
|
||||
{ // GR_1024
|
||||
14, 605, 775, 117
|
||||
}
|
||||
};
|
||||
|
||||
#define MAX_TEXT_LINES 20
|
||||
int Cutscene_max_text_lines[GR_NUM_RESOLUTIONS] = {
|
||||
10,
|
||||
MAX_TEXT_LINES
|
||||
};
|
||||
#define MAX_TEXT_LINE_LEN 256
|
||||
|
||||
static int Text_size;
|
||||
static int Text_offset = 0;
|
||||
static int Text_line_size[MAX_TEXT_LINES];
|
||||
static char *Text_lines[MAX_TEXT_LINES];
|
||||
|
||||
|
||||
int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
|
||||
{
|
||||
int cd_present = 0;
|
||||
int cd_drive_num;
|
||||
int cd_mve_is_on;
|
||||
char volume_name[128];
|
||||
|
||||
#ifdef RELEASE_REAL
|
||||
int num_attempts = 0;
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
int path_set_ok;
|
||||
|
||||
cd_mve_is_on = cutscenes_get_cd_num(mve_name);
|
||||
if ((cd_mve_is_on != 0) && (cd_mve_is_on != 1) && (cd_mve_is_on != 2)) {
|
||||
cd_present = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(OEM_BUILD)
|
||||
sprintf(volume_name, NOX("FS2_OEM"));
|
||||
#else
|
||||
sprintf(volume_name, NOX("FREESPACE2_%c"), '1' + cd_mve_is_on);
|
||||
#endif
|
||||
|
||||
|
||||
cd_drive_num = find_freespace_cd(volume_name);
|
||||
path_set_ok = set_cdrom_path(cd_drive_num);
|
||||
|
||||
if ( path_set_ok ) {
|
||||
cd_present = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef RELEASE_REAL
|
||||
if ( !prompt_for_cd ) {
|
||||
cd_present = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// no CD found, so prompt user
|
||||
char popup_msg[256];
|
||||
int popup_rval;
|
||||
|
||||
#if defined(DVD_MESSAGE_HACK)
|
||||
sprintf(popup_msg, XSTR( "Movie not found\n\nInsert FreeSpace DVD to continue", 203));
|
||||
#else
|
||||
sprintf(popup_msg, XSTR( "Movie not found\n\nInsert FreeSpace CD #%d to continue", 203), cd_mve_is_on+1);
|
||||
#endif
|
||||
|
||||
popup_rval = popup(PF_BODY_BIG, 2, POPUP_CANCEL, POPUP_OK, popup_msg);
|
||||
if ( popup_rval != 1 ) {
|
||||
cd_present = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( num_attempts++ > 5 ) {
|
||||
cd_present = 0;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
cd_present = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return cd_present;
|
||||
}
|
||||
|
||||
void cutscenes_screen_play()
|
||||
{
|
||||
char name[MAX_FILENAME_LEN]; // *full_name
|
||||
int which_cutscene;
|
||||
|
||||
Assert( (Selected_line >= 0) && (Selected_line < (int)Cutscene_list.size()) );
|
||||
which_cutscene = Cutscene_list[Selected_line];
|
||||
|
||||
strcpy_s(name, Cutscenes[which_cutscene].filename );
|
||||
// full_name = cf_add_ext(name, NOX(".mve"));
|
||||
|
||||
main_hall_stop_music();
|
||||
main_hall_stop_ambient();
|
||||
int rval = movie_play(name);
|
||||
main_hall_start_music();
|
||||
|
||||
if ( !rval ) {
|
||||
char str[256];
|
||||
|
||||
if (Cmdline_nomovies)
|
||||
sprintf(str, XSTR("Movies are currently disabled.", -1));
|
||||
else
|
||||
sprintf(str, XSTR("Unable to play movie %s.", 204), Cutscenes[which_cutscene].name);
|
||||
|
||||
popup(0, 1, POPUP_OK, str );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cutscenes_screen_scroll_line_up()
|
||||
{
|
||||
if (Selected_line) {
|
||||
Selected_line--;
|
||||
gamesnd_play_iface(SND_SCROLL);
|
||||
|
||||
} else
|
||||
gamesnd_play_iface(SND_GENERAL_FAIL);
|
||||
|
||||
if (Selected_line < Scroll_offset)
|
||||
Scroll_offset = Selected_line;
|
||||
}
|
||||
|
||||
void cutscenes_screen_scroll_line_down()
|
||||
{
|
||||
int h;
|
||||
|
||||
if (Selected_line < (int)Cutscene_list.size() - 1) {
|
||||
Selected_line++;
|
||||
gamesnd_play_iface(SND_SCROLL);
|
||||
|
||||
} else
|
||||
gamesnd_play_iface(SND_GENERAL_FAIL);
|
||||
|
||||
h = Cutscene_list_coords[gr_screen.res][3] / gr_get_font_height();
|
||||
if (Selected_line >= Scroll_offset + h){
|
||||
Scroll_offset++;
|
||||
}
|
||||
}
|
||||
|
||||
void cutscenes_screen_scroll_screen_up()
|
||||
{
|
||||
int h;
|
||||
|
||||
if (Scroll_offset) {
|
||||
Scroll_offset--;
|
||||
Assert(Selected_line > Scroll_offset);
|
||||
h = Cutscene_list_coords[gr_screen.res][3] / gr_get_font_height();
|
||||
while (Selected_line >= Scroll_offset + h){
|
||||
Selected_line--;
|
||||
}
|
||||
|
||||
gamesnd_play_iface(SND_SCROLL);
|
||||
|
||||
} else {
|
||||
gamesnd_play_iface(SND_GENERAL_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
void cutscenes_screen_scroll_screen_down()
|
||||
{
|
||||
int h;
|
||||
|
||||
h = Cutscene_list_coords[gr_screen.res][3] / gr_get_font_height();
|
||||
if (Scroll_offset + h < (int)Cutscene_list.size()) {
|
||||
Scroll_offset++;
|
||||
if (Selected_line < Scroll_offset){
|
||||
Selected_line = Scroll_offset;
|
||||
}
|
||||
|
||||
gamesnd_play_iface(SND_SCROLL);
|
||||
} else {
|
||||
gamesnd_play_iface(SND_GENERAL_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
int cutscenes_screen_button_pressed(int n)
|
||||
{
|
||||
switch (n) {
|
||||
case TECH_DATABASE_BUTTON:
|
||||
gamesnd_play_iface(SND_SWITCH_SCREENS);
|
||||
gameseq_post_event(GS_EVENT_TECH_MENU);
|
||||
return 1;
|
||||
|
||||
case SIMULATOR_BUTTON:
|
||||
gamesnd_play_iface(SND_SWITCH_SCREENS);
|
||||
gameseq_post_event(GS_EVENT_SIMULATOR_ROOM);
|
||||
return 1;
|
||||
|
||||
case CREDITS_BUTTON:
|
||||
gamesnd_play_iface(SND_SWITCH_SCREENS);
|
||||
gameseq_post_event(GS_EVENT_CREDITS);
|
||||
return 1;
|
||||
|
||||
case SCROLL_UP_BUTTON:
|
||||
cutscenes_screen_scroll_screen_up();
|
||||
break;
|
||||
|
||||
case SCROLL_DOWN_BUTTON:
|
||||
cutscenes_screen_scroll_screen_down();
|
||||
break;
|
||||
|
||||
case PLAY_BUTTON:
|
||||
cutscenes_screen_play();
|
||||
break;
|
||||
|
||||
case EXIT_BUTTON:
|
||||
gamesnd_play_iface(SND_COMMIT_PRESSED);
|
||||
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
||||
game_flush();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cutscenes_screen_init()
|
||||
{
|
||||
int i;
|
||||
ui_button_info *b;
|
||||
|
||||
Ui_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0);
|
||||
Ui_window.set_mask_bmap(Cutscene_mask_name[gr_screen.res]);
|
||||
|
||||
for (i=0; i<NUM_BUTTONS; i++) {
|
||||
b = &Buttons[gr_screen.res][i];
|
||||
|
||||
b->button.create(&Ui_window, "", b->x, b->y, 60, 30, (i < 2), 1);
|
||||
// set up callback for when a mouse first goes over a button
|
||||
b->button.set_highlight_action(common_play_highlight_sound);
|
||||
b->button.set_bmaps(b->filename);
|
||||
b->button.link_hotspot(b->hotspot);
|
||||
}
|
||||
|
||||
// add xstrs
|
||||
for(i=0; i<NUM_CUTSCENE_TEXT; i++){
|
||||
Ui_window.add_XSTR(&Cutscene_text[gr_screen.res][i]);
|
||||
}
|
||||
|
||||
Buttons[gr_screen.res][EXIT_BUTTON].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
|
||||
Buttons[gr_screen.res][SCROLL_UP_BUTTON].button.set_hotkey(KEY_PAGEUP);
|
||||
Buttons[gr_screen.res][SCROLL_DOWN_BUTTON].button.set_hotkey(KEY_PAGEDOWN);
|
||||
|
||||
List_region.create(&Ui_window, "", Cutscene_list_coords[gr_screen.res][0], Cutscene_list_coords[gr_screen.res][1], Cutscene_list_coords[gr_screen.res][2], Cutscene_list_coords[gr_screen.res][3], 0, 1);
|
||||
List_region.hide();
|
||||
|
||||
// set up hotkeys for buttons so we draw the correct animation frame when a key is pressed
|
||||
Buttons[gr_screen.res][SCROLL_UP_BUTTON].button.set_hotkey(KEY_PAGEUP);
|
||||
Buttons[gr_screen.res][SCROLL_DOWN_BUTTON].button.set_hotkey(KEY_PAGEDOWN);
|
||||
|
||||
Background_bitmap = bm_load(Cutscene_bitmap_name[gr_screen.res]);
|
||||
Scroll_offset = Selected_line = 0;
|
||||
Description_index = -1;
|
||||
|
||||
// when doing a debug version, just put all of the movie files here.
|
||||
#ifndef NDEBUG
|
||||
//Cutscenes_viewable = 0xffffffff; // makes all cutscenes viewble.
|
||||
#endif
|
||||
|
||||
// if (All_movies_enabled)
|
||||
// Cutscenes_viewable = 0xffffffff; // Cheat code enables all movies.
|
||||
|
||||
Cutscene_list.clear();
|
||||
for (size_t j = 0; j < Cutscenes.size(); j++ ) {
|
||||
if ( Cutscenes_viewable & (1<<j) ) {
|
||||
Cutscene_list.push_back((int)j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cutscenes_screen_close()
|
||||
{
|
||||
if (Background_bitmap)
|
||||
bm_release(Background_bitmap);
|
||||
|
||||
Ui_window.destroy();
|
||||
}
|
||||
|
||||
void cutscenes_screen_do_frame()
|
||||
{
|
||||
int i, k, y, z;
|
||||
int font_height = gr_get_font_height();
|
||||
int select_tease_line = -1;
|
||||
|
||||
k = Ui_window.process();
|
||||
switch (k) {
|
||||
case KEY_DOWN: // select next line
|
||||
cutscenes_screen_scroll_line_down();
|
||||
break;
|
||||
|
||||
case KEY_UP: // select previous line
|
||||
cutscenes_screen_scroll_line_up();
|
||||
break;
|
||||
|
||||
case KEY_TAB:
|
||||
case KEY_CTRLED | KEY_DOWN:
|
||||
cutscenes_screen_button_pressed(CREDITS_BUTTON);
|
||||
break;
|
||||
|
||||
case KEY_SHIFTED | KEY_TAB:
|
||||
case KEY_CTRLED | KEY_UP:
|
||||
cutscenes_screen_button_pressed(SIMULATOR_BUTTON);
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
cutscenes_screen_play();
|
||||
break;
|
||||
|
||||
case KEY_ESC: // cancel
|
||||
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
||||
game_flush();
|
||||
break;
|
||||
|
||||
case KEY_F1: // show help overlay
|
||||
break;
|
||||
|
||||
case KEY_F2: // goto options screen
|
||||
gameseq_post_event(GS_EVENT_OPTIONS_MENU);
|
||||
break;
|
||||
|
||||
// the "show-all" hotkey
|
||||
case KEY_CTRLED | KEY_SHIFTED | KEY_S:
|
||||
{
|
||||
Cutscene_list.clear();
|
||||
for (size_t t = 0; t < Cutscenes.size(); t++) {
|
||||
Cutscene_list.push_back((int)t);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
for (i=0; i<NUM_BUTTONS; i++){
|
||||
if (Buttons[gr_screen.res][i].button.pressed()){
|
||||
if (cutscenes_screen_button_pressed(i)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (List_region.button_down()) {
|
||||
List_region.get_mouse_pos(NULL, &y);
|
||||
z = Scroll_offset + y / font_height;
|
||||
if ((z >= 0) && (z < (int)Cutscene_list.size()))
|
||||
select_tease_line = z;
|
||||
}
|
||||
|
||||
if (List_region.pressed()) {
|
||||
List_region.get_mouse_pos(NULL, &y);
|
||||
z = Scroll_offset + y / font_height;
|
||||
if ((z >= 0) && (z < (int)Cutscene_list.size()))
|
||||
Selected_line = z;
|
||||
}
|
||||
|
||||
GR_MAYBE_CLEAR_RES(Background_bitmap);
|
||||
if (Background_bitmap >= 0) {
|
||||
gr_set_bitmap(Background_bitmap);
|
||||
gr_bitmap(0, 0);
|
||||
}
|
||||
|
||||
Ui_window.draw();
|
||||
|
||||
for (i=TECH_DATABASE_BUTTON; i<=CREDITS_BUTTON; i++){
|
||||
if (Buttons[gr_screen.res][i].button.button_down()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > CREDITS_BUTTON){
|
||||
Buttons[gr_screen.res][CUTSCENES_BUTTON].button.draw_forced(2);
|
||||
}
|
||||
|
||||
y = 0;
|
||||
z = Scroll_offset;
|
||||
while (y + font_height <= Cutscene_list_coords[gr_screen.res][3]) {
|
||||
if (z >= (int)Cutscene_list.size()){
|
||||
break;
|
||||
}
|
||||
|
||||
if (z == Selected_line){
|
||||
gr_set_color_fast(&Color_text_selected);
|
||||
} else if (z == select_tease_line) {
|
||||
gr_set_color_fast(&Color_text_subselected);
|
||||
} else {
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
}
|
||||
|
||||
gr_printf(Cutscene_list_coords[gr_screen.res][0], Cutscene_list_coords[gr_screen.res][1] + y, Cutscenes[Cutscene_list[z]].name);
|
||||
|
||||
y += font_height;
|
||||
z++;
|
||||
}
|
||||
|
||||
if (Description_index != Selected_line) {
|
||||
char *src = NULL;
|
||||
|
||||
Description_index = Selected_line;
|
||||
Text_size = 0;
|
||||
if ( Description_index < (int)Cutscene_list.size( ) &&
|
||||
(int)Cutscene_list[ Description_index ] < (int)Cutscenes.size( ) ) {
|
||||
src = Cutscenes[Cutscene_list[Description_index]].description;
|
||||
if (src) {
|
||||
Text_size = split_str(src, Cutscene_desc_coords[gr_screen.res][2], Text_line_size, Text_lines, Cutscene_max_text_lines[gr_screen.res]);
|
||||
Assert(Text_size >= 0 && Text_size < Cutscene_max_text_lines[gr_screen.res]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Description_index >= 0) {
|
||||
int len;
|
||||
char line[MAX_TEXT_LINE_LEN + 1];
|
||||
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
|
||||
y = 0;
|
||||
z = Text_offset;
|
||||
while (y + font_height <= Cutscene_desc_coords[gr_screen.res][3]) {
|
||||
if (z >= Text_size)
|
||||
break;
|
||||
|
||||
len = Text_line_size[z];
|
||||
if (len > MAX_TEXT_LINE_LEN)
|
||||
len = MAX_TEXT_LINE_LEN;
|
||||
|
||||
strncpy(line, Text_lines[z], len);
|
||||
line[len] = 0;
|
||||
gr_string(Cutscene_desc_coords[gr_screen.res][0], Cutscene_desc_coords[gr_screen.res][1] + y, line);
|
||||
|
||||
y += font_height;
|
||||
z++;
|
||||
}
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _FREESPACE_CUTSCENES_SCREEN_HEADER_FILE
|
||||
#define _FREESPACE_CUTSCENES_SCREEN_HEADER_FILE
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
// this cutscene is always available.
|
||||
#define INTRO_CUTSCENE_FLAG (1<<0)
|
||||
|
||||
typedef struct cutscene_info
|
||||
{
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
char name[NAME_LENGTH];
|
||||
char *description;
|
||||
int cd;
|
||||
} cutscene_info;
|
||||
|
||||
extern SCP_vector<cutscene_info> Cutscenes;
|
||||
extern int Cutscenes_viewable;
|
||||
|
||||
// initializa table data
|
||||
void cutscene_init();
|
||||
int cutscene_get_cd_num(char *filename);
|
||||
|
||||
|
||||
void cutscenes_screen_init();
|
||||
void cutscenes_screen_close();
|
||||
void cutscenes_screen_do_frame();
|
||||
|
||||
int cutscenes_validate_cd(char *mve_name, int prompt_for_cd = 1);
|
||||
void cutscene_mark_viewable(char *filename);
|
||||
|
||||
#endif
|
||||
@@ -1,654 +0,0 @@
|
||||
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
extern int g_width, g_height;
|
||||
extern void *g_vBackBuf1, *g_vBackBuf2;
|
||||
|
||||
/* 16 bit decoding routines */
|
||||
|
||||
static ushort *backBuf1, *backBuf2;
|
||||
static int lookup_initialized;
|
||||
|
||||
static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb);
|
||||
static void genLoopkupTable();
|
||||
|
||||
void decodeFrame16(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
|
||||
{
|
||||
unsigned char *pOrig;
|
||||
unsigned char *pOffData, *pEnd;
|
||||
ushort offset;
|
||||
int length;
|
||||
int op;
|
||||
int i, j;
|
||||
int xb, yb;
|
||||
|
||||
if (!lookup_initialized) {
|
||||
genLoopkupTable();
|
||||
}
|
||||
|
||||
backBuf1 = (ushort *)g_vBackBuf1;
|
||||
backBuf2 = (ushort *)g_vBackBuf2;
|
||||
|
||||
xb = g_width >> 3;
|
||||
yb = g_height >> 3;
|
||||
|
||||
offset = pData[0]|(pData[1]<<8);
|
||||
|
||||
pOffData = pData + offset;
|
||||
pEnd = pData + offset;
|
||||
|
||||
pData += 2;
|
||||
|
||||
pOrig = pData;
|
||||
length = offset - 2; /*dataRemain-2;*/
|
||||
|
||||
for (j=0; j<yb; j++) {
|
||||
for (i=0; i<xb/2; i++) {
|
||||
op = (*pMap) & 0xf;
|
||||
dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
|
||||
|
||||
op = ((*pMap) >> 4) & 0xf;
|
||||
dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
|
||||
|
||||
pMap++;
|
||||
mapRemain--;
|
||||
}
|
||||
|
||||
pFrame += 7*g_width*2;
|
||||
}
|
||||
|
||||
if ((length-(pData-pOrig)) != 0) {
|
||||
nprintf(("MVE", "DEBUG: junk left over: %d,%d,%d\n", (pData-pOrig), length, (length-(pData-pOrig))));
|
||||
}
|
||||
}
|
||||
|
||||
static ushort GETPIXEL(unsigned char **buf, int off)
|
||||
{
|
||||
ushort val = (*buf)[0+off] | ((*buf)[1+off] << 8);
|
||||
return val;
|
||||
}
|
||||
|
||||
static ushort GETPIXELI(unsigned char **buf, int off)
|
||||
{
|
||||
ushort val = (*buf)[0+off] | ((*buf)[1+off] << 8);
|
||||
(*buf) += 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
static void relClose(int i, int *x, int *y)
|
||||
{
|
||||
int ma, mi;
|
||||
|
||||
ma = i >> 4;
|
||||
mi = i & 0xf;
|
||||
|
||||
*x = mi - 8;
|
||||
*y = ma - 8;
|
||||
}
|
||||
|
||||
static void relFar(int i, int sign, int *x, int *y)
|
||||
{
|
||||
if (i < 56) {
|
||||
*x = sign * (8 + (i % 7));
|
||||
*y = sign * (i / 7);
|
||||
} else {
|
||||
*x = sign * (-14 + (i - 56) % 29);
|
||||
*y = sign * (8 + (i - 56) / 29);
|
||||
}
|
||||
}
|
||||
|
||||
static int close_table[512];
|
||||
static int far_p_table[512];
|
||||
static int far_n_table[512];
|
||||
|
||||
static void genLoopkupTable()
|
||||
{
|
||||
int i;
|
||||
int x, y;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
relClose(i, &x, &y);
|
||||
|
||||
close_table[i*2+0] = x;
|
||||
close_table[i*2+1] = y;
|
||||
|
||||
relFar(i, 1, &x, &y);
|
||||
|
||||
far_p_table[i*2+0] = x;
|
||||
far_p_table[i*2+1] = y;
|
||||
|
||||
relFar(i, -1, &x, &y);
|
||||
|
||||
far_n_table[i*2+0] = x;
|
||||
far_n_table[i*2+1] = y;
|
||||
}
|
||||
|
||||
lookup_initialized = 1;
|
||||
}
|
||||
|
||||
static void copyFrame(ushort *pDest, ushort *pSrc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
memcpy(pDest, pSrc, 16);
|
||||
pDest += g_width;
|
||||
pSrc += g_width;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow4Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, ushort *p)
|
||||
{
|
||||
ushort mask=0x0003;
|
||||
ushort shift=0;
|
||||
ushort pattern = (pat1 << 8) | pat0;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pattern) >> shift];
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow4Pixels2(ushort *pFrame, unsigned char pat0, ushort *p)
|
||||
{
|
||||
unsigned char mask=0x03;
|
||||
unsigned char shift=0;
|
||||
ushort pel;
|
||||
/* ORIGINAL VERSION IS BUGGY
|
||||
int skip=1;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat0) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[2] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 2] = pel;
|
||||
pFrame += skip;
|
||||
skip = 4 - skip;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
*/
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat0) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow4Pixels2x1(ushort *pFrame, unsigned char pat, ushort *p)
|
||||
{
|
||||
unsigned char mask=0x03;
|
||||
unsigned char shift=0;
|
||||
ushort pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternQuadrant4Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, unsigned char pat2, unsigned char pat3, ushort *p)
|
||||
{
|
||||
unsigned long mask = 0x00000003UL;
|
||||
int shift=0;
|
||||
int i;
|
||||
unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) >> shift];
|
||||
|
||||
if ((i&3) == 3)
|
||||
pFrame += g_width;
|
||||
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow2Pixels(ushort *pFrame, unsigned char pat, ushort *p)
|
||||
{
|
||||
unsigned char mask=0x01;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pat) ? 1 : 0];
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow2Pixels2(ushort *pFrame, unsigned char pat, ushort *p)
|
||||
{
|
||||
ushort pel;
|
||||
unsigned char mask=0x1;
|
||||
|
||||
/* ORIGINAL VERSION IS BUGGY
|
||||
int skip=1;
|
||||
while (mask != 0x10) {
|
||||
pel = p[(mask & pat) ? 1 : 0];
|
||||
pFrame[0] = pel;
|
||||
pFrame[2] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 2] = pel;
|
||||
pFrame += skip;
|
||||
skip = 4 - skip;
|
||||
mask <<= 1;
|
||||
}
|
||||
*/
|
||||
while (mask != 0x10) {
|
||||
pel = p[(mask & pat) ? 1 : 0];
|
||||
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 1] = pel;
|
||||
pFrame += 2;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternQuadrant2Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, ushort *p)
|
||||
{
|
||||
ushort mask = 0x0001;
|
||||
int i;
|
||||
ushort pat = (pat1 << 8) | pat0;
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) ? 1 : 0];
|
||||
|
||||
if ((i&3) == 3)
|
||||
pFrame += g_width;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb)
|
||||
{
|
||||
ushort p[4];
|
||||
unsigned char pat[16];
|
||||
int i, j, k;
|
||||
int x, y;
|
||||
ushort *pDstBak;
|
||||
|
||||
pDstBak = *pFrame;
|
||||
|
||||
switch(codeType) {
|
||||
case 0x0:
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1));
|
||||
break; // ADDED
|
||||
|
||||
case 0x1:
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
/* relFar(*(*pOffData)++, 1, &x, &y); */
|
||||
|
||||
k = *(*pOffData)++;
|
||||
x = far_p_table[k*2+0];
|
||||
y = far_p_table[k*2+1];
|
||||
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
/* relFar(*(*pOffData)++, -1, &x, &y); */
|
||||
|
||||
k = *(*pOffData)++;
|
||||
x = far_n_table[k*2+0];
|
||||
y = far_n_table[k*2+1];
|
||||
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
/* relClose(*(*pOffData)++, &x, &y); */
|
||||
|
||||
k = *(*pOffData)++;
|
||||
x = close_table[k*2+0];
|
||||
y = close_table[k*2+1];
|
||||
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
x = (char)*(*pData)++;
|
||||
y = (char)*(*pData)++;
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
|
||||
*pDataRemain -= 2;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
nprintf(("MVE", "STUB: encoding 6 not tested\n"));
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
*pFrame += 16;
|
||||
|
||||
if (++*curXb == (g_width >> 3)) {
|
||||
*pFrame += 7*g_width;
|
||||
*curXb = 0;
|
||||
|
||||
if (++*curYb == (g_height >> 3))
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
|
||||
if (!((p[0]/*|p[1]*/)&0x8000)) {
|
||||
for (i=0; i<8; i++) {
|
||||
patternRow2Pixels(*pFrame, *(*pData), p);
|
||||
(*pData)++;
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<2; i++) {
|
||||
patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow2Pixels2(*pFrame, *(*pData) >> 4, p);
|
||||
(*pData)++;
|
||||
|
||||
*pFrame += 2*g_width;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
(*pData) += 2;
|
||||
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p[2] = GETPIXEL(pData, 8);
|
||||
|
||||
if (!(p[2]&0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
if ((i & 1) == 0) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
}
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<8; i++) {
|
||||
if ((i & 3) == 0) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
}
|
||||
patternRow2Pixels(*pFrame, *(*pData), p);
|
||||
(*pData)++;
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
|
||||
*pDataRemain -= 8;
|
||||
|
||||
if (!(p[0] & 0x8000)) {
|
||||
if (!(p[2] & 0x8000)) {
|
||||
for (i=0; i<8; i++) {
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
(*pData) += 2;
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pDataRemain -= 16;
|
||||
} else {
|
||||
patternRow4Pixels2(*pFrame, (*pData)[0], p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow4Pixels2(*pFrame, (*pData)[1], p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow4Pixels2(*pFrame, (*pData)[2], p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow4Pixels2(*pFrame, (*pData)[3], p);
|
||||
|
||||
(*pData) += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
} else {
|
||||
if (!(p[2] & 0x8000)) {
|
||||
for (i=0; i<8; i++) {
|
||||
pat[0] = (*pData)[0];
|
||||
(*pData) += 1;
|
||||
patternRow4Pixels2x1(*pFrame, pat[0], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pDataRemain -= 8;
|
||||
} else {
|
||||
for (i=0; i<4; i++) {
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
|
||||
(*pData) += 2;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
pat[2] = (*pData)[2];
|
||||
pat[3] = (*pData)[3];
|
||||
|
||||
(*pData) += 4;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p[0] = GETPIXEL(pData, 16);
|
||||
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
if ((i&1) == 0) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
}
|
||||
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
pat[2] = (*pData)[2];
|
||||
pat[3] = (*pData)[3];
|
||||
|
||||
(*pData) += 4;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<8; i++) {
|
||||
if ((i&3) == 0) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
}
|
||||
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
|
||||
(*pData) += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
for (i=0; i<8; i++) {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
ubyte frame_tmp[16];
|
||||
memcpy(&frame_tmp, *pData, 16);
|
||||
|
||||
ushort *swap_tmp;
|
||||
for (j = 0; j < 16; j += 2) {
|
||||
swap_tmp = (ushort*)(frame_tmp + j);
|
||||
*swap_tmp = INTEL_SHORT(*swap_tmp);
|
||||
}
|
||||
memcpy(*pFrame, &frame_tmp, 16);
|
||||
#else
|
||||
memcpy(*pFrame, *pData, 16);
|
||||
#endif
|
||||
*pFrame += g_width;
|
||||
*pData += 16;
|
||||
*pDataRemain -= 16;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc:
|
||||
for (i=0; i<4; i++) {
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
p[1] = GETPIXEL(pData, 2);
|
||||
p[2] = GETPIXEL(pData, 4);
|
||||
p[3] = GETPIXEL(pData, 6);
|
||||
|
||||
for (j=0; j<2; j++) {
|
||||
for (k=0; k<4; k++) {
|
||||
(*pFrame)[2*k] = p[k];
|
||||
(*pFrame)[2*k+1] = p[k];
|
||||
// (*pFrame)[j+2*k] = p[k];
|
||||
// (*pFrame)[g_width+j+2*k] = p[k];
|
||||
}
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 8;
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xd:
|
||||
for (i=0; i<2; i++) {
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
p[1] = GETPIXEL(pData, 2);
|
||||
|
||||
for (j=0; j<4; j++) {
|
||||
for (k=0; k<4; k++) {
|
||||
(*pFrame)[k*g_width+j] = p[0];
|
||||
(*pFrame)[k*g_width+j+4] = p[1];
|
||||
}
|
||||
}
|
||||
|
||||
*pFrame += 4*g_width;
|
||||
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
(*pFrame)[j] = p[0];
|
||||
}
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
|
||||
break;
|
||||
|
||||
case 0xf:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
p[1] = GETPIXEL(pData, 1);
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
(*pFrame)[j] = p[(i+j)&1];
|
||||
}
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*pFrame = pDstBak+8;
|
||||
}
|
||||
@@ -1,533 +0,0 @@
|
||||
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
|
||||
extern int g_width, g_height;
|
||||
extern void *g_vBackBuf1, *g_vBackBuf2;
|
||||
|
||||
static void dispatchDecoder8(ubyte **pFrame, ubyte codeType, ubyte **pData, int *pDataRemain, int *curXb, int *curYb);
|
||||
|
||||
void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
|
||||
{
|
||||
int i, j;
|
||||
int xb, yb;
|
||||
|
||||
xb = g_width >> 3;
|
||||
yb = g_height >> 3;
|
||||
|
||||
for (j = 0; j < yb; j++) {
|
||||
for (i = 0; i < (xb / 2); i++) {
|
||||
dispatchDecoder8(&pFrame, (*pMap) & 0xf, &pData, &dataRemain, &i, &j);
|
||||
|
||||
dispatchDecoder8(&pFrame, (*pMap) >> 4, &pData, &dataRemain, &i, &j);
|
||||
|
||||
pMap++;
|
||||
mapRemain--;
|
||||
}
|
||||
|
||||
pFrame += 7*g_width;
|
||||
}
|
||||
}
|
||||
|
||||
static void relClose(int i, int *x, int *y)
|
||||
{
|
||||
int ma, mi;
|
||||
|
||||
ma = i >> 4;
|
||||
mi = i & 0xf;
|
||||
|
||||
*x = mi - 8;
|
||||
*y = ma - 8;
|
||||
}
|
||||
|
||||
static void relFar(int i, int sign, int *x, int *y)
|
||||
{
|
||||
if (i < 56) {
|
||||
*x = sign * (8 + (i % 7));
|
||||
*y = sign * (i / 7);
|
||||
} else {
|
||||
*x = sign * (-14 + (i - 56) % 29);
|
||||
*y = sign * (8 + (i - 56) / 29);
|
||||
}
|
||||
}
|
||||
|
||||
/* copies an 8x8 block from pSrc to pDest.
|
||||
pDest and pSrc are both g_width bytes wide */
|
||||
static void copyFrame(ubyte *pDest, ubyte *pSrc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
memcpy(pDest, pSrc, 8);
|
||||
pDest += g_width;
|
||||
pSrc += g_width;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next eight bytes with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0 and pat1
|
||||
static void patternRow4Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte *p)
|
||||
{
|
||||
ushort mask = 0x0003;
|
||||
ushort shift = 0;
|
||||
ushort pattern = (pat1 << 8) | pat0;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pattern) >> shift];
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next four 2x2 pixel blocks with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0.
|
||||
static void patternRow4Pixels2(ubyte *pFrame, ubyte pat0, ubyte *p)
|
||||
{
|
||||
ubyte mask = 0x03;
|
||||
ubyte shift = 0;
|
||||
ubyte pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat0) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next four 2x1 pixel blocks with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat.
|
||||
static void patternRow4Pixels2x1(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte mask = 0x03;
|
||||
ubyte shift = 0;
|
||||
ubyte pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next 4x4 pixel block with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0, pat1, pat2, and pat3.
|
||||
static void patternQuadrant4Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte pat2, ubyte pat3, ubyte *p)
|
||||
{
|
||||
unsigned long mask = 0x00000003UL;
|
||||
int shift=0;
|
||||
int i;
|
||||
unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) >> shift];
|
||||
|
||||
if ( (i & 3) == 3 )
|
||||
pFrame += g_width;
|
||||
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// fills the next 8 pixels with either p[0] or p[1], depending on pattern
|
||||
static void patternRow2Pixels(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte mask=0x01;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pat) ? 1 : 0];
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// fills the next four 2 x 2 pixel boxes with either p[0] or p[1], depending on pattern
|
||||
static void patternRow2Pixels2(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte pel;
|
||||
ubyte mask=0x1;
|
||||
|
||||
while (mask != 0x10) {
|
||||
pel = p[(mask & pat) ? 1 : 0];
|
||||
|
||||
pFrame[0] = pel; // upper-left
|
||||
pFrame[1] = pel; // upper-right
|
||||
pFrame[g_width + 0] = pel; // lower-left
|
||||
pFrame[g_width + 1] = pel; // lower-right
|
||||
pFrame += 2;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// fills pixels in the next 4 x 4 pixel boxes with either p[0] or p[1], depending on pat0 and pat1.
|
||||
static void patternQuadrant2Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte *p)
|
||||
{
|
||||
ubyte pel;
|
||||
ushort mask = 0x0001;
|
||||
int i, j;
|
||||
ushort pat = (pat1 << 8) | pat0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
pel = p[(pat & mask) ? 1 : 0];
|
||||
|
||||
pFrame[j + i * g_width] = pel;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dispatchDecoder8(ubyte **pFrame, ubyte codeType, ubyte **pData, int *pDataRemain, int *curXb, int *curYb)
|
||||
{
|
||||
ubyte p[4];
|
||||
ubyte pat[16];
|
||||
int i, j, k;
|
||||
int x, y;
|
||||
|
||||
switch(codeType) {
|
||||
case 0x0:
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1));
|
||||
*pFrame += 8;
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
*pFrame += 8;
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
relFar(*(*pData)++, 1, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
relFar(*(*pData)++, -1, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
relClose(*(*pData)++, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1) + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
x = (signed char)*(*pData)++;
|
||||
y = (signed char)*(*pData)++;
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1) + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
*pDataRemain -= 2;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
for (i = 0; i < 2; i++) {
|
||||
*pFrame += 16;
|
||||
|
||||
if (++*curXb == (g_width >> 3)) {
|
||||
*pFrame += 7*g_width;
|
||||
*curXb = 0;
|
||||
|
||||
if (++*curYb == (g_height >> 3))
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
|
||||
if (p[0] <= p[1]) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
patternRow2Pixels(*pFrame, *(*pData)++, p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 2; i++) {
|
||||
patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow2Pixels2(*pFrame, *(*pData)++ >> 4, p);
|
||||
*pFrame += 2*g_width;
|
||||
}
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
// four quadrant case
|
||||
for (i = 0; i < 4; i++) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
// alternate between moving down and moving up and right
|
||||
if (i & 1)
|
||||
*pFrame += 4 - 4*g_width; // up and right
|
||||
else
|
||||
*pFrame += 4*g_width; // down
|
||||
}
|
||||
} else if ( (*pData)[6] <= (*pData)[7] ) {
|
||||
// split horizontal
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((i & 1) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
// split vertical
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((i & 3) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
}
|
||||
|
||||
patternRow2Pixels(*pFrame, *(*pData)++, p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
if ( (*pData)[2] <= (*pData)[3] ) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
} else {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame -= (6*g_width - 8);
|
||||
}
|
||||
} else {
|
||||
if ( (*pData)[2] <= (*pData)[3] ) {
|
||||
// draw 2x1 strips
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels2x1(*pFrame, pat[0], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
} else {
|
||||
// draw 1x2 strips
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
pat[2] = *(*pData)++;
|
||||
pat[3] = *(*pData)++;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
if ( (*pData)[12] <= (*pData)[13] ) {
|
||||
// split vertical
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((i&1) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
pat[2] = *(*pData)++;
|
||||
pat[3] = *(*pData)++;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
// split horizontal
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((i&3) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
for (i = 0; i < 8; i++) {
|
||||
memcpy(*pFrame, *pData, 8);
|
||||
*pFrame += g_width;
|
||||
*pData += 8;
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xc:
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
(*pFrame)[2*k] = (*pData)[k];
|
||||
(*pFrame)[2*k+1] = (*pData)[k];
|
||||
}
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xd:
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
(*pFrame)[k*g_width+j] = (*pData)[0];
|
||||
(*pFrame)[k*g_width+j+4] = (*pData)[1];
|
||||
}
|
||||
}
|
||||
|
||||
*pFrame += 4*g_width;
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xe:
|
||||
for (i = 0; i < 8; i++) {
|
||||
memset(*pFrame, **pData, 8);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
(*pData)++;
|
||||
(*pDataRemain)--;
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xf:
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
(*pFrame)[j] = (*pData)[(i+j)&1];
|
||||
}
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "graphics/2d.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "cutscene/movie.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "cutscene/cutscenes.h" // cutscene_mark_viewable()
|
||||
#include "cutscene/mvelib.h"
|
||||
#include "cutscene/oggplayer.h"
|
||||
|
||||
extern int Game_mode;
|
||||
|
||||
|
||||
#define MOVIE_NONE -1
|
||||
#define MOVIE_OGG 0
|
||||
#define MOVIE_MVE 1
|
||||
|
||||
// This module links freespace movie calls to the actual API calls the play the movie.
|
||||
// This module handles all the different requires of OS and gfx API and finding the file to play
|
||||
|
||||
|
||||
// filename - file to search for
|
||||
// out_name - output, full path to file
|
||||
// returns non-zero if file is found
|
||||
int movie_find(char *filename, char *out_name)
|
||||
{
|
||||
char full_path[MAX_PATH];
|
||||
char tmp_name[MAX_PATH];
|
||||
int size, offset = 0;
|
||||
const int NUM_EXT = 2;
|
||||
const char *movie_ext[NUM_EXT] = { ".ogg", ".mve" };
|
||||
|
||||
if (out_name == NULL)
|
||||
return MOVIE_NONE;
|
||||
|
||||
|
||||
memset( full_path, 0, sizeof(full_path) );
|
||||
memset( tmp_name, 0, sizeof(tmp_name) );
|
||||
|
||||
// remove extension
|
||||
strcpy_s( tmp_name, filename );
|
||||
char *p = strrchr(tmp_name, '.');
|
||||
if ( p ) *p = 0;
|
||||
|
||||
int rc = cf_find_file_location_ext(tmp_name, NUM_EXT, movie_ext, CF_TYPE_ANY, sizeof(full_path) - 1, full_path, &size, &offset, 0);
|
||||
|
||||
if (rc == MOVIE_NONE)
|
||||
return MOVIE_NONE;
|
||||
|
||||
strcpy( out_name, full_path );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Play one movie
|
||||
bool movie_play(char *name)
|
||||
{
|
||||
// mark the movie as viewable to the player when in a campaign
|
||||
// do this before anything else so that we're sure the movie is available
|
||||
// to the player even if it's not going to play right now
|
||||
if (Game_mode & GM_CAMPAIGN_MODE) {
|
||||
cutscene_mark_viewable(name);
|
||||
}
|
||||
|
||||
extern int Mouse_hidden;
|
||||
extern int Is_standalone;
|
||||
|
||||
if (Cmdline_nomovies || Is_standalone)
|
||||
return false;
|
||||
|
||||
|
||||
char full_name[MAX_PATH];
|
||||
int rc = 0;
|
||||
|
||||
memset(full_name, 0, sizeof(full_name));
|
||||
|
||||
rc = movie_find(name, full_name);
|
||||
|
||||
if (rc == MOVIE_NONE) {
|
||||
strcpy_s(full_name, name);
|
||||
char *p = strrchr(full_name, '.');
|
||||
if ( p ) *p = 0;
|
||||
|
||||
mprintf(("Movie Error: Unable to open '%s' movie in any supported format.\n", full_name));
|
||||
return false;
|
||||
}
|
||||
|
||||
// clear the screen and hide the mouse cursor
|
||||
Mouse_hidden++;
|
||||
gr_reset_clip();
|
||||
gr_set_color(255, 255, 255);
|
||||
gr_set_clear_color(0, 0, 0);
|
||||
gr_zbuffer_clear(0);
|
||||
// clear first buffer
|
||||
gr_clear();
|
||||
gr_flip();
|
||||
// clear second buffer (may not be one, but that's ok)
|
||||
gr_clear();
|
||||
gr_flip();
|
||||
// clear third buffer (may not be one, but that's ok)
|
||||
gr_clear();
|
||||
|
||||
if (rc == MOVIE_OGG) {
|
||||
THEORAFILE *movie_ogg = theora_open(name);
|
||||
|
||||
if (movie_ogg) {
|
||||
// start playing ...
|
||||
theora_play(movie_ogg);
|
||||
|
||||
// ... done playing, close the movie
|
||||
theora_close(movie_ogg);
|
||||
} else {
|
||||
// uh-oh, movie is invalid... Abory, Retry, Fail?
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
return false;
|
||||
}
|
||||
} else if (rc == MOVIE_MVE) {
|
||||
MVESTREAM *movie_mve = mve_open(name);
|
||||
|
||||
if (movie_mve) {
|
||||
// start playing ...
|
||||
mve_init(movie_mve);
|
||||
mve_play(movie_mve);
|
||||
|
||||
// ... done playing, close the movie
|
||||
mve_shutdown();
|
||||
mve_close(movie_mve);
|
||||
} else {
|
||||
// uh-oh, movie is invalid... Abory, Retry, Fail?
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// show the mouse cursor again
|
||||
Mouse_hidden--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void movie_play_two(char *name1, char *name2)
|
||||
{
|
||||
if ( movie_play(name1) )
|
||||
movie_play(name2);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _MOVIE_HEADER_FILE
|
||||
#define _MOVIE_HEADER_FILE
|
||||
|
||||
bool movie_play(char *name);
|
||||
void movie_play_two(char *name1, char *name2);
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
|
||||
static int audio_exp_table[256] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47, 51, 56, 61,
|
||||
66, 72, 79, 86, 94, 102, 112, 122, 133, 145, 158, 173, 189, 206, 225, 245,
|
||||
267, 292, 318, 348, 379, 414, 452, 493, 538, 587, 640, 699, 763, 832, 908, 991,
|
||||
1081, 1180, 1288, 1405, 1534, 1673, 1826, 1993, 2175, 2373, 2590, 2826, 3084, 3365, 3672, 4008,
|
||||
4373, 4772, 5208, 5683, 6202, 6767, 7385, 8059, 8794, 9597, 10472, 11428, 12471, 13609, 14851, 16206,
|
||||
17685, 19298, 21060, 22981, 25078, 27367, 29864, 32589, -29973, -26728, -23186, -19322, -15105, -10503, -5481, -1,
|
||||
1, 1, 5481, 10503, 15105, 19322, 23186, 26728, 29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
|
||||
-17685, -16206, -14851, -13609, -12471, -11428, -10472, -9597, -8794, -8059, -7385, -6767, -6202, -5683, -5208, -4772,
|
||||
-4373, -4008, -3672, -3365, -3084, -2826, -2590, -2373, -2175, -1993, -1826, -1673, -1534, -1405, -1288, -1180,
|
||||
-1081, -991, -908, -832, -763, -699, -640, -587, -538, -493, -452, -414, -379, -348, -318, -292,
|
||||
-267, -245, -225, -206, -189, -173, -158, -145, -133, -122, -112, -102, -94, -86, -79, -72,
|
||||
-66, -61, -56, -51, -47, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33,
|
||||
-32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17,
|
||||
-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1
|
||||
};
|
||||
|
||||
static int getWord(unsigned char **fin)
|
||||
{
|
||||
int value = ((*fin)[1] << 8) | (*fin)[0];
|
||||
*fin += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
static void sendWord(short **fout, int nOffset)
|
||||
{
|
||||
*(*fout)++ = nOffset;
|
||||
}
|
||||
|
||||
static void processSwath(short *fout, unsigned char *data, int swath, int *offsets)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<swath; i++)
|
||||
{
|
||||
offsets[i&1] += audio_exp_table[data[i]];
|
||||
sendWord(&fout, offsets[i&1]);
|
||||
}
|
||||
}
|
||||
|
||||
void mveaudio_uncompress(short *buffer, unsigned char *data, int length)
|
||||
{
|
||||
int nCurOffsets[2];
|
||||
int swath;
|
||||
|
||||
data += 4;
|
||||
swath = getWord(&data) / 2;
|
||||
nCurOffsets[0] = getWord(&data);
|
||||
nCurOffsets[1] = getWord(&data);
|
||||
sendWord(&buffer, nCurOffsets[0]);
|
||||
sendWord(&buffer, nCurOffsets[1]);
|
||||
processSwath(buffer, data, swath, nCurOffsets);
|
||||
}
|
||||
@@ -1,371 +0,0 @@
|
||||
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cutscene/mvelib.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
static const char MVE_HEADER[] = "Interplay MVE File\x1A";
|
||||
static const short MVE_HDRCONST1 = 0x001A;
|
||||
static const short MVE_HDRCONST2 = 0x0100;
|
||||
static const short MVE_HDRCONST3 = 0x1133;
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// public MVEFILE functions
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// utility functions for mvefile and mveplayer
|
||||
short mve_get_short(ubyte *data)
|
||||
{
|
||||
short value;
|
||||
value = data[0] | (data[1] << 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
ushort mve_get_ushort(ubyte *data)
|
||||
{
|
||||
ushort value;
|
||||
value = data[0] | (data[1] << 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
int mve_get_int(ubyte *data)
|
||||
{
|
||||
int value;
|
||||
value = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
|
||||
return value;
|
||||
}
|
||||
|
||||
// open an MVE file
|
||||
MVEFILE *mvefile_open(char *filename)
|
||||
{
|
||||
int cf_opened = 0;
|
||||
int mve_valid = 1;
|
||||
char lower_name[MAX_FILENAME_LEN];
|
||||
char buffer[20];
|
||||
MVEFILE *file;
|
||||
|
||||
// create the file
|
||||
file = (MVEFILE *)vm_malloc(sizeof(MVEFILE));
|
||||
|
||||
// set defaults
|
||||
file->stream = NULL;
|
||||
file->cur_chunk = NULL;
|
||||
file->buf_size = 0;
|
||||
file->cur_fill = 0;
|
||||
file->next_segment = 0;
|
||||
|
||||
// lower case filename for checking
|
||||
strncpy(lower_name, filename, strlen(filename)+1);
|
||||
strlwr(lower_name);
|
||||
|
||||
char *p = strchr( lower_name, '.' );
|
||||
if ( p ) *p = 0;
|
||||
|
||||
strcat_s( lower_name, ".mve" );
|
||||
|
||||
// NOTE: CF_TYPE *must* be ANY to get movies off of the CDs
|
||||
// assume lower case filename for *nix
|
||||
file->stream = cfopen(lower_name, "rb", CFILE_NORMAL, CF_TYPE_ANY);
|
||||
if ( file->stream ) {
|
||||
cf_opened = 1;
|
||||
}
|
||||
|
||||
if (!cf_opened) {
|
||||
mvefile_close(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// initialize the buffer
|
||||
file->cur_chunk = (ubyte *)vm_malloc(100 + 1024);
|
||||
file->buf_size = 100 + 1024;
|
||||
|
||||
// verify the file's header
|
||||
cfread_string(buffer, 20, file->stream);
|
||||
|
||||
if (strcmp(buffer, MVE_HEADER))
|
||||
mve_valid = 0;
|
||||
|
||||
if (cfread_short(file->stream) != MVE_HDRCONST1)
|
||||
mve_valid = 0;
|
||||
|
||||
if (cfread_short(file->stream) != MVE_HDRCONST2)
|
||||
mve_valid = 0;
|
||||
|
||||
if (cfread_short(file->stream) != MVE_HDRCONST3)
|
||||
mve_valid = 0;
|
||||
|
||||
if (!mve_valid) {
|
||||
mvefile_close(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// now, prefetch the next chunk
|
||||
mvefile_fetch_next_chunk(file);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
// close a MVE file
|
||||
void mvefile_close(MVEFILE *file)
|
||||
{
|
||||
// free the stream
|
||||
if (file->stream)
|
||||
cfclose(file->stream);
|
||||
|
||||
file->stream = NULL;
|
||||
|
||||
// free the buffer
|
||||
if (file->cur_chunk)
|
||||
vm_free(file->cur_chunk);
|
||||
|
||||
file->cur_chunk = NULL;
|
||||
|
||||
// not strictly necessary
|
||||
file->buf_size = 0;
|
||||
file->cur_fill = 0;
|
||||
file->next_segment = 0;
|
||||
|
||||
// free the struct
|
||||
vm_free(file);
|
||||
}
|
||||
|
||||
// get the size of the next segment
|
||||
int mvefile_get_next_segment_size(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return -1;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return -1;
|
||||
|
||||
// otherwise, get the data length
|
||||
return mve_get_short(file->cur_chunk + file->next_segment);
|
||||
}
|
||||
|
||||
// get type of next segment in chunk (0xff if no more segments in chunk)
|
||||
ubyte mvefile_get_next_segment_major(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return 0xff;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return 0xff;
|
||||
|
||||
// otherwise, get the data length
|
||||
return file->cur_chunk[file->next_segment + 2];
|
||||
}
|
||||
|
||||
// get subtype (version) of next segment in chunk (0xff if no more segments in chunk)
|
||||
ubyte mvefile_get_next_segment_minor(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return 0xff;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return 0xff;
|
||||
|
||||
// otherwise, get the data length
|
||||
return file->cur_chunk[file->next_segment + 3];
|
||||
}
|
||||
|
||||
// see next segment (return NULL if no next segment)
|
||||
ubyte *mvefile_get_next_segment(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return NULL;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return NULL;
|
||||
|
||||
// otherwise, get the data length
|
||||
return file->cur_chunk + file->next_segment + 4;
|
||||
}
|
||||
|
||||
// advance to next segment
|
||||
void mvefile_advance_segment(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return;
|
||||
|
||||
// else, advance to next segment
|
||||
file->next_segment += (4 + mve_get_ushort(file->cur_chunk + file->next_segment));
|
||||
}
|
||||
|
||||
// fetch the next chunk (return 0 if at end of stream)
|
||||
int mvefile_fetch_next_chunk(MVEFILE *file)
|
||||
{
|
||||
ubyte buffer[4];
|
||||
ubyte *new_buffer;
|
||||
ushort length;
|
||||
|
||||
// fail if not open
|
||||
if (file->stream == NULL)
|
||||
return 0;
|
||||
|
||||
// fail if we can't read the next segment descriptor
|
||||
if (cfread(buffer, 1, 4, file->stream) < 4)
|
||||
return 0;
|
||||
|
||||
// pull out the next length
|
||||
length = mve_get_short(buffer);
|
||||
|
||||
// setup a new buffer if needed --
|
||||
// only allocate new buffer is old one is too small
|
||||
if (length > file->buf_size) {
|
||||
// allocate new buffer
|
||||
new_buffer = (ubyte *)vm_malloc(100 + length);
|
||||
|
||||
// copy old data
|
||||
if (file->cur_chunk && file->cur_fill)
|
||||
memcpy(new_buffer, file->cur_chunk, file->cur_fill);
|
||||
|
||||
// free old buffer
|
||||
if (file->cur_chunk) {
|
||||
vm_free(file->cur_chunk);
|
||||
file->cur_chunk = NULL;
|
||||
}
|
||||
|
||||
// install new buffer
|
||||
file->cur_chunk = new_buffer;
|
||||
file->buf_size = 100 + length;
|
||||
}
|
||||
|
||||
// read the chunk
|
||||
if (length > 0) {
|
||||
if (cfread(file->cur_chunk, 1, length, file->stream) < length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
file->cur_fill = length;
|
||||
file->next_segment = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// public MVESTREAM functions
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// open an MVE stream
|
||||
MVESTREAM *mve_open(char *filename)
|
||||
{
|
||||
MVESTREAM *stream;
|
||||
|
||||
// allocate
|
||||
stream = (MVESTREAM *)vm_malloc(sizeof(MVESTREAM));
|
||||
|
||||
// defaults
|
||||
stream->movie = NULL;
|
||||
|
||||
// open
|
||||
stream->movie = mvefile_open(filename);
|
||||
|
||||
if (stream->movie == NULL) {
|
||||
mve_close(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
// close an MVE stream
|
||||
void mve_close(MVESTREAM *stream)
|
||||
{
|
||||
// close MVEFILE
|
||||
if (stream->movie)
|
||||
mvefile_close(stream->movie);
|
||||
|
||||
stream->movie = NULL;
|
||||
|
||||
vm_free(stream);
|
||||
}
|
||||
|
||||
// play next chunk
|
||||
int mve_play_next_chunk(MVESTREAM *stream)
|
||||
{
|
||||
ubyte major, minor;
|
||||
ubyte *data;
|
||||
int len;
|
||||
|
||||
// loop over segments
|
||||
major = mvefile_get_next_segment_major(stream->movie);
|
||||
while (major != 0xff) {
|
||||
// check whether to handle the segment
|
||||
if (major < 32) {
|
||||
minor = mvefile_get_next_segment_minor(stream->movie);
|
||||
len = mvefile_get_next_segment_size(stream->movie);
|
||||
data = mvefile_get_next_segment(stream->movie);
|
||||
|
||||
switch (major) {
|
||||
case 0x00:
|
||||
mve_end_movie();
|
||||
break;
|
||||
case 0x01:
|
||||
mve_end_chunk();
|
||||
break;
|
||||
case 0x02:
|
||||
mve_timer_create(data);
|
||||
break;
|
||||
case 0x03:
|
||||
mve_audio_createbuf(minor, data);
|
||||
break;
|
||||
case 0x04:
|
||||
mve_audio_play();
|
||||
break;
|
||||
case 0x05:
|
||||
if (!mve_video_createbuf(minor, data))
|
||||
return 0;
|
||||
break;
|
||||
case 0x07:
|
||||
mve_video_display();
|
||||
break;
|
||||
case 0x08:
|
||||
mve_audio_data(major, data);
|
||||
break;
|
||||
case 0x09:
|
||||
mve_audio_data(major, data);
|
||||
break;
|
||||
case 0x0a:
|
||||
if (!mve_video_init(data))
|
||||
return 0;
|
||||
break;
|
||||
case 0x0c:
|
||||
mve_video_palette(data);
|
||||
break;
|
||||
case 0x0f:
|
||||
mve_video_codemap(data, len);
|
||||
break;
|
||||
case 0x11:
|
||||
mve_video_data(data, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// advance to next segment
|
||||
mvefile_advance_segment(stream->movie);
|
||||
major = mvefile_get_next_segment_major(stream->movie);
|
||||
}
|
||||
|
||||
if (!mvefile_fetch_next_chunk(stream->movie))
|
||||
return 0;
|
||||
|
||||
// return status
|
||||
return 1;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
|
||||
|
||||
#ifndef INCLUDED_MVELIB_H
|
||||
#define INCLUDED_MVELIB_H
|
||||
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct CFILE;
|
||||
|
||||
// structure for maintaining info on a MVEFILE stream
|
||||
typedef struct MVEFILE
|
||||
{
|
||||
CFILE *stream;
|
||||
ubyte *cur_chunk;
|
||||
int buf_size;
|
||||
int cur_fill;
|
||||
int next_segment;
|
||||
} MVEFILE;
|
||||
|
||||
// open a .MVE file
|
||||
MVEFILE *mvefile_open(char *filename);
|
||||
|
||||
// close a .MVE file
|
||||
void mvefile_close(MVEFILE *movie);
|
||||
|
||||
// get size of next segment in chunk (-1 if no more segments in chunk)
|
||||
int mvefile_get_next_segment_size(MVEFILE *movie);
|
||||
|
||||
// get type of next segment in chunk (0xff if no more segments in chunk)
|
||||
ubyte mvefile_get_next_segment_major(MVEFILE *movie);
|
||||
|
||||
// get subtype (version) of next segment in chunk (0xff if no more segments in chunk)
|
||||
ubyte mvefile_get_next_segment_minor(MVEFILE *movie);
|
||||
|
||||
// see next segment (return NULL if no next segment)
|
||||
ubyte *mvefile_get_next_segment(MVEFILE *movie);
|
||||
|
||||
// advance to next segment
|
||||
void mvefile_advance_segment(MVEFILE *movie);
|
||||
|
||||
// fetch the next chunk (return 0 if at end of stream)
|
||||
int mvefile_fetch_next_chunk(MVEFILE *movie);
|
||||
|
||||
// structure for maintaining an MVE stream
|
||||
typedef struct MVESTREAM
|
||||
{
|
||||
MVEFILE *movie;
|
||||
} MVESTREAM;
|
||||
|
||||
// open an MVE stream
|
||||
MVESTREAM *mve_open(char *filename);
|
||||
|
||||
// close an MVE stream
|
||||
void mve_close(MVESTREAM *movie);
|
||||
|
||||
// play next chunk
|
||||
int mve_play_next_chunk(MVESTREAM *movie);
|
||||
|
||||
// basic movie playing functions
|
||||
void mve_init(MVESTREAM *mve);
|
||||
void mve_play(MVESTREAM *mve);
|
||||
void mve_shutdown();
|
||||
|
||||
// utility functions
|
||||
short mve_get_short(ubyte *data);
|
||||
ushort mve_get_ushort(ubyte *data);
|
||||
int mve_get_int(ubyte *data);
|
||||
|
||||
// callbacks for data handling
|
||||
// audio
|
||||
void mve_audio_createbuf(ubyte minor, ubyte *data);
|
||||
int mve_audio_data(ubyte major, ubyte *data);
|
||||
void mve_audio_play();
|
||||
// video
|
||||
int mve_video_createbuf(ubyte minor, ubyte *data);
|
||||
int mve_video_init(ubyte *data);
|
||||
void mve_video_palette(ubyte *data);
|
||||
void mve_video_data(ubyte *data, int len);
|
||||
void mve_video_codemap(ubyte *data, int len);
|
||||
void mve_video_display();
|
||||
// misc
|
||||
void mve_end_movie();
|
||||
void mve_end_chunk();
|
||||
int mve_timer_create(ubyte *data);
|
||||
|
||||
typedef short mves;
|
||||
|
||||
#endif /* INCLUDED_MVELIB_H */
|
||||
@@ -1,800 +0,0 @@
|
||||
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropenglstate.h"
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cutscene/mvelib.h"
|
||||
#include "cutscene/movie.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "io/key.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "io/timer.h"
|
||||
#include "sound/sound.h"
|
||||
#include "sound/openal.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
//#include "sound/audiostr.h"
|
||||
|
||||
|
||||
extern int Cmdline_noscalevid;
|
||||
|
||||
static int mve_playing;
|
||||
|
||||
// timer variables
|
||||
static int micro_frame_delay = 0;
|
||||
static int timer_started = 0;
|
||||
#ifdef SCP_UNIX
|
||||
static struct timeval timer_expire = { 0, 0 };
|
||||
#else
|
||||
static int timer_expire;
|
||||
#endif
|
||||
|
||||
// audio variables
|
||||
#define MVE_AUDIO_BUFFERS 64 // total buffers to interact with stream
|
||||
static int mve_audio_buffer_tail = 0;
|
||||
static int mve_audio_playing = 0;
|
||||
static int mve_audio_canplay = 0;
|
||||
static int mve_audio_compressed = 0;
|
||||
static int audiobuf_created;
|
||||
|
||||
// struct for the audio stream information
|
||||
typedef struct MVE_AUDIO_T {
|
||||
ALenum format;
|
||||
int sample_rate;
|
||||
int bytes_per_sec;
|
||||
int channels;
|
||||
int bitsize;
|
||||
ALuint source_id;
|
||||
ALuint audio_buffer[MVE_AUDIO_BUFFERS];
|
||||
} mve_audio_t;
|
||||
|
||||
mve_audio_t *mas; // mve_audio_stream
|
||||
|
||||
// audio decompressor
|
||||
extern void mveaudio_uncompress(short *buffer, unsigned char *data, int length);
|
||||
|
||||
// video variables
|
||||
int g_width, g_height;
|
||||
void *g_vBuffers = NULL;
|
||||
void *g_vBackBuf1, *g_vBackBuf2;
|
||||
ushort *pixelbuf = NULL;
|
||||
static GLuint GLtex = 0;
|
||||
static GLint gl_screenYH = 0;
|
||||
static GLint gl_screenXW = 0;
|
||||
static GLfloat gl_screenU = 0;
|
||||
static GLfloat gl_screenV = 0;
|
||||
static int g_screenWidth, g_screenHeight;
|
||||
static int g_screenX, g_screenY;
|
||||
static int g_truecolor = 0;
|
||||
static ubyte g_palette[768];
|
||||
static ubyte *g_pCurMap = NULL;
|
||||
static int g_nMapLength = 0;
|
||||
static int videobuf_created, video_inited;
|
||||
static int hp2, wp2;
|
||||
static uint mve_video_skiptimer = 0;
|
||||
static int mve_scale_video = 0;
|
||||
|
||||
// video externs from API graphics functions
|
||||
extern void opengl_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out);
|
||||
extern GLenum GL_previous_texture_target;
|
||||
|
||||
// the decoders
|
||||
extern void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain);
|
||||
extern void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain);
|
||||
|
||||
|
||||
/*************************
|
||||
* general handlers
|
||||
*************************/
|
||||
void mve_end_movie()
|
||||
{
|
||||
mve_playing = 0;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* timer handlers
|
||||
*************************/
|
||||
|
||||
int mve_timer_create(ubyte *data)
|
||||
{
|
||||
int rate = mve_get_int(data);
|
||||
int subd = mve_get_short(data+4);
|
||||
|
||||
micro_frame_delay = rate * subd;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void mve_timer_start(void)
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
int nsec = 0;
|
||||
|
||||
gettimeofday(&timer_expire, NULL);
|
||||
|
||||
timer_expire.tv_usec += micro_frame_delay;
|
||||
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
#else
|
||||
timer_expire = timer_get_microseconds();
|
||||
timer_expire += micro_frame_delay;
|
||||
#endif
|
||||
|
||||
timer_started = 1;
|
||||
}
|
||||
|
||||
static int mve_do_timer_wait(void)
|
||||
{
|
||||
if (!timer_started)
|
||||
return 0;
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
int nsec = 0;
|
||||
struct timespec ts, tsRem;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (tv.tv_sec > timer_expire.tv_sec)
|
||||
goto end;
|
||||
|
||||
if ( (tv.tv_sec == timer_expire.tv_sec) && (tv.tv_usec >= timer_expire.tv_usec) )
|
||||
goto end;
|
||||
|
||||
ts.tv_sec = timer_expire.tv_sec - tv.tv_sec;
|
||||
ts.tv_nsec = 1000 * (timer_expire.tv_usec - tv.tv_usec);
|
||||
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_nsec += 1000000000UL;
|
||||
--ts.tv_sec;
|
||||
}
|
||||
|
||||
if ( (nanosleep(&ts, &tsRem) == -1) && (errno == EINTR) ) {
|
||||
// so we got an error that was a signal interupt, try to sleep again with remainder of time
|
||||
if ( (nanosleep(&tsRem, NULL) == -1) && (errno == EINTR) ) {
|
||||
mprintf(("MVE: Timer error! Aborting movie playback!\n"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
timer_expire.tv_usec += micro_frame_delay;
|
||||
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
#else
|
||||
int tv, ts, ts2;
|
||||
|
||||
tv = timer_get_microseconds();
|
||||
|
||||
if (tv > timer_expire)
|
||||
goto end;
|
||||
|
||||
ts = timer_expire - tv;
|
||||
|
||||
ts2 = ts/1000;
|
||||
|
||||
Sleep(ts2);
|
||||
|
||||
end:
|
||||
timer_expire += micro_frame_delay;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mve_timer_stop()
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
timer_expire.tv_sec = 0;
|
||||
timer_expire.tv_usec = 0;
|
||||
#else
|
||||
timer_expire = 0;
|
||||
#endif
|
||||
timer_started = 0;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* audio handlers
|
||||
*************************/
|
||||
|
||||
// setup the audio information from the data stream
|
||||
void mve_audio_createbuf(ubyte minor, ubyte *data)
|
||||
{
|
||||
if (audiobuf_created)
|
||||
return;
|
||||
|
||||
// if game sound disabled don't try and play movie audio
|
||||
if (!Sound_enabled) {
|
||||
mve_audio_canplay = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int flags, desired_buffer, sample_rate;
|
||||
|
||||
mas = (mve_audio_t *) vm_malloc ( sizeof(mve_audio_t) );
|
||||
memset(mas, 0, sizeof(mve_audio_t));
|
||||
|
||||
mas->format = AL_INVALID;
|
||||
|
||||
flags = mve_get_ushort(data + 2);
|
||||
sample_rate = mve_get_ushort(data + 4);
|
||||
desired_buffer = mve_get_int(data + 6);
|
||||
|
||||
mas->channels = (flags & 0x0001) ? 2 : 1;
|
||||
mas->bitsize = (flags & 0x0002) ? 16 : 8;
|
||||
|
||||
mas->sample_rate = sample_rate;
|
||||
|
||||
if (minor > 0) {
|
||||
mve_audio_compressed = flags & 0x0004 ? 1 : 0;
|
||||
} else {
|
||||
mve_audio_compressed = 0;
|
||||
}
|
||||
|
||||
if (mas->bitsize == 16) {
|
||||
if (mas->channels == 2) {
|
||||
mas->format = AL_FORMAT_STEREO16;
|
||||
} else if (mas->channels == 1) {
|
||||
mas->format = AL_FORMAT_MONO16;
|
||||
}
|
||||
} else if (mas->bitsize == 8) {
|
||||
if (mas->channels == 2) {
|
||||
mas->format = AL_FORMAT_STEREO8;
|
||||
} else if (mas->channels == 1) {
|
||||
mas->format = AL_FORMAT_MONO8;
|
||||
}
|
||||
}
|
||||
|
||||
// somethings wrong, bail now
|
||||
if (mas->format == AL_INVALID) {
|
||||
mve_audio_canplay = 0;
|
||||
audiobuf_created = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGenSources(1, &mas->source_id), { mve_audio_canplay = 0; return; } );
|
||||
|
||||
mve_audio_canplay = 1;
|
||||
|
||||
OpenAL_ErrorPrint( alSourcef(mas->source_id, AL_GAIN, 1.0f) );
|
||||
|
||||
memset(mas->audio_buffer, 0, MVE_AUDIO_BUFFERS * sizeof(ALuint));
|
||||
|
||||
mve_audio_buffer_tail = 0;
|
||||
|
||||
audiobuf_created = 1;
|
||||
}
|
||||
|
||||
// play and stream the audio
|
||||
void mve_audio_play()
|
||||
{
|
||||
if (mve_audio_canplay) {
|
||||
ALint status, bqueued;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return );
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return );
|
||||
|
||||
mve_audio_playing = 1;
|
||||
|
||||
if (status != AL_PLAYING && bqueued > 0) {
|
||||
OpenAL_ErrorPrint( alSourcePlay(mas->source_id) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call this in shutdown to stop and close audio
|
||||
static void mve_audio_stop()
|
||||
{
|
||||
if (!audiobuf_created)
|
||||
return;
|
||||
|
||||
ALint p = 0;
|
||||
|
||||
mve_audio_playing = 0;
|
||||
|
||||
OpenAL_ErrorPrint( alSourceStop(mas->source_id) );
|
||||
OpenAL_ErrorPrint( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &p) );
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(mas->source_id, p, mas->audio_buffer) );
|
||||
OpenAL_ErrorPrint( alDeleteSources(1, &mas->source_id) );
|
||||
|
||||
for (int i = 0; i < MVE_AUDIO_BUFFERS; i++) {
|
||||
// make sure that the buffer is real before trying to delete, it could crash for some otherwise
|
||||
if ( (mas->audio_buffer[i] != 0) && alIsBuffer(mas->audio_buffer[i]) ) {
|
||||
OpenAL_ErrorPrint( alDeleteBuffers(1, &mas->audio_buffer[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
if (mas != NULL) {
|
||||
vm_free(mas);
|
||||
mas = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int mve_audio_data(ubyte major, ubyte *data)
|
||||
{
|
||||
static const int selected_chan=1;
|
||||
int chan;
|
||||
int nsamp;
|
||||
|
||||
if (mve_audio_canplay) {
|
||||
chan = mve_get_ushort(data + 2);
|
||||
nsamp = mve_get_ushort(data + 4);
|
||||
|
||||
if (chan & selected_chan) {
|
||||
ALint bprocessed, bqueued, status;
|
||||
ALuint bid;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &bprocessed), return 0 );
|
||||
|
||||
while (bprocessed-- > 2)
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(mas->source_id, 1, &bid) );
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return 0 );
|
||||
|
||||
if (bqueued == 0)
|
||||
mprintf(("MVE: Buffer underun (First is normal)\n"));
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return 0 );
|
||||
|
||||
if ( (mve_audio_playing) && (status != AL_PLAYING) && (bqueued > 0) ) {
|
||||
OpenAL_ErrorCheck( alSourcePlay(mas->source_id), return 0 );
|
||||
}
|
||||
|
||||
if (bqueued < MVE_AUDIO_BUFFERS) {
|
||||
short *buf = NULL;
|
||||
|
||||
/* HACK: +4 mveaudio_uncompress adds 4 more bytes */
|
||||
if (major == 8) {
|
||||
if (mve_audio_compressed) {
|
||||
nsamp += 4;
|
||||
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
mveaudio_uncompress(buf, data, -1); /* XXX */
|
||||
} else {
|
||||
nsamp -= 8;
|
||||
data += 8;
|
||||
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
memcpy(buf, data, nsamp);
|
||||
}
|
||||
} else {
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
|
||||
memset(buf, 0, nsamp); /* XXX */
|
||||
}
|
||||
|
||||
|
||||
if (!mas->audio_buffer[mve_audio_buffer_tail]) {
|
||||
OpenAL_ErrorCheck( alGenBuffers(1,&mas->audio_buffer[mve_audio_buffer_tail]), { vm_free(buf); return 0; } );
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alBufferData(mas->audio_buffer[mve_audio_buffer_tail], mas->format, buf, nsamp, mas->sample_rate), { vm_free(buf); return 0; } );
|
||||
|
||||
OpenAL_ErrorCheck( alSourceQueueBuffers(mas->source_id, 1, &mas->audio_buffer[mve_audio_buffer_tail]), { vm_free(buf); return 0;} );
|
||||
|
||||
//fprintf(stderr,"Queued buffer %d(%d)\n", mve_audio_buftail, mas->audio_buffer[mve_audio_buftail]);
|
||||
|
||||
if (++mve_audio_buffer_tail == MVE_AUDIO_BUFFERS)
|
||||
mve_audio_buffer_tail = 0;
|
||||
|
||||
bqueued++;
|
||||
vm_free(buf);
|
||||
} else {
|
||||
mprintf(("MVE: Buffer overrun: Queue full\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* video handlers
|
||||
*************************/
|
||||
|
||||
int mve_video_createbuf(ubyte minor, ubyte *data)
|
||||
{
|
||||
if (videobuf_created)
|
||||
return 1;
|
||||
|
||||
short w, h;
|
||||
short count, truecolor;
|
||||
w = mve_get_short(data);
|
||||
h = mve_get_short(data+2);
|
||||
|
||||
if (minor > 0) {
|
||||
count = mve_get_short(data+4);
|
||||
} else {
|
||||
count = 1;
|
||||
}
|
||||
|
||||
if (minor > 1) {
|
||||
truecolor = mve_get_short(data+6);
|
||||
} else {
|
||||
truecolor = 0;
|
||||
}
|
||||
|
||||
g_width = w << 3;
|
||||
g_height = h << 3;
|
||||
|
||||
g_vBackBuf1 = g_vBuffers = vm_malloc(g_width * g_height * 4);
|
||||
|
||||
if (g_vBackBuf1 == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate video buffer"));
|
||||
videobuf_created = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (truecolor)
|
||||
g_vBackBuf2 = (ushort *)g_vBackBuf1 + (g_width * g_height);
|
||||
else
|
||||
g_vBackBuf2 = (ubyte *)g_vBackBuf1 + (g_width * g_height);
|
||||
|
||||
memset(g_vBackBuf1, 0, g_width * g_height * 4);
|
||||
|
||||
g_truecolor = truecolor;
|
||||
videobuf_created = 1;
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
GLfloat scale_by = 1.0f;
|
||||
|
||||
float screen_ratio = (float)gr_screen.max_w / (float)gr_screen.max_h;
|
||||
float movie_ratio = (float)g_width / (float)g_height;
|
||||
|
||||
if (screen_ratio > movie_ratio)
|
||||
scale_by = (float)gr_screen.max_h / (float)g_height;
|
||||
else
|
||||
scale_by = (float)gr_screen.max_w / (float)g_width;
|
||||
|
||||
// don't bother setting anything if we aren't going to need it
|
||||
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glScalef( scale_by, scale_by, 1.0f );
|
||||
mve_scale_video = 1;
|
||||
}
|
||||
|
||||
if (mve_scale_video) {
|
||||
g_screenX = ((fl2i(gr_screen.max_w / scale_by + 0.5f) - g_width) / 2);
|
||||
g_screenY = ((fl2i(gr_screen.max_h / scale_by + 0.5f) - g_height) / 2);
|
||||
} else {
|
||||
// centers on 1024x768, fills on 640x480
|
||||
g_screenX = ((gr_screen.max_w - g_width) / 2);
|
||||
g_screenY = ((gr_screen.max_h - g_height) / 2);
|
||||
}
|
||||
|
||||
// set additional values for screen width/height and UV coords
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
gl_screenYH = g_screenY + g_height;
|
||||
gl_screenXW = g_screenX + g_width;
|
||||
|
||||
gl_screenU = i2fl(g_width) / i2fl(wp2);
|
||||
gl_screenV = i2fl(g_height) / i2fl(hp2);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void mve_convert_and_draw()
|
||||
{
|
||||
ushort *pDests;
|
||||
ushort *pSrcs = NULL;
|
||||
ushort *pixels = (ushort *)g_vBackBuf1;
|
||||
int x, y;
|
||||
|
||||
ubyte *pSrcs8 = NULL;
|
||||
ubyte *pixels8 = (ubyte *)g_vBackBuf1;
|
||||
ubyte r, g, b;
|
||||
ushort bit_16;
|
||||
|
||||
if (g_truecolor)
|
||||
pSrcs = pixels;
|
||||
else
|
||||
pSrcs8 = pixels8;
|
||||
|
||||
pDests = pixelbuf;
|
||||
|
||||
if (gr_screen.mode != GR_OPENGL) {
|
||||
if (g_screenWidth > g_width)
|
||||
pDests += ((g_screenWidth - g_width) / 2) / 2;
|
||||
|
||||
if (g_screenHeight > g_height)
|
||||
pDests += ((g_screenHeight - g_height) / 2) * g_screenWidth;
|
||||
}
|
||||
|
||||
for (y=0; y<g_height; y++) {
|
||||
for (x = 0; x < g_width; x++) {
|
||||
if (g_truecolor) {
|
||||
Assert( pSrcs != NULL );
|
||||
|
||||
pDests[x] = (1<<15)|*pSrcs;
|
||||
pSrcs++;
|
||||
} else {
|
||||
Assert( pSrcs8 != NULL );
|
||||
|
||||
// grab rgb color
|
||||
r = (g_palette[(*pSrcs8)*3] / 2);
|
||||
g = (g_palette[(*pSrcs8)*3 + 1] / 2);
|
||||
b = (g_palette[(*pSrcs8)*3 + 2] / 2);
|
||||
|
||||
// stuff the color
|
||||
bit_16 = (ushort)(r << Gr_t_red.shift);
|
||||
bit_16 |= (ushort)(g << Gr_t_green.shift);
|
||||
bit_16 |= (ushort)(b << Gr_t_blue.shift);
|
||||
bit_16 |= (ushort)(Gr_t_alpha.mask);
|
||||
|
||||
// stuff the pixel
|
||||
pDests[x] = (1<<15)|bit_16;
|
||||
|
||||
pSrcs8++;
|
||||
}
|
||||
}
|
||||
|
||||
pDests += g_screenWidth;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mve_video_display()
|
||||
{
|
||||
fix t1 = timer_get_fixed_seconds();
|
||||
|
||||
mve_convert_and_draw();
|
||||
|
||||
// this thing is basically stupid but I don't care
|
||||
// micro_frame_delay is divided by 10 to match mve_video_skiptimer overflow catch
|
||||
if ( mve_video_skiptimer > (uint)(micro_frame_delay/10) ) {
|
||||
// we are running slow so subtract desired time from actual and skip this frame
|
||||
mve_video_skiptimer -= (micro_frame_delay/10);
|
||||
return;
|
||||
} else {
|
||||
// zero out so we can get a new count
|
||||
mve_video_skiptimer = 0;
|
||||
}
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_width, g_height, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixelbuf);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(g_screenX, g_screenY);
|
||||
|
||||
glTexCoord2f(0, gl_screenV);
|
||||
glVertex2i(g_screenX, gl_screenYH);
|
||||
|
||||
glTexCoord2f(gl_screenU, gl_screenV);
|
||||
glVertex2i(gl_screenXW, gl_screenYH);
|
||||
|
||||
glTexCoord2f(gl_screenU, 0);
|
||||
glVertex2i(gl_screenXW, g_screenY);
|
||||
glEnd();
|
||||
} else {
|
||||
// DDOI - This is probably really fricking slow
|
||||
int bitmap = bm_create (16, g_screenWidth, g_screenHeight, pixelbuf, 0);
|
||||
gr_set_bitmap (bitmap);
|
||||
gr_bitmap (g_screenX, g_screenY, true);
|
||||
bm_release (bitmap);
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
os_poll();
|
||||
|
||||
fix t2 = timer_get_fixed_seconds();
|
||||
|
||||
// only get a new count if we are definitely through with old count
|
||||
if ( mve_video_skiptimer == 0 ) {
|
||||
// for a more accurate count convert the frame rate to a float and multiply
|
||||
// by one-hundred-thousand before converting to an uint.
|
||||
mve_video_skiptimer = (uint)(f2fl(t2-t1) * 100000);
|
||||
}
|
||||
|
||||
int k = key_inkey();
|
||||
switch (k) {
|
||||
case KEY_ESC:
|
||||
case KEY_ENTER:
|
||||
case KEY_SPACEBAR:
|
||||
mve_playing = 0;
|
||||
}
|
||||
|
||||
//mprintf(("mve frame took this long: %.6f\n", f2fl(t2-t1) / 1000.0f));
|
||||
}
|
||||
|
||||
int mve_video_init(ubyte *data)
|
||||
{
|
||||
if (video_inited)
|
||||
return 1;
|
||||
|
||||
short width, height;
|
||||
|
||||
width = mve_get_short(data);
|
||||
height = mve_get_short(data+2);
|
||||
|
||||
g_screenWidth = width;
|
||||
g_screenHeight = height;
|
||||
|
||||
// DDOI - Allocate RGB565 pixel buffer
|
||||
pixelbuf = (ushort *)vm_malloc(g_screenWidth * g_screenHeight * 2);
|
||||
|
||||
if (pixelbuf == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
|
||||
video_inited = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(pixelbuf, 0, g_screenWidth * g_screenHeight * 2);
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
opengl_set_texture_target(GL_TEXTURE_2D);
|
||||
opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
|
||||
|
||||
glGenTextures(1, &GLtex);
|
||||
|
||||
Assert( GLtex != 0 );
|
||||
|
||||
if ( GLtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gr_set_lighting(false, false);
|
||||
GL_state.Texture.DisableAll();
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(GLtex);
|
||||
|
||||
GL_state.SetTextureSource(TEXTURE_SOURCE_DECAL);
|
||||
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
|
||||
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
|
||||
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB5_A1, wp2, hp2, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
|
||||
|
||||
// set our color so that we can make sure that it's correct
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
memset(g_palette, 0, 768);
|
||||
|
||||
video_inited = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mve_video_palette(ubyte *data)
|
||||
{
|
||||
short start, count;
|
||||
start = mve_get_short(data);
|
||||
count = mve_get_short(data+2);
|
||||
memcpy(g_palette + 3*start, data+4, 3*count);
|
||||
}
|
||||
|
||||
void mve_video_codemap(ubyte *data, int len)
|
||||
{
|
||||
g_pCurMap = data;
|
||||
g_nMapLength = len;
|
||||
}
|
||||
|
||||
void mve_video_data(ubyte *data, int len)
|
||||
{
|
||||
short nFrameHot, nFrameCold;
|
||||
short nXoffset, nYoffset;
|
||||
short nXsize, nYsize;
|
||||
ushort nFlags;
|
||||
ubyte *temp;
|
||||
|
||||
nFrameHot = mve_get_short(data);
|
||||
nFrameCold = mve_get_short(data+2);
|
||||
nXoffset = mve_get_short(data+4);
|
||||
nYoffset = mve_get_short(data+6);
|
||||
nXsize = mve_get_short(data+8);
|
||||
nYsize = mve_get_short(data+10);
|
||||
nFlags = mve_get_ushort(data+12);
|
||||
|
||||
if (nFlags & 1) {
|
||||
temp = (ubyte *)g_vBackBuf1;
|
||||
g_vBackBuf1 = g_vBackBuf2;
|
||||
g_vBackBuf2 = temp;
|
||||
}
|
||||
|
||||
if (g_truecolor)
|
||||
decodeFrame16((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
else
|
||||
decodeFrame8((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
}
|
||||
|
||||
void mve_end_chunk()
|
||||
{
|
||||
g_pCurMap = NULL;
|
||||
}
|
||||
|
||||
void mve_init(MVESTREAM *mve)
|
||||
{
|
||||
// reset to default values
|
||||
mve_audio_buffer_tail = 0;
|
||||
mve_audio_playing = 0;
|
||||
mve_audio_canplay = 0;
|
||||
mve_audio_compressed = 0;
|
||||
audiobuf_created = 0;
|
||||
|
||||
videobuf_created = 0;
|
||||
video_inited = 0;
|
||||
mve_scale_video = 0;
|
||||
|
||||
mve_playing = 1;
|
||||
}
|
||||
|
||||
void mve_play(MVESTREAM *mve)
|
||||
{
|
||||
int init_timer = 0, timer_error = 0;
|
||||
int cont = 1;
|
||||
|
||||
if (!timer_started)
|
||||
mve_timer_start();
|
||||
|
||||
while (cont && mve_playing && !timer_error) {
|
||||
cont = mve_play_next_chunk(mve);
|
||||
|
||||
if (micro_frame_delay && !init_timer) {
|
||||
mve_timer_start();
|
||||
init_timer = 1;
|
||||
}
|
||||
|
||||
timer_error = mve_do_timer_wait();
|
||||
}
|
||||
}
|
||||
|
||||
void mve_shutdown()
|
||||
{
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
if (mve_scale_video) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
GL_state.Texture.Disable();
|
||||
GL_state.Texture.Delete(GLtex);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
GLtex = 0;
|
||||
}
|
||||
|
||||
if (pixelbuf != NULL) {
|
||||
vm_free(pixelbuf);
|
||||
pixelbuf = NULL;
|
||||
}
|
||||
|
||||
if (g_vBuffers != NULL) {
|
||||
vm_free(g_vBuffers);
|
||||
g_vBuffers = NULL;
|
||||
}
|
||||
|
||||
mve_audio_stop();
|
||||
|
||||
mve_timer_stop();
|
||||
}
|
||||
@@ -1,940 +0,0 @@
|
||||
|
||||
|
||||
// This player code is based largely on the player example in the libtheora package
|
||||
// and so they get a fair bit of credit for this code, even if in ideas/comments only
|
||||
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropenglshader.h"
|
||||
#include "graphics/gropenglstate.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "io/key.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "sound/sound.h"
|
||||
#include "sound/openal.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "cutscene/oggplayer.h"
|
||||
#include "io/timer.h"
|
||||
|
||||
#include "theora/theora.h"
|
||||
#include "vorbis/codec.h"
|
||||
|
||||
|
||||
extern int Cmdline_noscalevid;
|
||||
|
||||
static int hp2, wp2;
|
||||
static int video_inited = 0;
|
||||
static int scale_video = 0;
|
||||
static int playing = 1;
|
||||
static ubyte *pixelbuf = NULL;
|
||||
static uint g_screenWidth = 0;
|
||||
static uint g_screenHeight = 0;
|
||||
static int g_screenX = 0;
|
||||
static int g_screenY = 0;
|
||||
|
||||
static GLuint GLtex = 0;
|
||||
static GLint gl_screenYH = 0;
|
||||
static GLint gl_screenXW = 0;
|
||||
static GLfloat gl_screenU = 0;
|
||||
static GLfloat gl_screenV = 0;
|
||||
|
||||
// video externs from API graphics functions
|
||||
extern void opengl_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out);
|
||||
|
||||
static int timer_started = 0;
|
||||
static longlong base_time = -1;
|
||||
#ifdef SCP_UNIX
|
||||
static struct timeval timer_expire = { 0, 0 };
|
||||
#else
|
||||
static int timer_expire;
|
||||
#endif
|
||||
|
||||
static int audio_inited = 0;
|
||||
static int audio_buffer_tail = 0;
|
||||
static ALuint audio_sid = 0;
|
||||
#define OGG_AUDIO_BUFFERS 15
|
||||
static ALuint audio_buffers[OGG_AUDIO_BUFFERS];
|
||||
|
||||
// single audio fragment audio buffering
|
||||
static int audiobuf_fill = 0;
|
||||
static short *audiobuf = NULL;
|
||||
static longlong audiobuf_granulepos = 0; // time position of last sample
|
||||
static int audiofd_fragsize = 0;
|
||||
|
||||
// single frame video buffering
|
||||
static longlong videobuf_granulepos = -1;
|
||||
static double videobuf_time = 0;
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Utility items
|
||||
//
|
||||
|
||||
// helper; just grab some more compressed bitstream and sync it for page extraction
|
||||
static int OGG_buffer_data(THEORAFILE *movie)
|
||||
{
|
||||
char *buffer = ogg_sync_buffer(&movie->osyncstate, 4096);
|
||||
int bytes = cfread(buffer, 1, 4096, movie->cfp);
|
||||
|
||||
ogg_sync_wrote(&movie->osyncstate, bytes);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
// helper: push a page into the appropriate steam
|
||||
// this can be done blindly; a stream won't accept a page that doesn't belong to it
|
||||
static void OGG_queue_page(THEORAFILE *movie)
|
||||
{
|
||||
Assert( movie->theora_p );
|
||||
|
||||
ogg_stream_pagein(&movie->t_osstate, &movie->opage);
|
||||
|
||||
if (movie->vorbis_p)
|
||||
ogg_stream_pagein(&movie->v_osstate, &movie->opage);
|
||||
}
|
||||
|
||||
// get relative time since beginning playback, compensating for A/V drift
|
||||
static double OGG_get_time()
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
longlong now;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
now = tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
|
||||
if (base_time == -1)
|
||||
base_time = now;
|
||||
|
||||
return (now - base_time) * 0.001;
|
||||
#else
|
||||
if (base_time == -1)
|
||||
base_time = timer_get_milliseconds();
|
||||
|
||||
return (timer_get_milliseconds() - base_time) * 0.001;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void OGG_timer_init()
|
||||
{
|
||||
#if SCP_UNIX
|
||||
int nsec = 0;
|
||||
|
||||
gettimeofday(&timer_expire, NULL);
|
||||
|
||||
timer_expire.tv_usec += (int)((videobuf_time - OGG_get_time()) * 1000000.0);
|
||||
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
#else
|
||||
timer_expire = timer_get_microseconds();
|
||||
timer_expire += (int)((videobuf_time - OGG_get_time()) * 1000000.0);
|
||||
#endif
|
||||
|
||||
timer_started = 1;
|
||||
}
|
||||
|
||||
static void OGG_timer_do_wait()
|
||||
{
|
||||
if (!timer_started)
|
||||
OGG_timer_init();
|
||||
|
||||
#if SCP_UNIX
|
||||
int nsec = 0;
|
||||
struct timespec ts, tsRem;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (tv.tv_sec > timer_expire.tv_sec)
|
||||
goto end;
|
||||
|
||||
if ( (tv.tv_sec == timer_expire.tv_sec) && (tv.tv_usec >= timer_expire.tv_usec) )
|
||||
goto end;
|
||||
|
||||
ts.tv_sec = timer_expire.tv_sec - tv.tv_sec;
|
||||
ts.tv_nsec = 1000 * (timer_expire.tv_usec - tv.tv_usec);
|
||||
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_nsec += 1000000000UL;
|
||||
--ts.tv_sec;
|
||||
}
|
||||
|
||||
if ( (nanosleep(&ts, &tsRem) == -1) && (errno == EINTR) ) {
|
||||
// so we got an error that was a signal interupt, try to sleep again with remainder of time
|
||||
if ( (nanosleep(&tsRem, NULL) == -1) && (errno == EINTR) ) {
|
||||
mprintf(("MVE: Timer error! Aborting movie playback!\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
timer_expire.tv_usec += (int)((videobuf_time - OGG_get_time()) * 1000000.0);
|
||||
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
#else
|
||||
int tv, ts, ts2;
|
||||
|
||||
tv = timer_get_microseconds();
|
||||
|
||||
if (tv > timer_expire)
|
||||
goto end;
|
||||
|
||||
ts = timer_expire - tv;
|
||||
|
||||
ts2 = ts/1000;
|
||||
|
||||
Sleep(ts2);
|
||||
|
||||
end:
|
||||
timer_expire += (int)((videobuf_time - OGG_get_time()) * 1000000.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// End Utility items
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// That wonderful Audio
|
||||
//
|
||||
|
||||
static void OGG_audio_init(vorbis_info *vinfo)
|
||||
{
|
||||
if (audio_inited)
|
||||
return;
|
||||
|
||||
Assert( vinfo != NULL );
|
||||
|
||||
audio_inited = 1;
|
||||
|
||||
OpenAL_ErrorCheck( alGenSources(1, &audio_sid), return );
|
||||
OpenAL_ErrorPrint( alSourcef(audio_sid, AL_GAIN, 1.0f) );
|
||||
|
||||
memset( &audio_buffers, 0, sizeof(ALuint) * OGG_AUDIO_BUFFERS );
|
||||
|
||||
audiofd_fragsize = (((vinfo->channels * 16) / 8) * vinfo->rate);
|
||||
|
||||
audiobuf = (short *) vm_malloc(audiofd_fragsize);
|
||||
}
|
||||
|
||||
static void OGG_audio_close()
|
||||
{
|
||||
if ( !audio_inited )
|
||||
return;
|
||||
|
||||
audio_inited = 0;
|
||||
|
||||
ALint p = 0;
|
||||
|
||||
OpenAL_ErrorPrint( alSourceStop(audio_sid) );
|
||||
OpenAL_ErrorPrint( alGetSourcei(audio_sid, AL_BUFFERS_PROCESSED, &p) );
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(audio_sid, p, audio_buffers) );
|
||||
OpenAL_ErrorPrint( alDeleteSources(1, &audio_sid) );
|
||||
|
||||
for (int i = 0; i < OGG_AUDIO_BUFFERS; i++) {
|
||||
// make sure that the buffer is real before trying to delete, it could crash for some otherwise
|
||||
if ( (audio_buffers[i] != 0) && alIsBuffer(audio_buffers[i]) ) {
|
||||
OpenAL_ErrorPrint( alDeleteBuffers(1, &audio_buffers[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
audio_sid = 0;
|
||||
audio_buffer_tail = 0;
|
||||
|
||||
audiobuf_fill = 0;
|
||||
audiobuf_granulepos = 0;
|
||||
audiofd_fragsize = 0;
|
||||
|
||||
if (audiobuf != NULL) {
|
||||
vm_free(audiobuf);
|
||||
audiobuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void OGG_audio_write(vorbis_info *vorbis, bool *ready)
|
||||
{
|
||||
ALint status, queued, processed = 0;
|
||||
ALuint bid = 0;
|
||||
|
||||
if ( !audio_inited || !(*ready) )
|
||||
return;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(audio_sid, AL_BUFFERS_PROCESSED, &processed), return );
|
||||
|
||||
while (processed-- > 2)
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(audio_sid, 1, &bid) );
|
||||
|
||||
if ( !(*ready) )
|
||||
return;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(audio_sid, AL_BUFFERS_QUEUED, &queued), return );
|
||||
|
||||
if ( audiobuf_fill && (queued < OGG_AUDIO_BUFFERS) ) {
|
||||
if ( !audio_buffers[audio_buffer_tail] )
|
||||
OpenAL_ErrorCheck( alGenBuffers(1, &audio_buffers[audio_buffer_tail]), return );
|
||||
|
||||
ALenum format = (vorbis->channels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
|
||||
|
||||
OpenAL_ErrorCheck( alBufferData(audio_buffers[audio_buffer_tail], format, audiobuf, audiobuf_fill, vorbis->rate), return );
|
||||
|
||||
OpenAL_ErrorCheck( alSourceQueueBuffers(audio_sid, 1, &audio_buffers[audio_buffer_tail]), return );
|
||||
|
||||
if (++audio_buffer_tail == OGG_AUDIO_BUFFERS)
|
||||
audio_buffer_tail = 0;
|
||||
|
||||
audiobuf_fill = 0;
|
||||
*ready = false;
|
||||
} else {
|
||||
// mprintf(("Theora WARN: Buffer overrun: Queue full\n"));
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(audio_sid, AL_SOURCE_STATE, &status), return );
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(audio_sid, AL_BUFFERS_QUEUED, &queued), return );
|
||||
|
||||
if ( (status != AL_PLAYING) && (queued > 0) )
|
||||
OpenAL_ErrorPrint( alSourcePlay(audio_sid) );
|
||||
}
|
||||
|
||||
//
|
||||
// End Audio stuff
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Video related stuff
|
||||
//
|
||||
|
||||
static void OGG_video_init(theora_info *tinfo)
|
||||
{
|
||||
float scale_by = 0.0f;
|
||||
|
||||
if (video_inited)
|
||||
return;
|
||||
|
||||
Assert( tinfo != NULL );
|
||||
|
||||
g_screenWidth = tinfo->frame_width;
|
||||
g_screenHeight = tinfo->frame_height;
|
||||
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
opengl_set_texture_target(GL_TEXTURE_2D);
|
||||
opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
|
||||
|
||||
glGenTextures(1, &GLtex);
|
||||
|
||||
Assert( GLtex != 0 );
|
||||
|
||||
if ( GLtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
gr_set_lighting(false, false);
|
||||
GL_state.Texture.DisableAll();
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(GLtex);
|
||||
|
||||
GL_state.SetTextureSource(TEXTURE_SOURCE_DECAL);
|
||||
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
|
||||
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
|
||||
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB8, wp2, hp2, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
float screen_ratio = (float)gr_screen.max_w / (float)gr_screen.max_h;
|
||||
float movie_ratio = (float)g_screenWidth / (float)g_screenHeight;
|
||||
|
||||
if (screen_ratio > movie_ratio)
|
||||
scale_by = (float)gr_screen.max_h / (float)g_screenHeight;
|
||||
else
|
||||
scale_by = (float)gr_screen.max_w / (float)g_screenWidth;
|
||||
|
||||
// don't bother setting anything if we aren't going to need it
|
||||
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glScalef( scale_by, scale_by, -1.0f );
|
||||
scale_video = 1;
|
||||
}
|
||||
|
||||
// set our color so that we can make sure that it's correct
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
pixelbuf = (ubyte *) vm_malloc_q(g_screenWidth * g_screenHeight * 3);
|
||||
|
||||
if (pixelbuf == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
memset( pixelbuf, 0, g_screenWidth * g_screenHeight * 3 );
|
||||
|
||||
if (scale_video) {
|
||||
g_screenX = ((fl2i(gr_screen.max_w / scale_by + 0.5f) - g_screenWidth) / 2);
|
||||
g_screenY = ((fl2i(gr_screen.max_h / scale_by + 0.5f) - g_screenHeight) / 2);
|
||||
} else {
|
||||
// centers on 1024x768, fills on 640x480
|
||||
g_screenX = ((gr_screen.max_w - g_screenWidth) / 2);
|
||||
g_screenY = ((gr_screen.max_h - g_screenHeight) / 2);
|
||||
}
|
||||
|
||||
// set additional values for screen width/height and UV coords
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
gl_screenYH = g_screenY + g_screenHeight;
|
||||
gl_screenXW = g_screenX + g_screenWidth;
|
||||
|
||||
gl_screenU = i2fl(g_screenWidth) / i2fl(wp2);
|
||||
gl_screenV = i2fl(g_screenHeight) / i2fl(hp2);
|
||||
}
|
||||
|
||||
video_inited = 1;
|
||||
}
|
||||
|
||||
static void OGG_video_close()
|
||||
{
|
||||
if ( !video_inited ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
if (scale_video) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
GL_state.Texture.Disable();
|
||||
GL_state.Texture.Delete(GLtex);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
|
||||
opengl_set_texture_target();
|
||||
|
||||
GLtex = 0;
|
||||
}
|
||||
|
||||
if (pixelbuf != NULL) {
|
||||
vm_free(pixelbuf);
|
||||
pixelbuf = NULL;
|
||||
}
|
||||
|
||||
video_inited = 0;
|
||||
scale_video = 0;
|
||||
pixelbuf = NULL;
|
||||
g_screenWidth = 0;
|
||||
g_screenHeight = 0;
|
||||
g_screenX = 0;
|
||||
g_screenY = 0;
|
||||
|
||||
GLtex = 0;
|
||||
gl_screenYH = 0;
|
||||
gl_screenXW = 0;
|
||||
gl_screenU = 0;
|
||||
gl_screenV = 0;
|
||||
}
|
||||
|
||||
static void convert_YUV_to_RGB(yuv_buffer *yuv)
|
||||
{
|
||||
int Y1, Y2, U, V;
|
||||
int R = 0, G = 0, B = 0;
|
||||
int C, D, E;
|
||||
uint x, y;
|
||||
uint width_2 = g_screenWidth/2;
|
||||
|
||||
ubyte *pix = &pixelbuf[0];
|
||||
|
||||
ubyte *y_ptr = (ubyte *)yuv->y;
|
||||
ubyte *u_ptr = (ubyte *)yuv->u;
|
||||
ubyte *v_ptr = (ubyte *)yuv->v;
|
||||
|
||||
for (y = 0; y < g_screenHeight; y++) {
|
||||
for (x = 0; x < width_2; x++) {
|
||||
// we need two pixels of Y
|
||||
Y1 = *y_ptr; y_ptr++;
|
||||
Y2 = *y_ptr; y_ptr++;
|
||||
|
||||
// only one pixel of U and V (half the size of Y)
|
||||
U = u_ptr[x];
|
||||
V = v_ptr[x];
|
||||
|
||||
D = (U - 128);
|
||||
E = (V - 128);
|
||||
|
||||
// first pixel
|
||||
C = (Y1 - 16) * 298;
|
||||
|
||||
R = ((C + 409 * E + 128) >> 8);
|
||||
G = ((C - 100 * D - 208 * E + 128) >> 8);
|
||||
B = ((C + 516 * D + 128) >> 8);
|
||||
|
||||
CLAMP(R, 0, 255);
|
||||
CLAMP(G, 0, 255);
|
||||
CLAMP(B, 0, 255);
|
||||
|
||||
*pix++ = (ubyte)B;
|
||||
*pix++ = (ubyte)G;
|
||||
*pix++ = (ubyte)R;
|
||||
|
||||
// second pixel (U and V values are resused)
|
||||
C = (Y2 - 16) * 298;
|
||||
|
||||
R = ((C + 409 * E + 128) >> 8);
|
||||
G = ((C - 100 * D - 208 * E + 128) >> 8);
|
||||
B = ((C + 516 * D + 128) >> 8);
|
||||
|
||||
CLAMP(R, 0, 255);
|
||||
CLAMP(G, 0, 255);
|
||||
CLAMP(B, 0, 255);
|
||||
|
||||
*pix++ = (ubyte)B;
|
||||
*pix++ = (ubyte)G;
|
||||
*pix++ = (ubyte)R;
|
||||
}
|
||||
|
||||
y_ptr += (yuv->y_stride - yuv->y_width);
|
||||
|
||||
// u and v have to be done every other row (it's a 2x2 block)
|
||||
if (y % 2) {
|
||||
u_ptr += yuv->uv_stride;
|
||||
v_ptr += yuv->uv_stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void OGG_video_draw(theora_state *tstate)
|
||||
{
|
||||
yuv_buffer yuv;
|
||||
|
||||
theora_decode_YUVout(tstate, &yuv);
|
||||
convert_YUV_to_RGB(&yuv);
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGR, GL_UNSIGNED_BYTE, pixelbuf);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(g_screenX, g_screenY);
|
||||
|
||||
glTexCoord2f(0, gl_screenV);
|
||||
glVertex2i(g_screenX, gl_screenYH);
|
||||
|
||||
glTexCoord2f(gl_screenU, gl_screenV);
|
||||
glVertex2i(gl_screenXW, gl_screenYH);
|
||||
|
||||
glTexCoord2f(gl_screenU, 0);
|
||||
glVertex2i(gl_screenXW, g_screenY);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
os_poll();
|
||||
|
||||
int k = key_inkey();
|
||||
switch (k) {
|
||||
case KEY_ESC:
|
||||
case KEY_ENTER:
|
||||
case KEY_SPACEBAR:
|
||||
playing = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// End Video related stuff
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// The global stuff...
|
||||
//
|
||||
|
||||
// close out a theora movie and free it's memory
|
||||
void theora_close(THEORAFILE *movie)
|
||||
{
|
||||
Assert( movie != NULL );
|
||||
|
||||
timer_started = 0;
|
||||
base_time = -1;
|
||||
|
||||
videobuf_granulepos = -1;
|
||||
videobuf_time = 0;
|
||||
|
||||
if (movie->vorbis_p) {
|
||||
ogg_stream_clear(&movie->v_osstate);
|
||||
|
||||
vorbis_block_clear(&movie->vblock);
|
||||
vorbis_dsp_clear(&movie->vstate);
|
||||
vorbis_comment_clear(&movie->vcomment);
|
||||
vorbis_info_clear(&movie->vinfo);
|
||||
}
|
||||
|
||||
if (movie->theora_p) {
|
||||
ogg_stream_clear(&movie->t_osstate);
|
||||
|
||||
theora_clear(&movie->tstate);
|
||||
theora_comment_clear(&movie->tcomment);
|
||||
theora_info_clear(&movie->tinfo);
|
||||
}
|
||||
|
||||
ogg_sync_clear(&movie->osyncstate);
|
||||
|
||||
// free the stream
|
||||
if (movie->cfp)
|
||||
cfclose(movie->cfp);
|
||||
|
||||
// free the struct
|
||||
vm_free(movie);
|
||||
|
||||
playing = 1;
|
||||
}
|
||||
|
||||
// opens a theora file, verifies we can use it, initializes everything needed
|
||||
// to decode and use the file
|
||||
THEORAFILE *theora_open(char *filename)
|
||||
{
|
||||
char lower_name[MAX_FILENAME_LEN];
|
||||
THEORAFILE *movie;
|
||||
int stateflag = 0;
|
||||
|
||||
|
||||
// create the file
|
||||
movie = (THEORAFILE *) vm_malloc_q( sizeof(THEORAFILE) );
|
||||
|
||||
if (movie == NULL)
|
||||
return NULL;
|
||||
|
||||
memset( movie, 0, sizeof(THEORAFILE) );
|
||||
|
||||
// lower case filename for checking
|
||||
memset( lower_name, 0, sizeof(lower_name) );
|
||||
strncpy( lower_name, filename, strlen(filename) );
|
||||
strlwr(lower_name);
|
||||
|
||||
char *p = strchr( lower_name, '.' );
|
||||
if ( p ) *p = 0;
|
||||
|
||||
strcat_s( lower_name, ".ogg" );
|
||||
|
||||
// NOTE: Because the .ogg extension is used for both movies and sounds, we have to
|
||||
// be a bit more specific about our search locations, so we look only in the
|
||||
// two places that Theora movies might exist.
|
||||
movie->cfp = cfopen(lower_name, "rb", CFILE_NORMAL, CF_TYPE_ROOT);
|
||||
|
||||
if (movie->cfp == NULL)
|
||||
movie->cfp = cfopen(lower_name, "rb", CFILE_NORMAL, CF_TYPE_MOVIES);
|
||||
|
||||
if (movie->cfp == NULL) {
|
||||
mprintf(("Theora ERROR: Unable to find and open movie file named '%s'\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// start up Ogg stream synchronization layer
|
||||
ogg_sync_init(&movie->osyncstate);
|
||||
|
||||
// init supporting Vorbis structures needed in header parsing
|
||||
vorbis_info_init(&movie->vinfo);
|
||||
vorbis_comment_init(&movie->vcomment);
|
||||
|
||||
// init supporting Theora structures needed in header parsing
|
||||
theora_comment_init(&movie->tcomment);
|
||||
theora_info_init(&movie->tinfo);
|
||||
|
||||
// ogg file open so parse the headers
|
||||
// we are only interested in Vorbis/Theora streams
|
||||
while ( !stateflag ) {
|
||||
int ret = OGG_buffer_data(movie);
|
||||
|
||||
if (ret == 0)
|
||||
break;
|
||||
|
||||
while (ogg_sync_pageout(&movie->osyncstate, &movie->opage) > 0) {
|
||||
ogg_stream_state test;
|
||||
|
||||
// is this a mandated initial header? If not, stop parsing
|
||||
if ( !ogg_page_bos(&movie->opage) ) {
|
||||
// don't leak the page; get it into the appropriate stream
|
||||
OGG_queue_page(movie);
|
||||
stateflag = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
ogg_stream_init(&test, ogg_page_serialno(&movie->opage));
|
||||
ogg_stream_pagein(&test, &movie->opage);
|
||||
ogg_stream_packetout(&test, &movie->opacket);
|
||||
|
||||
// identify the codec: try theora
|
||||
if ( !movie->theora_p && (theora_decode_header(&movie->tinfo, &movie->tcomment, &movie->opacket) >= 0) ) {
|
||||
// it is theora
|
||||
memcpy( &movie->t_osstate, &test, sizeof(test) );
|
||||
movie->theora_p = 1;
|
||||
} else if ( !movie->vorbis_p && (vorbis_synthesis_headerin(&movie->vinfo, &movie->vcomment, &movie->opacket) >= 0) ) {
|
||||
// it is vorbis
|
||||
memcpy( &movie->v_osstate, &test, sizeof(test) );
|
||||
movie->vorbis_p = 1;
|
||||
} else {
|
||||
// whatever it is, we don't care about it
|
||||
ogg_stream_clear(&test);
|
||||
}
|
||||
}
|
||||
// fall through to non-bos page parsing
|
||||
}
|
||||
|
||||
// if we don't have usable video then bail out now
|
||||
if ( !movie->theora_p ) {
|
||||
mprintf(("Theora ERROR: Unable to find video data in '%s'\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// go ahead and do some audio stream error checking...
|
||||
if ( (movie->vinfo.channels < 0) || (movie->vinfo.channels > 2) ) {
|
||||
mprintf(("Theora ERROR: Unsupported number of audio channels!\n"));
|
||||
movie->vorbis_p = 0;
|
||||
}
|
||||
|
||||
// if we don't have usable audio then close out it's partial setup and just use the video
|
||||
if ( !Sound_enabled || !movie->vorbis_p ) {
|
||||
vorbis_info_clear(&movie->vinfo);
|
||||
vorbis_comment_clear(&movie->vcomment);
|
||||
movie->vorbis_p = 0;
|
||||
}
|
||||
|
||||
int ret;
|
||||
|
||||
// we're expecting more header packets.
|
||||
while ( (movie->theora_p < 3) || (movie->vorbis_p && (movie->vorbis_p < 3)) ) {
|
||||
|
||||
ret = ogg_stream_packetout(&movie->t_osstate, &movie->opacket);
|
||||
// look for further theora headers
|
||||
while ( (movie->theora_p < 3) && (ret) ){
|
||||
if ( (ret < 0) || theora_decode_header(&movie->tinfo, &movie->tcomment, &movie->opacket) ) {
|
||||
mprintf(("Theora ERROR: Error parsing Theora stream headers on '%s'! Corrupt stream?\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (++movie->theora_p == 3)
|
||||
break;
|
||||
|
||||
ret = ogg_stream_packetout(&movie->t_osstate, &movie->opacket);
|
||||
}
|
||||
|
||||
ret = ogg_stream_packetout(&movie->v_osstate, &movie->opacket);
|
||||
|
||||
// look for more vorbis header packets
|
||||
while ( movie->vorbis_p && (movie->vorbis_p < 3) && (ret) ) {
|
||||
if ( (ret < 0) || vorbis_synthesis_headerin(&movie->vinfo, &movie->vcomment, &movie->opacket) ) {
|
||||
mprintf(("Theora ERROR: Error parsing Vorbis stream headers on '%s'! Corrupt stream?\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (++movie->vorbis_p == 3)
|
||||
break;
|
||||
|
||||
ret = ogg_stream_packetout(&movie->v_osstate, &movie->opacket);
|
||||
}
|
||||
|
||||
// The header pages/packets will arrive before anything else we care about, or the stream is not obeying spec
|
||||
|
||||
if ( ogg_sync_pageout(&movie->osyncstate, &movie->opage) > 0 ) {
|
||||
OGG_queue_page(movie); // demux into the appropriate stream
|
||||
} else {
|
||||
ret = OGG_buffer_data(movie); // someone needs more data
|
||||
|
||||
if ( ret == 0 ) {
|
||||
mprintf(("Theora ERROR: End of file while searching for codec headers in '%s'!\n", lower_name));
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialize video decoder
|
||||
theora_decode_init(&movie->tstate, &movie->tinfo);
|
||||
|
||||
// and now for video stream error checking...
|
||||
if (movie->tinfo.pixelformat != OC_PF_420) {
|
||||
mprintf(("Theora ERROR: Only the yuv420p chroma is supported!\n"));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (movie->tinfo.offset_x || movie->tinfo.offset_y) {
|
||||
mprintf(("Theora ERROR: Player does not support frame offsets!\n"));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// initialize audio decoder, if there is audio
|
||||
if (movie->vorbis_p) {
|
||||
vorbis_synthesis_init(&movie->vstate, &movie->vinfo);
|
||||
vorbis_block_init(&movie->vstate, &movie->vblock);
|
||||
}
|
||||
|
||||
return movie;
|
||||
|
||||
|
||||
Error:
|
||||
theora_close(movie);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// play that funky music... err, movie!
|
||||
void theora_play(THEORAFILE *movie)
|
||||
{
|
||||
int i, j;
|
||||
bool stateflag = false;
|
||||
bool videobuf_ready = false;
|
||||
bool audiobuf_ready = false;
|
||||
double last_time = 0.0; // for frame skipper
|
||||
|
||||
if ( (movie == NULL) || !movie->theora_p )
|
||||
return;
|
||||
|
||||
// only OGL is supported
|
||||
if (gr_screen.mode != GR_OPENGL)
|
||||
return;
|
||||
|
||||
// open audio
|
||||
if (movie->vorbis_p)
|
||||
OGG_audio_init(&movie->vinfo);
|
||||
|
||||
// open video
|
||||
OGG_video_init(&movie->tinfo);
|
||||
|
||||
// on to the main decode loop. We assume in this example that audio
|
||||
// and video start roughly together, and don't begin playback until
|
||||
// we have a start frame for both. This is not necessarily a valid
|
||||
// assumption in Ogg A/V streams! It will always be true of the
|
||||
// example_encoder (and most streams) though.
|
||||
|
||||
while (playing) {
|
||||
// we want a video and audio frame ready to go at all times. If
|
||||
// we have to buffer incoming, buffer the compressed data (ie, let
|
||||
// ogg do the buffering)
|
||||
while ( movie->vorbis_p && !audiobuf_ready ) {
|
||||
int ret;
|
||||
float **pcm;
|
||||
|
||||
// if there's pending, decoded audio, grab it
|
||||
if ( (ret = vorbis_synthesis_pcmout(&movie->vstate, &pcm)) > 0 ) {
|
||||
int count = (audiobuf_fill / 2);
|
||||
int maxsamples = (audiofd_fragsize - audiobuf_fill) / 2 / movie->vinfo.channels;
|
||||
|
||||
for (i = 0; (i < ret) && (i < maxsamples); i++) {
|
||||
for (j = 0; j < movie->vinfo.channels; j++) {
|
||||
float val = pcm[j][i] * 32767.0f + 0.5f;
|
||||
|
||||
if (val > 32767.0f)
|
||||
val = 32767.0f;
|
||||
|
||||
if (val < -32768.0f)
|
||||
val = -32768.0f;
|
||||
|
||||
audiobuf[count++] = (short)val;
|
||||
}
|
||||
}
|
||||
|
||||
vorbis_synthesis_read(&movie->vstate, i);
|
||||
|
||||
audiobuf_fill += (i * movie->vinfo.channels * 2);
|
||||
|
||||
if (audiobuf_fill == audiofd_fragsize)
|
||||
audiobuf_ready = true;
|
||||
|
||||
if (movie->vstate.granulepos >= 0)
|
||||
audiobuf_granulepos = movie->vstate.granulepos - ret + i;
|
||||
else
|
||||
audiobuf_granulepos += i;
|
||||
} else {
|
||||
// no pending audio; is there a pending packet to decode?
|
||||
if ( ogg_stream_packetout(&movie->v_osstate, &movie->opacket) > 0 ) {
|
||||
if ( vorbis_synthesis(&movie->vblock, &movie->opacket) == 0 )
|
||||
vorbis_synthesis_blockin(&movie->vstate, &movie->vblock);
|
||||
}
|
||||
// we need more data; break out to suck in another page
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ( !videobuf_ready ) {
|
||||
// theora is one in, one out...
|
||||
if ( ogg_stream_packetout(&movie->t_osstate, &movie->opacket) <= 0 )
|
||||
break;
|
||||
|
||||
theora_decode_packetin(&movie->tstate, &movie->opacket);
|
||||
|
||||
videobuf_time = theora_granule_time(&movie->tstate, movie->tstate.granulepos);
|
||||
|
||||
double now_time = OGG_get_time();
|
||||
double delay = videobuf_time - OGG_get_time();
|
||||
|
||||
// if we are running slow then skip the frame, otherwise to go into ready mode
|
||||
if ( (delay >= 0.0) || (now_time - last_time >= 1.0) )
|
||||
videobuf_ready = true;
|
||||
}
|
||||
|
||||
if ( !videobuf_ready && (movie->vorbis_p && !audiobuf_ready) && cfeof(movie->cfp) )
|
||||
break;
|
||||
|
||||
if ( !videobuf_ready || (movie->vorbis_p && !audiobuf_ready) ) {
|
||||
// no data yet for somebody. Grab another page
|
||||
OGG_buffer_data(movie);
|
||||
|
||||
while (ogg_sync_pageout(&movie->osyncstate, &movie->opage) > 0)
|
||||
OGG_queue_page(movie);
|
||||
}
|
||||
|
||||
// If playback has begun, top audio buffer off immediately.
|
||||
if ( stateflag )
|
||||
OGG_audio_write(&movie->vinfo, &audiobuf_ready);
|
||||
|
||||
// are we at or past time for this video frame?
|
||||
if ( stateflag && videobuf_ready && (videobuf_time <= OGG_get_time()) ) {
|
||||
OGG_video_draw(&movie->tstate);
|
||||
last_time = OGG_get_time();
|
||||
videobuf_ready = false;
|
||||
}
|
||||
|
||||
// if our buffers either don't exist or are ready to go, we can begin playback
|
||||
if ( videobuf_ready && (audiobuf_ready || !movie->vorbis_p) )
|
||||
stateflag = true;
|
||||
|
||||
// bail if we run into eof
|
||||
// if ( cfeof(movie->cfp) )
|
||||
// break;
|
||||
|
||||
if (videobuf_ready)
|
||||
OGG_timer_do_wait();
|
||||
}
|
||||
|
||||
// tear it all down
|
||||
OGG_audio_close();
|
||||
OGG_video_close();
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
|
||||
#ifndef _OGGPLAYER_H
|
||||
#define _OGGPLAYER_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include "theora/theora.h"
|
||||
#include "vorbis/codec.h"
|
||||
|
||||
struct CFILE;
|
||||
|
||||
// structure for maintaining info on a THEORAFILE stream
|
||||
typedef struct THEORAFILE
|
||||
{
|
||||
CFILE *cfp;
|
||||
ubyte theora_p;
|
||||
ubyte vorbis_p;
|
||||
|
||||
ogg_sync_state osyncstate;
|
||||
ogg_page opage;
|
||||
ogg_packet opacket;
|
||||
ogg_stream_state v_osstate;
|
||||
ogg_stream_state t_osstate;
|
||||
|
||||
theora_info tinfo;
|
||||
theora_comment tcomment;
|
||||
theora_state tstate;
|
||||
|
||||
vorbis_info vinfo;
|
||||
vorbis_dsp_state vstate;
|
||||
vorbis_block vblock;
|
||||
vorbis_comment vcomment;
|
||||
} THEORAFILE;
|
||||
|
||||
void theora_play(THEORAFILE *movie);
|
||||
THEORAFILE *theora_open(char *filename);
|
||||
void theora_close(THEORAFILE *movie);
|
||||
|
||||
#endif
|
||||
@@ -1,501 +0,0 @@
|
||||
|
||||
#include "ddsutils/ddsutils.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "osapi/osregistry.h"
|
||||
|
||||
|
||||
/* Currently supported formats:
|
||||
* DXT1a (compressed)
|
||||
* DXT1c (compressed)
|
||||
* DXT3 (compressed)
|
||||
* DXT5 (compressed)
|
||||
* uncompressed 1555 (16-bit, 1-bit being alpha)
|
||||
* uncompressed 8888 (32-bit)
|
||||
* uncompressed 888 (24-bit, no alpha)
|
||||
* paletted 8-bit (256 colors)
|
||||
*/
|
||||
|
||||
|
||||
int Texture_compression_available = 0;
|
||||
int Use_compressed_textures = 0;
|
||||
|
||||
// power of two check, to verify that a given DDS will always be usable since
|
||||
// some may not be power-of-2
|
||||
static inline int is_power_of_two(int w, int h)
|
||||
{
|
||||
return ( (w && !(w & (w-1))) && (h && !(h & (h-1))) );
|
||||
}
|
||||
|
||||
|
||||
int dds_read_header(char *filename, CFILE *img_cfp, int *width, int *height, int *bpp, int *compression_type, int *levels, int *size, ubyte *palette)
|
||||
{
|
||||
DDSURFACEDESC2 dds_header;
|
||||
int code = 0;
|
||||
CFILE *ddsfile;
|
||||
char real_name[MAX_FILENAME_LEN];
|
||||
int retval = DDS_ERROR_NONE;
|
||||
int ct = DDS_UNCOMPRESSED;
|
||||
int bits = 0;
|
||||
int i, trash, is_cubemap = 0;
|
||||
int d_width = 0, d_height = 0, d_depth = 0, d_size = 0;
|
||||
|
||||
|
||||
if (img_cfp == NULL) {
|
||||
// this better not happen.. ever
|
||||
Assert(filename != NULL);
|
||||
|
||||
// make sure there is an extension
|
||||
strcpy_s(real_name, filename);
|
||||
char *p = strchr(real_name, '.');
|
||||
if (p) { *p=0; }
|
||||
strcat_s(real_name, ".dds");
|
||||
|
||||
// try to open the file
|
||||
ddsfile = cfopen(real_name, "rb");
|
||||
|
||||
// file not found
|
||||
if (ddsfile == NULL)
|
||||
return DDS_ERROR_INVALID_FILENAME;
|
||||
} else {
|
||||
ddsfile = img_cfp;
|
||||
}
|
||||
|
||||
// read the code
|
||||
code = cfread_int(ddsfile);
|
||||
|
||||
// check it
|
||||
if (code != DDS_FILECODE) {
|
||||
retval = DDS_ERROR_BAD_HEADER;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// read header variables
|
||||
dds_header.dwSize = cfread_uint(ddsfile);
|
||||
dds_header.dwFlags = cfread_uint(ddsfile);
|
||||
dds_header.dwHeight = cfread_uint(ddsfile);
|
||||
dds_header.dwWidth = cfread_uint(ddsfile);
|
||||
dds_header.dwPitchOrLinearSize = cfread_uint(ddsfile);
|
||||
dds_header.dwDepth = cfread_uint(ddsfile);
|
||||
dds_header.dwMipMapCount = cfread_uint(ddsfile);
|
||||
|
||||
// skip over the crap we don't care about
|
||||
for (i = 0; i < 11; i++)
|
||||
trash = cfread_uint(ddsfile);
|
||||
|
||||
dds_header.ddpfPixelFormat.dwSize = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwFlags = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwFourCC = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwRGBBitCount = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwRBitMask = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwGBitMask = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwBBitMask = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwRGBAlphaBitMask = cfread_uint(ddsfile);
|
||||
|
||||
dds_header.ddsCaps.dwCaps1 = cfread_uint(ddsfile);
|
||||
dds_header.ddsCaps.dwCaps2 = cfread_uint(ddsfile);
|
||||
|
||||
// sanity
|
||||
if (dds_header.dwDepth == 0)
|
||||
dds_header.dwDepth = 1;
|
||||
|
||||
if (dds_header.dwMipMapCount < 1)
|
||||
dds_header.dwMipMapCount = 1;
|
||||
|
||||
d_width = dds_header.dwWidth;
|
||||
d_height = dds_header.dwHeight;
|
||||
d_depth = dds_header.dwDepth;
|
||||
|
||||
// calculate the type and size of the data
|
||||
if (dds_header.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
|
||||
// did I mention lately that I hate Microsoft?
|
||||
// this is here to fix the situation where Microsoft doesn't follow their own docs
|
||||
if ( dds_header.dwPitchOrLinearSize <= 0 ) {
|
||||
// calculate the block size, mult by 8 for DXT1, 16 for DXT3 & 5
|
||||
d_size = ((dds_header.dwWidth + 3)/4) * ((dds_header.dwHeight + 3)/4) * ((dds_header.dwDepth + 3)/4) * ((dds_header.ddpfPixelFormat.dwFourCC == FOURCC_DXT1) ? 8 : 16);
|
||||
} else {
|
||||
d_size = dds_header.dwPitchOrLinearSize;
|
||||
}
|
||||
|
||||
// if we have mipmaps then compute them into the final size too
|
||||
for (i = 1; i < (int)dds_header.dwMipMapCount; i++) {
|
||||
// reduce size by half for the next pass
|
||||
d_width /= 2;
|
||||
d_height /= 2;
|
||||
|
||||
if (d_width <= 0)
|
||||
d_width = 1;
|
||||
|
||||
if (d_height <= 0)
|
||||
d_height = 1;
|
||||
|
||||
// size of data block (4x4)
|
||||
d_size += ((d_width + 3) / 4) * ((d_height + 3) / 4) * ((dds_header.ddpfPixelFormat.dwFourCC == FOURCC_DXT1) ? 8 : 16);
|
||||
}
|
||||
|
||||
if ( dds_header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP ) {
|
||||
if ( !(dds_header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) ) {
|
||||
retval = DDS_ERROR_CUBEMAP_FACES;
|
||||
ct = DDS_DXT_INVALID;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// it's a valid cubemap, probably
|
||||
is_cubemap = 1;
|
||||
|
||||
// the previously computed size is just per face, mult by 6 for full size
|
||||
d_size *= 6;
|
||||
}
|
||||
|
||||
Assert( d_size > 0 );
|
||||
*size = d_size;
|
||||
|
||||
switch (dds_header.ddpfPixelFormat.dwFourCC) {
|
||||
case FOURCC_DXT1:
|
||||
bits = 24;
|
||||
ct = (is_cubemap) ? DDS_CUBEMAP_DXT1 : DDS_DXT1;
|
||||
break;
|
||||
|
||||
case FOURCC_DXT3:
|
||||
bits = 32;
|
||||
ct = (is_cubemap) ? DDS_CUBEMAP_DXT3 : DDS_DXT3;
|
||||
break;
|
||||
|
||||
case FOURCC_DXT5:
|
||||
bits = 32;
|
||||
ct = (is_cubemap) ? DDS_CUBEMAP_DXT5 : DDS_DXT5;
|
||||
break;
|
||||
|
||||
// dxt2 and dxt4 aren't supported
|
||||
case FOURCC_DXT2:
|
||||
case FOURCC_DXT4:
|
||||
retval = DDS_ERROR_UNSUPPORTED;
|
||||
ct = DDS_DXT_INVALID;
|
||||
goto Done;
|
||||
break;
|
||||
|
||||
// none of the above
|
||||
default:
|
||||
retval = DDS_ERROR_INVALID_FORMAT;
|
||||
ct = DDS_DXT_INVALID;
|
||||
goto Done;
|
||||
break;
|
||||
}
|
||||
} else if ( dds_header.ddpfPixelFormat.dwFlags & (DDPF_RGB | DDPF_PALETTEINDEXED8) ) {
|
||||
d_size += d_width * d_height * d_depth * (dds_header.ddpfPixelFormat.dwRGBBitCount / 8);
|
||||
|
||||
// calculate full data size for all mipmap levels
|
||||
for (i = 1; i < (int)dds_header.dwMipMapCount; i++) {
|
||||
d_width /= 2;
|
||||
d_height /= 2;
|
||||
d_depth /= 2;
|
||||
|
||||
if (d_width < 1)
|
||||
d_width = 1;
|
||||
|
||||
if (d_height < 1)
|
||||
d_height = 1;
|
||||
|
||||
if (d_depth < 1)
|
||||
d_depth = 1;
|
||||
|
||||
d_size += d_width * d_height * d_depth * (dds_header.ddpfPixelFormat.dwRGBBitCount / 8);
|
||||
}
|
||||
|
||||
Assert( d_size > 0 );
|
||||
|
||||
if ( dds_header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP ) {
|
||||
if ( !(dds_header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) ) {
|
||||
retval = DDS_ERROR_CUBEMAP_FACES;
|
||||
ct = DDS_DXT_INVALID;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// it's a valid cubemap, probably
|
||||
is_cubemap = 1;
|
||||
|
||||
// the previously computed size is just per face, mult by 6 for full size
|
||||
d_size *= 6;
|
||||
}
|
||||
|
||||
*size = d_size;
|
||||
|
||||
bits = dds_header.ddpfPixelFormat.dwRGBBitCount;
|
||||
ct = (is_cubemap) ? DDS_CUBEMAP_UNCOMPRESSED : DDS_UNCOMPRESSED;
|
||||
} else {
|
||||
// it's not a readable format
|
||||
retval = DDS_ERROR_INVALID_FORMAT;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// we don't support compressed, non-power-of-2 images
|
||||
if ( (ct != DDS_UNCOMPRESSED) && (!is_power_of_two(dds_header.dwWidth, dds_header.dwHeight)) ) {
|
||||
retval = DDS_ERROR_NON_POWER_OF_2;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// make sure that the video card can handle compressed textures before using them
|
||||
if ( !Use_compressed_textures && (ct != DDS_UNCOMPRESSED) && (ct != DDS_DXT_INVALID) ) {
|
||||
retval = DDS_ERROR_NO_COMPRESSION;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// stuff important info
|
||||
if (bpp)
|
||||
*bpp = bits;
|
||||
|
||||
if (compression_type)
|
||||
*compression_type = ct;
|
||||
|
||||
if (width)
|
||||
*width = dds_header.dwWidth;
|
||||
|
||||
if (height)
|
||||
*height = dds_header.dwHeight;
|
||||
|
||||
if (levels)
|
||||
*levels = dds_header.dwMipMapCount;
|
||||
|
||||
if (palette && (bits == 8)) {
|
||||
cfseek(ddsfile, DDS_OFFSET, CF_SEEK_SET);
|
||||
cfread(palette, 1, 1024, ddsfile);
|
||||
}
|
||||
|
||||
|
||||
Done:
|
||||
if (img_cfp == NULL) {
|
||||
// close file and return
|
||||
cfclose(ddsfile);
|
||||
ddsfile = NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
//reads pixel info from a dds file
|
||||
int dds_read_bitmap(char *filename, ubyte *data, ubyte *bpp, int cf_type)
|
||||
{
|
||||
int retval;
|
||||
int w,h,ct,lvl;
|
||||
int size = 0, bits = 0;
|
||||
CFILE *cfp;
|
||||
char real_name[MAX_FILENAME_LEN];
|
||||
|
||||
// this better not happen.. ever
|
||||
Assert(filename != NULL);
|
||||
|
||||
// make sure there is an extension
|
||||
strcpy_s(real_name, filename);
|
||||
char *p = strchr(real_name, '.');
|
||||
if (p) { *p = 0; }
|
||||
strcat_s(real_name, ".dds");
|
||||
|
||||
// open it up and go to the data section
|
||||
cfp = cfopen(real_name, "rb", CFILE_NORMAL, cf_type);
|
||||
|
||||
// just in case
|
||||
if (cfp == NULL)
|
||||
return DDS_ERROR_INVALID_FILENAME;
|
||||
|
||||
// read the header -- if its at this stage, it should be legal.
|
||||
retval = dds_read_header(real_name, cfp, &w, &h, &bits, &ct, &lvl, &size);
|
||||
Assert(retval == DDS_ERROR_NONE);
|
||||
|
||||
// this really shouldn't be needed but better safe than sorry
|
||||
if (retval != DDS_ERROR_NONE) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
cfseek(cfp, DDS_OFFSET, CF_SEEK_SET);
|
||||
|
||||
// read in the data
|
||||
cfread(data, 1, size, cfp);
|
||||
|
||||
if (bpp)
|
||||
*bpp = (ubyte)bits;
|
||||
|
||||
// we look done here
|
||||
cfclose(cfp);
|
||||
|
||||
return DDS_ERROR_NONE;
|
||||
}
|
||||
|
||||
// save some image data as a DDS image
|
||||
// NOTE: we only support, uncompressed, 24-bit RGB and 32-bit RGBA images here!!
|
||||
void dds_save_image(int width, int height, int bpp, int num_mipmaps, ubyte *data, int cubemap, char *filename)
|
||||
{
|
||||
DDSURFACEDESC2 dds_header;
|
||||
char real_filename[MAX_FILENAME_LEN];
|
||||
|
||||
if (data == NULL) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
// header size check
|
||||
if (sizeof(DDSURFACEDESC2) != 124) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// not that that's out of the way we can get down to business, constructing a sane filename
|
||||
memset( &real_filename, 0, sizeof(real_filename) );
|
||||
|
||||
int count = os_config_read_uint(NULL, "ImageExportNum", 0);
|
||||
|
||||
if (count > 999)
|
||||
count = 0;
|
||||
|
||||
if (filename == NULL) {
|
||||
if (cubemap) {
|
||||
sprintf(real_filename, "cubemap%.3d.dds", count++);
|
||||
} else {
|
||||
sprintf(real_filename, "image%.3d.dds", count++);
|
||||
}
|
||||
os_config_write_uint(NULL, "ImageExportNum", count);
|
||||
} else {
|
||||
Assert( strlen(filename) < MAX_FILENAME_LEN-5 );
|
||||
|
||||
strcpy_s(real_filename, filename);
|
||||
|
||||
char *p = strchr(real_filename, '.');
|
||||
if (p) { *p = 0; }
|
||||
|
||||
strcat_s(real_filename, ".dds");
|
||||
}
|
||||
|
||||
CFILE *image = cfopen( real_filename, "wb", CFILE_NORMAL, CF_TYPE_CACHE );
|
||||
|
||||
if (image == NULL) {
|
||||
mprintf(("Unable to open DDS image for saving!!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (num_mipmaps < 1)
|
||||
num_mipmaps = 1;
|
||||
|
||||
// we have a filename and file handle, so now lets create our DDS header...
|
||||
memset( &dds_header, 0, sizeof(DDSURFACEDESC2) );
|
||||
|
||||
uint flags = (DDSD_CAPS | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT);
|
||||
uint pixel_flags = DDPF_RGB;
|
||||
uint caps1 = DDSCAPS_TEXTURE;
|
||||
uint caps2 = 0;
|
||||
|
||||
if (bpp == 32) {
|
||||
pixel_flags |= DDPF_ALPHAPIXELS;
|
||||
}
|
||||
|
||||
if (num_mipmaps > 1) {
|
||||
flags |= DDSD_MIPMAPCOUNT;
|
||||
caps1 |= (DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
|
||||
}
|
||||
|
||||
if (cubemap) {
|
||||
caps1 |= DDSCAPS_COMPLEX;
|
||||
caps2 |= (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES);
|
||||
}
|
||||
|
||||
dds_header.dwSize = 124;
|
||||
dds_header.dwFlags = flags;
|
||||
dds_header.dwHeight = height;
|
||||
dds_header.dwWidth = width;
|
||||
dds_header.dwPitchOrLinearSize = (width * (bpp >> 3));
|
||||
dds_header.dwDepth = 0;
|
||||
dds_header.dwMipMapCount = num_mipmaps;
|
||||
|
||||
dds_header.ddpfPixelFormat.dwSize = 32;
|
||||
dds_header.ddpfPixelFormat.dwFlags = pixel_flags;
|
||||
dds_header.ddpfPixelFormat.dwFourCC = 0;
|
||||
dds_header.ddpfPixelFormat.dwRGBBitCount = bpp;
|
||||
dds_header.ddpfPixelFormat.dwRBitMask = 0x00ff0000;
|
||||
dds_header.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
|
||||
dds_header.ddpfPixelFormat.dwBBitMask = 0x000000ff;
|
||||
dds_header.ddpfPixelFormat.dwRGBAlphaBitMask = (bpp == 32) ? 0xff000000 : 0x00000000;
|
||||
|
||||
dds_header.ddsCaps.dwCaps1 = caps1;
|
||||
dds_header.ddsCaps.dwCaps2 = caps2;
|
||||
|
||||
// now save it all...
|
||||
uint dds_id = DDS_FILECODE;
|
||||
cfwrite(&dds_id, 1, 4, image);
|
||||
cfwrite(&dds_header, 1, sizeof(DDSURFACEDESC2), image);
|
||||
|
||||
int faces = (cubemap) ? 6 : 1;
|
||||
int f_width = width;
|
||||
int f_height = height;
|
||||
int f_size = 0, f_offset = 0;
|
||||
|
||||
// cubemaps are written:
|
||||
// face 1
|
||||
// all face 1 mipmaps
|
||||
// face 2
|
||||
// all face 2 mipmaps
|
||||
// ... etc.
|
||||
|
||||
for (int i = 0; i < faces; i++) {
|
||||
for (int j = 0; j < num_mipmaps; j++) {
|
||||
f_size = (f_width * f_height * (bpp >> 3));
|
||||
|
||||
cfwrite(data + f_offset, 1, f_size, image);
|
||||
|
||||
// increase offset for next mipmap level
|
||||
f_offset += f_size;
|
||||
|
||||
// half width and height for next mipmap level
|
||||
f_width /= 2;
|
||||
f_height /= 2;
|
||||
|
||||
if (f_width < 1)
|
||||
f_width = 1;
|
||||
|
||||
if (f_height < 1)
|
||||
f_height = 1;
|
||||
}
|
||||
|
||||
// reset width and height to original values for the next face
|
||||
f_width = width;
|
||||
f_height = height;
|
||||
}
|
||||
|
||||
// done! now lets go get something to eat...
|
||||
cfclose(image);
|
||||
}
|
||||
|
||||
|
||||
// returns string representation of DDS_** error code
|
||||
const char *dds_error_string(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case DDS_ERROR_NONE:
|
||||
return "No error";
|
||||
|
||||
case DDS_ERROR_INVALID_FILENAME:
|
||||
return "File not found";
|
||||
|
||||
case DDS_ERROR_BAD_HEADER:
|
||||
return "Filecode did not equal \"DDS \"";
|
||||
|
||||
case DDS_ERROR_INVALID_FORMAT:
|
||||
return "DDS was in an unsupported/unknown format";
|
||||
|
||||
case DDS_ERROR_UNSUPPORTED:
|
||||
return "DDS format was known but is not supported (ie. DXT2/DXT4)";
|
||||
|
||||
case DDS_ERROR_NO_COMPRESSION:
|
||||
return "DDS is compressed but compression support is not enabled";
|
||||
|
||||
case DDS_ERROR_NON_POWER_OF_2:
|
||||
return "Cannot load DDS if not power-of-2";
|
||||
|
||||
case DDS_ERROR_CUBEMAP_FACES:
|
||||
return "Cubemaps must have all 6 faces";
|
||||
|
||||
default:
|
||||
return "Abort, retry, fail?";
|
||||
}
|
||||
|
||||
//get a warning otherwise
|
||||
return "Abort, retry, fail?";
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
//header file to load .dds files
|
||||
//these use dxtc texture compression
|
||||
|
||||
#ifndef __DDS_H
|
||||
#define __DDS_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
#define DDS_ERROR_NONE 0 // everything went fine
|
||||
#define DDS_ERROR_INVALID_FILENAME 1 // bad or missing file
|
||||
#define DDS_ERROR_UNSUPPORTED 2 // a known format but one we don't support
|
||||
#define DDS_ERROR_INVALID_FORMAT 3 // format that's not supported
|
||||
#define DDS_ERROR_BAD_HEADER 4 // header was not "DDS "
|
||||
#define DDS_ERROR_NO_COMPRESSION 5 // file is compressed, compression isn't supported
|
||||
#define DDS_ERROR_NON_POWER_OF_2 6 // file is not a power of 2 in dimensions
|
||||
#define DDS_ERROR_CUBEMAP_FACES 7 // file is a cubemap, but doesn't have all six faces
|
||||
|
||||
|
||||
#define DDS_DXT_INVALID -1
|
||||
#define DDS_UNCOMPRESSED 0
|
||||
#define DDS_DXT1 1
|
||||
#define DDS_DXT3 3
|
||||
#define DDS_DXT5 5
|
||||
#define DDS_CUBEMAP_UNCOMPRESSED 10
|
||||
#define DDS_CUBEMAP_DXT1 11
|
||||
#define DDS_CUBEMAP_DXT3 13
|
||||
#define DDS_CUBEMAP_DXT5 15
|
||||
|
||||
#ifndef MAKEFOURCC
|
||||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||
((uint)(ubyte)(ch0) | ((uint)(ubyte)(ch1) << 8) | \
|
||||
((uint)(ubyte)(ch2) << 16) | ((uint)(ubyte)(ch3) << 24 ))
|
||||
#endif //defined(MAKEFOURCC)
|
||||
|
||||
// FOURCC codes for DX compressed-texture pixel formats
|
||||
#define FOURCC_DXT1 (MAKEFOURCC('D','X','T','1'))
|
||||
#define FOURCC_DXT2 (MAKEFOURCC('D','X','T','2'))
|
||||
#define FOURCC_DXT3 (MAKEFOURCC('D','X','T','3'))
|
||||
#define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4'))
|
||||
#define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5'))
|
||||
|
||||
#define DDS_FILECODE 0x20534444 // "DDS " in file
|
||||
|
||||
// DDS format stuff ...
|
||||
#define DDSD_LINEARSIZE 0x00080000
|
||||
#define DDSD_PITCH 0x00000008
|
||||
#define DDPF_ALPHAPIXELS 0x00000001
|
||||
#define DDPF_FOURCC 0x00000004
|
||||
#define DDPF_PALETTEINDEXED4 0x00000008
|
||||
#define DDPF_PALETTEINDEXEDTO8 0x00000010
|
||||
#define DDPF_PALETTEINDEXED8 0x00000020
|
||||
#define DDPF_RGB 0x00000040
|
||||
#define DDSD_PIXELFORMAT 0x00001000
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_CAPS 0x00000001
|
||||
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||
|
||||
#define DDSCAPS_COMPLEX 0x00000008
|
||||
#define DDSCAPS_PRIMARYSURFACE 0x00000200
|
||||
#define DDSCAPS_MIPMAP 0x00400000
|
||||
#define DDSCAPS_TEXTURE 0x00001000
|
||||
|
||||
#define DDSCAPS2_CUBEMAP 0x00000200
|
||||
#define DDSCAPS2_VOLUME 0x00200000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
|
||||
|
||||
#define DDSCAPS2_CUBEMAP_ALLFACES ( DDSCAPS2_CUBEMAP_POSITIVEX | \
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEX | \
|
||||
DDSCAPS2_CUBEMAP_POSITIVEY | \
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEY | \
|
||||
DDSCAPS2_CUBEMAP_POSITIVEZ | \
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEZ )
|
||||
|
||||
#pragma pack(1)
|
||||
// these structures are the headers for a dds file
|
||||
/*typedef struct _DDPIXELFORMAT {
|
||||
uint dwSize;
|
||||
uint dwFlags;
|
||||
uint dwFourCC;
|
||||
uint dwRGBBitCount;
|
||||
uint dwRBitMask;
|
||||
uint dwGBitMask;
|
||||
uint dwBBitMask;
|
||||
uint dwRGBAlphaBitMask;
|
||||
} DDPIXELFORMAT;
|
||||
|
||||
typedef struct _DDSCAPS2
|
||||
{
|
||||
uint dwCaps1;
|
||||
uint dwCaps2;
|
||||
uint Reserved[2];
|
||||
} DDSCAPS2;*/
|
||||
|
||||
typedef struct _DDSURFACEDESC2
|
||||
{
|
||||
uint dwSize; // size of the DDSURFACEDESC structure
|
||||
uint dwFlags; // determines what fields are valid
|
||||
uint dwHeight; // height of surface to be created
|
||||
uint dwWidth; // width of input surface
|
||||
uint dwPitchOrLinearSize;
|
||||
uint dwDepth;
|
||||
uint dwMipMapCount;
|
||||
uint dwReserved1[11];
|
||||
|
||||
struct {
|
||||
uint dwSize;
|
||||
uint dwFlags;
|
||||
uint dwFourCC;
|
||||
uint dwRGBBitCount;
|
||||
uint dwRBitMask;
|
||||
uint dwGBitMask;
|
||||
uint dwBBitMask;
|
||||
uint dwRGBAlphaBitMask;
|
||||
} ddpfPixelFormat;
|
||||
|
||||
struct {
|
||||
uint dwCaps1;
|
||||
uint dwCaps2;
|
||||
uint Reserved[2];
|
||||
} ddsCaps;
|
||||
|
||||
// DDPIXELFORMAT ddpfPixelFormat;
|
||||
// DDSCAPS2 ddsCaps; // direct draw surface capabilities
|
||||
uint dwReserved2;
|
||||
} DDSURFACEDESC2;
|
||||
#pragma pack()
|
||||
|
||||
#define DDS_OFFSET 4+sizeof(DDSURFACEDESC2) //place where the data starts -- should be 128
|
||||
|
||||
//reads a dds header
|
||||
//returns one of the error values
|
||||
//'compression_type' comes back as one of the DDS_DXTC* defines
|
||||
int dds_read_header(char *filename, CFILE *img_cfp = NULL, int *width = 0, int *height = 0, int *bpp = 0, int *compression_type = 0, int *levels = 0, int *size = 0, ubyte *palette = NULL);
|
||||
|
||||
//reads bitmap
|
||||
//size of the data it stored in size
|
||||
int dds_read_bitmap(char *filename, ubyte *data, ubyte *bpp = NULL, int cf_type = CF_TYPE_ANY);
|
||||
|
||||
// writes a DDS file using given data
|
||||
void dds_save_image(int width, int height, int bpp, int num_mipmaps, ubyte *data = NULL, int cubemap = 0, char *filename = NULL);
|
||||
|
||||
//returns a string from a DDS error code
|
||||
const char *dds_error_string(int code);
|
||||
|
||||
extern int Texture_compression_available;
|
||||
extern int Use_compressed_textures;
|
||||
|
||||
#endif //__DDS_H
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _DEBRIS_H
|
||||
#define _DEBRIS_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct object;
|
||||
struct CFILE;
|
||||
|
||||
#define MAX_DEBRIS_ARCS 8 // Must be less than MAX_ARC_EFFECTS in model.h
|
||||
|
||||
typedef struct debris {
|
||||
debris *next, *prev; // used for a linked list of the hull debris chunks
|
||||
int flags; // See DEBRIS_??? defines
|
||||
int source_objnum; // What object this came from
|
||||
int source_sig; // Signature of the source object
|
||||
int ship_info_index; // Ship info index of the ship type debris came from
|
||||
int team; // Team of the ship where the debris came from
|
||||
int objnum; // What object this is linked to
|
||||
float lifeleft; // When 0 or less object dies
|
||||
int must_survive_until; //WMC - timestamp of earliest point that it can be murthered.
|
||||
int model_num; // What model this uses
|
||||
int submodel_num; // What submodel this uses
|
||||
int next_fireball; // When to start a fireball
|
||||
int is_hull; // indicates a large hull chunk of debris
|
||||
int species; // What species this is from. -1 if don't care.
|
||||
int fire_timeout; // timestamp that holds time for fireballs to stop appearing
|
||||
int sound_delay; // timestamp to signal when sound should start
|
||||
fix time_started; // time when debris was created
|
||||
int next_distance_check; // timestamp to determine whether to delete this piece of debris.
|
||||
|
||||
vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
|
||||
int arc_timestamp[MAX_DEBRIS_ARCS]; // When this times out, the spark goes away. -1 is not used
|
||||
int arc_frequency; // Starts at 0, gets bigger
|
||||
int parent_alt_name;
|
||||
float damage_mult;
|
||||
|
||||
} debris;
|
||||
|
||||
|
||||
// flags for debris pieces
|
||||
#define DEBRIS_USED (1<<0)
|
||||
#define DEBRIS_EXPIRE (1<<1) // debris can expire (ie hull chunks from small ships)
|
||||
|
||||
|
||||
#define MAX_DEBRIS_PIECES 64
|
||||
|
||||
extern debris Debris[MAX_DEBRIS_PIECES];
|
||||
|
||||
extern int Num_debris_pieces;
|
||||
|
||||
struct collision_info_struct;
|
||||
|
||||
void debris_init();
|
||||
void debris_render( object * obj );
|
||||
void debris_delete( object * obj );
|
||||
void debris_process_pre( object * obj, float frame_time);
|
||||
void debris_process_post( object * obj, float frame_time);
|
||||
object *debris_create( object * source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force );
|
||||
int debris_check_collision( object * obj, object * other_obj, vec3d * hitpos, collision_info_struct *debris_hit_info=NULL );
|
||||
void debris_hit( object * debris_obj, object * other_obj, vec3d * hitpos, float damage );
|
||||
int debris_get_team(object *objp);
|
||||
void debris_clear_expired_flag(debris *db);
|
||||
|
||||
#endif // _DEBRIS_H
|
||||
@@ -1,718 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/font.h"
|
||||
#include "io/timer.h"
|
||||
#include "io/key.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
|
||||
|
||||
#define MAX_COMMANDS 300
|
||||
|
||||
static int Num_debug_commands = 0;
|
||||
static debug_command *Debug_command[MAX_COMMANDS];
|
||||
|
||||
|
||||
debug_command::debug_command(char *_name, char *_help, void (*_func)() )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( Num_debug_commands >= MAX_COMMANDS ) {
|
||||
Int3(); // Too many debug console commands!! Increase MAX_COMMANDS!!
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
int ret = stricmp( Debug_command[i]->name, _name );
|
||||
|
||||
if ( ret == 0) {
|
||||
Int3(); // This debug console command already exists!!!!
|
||||
return;
|
||||
} else if ( ret > 0 ) {
|
||||
break; // Insert it here
|
||||
|
||||
} else if ( ret < 0 ) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
if ( i < Num_debug_commands ) {
|
||||
// Insert it at element i
|
||||
int j;
|
||||
for (j=Num_debug_commands; j>i; j-- ) {
|
||||
Debug_command[j] = Debug_command[j-1];
|
||||
}
|
||||
Debug_command[i] = this;
|
||||
Num_debug_commands++;
|
||||
} else {
|
||||
Debug_command[Num_debug_commands] = this;
|
||||
Num_debug_commands++;
|
||||
}
|
||||
|
||||
name = _name;
|
||||
help = _help;
|
||||
func = _func;
|
||||
}
|
||||
|
||||
// some global variables
|
||||
int Dc_command; // If this is set, then process the command
|
||||
int Dc_help; // If this is set, then print out the help text in the form, "usage: ... \nLong description\n" );
|
||||
int Dc_status; // If this is set, then print out the current status of the command.
|
||||
char *Dc_arg; // The (lowercased) string value of the argument retrieved from dc_arg
|
||||
char *Dc_arg_org; // Dc_arg before it got converted to lowercase
|
||||
uint Dc_arg_type; // The type of dc_arg.
|
||||
char *Dc_command_line; // The rest of the command line, from the end of the last processed arg on.
|
||||
int Dc_arg_int; // If Dc_arg_type & ARG_INT is set, then this is the value
|
||||
float Dc_arg_float; // If Dc_arg_type & ARG_FLOAT is set, then this is the value
|
||||
|
||||
int scroll_times = 0; // incremented each time display scrolls
|
||||
|
||||
int debug_inited = 0;
|
||||
|
||||
#define DROWS 25
|
||||
#define DCOLS 80
|
||||
|
||||
int debug_x=0, debug_y=0;
|
||||
char debug_text[DROWS][DCOLS];
|
||||
|
||||
|
||||
static char command_line[1024];
|
||||
static int command_line_pos = 0;
|
||||
#define DEBUG_HISTORY 16
|
||||
static char oldcommand_line[DEBUG_HISTORY][1024];
|
||||
int last_oldcommand=-1;
|
||||
int command_scroll = 0;
|
||||
|
||||
///=========================== SCANNER =======================
|
||||
typedef enum {
|
||||
LETTER, QUOTE, SPECIAL, EOF_CODE, DIGIT
|
||||
} CHAR_CODE;
|
||||
|
||||
typedef enum {
|
||||
NO_TOKEN, IDENTIFIER, NUMBER, STRING
|
||||
} TOKEN_CODE;
|
||||
|
||||
|
||||
#define MAX_TOKEN_STRING_LENGTH 128
|
||||
|
||||
char scanner_ch;
|
||||
TOKEN_CODE scanner_token;
|
||||
|
||||
char scanner_token_string[MAX_TOKEN_STRING_LENGTH];
|
||||
char scanner_word_string[MAX_TOKEN_STRING_LENGTH];
|
||||
char * scanner_bufferp = "";
|
||||
char * scanner_tokenp = scanner_token_string;
|
||||
|
||||
CHAR_CODE scanner_char_table[256];
|
||||
|
||||
#define scanner_char_code(x) scanner_char_table[x]
|
||||
|
||||
void scanner_get_char()
|
||||
{
|
||||
if ( *scanner_bufferp == '\0' ) {
|
||||
scanner_ch = 0;
|
||||
return;
|
||||
}
|
||||
scanner_ch = *scanner_bufferp++;
|
||||
}
|
||||
|
||||
void scanner_init()
|
||||
{
|
||||
int ch;
|
||||
for (ch=0; ch<256; ++ch) scanner_char_table[ch] = SPECIAL;
|
||||
for (ch='0'; ch<='9'; ++ch) scanner_char_table[ch] = DIGIT;
|
||||
for (ch='A'; ch<='Z'; ++ch) scanner_char_table[ch] = LETTER;
|
||||
for (ch='a'; ch<='z'; ++ch) scanner_char_table[ch] = LETTER;
|
||||
|
||||
scanner_char_table['.'] = DIGIT;
|
||||
scanner_char_table['-'] = DIGIT;
|
||||
scanner_char_table['+'] = DIGIT;
|
||||
|
||||
scanner_char_table['_'] = LETTER;
|
||||
scanner_char_table[34] = QUOTE;
|
||||
scanner_char_table[0] = EOF_CODE;
|
||||
|
||||
|
||||
scanner_char_table[':'] = LETTER;
|
||||
scanner_char_table['\\'] = LETTER;
|
||||
|
||||
scanner_ch = 0;
|
||||
}
|
||||
|
||||
|
||||
void scanner_skip_blanks()
|
||||
{
|
||||
while( (scanner_ch ==' ') || (scanner_ch =='\t') )
|
||||
scanner_get_char();
|
||||
}
|
||||
|
||||
|
||||
void scanner_downshift_word()
|
||||
{
|
||||
int offset = 'a' - 'A';
|
||||
char * tp;
|
||||
|
||||
strcpy_s( scanner_word_string, scanner_token_string );
|
||||
|
||||
tp = scanner_word_string;
|
||||
do {
|
||||
*tp = (char)((*tp>='A') && (*tp <='Z') ? *tp + offset : *tp) ;
|
||||
tp++;
|
||||
} while (*tp != '\0' );
|
||||
}
|
||||
|
||||
|
||||
void scanner_get_word()
|
||||
{
|
||||
while( (scanner_char_code(scanner_ch)==LETTER) || (scanner_char_code(scanner_ch)==DIGIT) ) {
|
||||
*scanner_tokenp++ = scanner_ch;
|
||||
scanner_get_char();
|
||||
}
|
||||
*scanner_tokenp = '\0';
|
||||
|
||||
scanner_token = IDENTIFIER;
|
||||
}
|
||||
|
||||
|
||||
void scanner_get_string()
|
||||
{
|
||||
*scanner_tokenp++ = 34;
|
||||
scanner_get_char();
|
||||
|
||||
while(scanner_ch != 34 ) {
|
||||
*scanner_tokenp++ = scanner_ch;
|
||||
scanner_get_char();
|
||||
}
|
||||
scanner_get_char();
|
||||
*scanner_tokenp++ = 34;
|
||||
*scanner_tokenp = '\0';
|
||||
scanner_token = STRING;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void scanner_get_token()
|
||||
{
|
||||
scanner_skip_blanks();
|
||||
scanner_tokenp = scanner_token_string;
|
||||
*scanner_tokenp = 0;
|
||||
|
||||
|
||||
switch( scanner_char_code(scanner_ch) ) {
|
||||
case QUOTE: scanner_get_string(); break;
|
||||
case EOF_CODE: scanner_token = NO_TOKEN; break;
|
||||
case DIGIT:
|
||||
case LETTER: scanner_get_word(); break;
|
||||
default:
|
||||
*scanner_tokenp++ = scanner_ch;
|
||||
*scanner_tokenp = '\0';
|
||||
scanner_get_char();
|
||||
scanner_token = IDENTIFIER;
|
||||
break;
|
||||
}
|
||||
|
||||
scanner_downshift_word();
|
||||
}
|
||||
|
||||
void scanner_start_command( char * s )
|
||||
{
|
||||
scanner_bufferp = s;
|
||||
scanner_get_char();
|
||||
}
|
||||
|
||||
|
||||
int Dc_debug_on = 0;
|
||||
jmp_buf dc_bad_arg;
|
||||
|
||||
void dc_get_arg(uint type)
|
||||
{
|
||||
scanner_get_token();
|
||||
|
||||
Dc_command_line = scanner_bufferp;
|
||||
Dc_arg_org = scanner_token_string;
|
||||
Dc_arg = scanner_word_string;
|
||||
|
||||
if (Dc_debug_on) {
|
||||
dc_printf( "next arg is '%s', was originally '%s'\n", Dc_arg, Dc_arg_org );
|
||||
dc_printf( "Rest of the command line is '%s'\n", Dc_command_line );
|
||||
}
|
||||
|
||||
if ( scanner_token == NO_TOKEN ) {
|
||||
Dc_arg_type = ARG_NONE;
|
||||
} else if ( scanner_token == IDENTIFIER ) {
|
||||
Dc_arg_type = ARG_STRING;
|
||||
} else if ( scanner_token == STRING ) {
|
||||
Dc_arg_type = ARG_QUOTE;
|
||||
} else {
|
||||
Dc_arg_type = ARG_STRING;
|
||||
}
|
||||
|
||||
if ( Dc_arg_type & ARG_STRING ) {
|
||||
int i, num_digits, len;
|
||||
|
||||
len = strlen(Dc_arg);
|
||||
num_digits = 0;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
if ( scanner_char_table[Dc_arg[i]] == DIGIT ) num_digits++;
|
||||
|
||||
if ( num_digits==len ) {
|
||||
Dc_arg_type |= ARG_FLOAT;
|
||||
Dc_arg_float = (float)atof(Dc_arg);
|
||||
if ( !strchr( Dc_arg, '.' )) {
|
||||
Dc_arg_type |= ARG_INT;
|
||||
Dc_arg_int = atoi(Dc_arg);
|
||||
}
|
||||
} else {
|
||||
if ( (Dc_arg[0] == '0') && (Dc_arg[1] == 'x') ) {
|
||||
char *p;
|
||||
int n;
|
||||
n = strtol(Dc_arg,&p,0);
|
||||
if ( *p == 0 ) {
|
||||
Dc_arg_type |= ARG_INT|ARG_HEX;
|
||||
Dc_arg_int = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Dc_debug_on) {
|
||||
if ( Dc_arg_type & ARG_FLOAT )
|
||||
dc_printf( "Found float number! %f\n", Dc_arg_float );
|
||||
|
||||
if ( Dc_arg_type & ARG_INT )
|
||||
dc_printf( "Found int number! %d\n", Dc_arg_int );
|
||||
|
||||
if ( Dc_arg_type & ARG_HEX )
|
||||
dc_printf( "Found hex number! 0x%x\n", Dc_arg_int );
|
||||
}
|
||||
|
||||
if ( !stricmp( Dc_arg, "on" ))
|
||||
Dc_arg_type |= ARG_TRUE;
|
||||
if ( !stricmp( Dc_arg, "true" ))
|
||||
Dc_arg_type |= ARG_TRUE;
|
||||
if ( !stricmp( Dc_arg, "off" ))
|
||||
Dc_arg_type |= ARG_FALSE;
|
||||
if ( !stricmp( Dc_arg, "false" ))
|
||||
Dc_arg_type |= ARG_FALSE;
|
||||
|
||||
if ( !stricmp( Dc_arg, "+" ))
|
||||
Dc_arg_type |= ARG_PLUS;
|
||||
|
||||
if ( !stricmp( Dc_arg, "-" ))
|
||||
Dc_arg_type |= ARG_MINUS;
|
||||
|
||||
if ( !stricmp( Dc_arg, "," ))
|
||||
Dc_arg_type |= ARG_COMMA;
|
||||
}
|
||||
|
||||
if ( Dc_arg_type & ARG_INT) {
|
||||
if ( Dc_arg_int )
|
||||
Dc_arg_type |= ARG_TRUE;
|
||||
else
|
||||
Dc_arg_type |= ARG_FALSE;
|
||||
}
|
||||
|
||||
if ( !(Dc_arg_type&type) ) {
|
||||
if ( (Dc_arg_type & ARG_NONE) && !(type & ARG_NONE))
|
||||
dc_printf( "Error: Not enough parameters.\n" );
|
||||
else
|
||||
dc_printf( "Error: '%s' invalid type\n", Dc_arg );
|
||||
longjmp(dc_bad_arg,1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void debug_help();
|
||||
|
||||
void debug_do_command(char * command)
|
||||
{
|
||||
|
||||
int i;
|
||||
int mode = 0;
|
||||
|
||||
if ( strlen(command) < 1 ) return;
|
||||
|
||||
Dc_debug_on = 0;
|
||||
Dc_command_line = command;
|
||||
scanner_start_command(command);
|
||||
|
||||
if (setjmp(dc_bad_arg) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
dc_get_arg( ARG_ANY );
|
||||
|
||||
if ( !strcmp( Dc_arg, "debug" ) ) {
|
||||
Dc_debug_on = 1;
|
||||
dc_printf( "Command line: '%s'\n", Dc_command_line );
|
||||
dc_get_arg( ARG_ANY );
|
||||
}
|
||||
|
||||
if ( !stricmp( Dc_arg, "xyzzy" ) ) {
|
||||
dc_printf("Nothing happens.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !strcmp( Dc_arg, "?" ) ) {
|
||||
mode = 1;
|
||||
dc_get_arg( ARG_ANY );
|
||||
|
||||
if ( Dc_arg_type&ARG_NONE ) {
|
||||
debug_help();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !strcmp( Dc_arg, "help" ) || !strcmp( Dc_arg, "man" ) ) {
|
||||
mode = 2;
|
||||
dc_get_arg( ARG_ANY );
|
||||
if ( Dc_arg_type&ARG_NONE ) {
|
||||
debug_help();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( strstr( Dc_command_line, "?" ) ) {
|
||||
mode = 2;
|
||||
}
|
||||
|
||||
if ( !(Dc_arg_type&ARG_STRING) ) {
|
||||
dc_printf( "Invalid keyword '%s'\n", Dc_arg );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Dc_debug_on) {
|
||||
dc_printf( "Searching for command '%s'\n", Dc_arg );
|
||||
}
|
||||
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
if ( !stricmp( Debug_command[i]->name, Dc_arg )) {
|
||||
|
||||
if (mode==0) {
|
||||
if (Dc_debug_on)
|
||||
dc_printf( "Calling function '%s'\n", Dc_arg );
|
||||
Dc_command = 1;
|
||||
Dc_help = 0;
|
||||
Dc_status = 1;
|
||||
} else if (mode==1) {
|
||||
if (Dc_debug_on)
|
||||
dc_printf( "Checking status for '%s'\n", Dc_arg );
|
||||
Dc_command = 0;
|
||||
Dc_help = 0;
|
||||
Dc_status = 1;
|
||||
} else {
|
||||
if (Dc_debug_on)
|
||||
dc_printf( "Doing help for '%s'\n", Dc_arg );
|
||||
Dc_command = 0;
|
||||
Dc_help = 1;
|
||||
Dc_status = 0;
|
||||
}
|
||||
|
||||
(*Debug_command[i]->func)();
|
||||
|
||||
if (mode==0) {
|
||||
dc_get_arg(ARG_ANY);
|
||||
if (!(Dc_arg_type&ARG_NONE)) {
|
||||
dc_printf( "Ignoring the unused command line tail '%s %s'\n", Dc_arg_org, Dc_command_line );
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dc_printf( "Unknown command '%s'\n", Dc_arg );
|
||||
}
|
||||
|
||||
void debug_draw()
|
||||
{
|
||||
int i;
|
||||
|
||||
gr_clear();
|
||||
gr_set_font(FONT1);
|
||||
gr_set_color_fast( &Color_bright );
|
||||
gr_string( 0x8000, 3, "Debug Console" );
|
||||
|
||||
gr_set_color_fast( &Color_normal );
|
||||
|
||||
for (i=0; i<DROWS; i++ ) {
|
||||
gr_string( 0, i*16+16, debug_text[i] );
|
||||
}
|
||||
|
||||
int t = timer_get_fixed_seconds() / (F1_0/3);
|
||||
if ( t & 1 ) {
|
||||
int w,h;
|
||||
char c;
|
||||
|
||||
c = debug_text[debug_y][command_line_pos+1];
|
||||
debug_text[debug_y][command_line_pos+1] = 0;
|
||||
|
||||
gr_get_string_size( &w, &h, debug_text[debug_y] );
|
||||
|
||||
//gr_string( w, debug_y*16, "_" );
|
||||
gr_rect(w+1,debug_y*16+1+16,2,14);
|
||||
|
||||
debug_text[debug_y][command_line_pos+1] = c;
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
}
|
||||
|
||||
|
||||
void debug_output( char c )
|
||||
{
|
||||
if ( c == '\t' ) {
|
||||
int next_tab = ((debug_x/28)+1)*28;
|
||||
|
||||
if ( next_tab >= DCOLS-1 ) {
|
||||
debug_x=0;
|
||||
debug_y++;
|
||||
scroll_times++;
|
||||
if ( debug_y >= DROWS ) {
|
||||
int i;
|
||||
for (i=1; i<DROWS; i++ )
|
||||
strcpy_s( debug_text[i-1], debug_text[i] );
|
||||
debug_y = DROWS-1;
|
||||
debug_x = 0;
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
}
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for ( ; debug_x < next_tab; )
|
||||
debug_text[debug_y][debug_x++] = ' ';
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (c == '\n') || (debug_x >= DCOLS-1) ) {
|
||||
debug_x=0;
|
||||
debug_y++;
|
||||
scroll_times++;
|
||||
if ( debug_y >= DROWS ) {
|
||||
int i;
|
||||
for (i=1; i<DROWS; i++ )
|
||||
strcpy_s( debug_text[i-1], debug_text[i] );
|
||||
debug_y = DROWS-1;
|
||||
debug_x = 0;
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
}
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
if ( c == '\n' ) return;
|
||||
}
|
||||
|
||||
debug_text[debug_y][debug_x++] = c;
|
||||
debug_text[debug_y][debug_x] = 0;
|
||||
}
|
||||
|
||||
void dc_printf(char *format, ...)
|
||||
{
|
||||
char tmp[DCOLS*DROWS];
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(tmp, format, args);
|
||||
va_end(args);
|
||||
|
||||
char *p = tmp;
|
||||
while( *p != '\0' ) {
|
||||
debug_output(*p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void debug_init()
|
||||
{
|
||||
int i;
|
||||
if ( debug_inited ) return;
|
||||
|
||||
debug_inited = 1;
|
||||
|
||||
debug_x=0;
|
||||
debug_y=0;
|
||||
|
||||
for (i=0; i<DROWS; i++ ) {
|
||||
debug_text[i][0] = 0;
|
||||
}
|
||||
|
||||
dc_printf("Debug console started.\n" );
|
||||
}
|
||||
|
||||
|
||||
void debug_console( void (*_func)() )
|
||||
{
|
||||
int done = 0;
|
||||
|
||||
scanner_init();
|
||||
|
||||
while( key_inkey() ){
|
||||
os_poll();
|
||||
}
|
||||
|
||||
if ( !debug_inited ) debug_init();
|
||||
|
||||
|
||||
debug_draw();
|
||||
|
||||
while (!done) {
|
||||
// poll the os
|
||||
os_poll();
|
||||
|
||||
int k = key_inkey();
|
||||
switch( k ) {
|
||||
|
||||
case KEY_SHIFTED+KEY_ENTER:
|
||||
case KEY_ESC:
|
||||
done=1; break;
|
||||
|
||||
case KEY_BACKSP:
|
||||
if ( command_line_pos > 0 ) {
|
||||
command_line[--command_line_pos] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_F3:
|
||||
if ( last_oldcommand > -1 ) {
|
||||
strcpy_s( command_line, oldcommand_line[last_oldcommand] );
|
||||
command_line_pos = strlen(command_line);
|
||||
command_line[command_line_pos] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_UP:
|
||||
command_scroll--;
|
||||
if (command_scroll<0)
|
||||
command_scroll = last_oldcommand;
|
||||
|
||||
if ( command_scroll > -1 ) {
|
||||
strcpy_s( command_line, oldcommand_line[command_scroll] );
|
||||
command_line_pos = strlen(command_line);
|
||||
command_line[command_line_pos] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_DOWN:
|
||||
command_scroll++;
|
||||
if (command_scroll>last_oldcommand)
|
||||
command_scroll = 0;
|
||||
if (command_scroll>last_oldcommand)
|
||||
command_scroll = -1;
|
||||
if ( command_scroll > -1 ) {
|
||||
strcpy_s( command_line, oldcommand_line[command_scroll] );
|
||||
command_line_pos = strlen(command_line);
|
||||
command_line[command_line_pos] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_ENTER: {
|
||||
debug_output( '\n' );
|
||||
debug_draw();
|
||||
|
||||
debug_do_command(command_line);
|
||||
|
||||
int i, found = 0;
|
||||
for (i=0; i<=last_oldcommand; i++ ) {
|
||||
if (!stricmp( oldcommand_line[i], command_line )) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if ( !found ) {
|
||||
if ( last_oldcommand < DEBUG_HISTORY-1 ) {
|
||||
last_oldcommand++;
|
||||
strcpy_s( oldcommand_line[last_oldcommand], command_line);
|
||||
} else {
|
||||
int iLoop;
|
||||
for (iLoop=0; iLoop<last_oldcommand; iLoop++ ) {
|
||||
strcpy_s( oldcommand_line[iLoop], oldcommand_line[iLoop+1] );
|
||||
}
|
||||
strcpy_s( oldcommand_line[last_oldcommand], command_line);
|
||||
}
|
||||
}
|
||||
// int i;
|
||||
// for (i=0; i<=last_oldcommand; i++ ) {
|
||||
// dc_printf( "OC %d. %s\n", i, oldcommand_line[i] );
|
||||
// }
|
||||
|
||||
debug_output( '\n' );
|
||||
command_line_pos = 0;
|
||||
command_line[command_line_pos] = 0;
|
||||
|
||||
command_scroll = 0;
|
||||
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
ubyte c = (ubyte)key_to_ascii(k);
|
||||
if ( c != 255 ) {
|
||||
command_line[command_line_pos++] = c;
|
||||
command_line[command_line_pos] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcpy_s( debug_text[debug_y], ">" );
|
||||
strcat_s( debug_text[debug_y], command_line );
|
||||
debug_draw();
|
||||
|
||||
if ( _func ){
|
||||
_func();
|
||||
}
|
||||
}
|
||||
|
||||
while( key_inkey() ){
|
||||
os_poll();
|
||||
}
|
||||
}
|
||||
|
||||
void debug_help()
|
||||
{
|
||||
int s, i;
|
||||
|
||||
dc_printf( "Available functions:\n\n" );
|
||||
|
||||
s = scroll_times;
|
||||
for (i=0; i<Num_debug_commands; i++ ) {
|
||||
dc_printf( " %s - %s\n", Debug_command[i]->name, Debug_command[i]->help );
|
||||
//mprintf(( "Scroll times %d\n", scroll_times - s ));
|
||||
if ( scroll_times - s > DROWS - 3 ) {
|
||||
int k;
|
||||
dc_printf( " Press a key...B for back\n" );
|
||||
debug_draw();
|
||||
k = key_getch();
|
||||
s = scroll_times;
|
||||
if ( k == KEY_B ) {
|
||||
i -= ((DROWS-3)*2);
|
||||
if ( i <= 0 )
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
debug_draw();
|
||||
}
|
||||
dc_printf( "\n" );
|
||||
|
||||
dc_printf( "Typing '? function_name' will give the current status.\n" );
|
||||
dc_printf( "Typing 'function_name ?' will give help on the function.\n" );
|
||||
dc_printf( "Typing ? or help will give you help.\n");
|
||||
dc_printf( "F3 selects last command line.\n" );
|
||||
}
|
||||
@@ -1,406 +0,0 @@
|
||||
#include "dbugfile.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
|
||||
int dbugfile_counters[MAX_COUNTERS];
|
||||
bool dbugfile_init_var = false;
|
||||
|
||||
char dbugfile_filename[512];
|
||||
|
||||
void dbugfile_output(char *buffer)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FILE *fp = fopen(dbugfile_filename, "a");
|
||||
|
||||
if(fp == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(buffer, sizeof(char) * strlen(buffer), 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void dbugfile_init()
|
||||
{
|
||||
// Clear the counters
|
||||
memset(dbugfile_counters, 0, sizeof(int) * MAX_COUNTERS);
|
||||
|
||||
char big_buffer[1000];
|
||||
char temp_buff[512];
|
||||
|
||||
dbugfile_filename[0] = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
char path[MAX_PATH];
|
||||
|
||||
GetCurrentDirectory(MAX_PATH, path);
|
||||
|
||||
int path_len = strlen(path);
|
||||
if(path[path_len - 1] != '\\')
|
||||
{
|
||||
path[path_len] = '\\';
|
||||
path[path_len + 1] = '\0';
|
||||
}
|
||||
|
||||
strcpy_s(dbugfile_filename, path);
|
||||
|
||||
#endif
|
||||
|
||||
strcat_s(dbugfile_filename, "DBUG-");
|
||||
strcpy_s(big_buffer, "DBUGFILE Active: ");
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
unsigned long len = 512;
|
||||
GetUserName(temp_buff, &len);
|
||||
|
||||
strcat_s(dbugfile_filename, temp_buff);
|
||||
strcat_s(big_buffer, temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, "-");
|
||||
strcat_s(big_buffer, " ");
|
||||
}
|
||||
#endif
|
||||
|
||||
_tzset();
|
||||
|
||||
// Display operating system-style date and time.
|
||||
_strdate( temp_buff);
|
||||
strcat_s(dbugfile_filename, "D(");
|
||||
strcat_s(dbugfile_filename,temp_buff);
|
||||
strcat_s(big_buffer,temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, ") T(");
|
||||
strcat_s(big_buffer, " ");
|
||||
|
||||
_strtime( temp_buff);
|
||||
strcat_s(dbugfile_filename,temp_buff);
|
||||
strcat_s(big_buffer,temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, ").txt");
|
||||
strcat_s(big_buffer, "\n");
|
||||
|
||||
// Remove invalid slash chars
|
||||
int len = strlen(dbugfile_filename);
|
||||
while(len >= 2)
|
||||
{
|
||||
if(dbugfile_filename[len] == '/' || dbugfile_filename[len] == ':')
|
||||
{
|
||||
dbugfile_filename[len] = '-';
|
||||
}
|
||||
len--;
|
||||
}
|
||||
|
||||
// open file
|
||||
// Uncomment this to see where the file is going
|
||||
//MessageBox(NULL, dbugfile_filename, "das", MB_OK);
|
||||
FILE *fp = fopen(dbugfile_filename, "w");
|
||||
|
||||
if(fp == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(big_buffer, sizeof(char) * strlen(big_buffer), 1, fp);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// detect OS type
|
||||
|
||||
OSVERSIONINFO version_info;
|
||||
version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
if(GetVersionEx(&version_info) != false)
|
||||
{
|
||||
char *error = "Error in detecting OS version";
|
||||
char *version = error;
|
||||
|
||||
switch(version_info.dwMajorVersion)
|
||||
{
|
||||
case 4:
|
||||
{
|
||||
if(version_info.dwMinorVersion == 0)
|
||||
{
|
||||
version = "Windows 95";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 10)
|
||||
{
|
||||
version = "Windows 98";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 90)
|
||||
{
|
||||
version = "Windows Me";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
if(version_info.dwMinorVersion == 0)
|
||||
{
|
||||
version = "Windows 2000";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 1)
|
||||
{
|
||||
version = "Windows XP";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *release_type = NULL;
|
||||
#ifdef _DEBUG
|
||||
release_type = "Debug";
|
||||
#else
|
||||
release_type = "Release";
|
||||
#endif
|
||||
sprintf(big_buffer, "OS: %s %s, ", version, release_type);
|
||||
}
|
||||
|
||||
fwrite(big_buffer, sizeof(char) * strlen(big_buffer), 1, fp);
|
||||
|
||||
char exe_name[MAX_PATH];
|
||||
|
||||
GetModuleFileName(NULL, exe_name, MAX_PATH);
|
||||
strcat_s(exe_name, "\n");
|
||||
fwrite(exe_name, sizeof(char) * strlen(exe_name), 1, fp);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
fclose(fp);
|
||||
|
||||
dbugfile_init_var = true;
|
||||
}
|
||||
|
||||
void dbugfile_deinit()
|
||||
{
|
||||
dbugfile_output("Normal end");
|
||||
dbugfile_init_var = false;
|
||||
}
|
||||
|
||||
void dbugfile_sprintf(int line, char *file, const char *format, ...)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
int i = sprintf(buffer, "[%s,%4d] ", ptr, line);
|
||||
|
||||
va_list ap;
|
||||
char *p, *sval;
|
||||
long ival;
|
||||
double dval;
|
||||
|
||||
// Add each extra parameter to string
|
||||
va_start(ap, format);
|
||||
|
||||
for(p = (char *) format; *p; p++)
|
||||
{
|
||||
if(*p != '%')
|
||||
{
|
||||
*(buffer + i) = *p;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
p++;
|
||||
|
||||
switch(*p)
|
||||
{
|
||||
case 'd':
|
||||
{
|
||||
ival = va_arg(ap, int);
|
||||
i += sprintf(buffer+i,"%d", ival);
|
||||
break;
|
||||
}
|
||||
case 'c':
|
||||
{
|
||||
ival = va_arg(ap, char);
|
||||
buffer[i] = (char) ival;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
case 'x':
|
||||
{
|
||||
ival = va_arg(ap, int);
|
||||
i += sprintf(buffer+i,"%x", ival);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
{
|
||||
dval = va_arg(ap, double);
|
||||
i += sprintf(buffer+i,"%f", dval);
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
{
|
||||
for(sval = va_arg(ap, char *); *sval; sval++)
|
||||
{
|
||||
*(buffer + i++) = *sval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
i += sprintf(buffer+i,"N/A: %%%c", *p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
i += sprintf(buffer + i, "\n");
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_matrix_4x4(int line, char *file, float *matrix, char *text)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(matrix == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if(text == NULL)
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
|
||||
sprintf(buffer,"[%s,%4d] Matrix %s:\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n",
|
||||
ptr,line, text,
|
||||
matrix[0],
|
||||
matrix[1],
|
||||
matrix[2],
|
||||
matrix[3],
|
||||
matrix[4],
|
||||
matrix[5],
|
||||
matrix[6],
|
||||
matrix[7],
|
||||
matrix[8],
|
||||
matrix[9],
|
||||
matrix[10],
|
||||
matrix[11],
|
||||
matrix[12],
|
||||
matrix[13],
|
||||
matrix[14],
|
||||
matrix[15]);
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_matrix_3x3(int line, char *file, float *matrix, char *text)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(matrix == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if(text == NULL)
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
|
||||
sprintf(buffer,"[%s,%4d] Matrix %s:\n"
|
||||
"%f %f %f\n"
|
||||
"%f %f %f\n"
|
||||
"%f %f %f\n",
|
||||
ptr,line, text,
|
||||
matrix[0],
|
||||
matrix[1],
|
||||
matrix[2],
|
||||
matrix[3],
|
||||
matrix[4],
|
||||
matrix[5],
|
||||
matrix[6],
|
||||
matrix[7],
|
||||
matrix[8]);
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_counter(int line, char *file, int counter_num, char *string)
|
||||
{
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, string);
|
||||
strcat_s(buffer, " %d");
|
||||
|
||||
dbugfile_sprintf(line, file, buffer, dbugfile_counters[counter_num]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
|
||||
#ifndef _DBUGFILE_HEADER_
|
||||
#define _DBUGFILE_HEADER_
|
||||
|
||||
#define MAX_COUNTERS 10
|
||||
|
||||
void dbugfile_init();
|
||||
void dbugfile_deinit();
|
||||
void dbugfile_sprintf(int line, char *file, const char *format, ...);
|
||||
void dbugfile_print_matrix_3x3(int line, char *file, float *matrix, char *text);
|
||||
void dbugfile_print_matrix_4x4(int line, char *file, float *matrix, char *text);
|
||||
void dbugfile_print_counter(int line, char *file, int counter_num, char *string);
|
||||
|
||||
#ifdef DBUGFILE_ACTIVE
|
||||
|
||||
#define DBUGFILE_INIT() dbugfile_init();
|
||||
#define DBUGFILE_DEINIT() dbugfile_deinit();
|
||||
|
||||
#define DBUGFILE_OUTPUT_0(t) dbugfile_sprintf(__LINE__, __FILE__, t);
|
||||
#define DBUGFILE_OUTPUT_1(t,a) dbugfile_sprintf(__LINE__, __FILE__, t,a);
|
||||
#define DBUGFILE_OUTPUT_2(t,a,b) dbugfile_sprintf(__LINE__, __FILE__, t,a,b);
|
||||
#define DBUGFILE_OUTPUT_3(t,a,b,c) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c);
|
||||
#define DBUGFILE_OUTPUT_4(t,a,b,c,d) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d);
|
||||
#define DBUGFILE_OUTPUT_5(t,a,b,c,d,e) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e);
|
||||
#define DBUGFILE_OUTPUT_6(t,a,b,c,d,e,f) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f);
|
||||
#define DBUGFILE_OUTPUT_7(t,a,b,c,d,e,f,g) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g);
|
||||
#define DBUGFILE_OUTPUT_8(t,a,b,c,d,e,f,g,h) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g,h);
|
||||
#define DBUGFILE_OUTPUT_9(t,a,b,c,d,e,f,g,h,i) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g,h,i);
|
||||
|
||||
#define DBUGFILE_OUTPUT_MATRIX_3X3(m,t) dbugfile_print_matrix_3x3(__LINE__, __FILE__, m,t);
|
||||
#define DBUGFILE_OUTPUT_MATRIX_4X4(m,t) dbugfile_print_matrix_4x4(__LINE__, __FILE__, m,t);
|
||||
|
||||
extern int dbugfile_counters[MAX_COUNTERS];
|
||||
#define DBUGFILE_INC_COUNTER(n) if(n < MAX_COUNTERS) dbugfile_counters[n]++;
|
||||
#define DBUGFILE_DEC_COUNTER(n) if(n < MAX_COUNTERS) dbugfile_counters[n]--;
|
||||
|
||||
#define DBUGFILE_OUTPUT_COUNTER(n,s) dbugfile_print_counter(__LINE__, __FILE__, n, s);
|
||||
|
||||
#else
|
||||
|
||||
#define DBUGFILE_INIT() ;
|
||||
#define DBUGFILE_DEINIT() ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_0(t) ;
|
||||
#define DBUGFILE_OUTPUT_1(t,a) ;
|
||||
#define DBUGFILE_OUTPUT_2(t,a,b) ;
|
||||
#define DBUGFILE_OUTPUT_3(t,a,b,c) ;
|
||||
#define DBUGFILE_OUTPUT_4(t,a,b,c,d) ;
|
||||
#define DBUGFILE_OUTPUT_5(t,a,b,c,d,e) ;
|
||||
#define DBUGFILE_OUTPUT_6(t,a,b,c,d,e,f) ;
|
||||
#define DBUGFILE_OUTPUT_7(t,a,b,c,d,e,f,g) ;
|
||||
#define DBUGFILE_OUTPUT_8(t,a,b,c,d,e,f,g,h) ;
|
||||
#define DBUGFILE_OUTPUT_9(t,a,b,c,d,e,f,g,h,i) ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_MATRIX_3X3(m,t) ;
|
||||
#define DBUGFILE_OUTPUT_MATRIX_4X4(m,t) ;
|
||||
|
||||
#define DBUGFILE_INC_COUNTER(n) ;
|
||||
#define DBUGFILE_DEC_COUNTER(n) ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_COUNTER(n,s) ;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
/*
|
||||
* Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
|
||||
*
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* created based on the source.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This module is intended as a debug tool to measure the speed of blocks of code and display
|
||||
* that information as coloured bars across the top of the screen.
|
||||
*
|
||||
* This allows interactive measuring of components of the code, very useful for optimisztion.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#endif
|
||||
|
||||
#include "timerbar.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
|
||||
// Internal structure for handling frame data
|
||||
typedef struct
|
||||
{
|
||||
LARGE_INTEGER start_value;
|
||||
LARGE_INTEGER total_value;
|
||||
|
||||
LARGE_INTEGER average;
|
||||
LARGE_INTEGER frame_total;
|
||||
|
||||
} timerbar_profile;
|
||||
|
||||
timerbar_profile profiles[MAX_NUM_TIMERBARS];
|
||||
int timerbar_current_profile = 0;
|
||||
|
||||
LARGE_INTEGER timerbar_ultimate_start_value;
|
||||
LARGE_INTEGER timerbar_last_start_value;
|
||||
|
||||
// Data needed for push and pop functionality
|
||||
const int MAX_TB_STACK_SIZE = 100;
|
||||
|
||||
int timerbar_stack[MAX_TB_STACK_SIZE];
|
||||
int timerbar_current_stack_layer = 0;
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
void timerbar_push(int value)
|
||||
{
|
||||
if(timerbar_current_stack_layer >= MAX_TB_STACK_SIZE)
|
||||
{
|
||||
// To many pushs, this must be a bug
|
||||
// Someone is letting code miss the pops, check for early retuns
|
||||
Assert(!(timerbar_current_stack_layer >= MAX_TB_STACK_SIZE));
|
||||
return;
|
||||
}
|
||||
|
||||
timerbar_stack[timerbar_current_stack_layer] = timerbar_current_profile;
|
||||
timerbar_current_stack_layer++;
|
||||
|
||||
timerbar_switch_type(value);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
void timerbar_pop()
|
||||
{
|
||||
timerbar_current_stack_layer--;
|
||||
if(timerbar_current_stack_layer < 0)
|
||||
{
|
||||
Assert(!(timerbar_current_stack_layer < 0));
|
||||
timerbar_current_stack_layer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
timerbar_switch_type(timerbar_stack[timerbar_current_stack_layer]);
|
||||
}
|
||||
|
||||
// This pointer holds the draw function to use or NULL
|
||||
void (*draw_func_ptr)(int colour, float x, float y, float w, float h) = NULL;
|
||||
|
||||
void timerbar_start_frame()
|
||||
{
|
||||
timerbar_current_stack_layer = 0;
|
||||
timerbar_current_profile = 0;
|
||||
|
||||
if(QueryPerformanceCounter(&timerbar_ultimate_start_value) == FALSE)
|
||||
{
|
||||
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
|
||||
draw_func_ptr = NULL;
|
||||
}
|
||||
|
||||
timerbar_last_start_value = timerbar_ultimate_start_value;
|
||||
|
||||
}
|
||||
|
||||
// Constants need for timerbar_conv_and_draw calculations
|
||||
const int WIDTH = 480;
|
||||
const float WIDTHF = ((float) WIDTH) * 1.01f;
|
||||
|
||||
/**
|
||||
* Internal conversion function to convert draw data into bars for the screen
|
||||
*
|
||||
* @param int colour - colour index (>=0)
|
||||
* @param int xpos - x position to start bar on
|
||||
* @param int xwidth - width of bar
|
||||
* @param int yrow - Index of row bar belongs to
|
||||
*/
|
||||
void timerbar_conv_and_draw(int colour, int xpos, int xwidth, int yrow)
|
||||
{
|
||||
float fxpos = (float) xpos;
|
||||
float fxwidth = (float) xwidth;
|
||||
|
||||
draw_func_ptr(colour,
|
||||
fxpos / WIDTHF,
|
||||
yrow * 0.01f,
|
||||
fxwidth / WIDTHF,
|
||||
0.005f);
|
||||
}
|
||||
|
||||
void timerbar_end_frame()
|
||||
{
|
||||
// Now we want to draw the bars
|
||||
if(draw_func_ptr == NULL)
|
||||
{
|
||||
// we have not been given a draw function so we are going to have to quit
|
||||
return;
|
||||
}
|
||||
|
||||
timerbar_switch_type(-1);
|
||||
|
||||
int last_xpos = 0;
|
||||
int y_pos = 0;
|
||||
|
||||
|
||||
for(int i = 0; i < MAX_NUM_TIMERBARS; i++)
|
||||
{
|
||||
// Nothing to render this frame
|
||||
if(profiles[i].frame_total.QuadPart == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int xsize = (int) profiles[i].frame_total.QuadPart / 90;
|
||||
|
||||
// break condition in else
|
||||
while(1)
|
||||
{
|
||||
// if bar runs over
|
||||
if(last_xpos + xsize > WIDTH)
|
||||
{
|
||||
int rem_len = WIDTH - last_xpos;
|
||||
|
||||
// Draw from current position to the end of the bar
|
||||
timerbar_conv_and_draw(i, last_xpos, rem_len, y_pos);
|
||||
|
||||
xsize -= rem_len;
|
||||
last_xpos = 0;
|
||||
y_pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw whats left and break for the next bar
|
||||
timerbar_conv_and_draw(i,last_xpos, xsize, y_pos);
|
||||
|
||||
last_xpos += xsize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// reset for next frame
|
||||
profiles[i].frame_total.QuadPart = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void timerbar_switch_type(int num)
|
||||
{
|
||||
if(num >= MAX_NUM_TIMERBARS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate old profile's total
|
||||
LARGE_INTEGER now;
|
||||
if(QueryPerformanceCounter(&now) == FALSE)
|
||||
{
|
||||
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
|
||||
}
|
||||
|
||||
profiles[timerbar_current_profile].frame_total.QuadPart +=
|
||||
(now.QuadPart - timerbar_last_start_value.QuadPart);
|
||||
|
||||
if(num != -1)
|
||||
{
|
||||
// Switch to new profile
|
||||
timerbar_current_profile = num;
|
||||
}
|
||||
|
||||
// Update time to count from
|
||||
if(QueryPerformanceCounter(&timerbar_last_start_value) == FALSE)
|
||||
{
|
||||
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param void (*new_draw_func_ptr)(int colour, float x, float y, float w, float h) - pointer to draw function
|
||||
*
|
||||
* Sets the draw function used to output the timer data, designed to be generic allowing any API
|
||||
* to take advantage of this module. Set to NULL to disable drawing.
|
||||
*
|
||||
* By default the draw function is set to NULL
|
||||
*/
|
||||
void timerbar_set_draw_func(void (*new_draw_func_ptr)(int colour, float x, float y, float w, float h))
|
||||
{
|
||||
draw_func_ptr = new_draw_func_ptr;
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
|
||||
*
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* created based on the source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _TIMERBAR_HEADER_
|
||||
#define _TIMERBAR_HEADER_
|
||||
|
||||
const int MAX_NUM_TIMERBARS = 20;
|
||||
|
||||
#include "cmdline/cmdline.h"
|
||||
|
||||
// These functions should never be used directly, always use macros below
|
||||
void timerbar_start_frame();
|
||||
void timerbar_end_frame();
|
||||
void timerbar_set_draw_func(void (*new_draw_func_ptr)(int colour, float x, float y, float w, float h));
|
||||
|
||||
void timerbar_push(int value);
|
||||
void timerbar_pop();
|
||||
|
||||
// This function shouldnt not be used any more or it will break push and pop calls
|
||||
void timerbar_switch_type(int num);
|
||||
|
||||
#define TIMERBAR_SET_DRAW_FUNC(f) if (Cmdline_timerbar) timerbar_set_draw_func(f);
|
||||
#define TIMERBAR_START_FRAME() if (Cmdline_timerbar) timerbar_start_frame();
|
||||
#define TIMERBAR_END_FRAME() if (Cmdline_timerbar) timerbar_end_frame();
|
||||
#define TIMERBAR_SWITCH_TYPE(n) if (Cmdline_timerbar) timerbar_switch_type(n);
|
||||
|
||||
#define TIMERBAR_PUSH(v) if (Cmdline_timerbar) timerbar_push(v);
|
||||
#define TIMERBAR_POP() if (Cmdline_timerbar) timerbar_pop();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,974 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "demo/demo.h"
|
||||
#include "ship/ship.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "freespace2/freespace.h"
|
||||
#include "object/object.h"
|
||||
#include "io/timer.h"
|
||||
#include "gamesequence/gamesequence.h"
|
||||
#include "mission/missionmessage.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "ship/shipfx.h"
|
||||
#include "ship/shiphit.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO DEFINES/VARS
|
||||
//
|
||||
|
||||
CFILE *Demo_file = NULL;
|
||||
|
||||
// how often we dump
|
||||
#define DEMO_DEFAULT_FPS 15
|
||||
int Demo_fps = 1000 / DEMO_DEFAULT_FPS;
|
||||
|
||||
// timestamp for frame dumping
|
||||
int Demo_stamp = -1;
|
||||
|
||||
// missiontime
|
||||
float Demo_missiontime = 0.0f;
|
||||
|
||||
// buffer for reading and writing demo stuff
|
||||
#define DEMO_BUF_SIZE 32768
|
||||
char *Demo_buf = NULL;
|
||||
int Demo_buf_pos = 0;
|
||||
|
||||
// # of events posted for this frame
|
||||
int Demo_frame_events = 0;
|
||||
|
||||
// current offset into the demo file - only used for playback
|
||||
int Demo_cur_offset = -1;
|
||||
|
||||
// demo version #
|
||||
#define DEMO_VERSION 2
|
||||
|
||||
// an error reading or writing the demo file
|
||||
int Demo_error = DEMO_ERROR_NONE;
|
||||
|
||||
// all strings read out of the demo file must be no longer than this
|
||||
#define DEMO_STRING_LEN 255
|
||||
|
||||
// macros
|
||||
#define DEMO_DATA_FRAME() do { \
|
||||
if(Demo_file == NULL){\
|
||||
Int3();\
|
||||
DEMO_ERROR(DEMO_ERROR_GENERAL);\
|
||||
break;\
|
||||
}\
|
||||
if(Game_mode & GM_DEMO_RECORD){\
|
||||
if(Demo_buf_pos == 0) {\
|
||||
Int3();\
|
||||
break;\
|
||||
}\
|
||||
if(Demo_frame_events <= 0){\
|
||||
break;\
|
||||
}\
|
||||
if(!cfwrite_ushort((ushort)Demo_buf_pos, Demo_file)){\
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_SPACE);\
|
||||
break;\
|
||||
}\
|
||||
if(!cfwrite(Demo_buf, Demo_buf_pos, 1, Demo_file)){\
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_SPACE);\
|
||||
break;\
|
||||
}\
|
||||
} else if(Game_mode & GM_DEMO_PLAYBACK){\
|
||||
Demo_buf_pos = (int)cfread_ushort(Demo_file);\
|
||||
if(!cfread(Demo_buf, Demo_buf_pos, 1, Demo_file)){\
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
} while(0)
|
||||
#define DEMO_DATA(vl, vl_size) do { if(Demo_buf == NULL){ DEMO_ERROR(DEMO_ERROR_GENERAL); break; } if((Demo_buf_pos + vl_size) >= DEMO_BUF_SIZE){ Int3(); DEMO_ERROR(DEMO_ERROR_FRAMESIZE); break; } if(Game_mode & GM_DEMO_RECORD){ memcpy(Demo_buf + Demo_buf_pos, &vl, vl_size); } else if(Game_mode & GM_DEMO_PLAYBACK){ memcpy(&vl, Demo_buf + Demo_buf_pos, vl_size); } Demo_buf_pos += vl_size; } while(0)
|
||||
#define DEMO_INT(vl) do { DEMO_DATA(vl, sizeof(int)); } while(0)
|
||||
#define DEMO_UINT(vl) do { DEMO_DATA(vl, sizeof(uint)); } while(0)
|
||||
#define DEMO_SHORT(vl) do { DEMO_DATA(vl, sizeof(short)); } while(0)
|
||||
#define DEMO_USHORT(vl) do { DEMO_DATA(vl, sizeof(ushort)); } while(0)
|
||||
#define DEMO_BYTE(vl) do { DEMO_DATA(vl, sizeof(char)); } while(0)
|
||||
#define DEMO_UBYTE(vl) do { DEMO_DATA(vl, sizeof(ubyte)); } while(0)
|
||||
#define DEMO_FLOAT(vl) do { DEMO_DATA(vl, sizeof(float)); } while(0)
|
||||
#define DEMO_VECTOR(vl) do { DEMO_DATA(vl, sizeof(vec3d)); } while(0)
|
||||
#define DEMO_MATRIX(vl) do { DEMO_DATA(vl, sizeof(matrix)); } while(0)
|
||||
#define DEMO_STRING(vl) do { int stlen; if(Game_mode & GM_DEMO_RECORD){ stlen = strlen(vl); if(stlen <= 0){ break; } DEMO_DATA(stlen, sizeof(ushort)); DEMO_DATA(*vl, strlen(vl)); } else { ushort len = 0; DEMO_USHORT(len); DEMO_DATA(*vl, len); vl[len] = '\0'; } } while(0)
|
||||
|
||||
// demo events types
|
||||
#define DE_DUMP 1 // standard object dump
|
||||
#define DE_TRAILER 2 // end of demo trailer
|
||||
#define DE_PRIMARY 3 // primary weapon fired
|
||||
#define DE_UNIQUE_MESSAGE 4 // unique hud message
|
||||
#define DE_BUILTIN_MESSAGE 5 // builtin hud message
|
||||
#define DE_OBJ_CREATE 6 // object create message
|
||||
#define DE_OBJ_WARPIN 7 // ship warpin
|
||||
#define DE_OBJ_WARPOUT 8 // ship warpout
|
||||
#define DE_OBJ_DEPARTED 9 // ship departed
|
||||
#define DE_SHIP_KILL 10 // ship kill
|
||||
|
||||
// call this when posting an error
|
||||
#define DEMO_ERROR(er) do { Demo_error = er; Int3(); } while(0)
|
||||
|
||||
int Demo_make = 0;
|
||||
DCF(demo, "")
|
||||
{
|
||||
Demo_make = !Demo_make;
|
||||
if(Demo_make){
|
||||
dc_printf("Demo will be recorded\n");
|
||||
} else {
|
||||
dc_printf("Demo will NOT be recorded\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO FORWARD DECLARATIONS
|
||||
//
|
||||
|
||||
// write demo header
|
||||
int demo_write_header();
|
||||
|
||||
// read the demo header
|
||||
int demo_read_header();
|
||||
|
||||
// write the demo trailer
|
||||
void demo_write_trailer();
|
||||
|
||||
// do a recording frame
|
||||
void demo_do_recording_frame_start();
|
||||
|
||||
// do a recording frame
|
||||
void demo_do_recording_frame_end();
|
||||
|
||||
// do a playback frame
|
||||
void demo_do_playback_frame();
|
||||
|
||||
// seek through the demo file to the proper location
|
||||
// return 0 on error, 1 on success/continue, 2 if the demo is done
|
||||
int demo_playback_seek();
|
||||
|
||||
// scan through a read in frame of data and apply everything necessary. returns true if the trailer (end of demo) was found
|
||||
int demo_playback_seek_sub(int frame_size);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO FUNCTIONS
|
||||
//
|
||||
|
||||
// do frame for the demo - playback and recording, returns 0 if errors were encountered during frame processing
|
||||
int demo_do_frame_start()
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 1;
|
||||
#else
|
||||
// if we're not doing any demo stuff
|
||||
if(!(Game_mode & GM_DEMO)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// bad
|
||||
if(Demo_file == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make sure we're not trying to record and playback at the same time
|
||||
Assert( ((Game_mode & GM_DEMO_RECORD) && !(Game_mode & GM_DEMO_PLAYBACK)) || (!(Game_mode & GM_DEMO_RECORD) && (Game_mode & GM_DEMO_PLAYBACK)) );
|
||||
|
||||
// recording
|
||||
if(Game_mode & GM_DEMO_RECORD){
|
||||
demo_do_recording_frame_start();
|
||||
} else {
|
||||
demo_do_playback_frame();
|
||||
}
|
||||
|
||||
// bad bad bad, get mwa
|
||||
if(Demo_error){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// continue
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// do frame for the demo - playback and recording, returns 0 if errors were encountered during frame processing
|
||||
int demo_do_frame_end()
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 1;
|
||||
#else
|
||||
// if we're not doing any demo stuff
|
||||
if(!(Game_mode & GM_DEMO)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// bad
|
||||
if(Demo_file == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make sure we're not trying to record and playback at the same time
|
||||
Assert( ((Game_mode & GM_DEMO_RECORD) && !(Game_mode & GM_DEMO_PLAYBACK)) || (!(Game_mode & GM_DEMO_RECORD) && (Game_mode & GM_DEMO_PLAYBACK)) );
|
||||
|
||||
// recording. there's nothing to do here for playback
|
||||
if(Game_mode & GM_DEMO_RECORD){
|
||||
demo_do_recording_frame_end();
|
||||
}
|
||||
|
||||
// bad bad bad, get mwa
|
||||
if(Demo_error){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// continue
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// initialize a demo for recording
|
||||
// NOTE : call this after loading the mission and going through the briefing, but _before_ physically moving into the mission
|
||||
int demo_start_record(char *file)
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 0;
|
||||
#else
|
||||
char full_name[MAX_FILENAME_LEN] = "";
|
||||
|
||||
// try and allocate the buffer
|
||||
Demo_buf = (char*)vm_malloc(DEMO_BUF_SIZE);
|
||||
if(Demo_buf == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// open the outfile
|
||||
strcpy_s(full_name, file);
|
||||
cf_add_ext(full_name, ".fsd");
|
||||
Demo_file = cfopen(full_name, "wb", CFILE_NORMAL, CF_TYPE_DEMOS);
|
||||
if(Demo_file == NULL){
|
||||
Int3();
|
||||
Demo_error = DEMO_ERROR_DISK_ACCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// no errors
|
||||
Demo_error = DEMO_ERROR_NONE;
|
||||
|
||||
// write the header
|
||||
if(!demo_write_header()){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// flag demo mode
|
||||
Game_mode |= GM_DEMO_RECORD;
|
||||
|
||||
// no events yet
|
||||
Demo_frame_events = 0;
|
||||
|
||||
// success
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// initialize a demo for playback - calling this will load up the demo file and move the player into the playback state
|
||||
int demo_start_playback(char *file)
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 0;
|
||||
#else
|
||||
char full_name[MAX_FILENAME_LEN] = "";
|
||||
|
||||
// try and allocate the buffer
|
||||
Demo_buf = (char*)vm_malloc(DEMO_BUF_SIZE);
|
||||
if(Demo_buf == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// open the outfile
|
||||
strcpy_s(full_name, file);
|
||||
cf_add_ext(full_name, ".fsd");
|
||||
Demo_file = cfopen(full_name, "rb", CFILE_NORMAL, CF_TYPE_DEMOS);
|
||||
if(Demo_file == NULL){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// no errors
|
||||
Demo_error = DEMO_ERROR_NONE;
|
||||
|
||||
// read the header
|
||||
Demo_cur_offset = -1;
|
||||
if(!demo_read_header()){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// flag demo mode
|
||||
Game_mode |= GM_DEMO_PLAYBACK;
|
||||
|
||||
// everything is cool, so jump into the mission
|
||||
gameseq_post_event(GS_EVENT_ENTER_GAME);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// finish the demo
|
||||
void demo_close()
|
||||
{
|
||||
#ifdef DEMO_SYSTEM
|
||||
// if we're recording, write the trailer
|
||||
if(Game_mode & GM_DEMO_RECORD){
|
||||
demo_write_trailer();
|
||||
}
|
||||
|
||||
// close the demo file
|
||||
if(Demo_file != NULL){
|
||||
cfclose(Demo_file);
|
||||
Demo_file = NULL;
|
||||
}
|
||||
|
||||
// free the buffer
|
||||
if(Demo_buf != NULL){
|
||||
vm_free(Demo_buf);
|
||||
Demo_buf = NULL;
|
||||
}
|
||||
|
||||
// if we're playing back, go back to the main hall
|
||||
if(Game_mode & GM_DEMO_PLAYBACK){
|
||||
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
||||
}
|
||||
|
||||
// unflag demo mode
|
||||
Game_mode &= ~(GM_DEMO_RECORD | GM_DEMO_PLAYBACK);
|
||||
#endif
|
||||
}
|
||||
|
||||
// if we should run the simulation for this object, or let the demo system handle it
|
||||
int demo_should_sim(object *objp)
|
||||
{
|
||||
#ifndef DEMO_SYSTEM
|
||||
return 1;
|
||||
#else
|
||||
// always sim stuff in non-demo mode
|
||||
if(!(Game_mode & GM_DEMO)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// don't sim ships or missiles
|
||||
if((objp->type == OBJ_SHIP) || ((objp->type == OBJ_WEAPON) && (objp->instance >= 0) && (Weapon_info[Weapons[objp->instance].weapon_info_index].subtype == WP_MISSILE))){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// sim everything else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO RECORDING FUNCTIONS
|
||||
//
|
||||
|
||||
// write demo header
|
||||
int demo_write_header()
|
||||
{
|
||||
uint chksum;
|
||||
char *full_name;
|
||||
|
||||
// write demo version #
|
||||
if(!cfwrite_int(DEMO_VERSION, Demo_file)){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write mission filename
|
||||
if(!cfwrite_string_len(Game_current_mission_filename, Demo_file)){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write mission checksum
|
||||
full_name = cf_add_ext(Game_current_mission_filename, FS_MISSION_FILE_EXT);
|
||||
cf_chksum_long(full_name, &chksum);
|
||||
if(!cfwrite_int(chksum, Demo_file)){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
// write the demo trailer
|
||||
void demo_write_trailer()
|
||||
{
|
||||
// start a new chunk
|
||||
demo_do_recording_frame_start();
|
||||
|
||||
// trailer event
|
||||
ubyte frame_type = DE_TRAILER;
|
||||
DEMO_UBYTE(frame_type);
|
||||
|
||||
// 1 event
|
||||
Demo_frame_events++;
|
||||
|
||||
// write frame data to disk
|
||||
DEMO_DATA_FRAME();
|
||||
}
|
||||
|
||||
// start recording frame
|
||||
void demo_do_recording_frame_start()
|
||||
{
|
||||
// if we're not physically doing the mission
|
||||
if(gameseq_get_state() != GS_STATE_GAME_PLAY){
|
||||
return;
|
||||
}
|
||||
|
||||
// add in frametime
|
||||
Demo_missiontime += flFrametime;
|
||||
|
||||
// clear the buffer, set no events, and write the header
|
||||
Demo_buf_pos = 0;
|
||||
Demo_frame_events = 0;
|
||||
|
||||
// missiontime
|
||||
float fl_time = f2fl(Missiontime);
|
||||
DEMO_FLOAT(fl_time);
|
||||
}
|
||||
|
||||
// end recording frame
|
||||
void demo_do_recording_frame_end()
|
||||
{
|
||||
// if we're not physically doing the mission
|
||||
if(gameseq_get_state() != GS_STATE_GAME_PLAY){
|
||||
return;
|
||||
}
|
||||
|
||||
// if its time to dump objects (the last thing we might dump per frame)
|
||||
if((Demo_stamp == -1) || timestamp_elapsed(Demo_stamp)){
|
||||
// post an object dump event
|
||||
demo_POST_object_dump();
|
||||
|
||||
// reset the stamp
|
||||
Demo_stamp = timestamp(Demo_fps);
|
||||
}
|
||||
|
||||
// write all accumulated frame data to disk if necessary
|
||||
DEMO_DATA_FRAME();
|
||||
}
|
||||
|
||||
// post an object dump event
|
||||
void demo_POST_object_dump()
|
||||
{
|
||||
ship_obj *sobjp;
|
||||
object *objp;
|
||||
ushort obj_count;
|
||||
ubyte team;
|
||||
|
||||
// object dump event
|
||||
ubyte event_type = DE_DUMP;
|
||||
DEMO_UBYTE(event_type);
|
||||
|
||||
// go through the ship list and count
|
||||
obj_count = 0;
|
||||
for ( sobjp = GET_FIRST(&Ship_obj_list); sobjp !=END_OF_LIST(&Ship_obj_list); sobjp = GET_NEXT(sobjp) ){
|
||||
// object pointer
|
||||
if(sobjp->objnum < 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
obj_count++;
|
||||
}
|
||||
|
||||
// write out the object count
|
||||
DEMO_USHORT(obj_count);
|
||||
|
||||
// go through the ship list and dump necessary stuff
|
||||
for ( sobjp = GET_FIRST(&Ship_obj_list); sobjp !=END_OF_LIST(&Ship_obj_list); sobjp = GET_NEXT(sobjp) ){
|
||||
// object pointer
|
||||
if(sobjp->objnum < 0){
|
||||
continue;
|
||||
}
|
||||
objp = &Objects[sobjp->objnum];
|
||||
|
||||
// just ships for now
|
||||
DEMO_INT(objp->signature);
|
||||
DEMO_VECTOR(objp->pos);
|
||||
DEMO_MATRIX(objp->orient);
|
||||
DEMO_FLOAT(objp->phys_info.forward_thrust);
|
||||
team = (ubyte)Ships[objp->instance].team;
|
||||
DEMO_UBYTE(team);
|
||||
DEMO_INT(Ships[objp->instance].flags);
|
||||
}
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a primary fired event
|
||||
void demo_POST_primary_fired(object *objp, int banks, int linked)
|
||||
{
|
||||
ubyte fire_info = 0;
|
||||
|
||||
// object dump event
|
||||
ubyte event_type = DE_PRIMARY;
|
||||
DEMO_UBYTE(event_type);
|
||||
|
||||
// object signature
|
||||
DEMO_INT(objp->signature);
|
||||
|
||||
// get fire info
|
||||
fire_info = (ubyte)banks;
|
||||
fire_info &= ~(1<<7);
|
||||
if(linked){
|
||||
fire_info |= (1<<7);
|
||||
}
|
||||
DEMO_UBYTE(fire_info);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a unique message
|
||||
void demo_POST_unique_message(char *id, char *who_from, int m_source, int priority)
|
||||
{
|
||||
// sanity
|
||||
if((id == NULL) || (who_from == NULL) || (strlen(id) <= 0) || (strlen(who_from) <= 0)){
|
||||
return;
|
||||
}
|
||||
|
||||
// write it
|
||||
ubyte event = DE_UNIQUE_MESSAGE;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_STRING(id);
|
||||
DEMO_STRING(who_from);
|
||||
DEMO_INT(m_source);
|
||||
DEMO_INT(priority);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a builtin message
|
||||
void demo_POST_builtin_message(int type, ship *shipp, int priority, int timing)
|
||||
{
|
||||
int sig = 0;
|
||||
|
||||
// write it
|
||||
ubyte event = DE_BUILTIN_MESSAGE;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(type);
|
||||
if(shipp == NULL){
|
||||
sig = -1;
|
||||
} else if(shipp->objnum >= 0){
|
||||
sig = Objects[shipp->objnum].signature;
|
||||
}
|
||||
DEMO_INT(sig);
|
||||
DEMO_INT(priority);
|
||||
DEMO_INT(timing);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post an object create message
|
||||
void demo_POST_obj_create(char *pobj_name, int signature)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_OBJ_CREATE;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_STRING(pobj_name);
|
||||
DEMO_INT(signature);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a warpin event
|
||||
void demo_POST_warpin(int signature, int ship_flags)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_OBJ_WARPIN;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(signature);
|
||||
DEMO_INT(ship_flags);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a warpout event
|
||||
void demo_POST_warpout(int signature, int ship_flags)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_OBJ_WARPOUT;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(signature);
|
||||
DEMO_INT(ship_flags);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a departed event
|
||||
void demo_POST_departed(int signature, int ship_flags)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_OBJ_DEPARTED;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(signature);
|
||||
DEMO_INT(ship_flags);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
// post a ship kill event
|
||||
void demo_POST_ship_kill(object *objp)
|
||||
{
|
||||
// write it
|
||||
ubyte event = DE_SHIP_KILL;
|
||||
DEMO_UBYTE(event);
|
||||
DEMO_INT(objp->signature);
|
||||
|
||||
// up the event count
|
||||
Demo_frame_events++;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO PLAYBACK FUNCTIONS
|
||||
//
|
||||
|
||||
// read the demo header
|
||||
int demo_read_header()
|
||||
{
|
||||
int version;
|
||||
uint file_checksum, my_checksum;
|
||||
char *full_name;
|
||||
|
||||
// read the version #
|
||||
version = cfread_int(Demo_file);
|
||||
if(version != DEMO_VERSION){
|
||||
DEMO_ERROR(DEMO_ERROR_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read mission filename
|
||||
cfread_string_len(Game_current_mission_filename, MAX_FILENAME_LEN, Demo_file);
|
||||
|
||||
// get mission checksum
|
||||
file_checksum = cfread_int(Demo_file);
|
||||
full_name = cf_add_ext(Game_current_mission_filename, FS_MISSION_FILE_EXT);
|
||||
if(!cf_chksum_long(full_name, &my_checksum)){
|
||||
DEMO_ERROR(DEMO_ERROR_DISK_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
if(file_checksum != my_checksum){
|
||||
DEMO_ERROR(DEMO_ERROR_MISSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get the file offset of this first frame
|
||||
Demo_cur_offset = cftell(Demo_file);
|
||||
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
// do a playback frame
|
||||
void demo_do_playback_frame()
|
||||
{
|
||||
// seek to the best location in the demo file
|
||||
switch(demo_playback_seek()){
|
||||
// error
|
||||
case 0:
|
||||
return;
|
||||
|
||||
// continue
|
||||
case 1:
|
||||
break;
|
||||
|
||||
// found the trailer - this demo is done
|
||||
case 2:
|
||||
demo_close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// seek through the demo file to the proper location
|
||||
// return 0 on error, 1 on success/continue, 2 if the demo is done
|
||||
int demo_playback_seek()
|
||||
{
|
||||
float this_time = 0.0f;
|
||||
int frame_size;
|
||||
int this_offset;
|
||||
int ret = 0;
|
||||
|
||||
// scan until we find something useful
|
||||
while(1){
|
||||
// record the beginning of this chunk
|
||||
this_offset = cftell(Demo_file);
|
||||
|
||||
// read in the data for the next frame
|
||||
DEMO_DATA_FRAME();
|
||||
frame_size = Demo_buf_pos;
|
||||
Demo_buf_pos = 0;
|
||||
|
||||
// check the time
|
||||
DEMO_FLOAT(this_time);
|
||||
|
||||
// ahead of us
|
||||
if(this_time > f2fl(Missiontime)){
|
||||
// success
|
||||
ret = 1;
|
||||
|
||||
// seek back to the beginning of this chunk
|
||||
Demo_cur_offset = this_offset;
|
||||
|
||||
// bust out
|
||||
break;
|
||||
}
|
||||
// we should scan through this chunk
|
||||
else {
|
||||
// returns true if it finds the demo trailer
|
||||
if(demo_playback_seek_sub(frame_size)){
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// seek back to the new frame
|
||||
cfseek(Demo_file, Demo_cur_offset, CF_SEEK_SET);
|
||||
|
||||
// return
|
||||
return ret;
|
||||
}
|
||||
|
||||
// scan through a read in frame of data and apply everything necessary. returns true if the trailer (end of demo) was found
|
||||
int demo_playback_seek_sub(int frame_size)
|
||||
{
|
||||
ubyte event = 0;
|
||||
int idx;
|
||||
|
||||
// apply everything
|
||||
while(Demo_buf_pos < frame_size){
|
||||
// next event
|
||||
DEMO_UBYTE(event);
|
||||
|
||||
// process it
|
||||
switch(event){
|
||||
// oops, trailer. we're done
|
||||
case DE_TRAILER:
|
||||
return 1;
|
||||
|
||||
// object dump
|
||||
case DE_DUMP: {
|
||||
ushort obj_count = 0;
|
||||
int obj_sig = 0;
|
||||
ubyte team = 0;
|
||||
vec3d obj_pos = vmd_zero_vector;
|
||||
matrix obj_orient = vmd_identity_matrix;
|
||||
float obj_fthrust = 0;
|
||||
int ship_index = 0;
|
||||
int ship_flags = 0;
|
||||
|
||||
// get the object count
|
||||
DEMO_USHORT(obj_count);
|
||||
|
||||
// read in all the objects
|
||||
for(idx=0; idx<obj_count; idx++){
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_VECTOR(obj_pos);
|
||||
DEMO_MATRIX(obj_orient);
|
||||
DEMO_FLOAT(obj_fthrust);
|
||||
DEMO_UBYTE(team);
|
||||
DEMO_INT(ship_flags);
|
||||
|
||||
// find our ship object
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
// Assert(ship_index >= 0);
|
||||
if(ship_index >= 0){
|
||||
Objects[Ships[ship_index].objnum].pos = obj_pos;
|
||||
Objects[Ships[ship_index].objnum].orient = obj_orient;
|
||||
Objects[Ships[ship_index].objnum].phys_info.forward_thrust = obj_fthrust;
|
||||
Ships[ship_index].team = team;
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// primary fired
|
||||
case DE_PRIMARY: {
|
||||
int obj_sig = 0 ;
|
||||
ubyte fire_info = 0;
|
||||
int ship_index = -1;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_UBYTE(fire_info);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].weapons.current_primary_bank = (int)(fire_info & ~(1<<7));
|
||||
if(fire_info & (1<<7)){
|
||||
Ships[ship_index].flags |= SF_PRIMARY_LINKED;
|
||||
} else {
|
||||
Ships[ship_index].flags &= ~(SF_PRIMARY_LINKED);
|
||||
}
|
||||
|
||||
// fire
|
||||
ship_fire_primary(&Objects[Ships[ship_index].objnum], 0, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// unique message
|
||||
case DE_UNIQUE_MESSAGE: {
|
||||
char id[255] = "";
|
||||
char who_from[255] = "";
|
||||
int m_source = 0;
|
||||
int priority = 0;
|
||||
|
||||
// read the stuff in
|
||||
DEMO_STRING(id);
|
||||
DEMO_STRING(who_from);
|
||||
DEMO_INT(m_source);
|
||||
DEMO_INT(priority);
|
||||
|
||||
// send the message
|
||||
message_send_unique_to_player(id, who_from, m_source, priority, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
// builtin message
|
||||
case DE_BUILTIN_MESSAGE:{
|
||||
int type = 0;
|
||||
int sig = 0;
|
||||
int ship_index = 0;
|
||||
int priority = 0;
|
||||
int timing = 0;
|
||||
|
||||
// get data and ship
|
||||
DEMO_INT(type);
|
||||
DEMO_INT(sig);
|
||||
DEMO_INT(priority);
|
||||
DEMO_INT(timing);
|
||||
if(sig == -1){
|
||||
// message_send_builtin_to_player(type, NULL, priority, timing, 0, 0);
|
||||
} else {
|
||||
ship_index = ship_get_by_signature(sig);
|
||||
if(ship_index >= 0){
|
||||
// message_send_builtin_to_player(type, &Ships[ship_index], priority, timing, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// obj create
|
||||
case DE_OBJ_CREATE:{
|
||||
char pobj_name[255] = "";
|
||||
int obj_sig = 0;
|
||||
int objnum = 0;
|
||||
p_object *objp = NULL;
|
||||
|
||||
// try and create the ship
|
||||
DEMO_STRING(pobj_name);
|
||||
DEMO_INT(obj_sig);
|
||||
|
||||
objp = mission_parse_get_arrival_ship( pobj_name );
|
||||
if(objp != NULL){
|
||||
objnum = parse_create_object(objp);
|
||||
if(objnum >= 0){
|
||||
Objects[objnum].signature = obj_sig;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// warpin effect
|
||||
case DE_OBJ_WARPIN:{
|
||||
int obj_sig = 0;
|
||||
int ship_flags = 0;
|
||||
int ship_index = 0;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_INT(ship_flags);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
shipfx_warpin_start(&Objects[Ships[ship_index].objnum]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// warpout effect
|
||||
case DE_OBJ_WARPOUT:{
|
||||
int obj_sig = 0;
|
||||
int ship_flags = 0;
|
||||
int ship_index = 0;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_INT(ship_flags);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
shipfx_warpout_start(&Objects[Ships[ship_index].objnum]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// departed
|
||||
case DE_OBJ_DEPARTED:{
|
||||
int obj_sig = 0;
|
||||
int ship_flags = 0;
|
||||
int ship_index = 0;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
DEMO_INT(ship_flags);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Ships[ship_index].flags = ship_flags;
|
||||
ship_actually_depart(ship_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// ship kill
|
||||
case DE_SHIP_KILL:{
|
||||
int obj_sig = 0;
|
||||
int ship_index = 0;
|
||||
|
||||
// get the data and ship
|
||||
DEMO_INT(obj_sig);
|
||||
ship_index = ship_get_by_signature(obj_sig);
|
||||
if(ship_index >= 0){
|
||||
Objects[Ships[ship_index].objnum].hull_strength = 0.0f;
|
||||
ship_generic_kill_stuff(&Objects[Ships[ship_index].objnum], 1.0f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef _FS2_DEMO_SYSTEM_HEADER_FILE
|
||||
#define _FS2_DEMO_SYSTEM_HEADER_FILE
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO DEFINES/VARS
|
||||
//
|
||||
|
||||
// compile in the demo system
|
||||
#define DEMO_SYSTEM
|
||||
|
||||
struct object;
|
||||
struct ship;
|
||||
|
||||
// an error reading or writing the demo file
|
||||
#define DEMO_ERROR_NONE 0 // no error
|
||||
#define DEMO_ERROR_GENERAL 1 // general problem
|
||||
#define DEMO_ERROR_FRAMESIZE 2 // frame size was too big (> 32k)
|
||||
#define DEMO_ERROR_DISK_SPACE 3 // out of disk space
|
||||
#define DEMO_ERROR_DISK_ACCESS 4 // problem accessing disk
|
||||
#define DEMO_ERROR_VERSION 5 // bad version #
|
||||
#define DEMO_ERROR_MISSION 6 // different mission file checksums
|
||||
extern int Demo_error;
|
||||
|
||||
extern int Demo_make;
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
// DEMO FUNCTIONS
|
||||
//
|
||||
|
||||
// do frame for the demo - start for the frame
|
||||
int demo_do_frame_start();
|
||||
|
||||
// do frame for the demo - end for the frame
|
||||
int demo_do_frame_end();
|
||||
|
||||
// initialize a demo for recording
|
||||
// NOTE : call this after loading the mission and going through the briefing, but _before_ physically moving into the mission
|
||||
int demo_start_record(char *file);
|
||||
|
||||
// initialize a demo for playback - calling this will load up the demo file and move the player into the playback state
|
||||
int demo_start_playback(char *file);
|
||||
|
||||
// finish the demo, whether recording or playing back
|
||||
void demo_close();
|
||||
|
||||
// if we should run the simulation for this object, or let the demo system handle it
|
||||
int demo_should_sim(object *objp);
|
||||
|
||||
|
||||
// functions for posting critical events to the demo system ------------------------------------------------------------
|
||||
|
||||
// post an object dump event (only used internally)
|
||||
void demo_POST_object_dump();
|
||||
|
||||
// post a primary fired event
|
||||
void demo_POST_primary_fired(object *objp, int banks, int linked);
|
||||
|
||||
// post a unique message
|
||||
void demo_POST_unique_message(char *id, char *who_from, int m_source, int priority);
|
||||
|
||||
// post a builtin message
|
||||
void demo_POST_builtin_message(int type, ship *shipp, int priority, int timing);
|
||||
|
||||
// post an object create message
|
||||
void demo_POST_obj_create(char *pobj_name, int signature);
|
||||
|
||||
// post a warpin event
|
||||
void demo_POST_warpin(int signature, int ship_flags);
|
||||
|
||||
// post a warpout event
|
||||
void demo_POST_warpout(int signature, int ship_flags);
|
||||
|
||||
// post a departed event
|
||||
void demo_POST_departed(int signature, int ship_flags);
|
||||
|
||||
// post a ship kill event
|
||||
void demo_POST_ship_kill(object *objp);
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,132 +0,0 @@
|
||||
/*==========================================================================;
|
||||
*
|
||||
* Copyright (C) 1996-1997 Microsoft Corporation. All Rights Reserved.
|
||||
*
|
||||
* File: async.h
|
||||
* Content: AsyncData object include file
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __ASYNC_INCLUDED__
|
||||
#define __ASYNC_INCLUDED__
|
||||
|
||||
|
||||
#include <ole2.h> // for DECLARE_INTERFACE and HRESULT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* GUIDS used by DPAsyncData objects
|
||||
*/
|
||||
|
||||
// {47BCD7E0-2E89-11d0-A889-00A0C905433C}
|
||||
DEFINE_GUID(IID_IDPAsyncData, 0x47bcd7e0, 0x2e89, 0x11d0, 0xa8, 0x89, 0x0, 0xa0, 0xc9, 0x5, 0x43, 0x3c);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* IDPAsyncData Structures
|
||||
*
|
||||
* Various structures used to invoke DPAsyncData.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct IDPAsyncData FAR *LPDPASYNCDATA;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* IDPAsyncData Interface
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IDPAsyncData
|
||||
DECLARE_INTERFACE_( IDPAsyncData, IUnknown )
|
||||
{
|
||||
/* IUnknown Methods */
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
/* IDPAsyncData Methods */
|
||||
STDMETHOD(AddItem) (THIS_ LPDWORD, LPVOID, DWORD) PURE;
|
||||
STDMETHOD(Cancel) (THIS) PURE;
|
||||
STDMETHOD(GetFlags) (THIS_ LPDWORD) PURE;
|
||||
STDMETHOD(GetItem) (THIS_ DWORD, LPVOID *) PURE;
|
||||
STDMETHOD(GetItemCount) (THIS_ LPDWORD) PURE;
|
||||
STDMETHOD(GetStatus) (THIS_ LPDWORD, LPDWORD, HRESULT *) PURE;
|
||||
STDMETHOD(IsSnapshotCurrent) (THIS) PURE;
|
||||
STDMETHOD(RefreshSnapshot) (THIS) PURE;
|
||||
STDMETHOD(RemoveItem) (THIS_ DWORD) PURE;
|
||||
STDMETHOD(SetFlags) (THIS_ DWORD) PURE;
|
||||
STDMETHOD(SetItem) (THIS_ DWORD, LPVOID, DWORD) PURE;
|
||||
STDMETHOD(SetStatus) (THIS_ DWORD) PURE;
|
||||
STDMETHOD(SetStatusEvent) (THIS_ DWORD, HANDLE) PURE;
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* IDPAsyncData interface macros
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
|
||||
#define IDPAsyncData_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IDPAsyncData_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IDPAsyncData_Release(p) (p)->lpVtbl->Release(p)
|
||||
#define IDPAsyncData_AddItem(p) (p)->lpVtbl->AddItem(p)
|
||||
#define IDPAsyncData_Cancel(p) (p)->lpVtbl->Cancel(p)
|
||||
#define IDPAsyncData_GetItem(p,a,b) (p)->lpVtbl->GetItem(p,a,b)
|
||||
#define IDPAsyncData_GetItemCount(p,a) (p)->lpVtbl->GetItemCount(p,a)
|
||||
#define IDPAsyncData_GetStatus(p,a,b,c) (p)->lpVtbl->GetStatus(p,a,b,c)
|
||||
#define IDPAsyncData_IsSnapshotCurrent(p) (p)->lpVtbl->IsSnapshotCurrent(p)
|
||||
#define IDPAsyncData_RefreshSnapshot(p) (p)->lpVtbl->RefreshSnapshot(p)
|
||||
#define IDPAsyncData_RemoveItem(p) (p)->lpVtbl->RemoveItem(p)
|
||||
#define IDPAsyncData_SetFlags(p) (p)->lpVtbl->SetFlags(p)
|
||||
#define IDPAsyncData_SetItem(p) (p)->lpVtbl->SetItem(p)
|
||||
#define IDPAsyncData_SetStatus(p) (p)->lpVtbl->SetStatus(p)
|
||||
#define IDPAsyncData_SetStatusEvent(p,a,b) (p)->lpVtbl->SetStatusEvent(p,a,b)
|
||||
|
||||
#else /* C++ */
|
||||
|
||||
#define IDPAsyncData_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
|
||||
#define IDPAsyncData_AddRef(p) (p)->AddRef()
|
||||
#define IDPAsyncData_Release(p) (p)->Release()
|
||||
#define IDPAsyncData_AddItem(p) (p)->AddItem()
|
||||
#define IDPAsyncData_Cancel(p) (p)->Cancel()
|
||||
#define IDPAsyncData_GetItem(p,a,b) (p)->GetItem(a,b)
|
||||
#define IDPAsyncData_GetItemCount(p,a) (p)->GetItemCount(a)
|
||||
#define IDPAsyncData_GetStatus(p,a,b,c) (p)->GetStatus(a,b,c)
|
||||
#define IDPAsyncData_IsSnapshotCurrent(p) (p)->IsSnapshotCurrent()
|
||||
#define IDPAsyncData_RefreshSnapshot(p) (p)->RefreshSnapshot()
|
||||
#define IDPAsyncData_RemoveItem(p) (p)->RemoveItem()
|
||||
#define IDPAsyncData_SetFlags(p) (p)->SetFlags()
|
||||
#define IDPAsyncData_SetItem(p) (p)->SetItem()
|
||||
#define IDPAsyncData_SetStatus(p) (p)->SetStatus()
|
||||
#define IDPAsyncData_SetStatusEvent(p,a,b) (p)->SetStatusEvent(a,b)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* AsyncData Flags
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* This flag is set if the ItemData is ANSI. If it is not set, the ItemData
|
||||
* is either Unicode or doesn't contain any string information.
|
||||
*/
|
||||
#define DPASYNCDATA_ANSI (0x00000001)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __ASYNC_INCLUDED__ */
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
Binary file not shown.
File diff suppressed because it is too large.
Load diff
@@ -1,628 +0,0 @@
|
||||
/*==========================================================================;
|
||||
*
|
||||
* Copyright (C) 1996-1997 Microsoft Corporation. All Rights Reserved.
|
||||
*
|
||||
* File: dplobby.h
|
||||
* Content: DirectPlayLobby include file
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __DPLOBBY_INCLUDED__
|
||||
#define __DPLOBBY_INCLUDED__
|
||||
|
||||
#include "directx/vdplay.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* GUIDS used by DirectPlay objects
|
||||
*/
|
||||
|
||||
/* {AF465C71-9588-11cf-A020-00AA006157AC} */
|
||||
DEFINE_GUID(IID_IDirectPlayLobby, 0xaf465c71, 0x9588, 0x11cf, 0xa0, 0x20, 0x0, 0xaa, 0x0, 0x61, 0x57, 0xac);
|
||||
/* {26C66A70-B367-11cf-A024-00AA006157AC} */
|
||||
DEFINE_GUID(IID_IDirectPlayLobbyA, 0x26c66a70, 0xb367, 0x11cf, 0xa0, 0x24, 0x0, 0xaa, 0x0, 0x61, 0x57, 0xac);
|
||||
/* {0194C220-A303-11d0-9C4F-00A0C905425E} */
|
||||
DEFINE_GUID(IID_IDirectPlayLobby2, 0x194c220, 0xa303, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
/* {1BB4AF80-A303-11d0-9C4F-00A0C905425E} */
|
||||
DEFINE_GUID(IID_IDirectPlayLobby2A, 0x1bb4af80, 0xa303, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
/* {2FE8F810-B2A5-11d0-A787-0000F803ABFC} */
|
||||
DEFINE_GUID(CLSID_DirectPlayLobby, 0x2fe8f810, 0xb2a5, 0x11d0, 0xa7, 0x87, 0x0, 0x0, 0xf8, 0x3, 0xab, 0xfc);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* IDirectPlayLobby Structures
|
||||
*
|
||||
* Various structures used to invoke DirectPlayLobby.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct IDirectPlayLobby FAR *LPDIRECTPLAYLOBBY;
|
||||
typedef struct IDirectPlayLobby FAR *LPDIRECTPLAYLOBBYA;
|
||||
typedef struct IDirectPlayLobby IDirectPlayLobbyA;
|
||||
|
||||
typedef struct IDirectPlayLobby2 FAR *LPDIRECTPLAYLOBBY2;
|
||||
typedef struct IDirectPlayLobby2 FAR *LPDIRECTPLAYLOBBY2A;
|
||||
typedef struct IDirectPlayLobby2 IDirectPlayLobby2A;
|
||||
|
||||
|
||||
/*
|
||||
* DPLAPPINFO
|
||||
* Used to hold information about a registered DirectPlay
|
||||
* application
|
||||
*/
|
||||
typedef struct DPLAPPINFO
|
||||
{
|
||||
DWORD dwSize; // Size of this structure
|
||||
GUID guidApplication; // GUID of the Application
|
||||
union
|
||||
{
|
||||
LPSTR lpszAppNameA; // Pointer to the Application Name
|
||||
LPWSTR lpszAppName;
|
||||
};
|
||||
|
||||
} DPLAPPINFO, FAR *LPDPLAPPINFO;
|
||||
|
||||
/*
|
||||
* LPCDPLAPPINFO
|
||||
* A constant pointer to DPLAPPINFO
|
||||
*/
|
||||
typedef const DPLAPPINFO FAR *LPCDPLAPPINFO;
|
||||
|
||||
/*
|
||||
* DPCOMPOUNDADDRESSELEMENT
|
||||
*
|
||||
* An array of these is passed to CreateCompoundAddresses()
|
||||
*/
|
||||
typedef struct DPCOMPOUNDADDRESSELEMENT
|
||||
{
|
||||
GUID guidDataType;
|
||||
DWORD dwDataSize;
|
||||
LPVOID lpData;
|
||||
} DPCOMPOUNDADDRESSELEMENT, FAR *LPDPCOMPOUNDADDRESSELEMENT;
|
||||
|
||||
/*
|
||||
* LPCDPCOMPOUNDADDRESSELEMENT
|
||||
* A constant pointer to DPCOMPOUNDADDRESSELEMENT
|
||||
*/
|
||||
typedef const DPCOMPOUNDADDRESSELEMENT FAR *LPCDPCOMPOUNDADDRESSELEMENT;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Enumeration Method Callback Prototypes
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Callback for EnumAddress()
|
||||
*/
|
||||
typedef BOOL (FAR PASCAL *LPDPENUMADDRESSCALLBACK)(
|
||||
REFGUID guidDataType,
|
||||
DWORD dwDataSize,
|
||||
LPCVOID lpData,
|
||||
LPVOID lpContext);
|
||||
|
||||
/*
|
||||
* Callback for EnumAddressTypes()
|
||||
*/
|
||||
typedef BOOL (FAR PASCAL *LPDPLENUMADDRESSTYPESCALLBACK)(
|
||||
REFGUID guidDataType,
|
||||
LPVOID lpContext,
|
||||
DWORD dwFlags);
|
||||
|
||||
/*
|
||||
* Callback for EnumLocalApplications()
|
||||
*/
|
||||
typedef BOOL (FAR PASCAL * LPDPLENUMLOCALAPPLICATIONSCALLBACK)(
|
||||
LPCDPLAPPINFO lpAppInfo,
|
||||
LPVOID lpContext,
|
||||
DWORD dwFlags);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DirectPlayLobby API Prototypes
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifdef UNICODE
|
||||
#define DirectPlayLobbyCreate DirectPlayLobbyCreateW
|
||||
#else
|
||||
#define DirectPlayLobbyCreate DirectPlayLobbyCreateA
|
||||
#endif /* UNICODE */
|
||||
|
||||
extern HRESULT WINAPI DirectPlayLobbyCreateW(LPGUID, LPDIRECTPLAYLOBBY *, IUnknown *, LPVOID, DWORD );
|
||||
extern HRESULT WINAPI DirectPlayLobbyCreateA(LPGUID, LPDIRECTPLAYLOBBYA *, IUnknown *, LPVOID, DWORD );
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* IDirectPlayLobby (and IDirectPlayLobbyA) Interface
|
||||
*
|
||||
****************************************************************************/
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IDirectPlayLobby
|
||||
DECLARE_INTERFACE_( IDirectPlayLobby, IUnknown )
|
||||
{
|
||||
/* IUnknown Methods */
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
/* IDirectPlayLobby Methods */
|
||||
STDMETHOD(Connect) (THIS_ DWORD, LPDIRECTPLAY2 *, IUnknown FAR *) PURE;
|
||||
STDMETHOD(CreateAddress) (THIS_ REFGUID, REFGUID, LPCVOID, DWORD, LPVOID, LPDWORD) PURE;
|
||||
STDMETHOD(EnumAddress) (THIS_ LPDPENUMADDRESSCALLBACK, LPCVOID, DWORD, LPVOID) PURE;
|
||||
STDMETHOD(EnumAddressTypes) (THIS_ LPDPLENUMADDRESSTYPESCALLBACK, REFGUID, LPVOID, DWORD) PURE;
|
||||
STDMETHOD(EnumLocalApplications)(THIS_ LPDPLENUMLOCALAPPLICATIONSCALLBACK, LPVOID, DWORD) PURE;
|
||||
STDMETHOD(GetConnectionSettings)(THIS_ DWORD, LPVOID, LPDWORD) PURE;
|
||||
STDMETHOD(ReceiveLobbyMessage) (THIS_ DWORD, DWORD, LPDWORD, LPVOID, LPDWORD) PURE;
|
||||
STDMETHOD(RunApplication) (THIS_ DWORD, LPDWORD, LPDPLCONNECTION, HANDLE) PURE;
|
||||
STDMETHOD(SendLobbyMessage) (THIS_ DWORD, DWORD, LPVOID, DWORD) PURE;
|
||||
STDMETHOD(SetConnectionSettings)(THIS_ DWORD, DWORD, LPDPLCONNECTION) PURE;
|
||||
STDMETHOD(SetLobbyMessageEvent) (THIS_ DWORD, DWORD, HANDLE) PURE;
|
||||
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* IDirectPlayLobby2 (and IDirectPlayLobby2A) Interface
|
||||
*
|
||||
****************************************************************************/
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IDirectPlayLobby2
|
||||
DECLARE_INTERFACE_( IDirectPlayLobby2, IDirectPlayLobby )
|
||||
{
|
||||
/* IUnknown Methods */
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
/* IDirectPlayLobby Methods */
|
||||
STDMETHOD(Connect) (THIS_ DWORD, LPDIRECTPLAY2 *, IUnknown FAR *) PURE;
|
||||
STDMETHOD(CreateAddress) (THIS_ REFGUID, REFGUID, LPCVOID, DWORD, LPVOID, LPDWORD) PURE;
|
||||
STDMETHOD(EnumAddress) (THIS_ LPDPENUMADDRESSCALLBACK, LPCVOID, DWORD, LPVOID) PURE;
|
||||
STDMETHOD(EnumAddressTypes) (THIS_ LPDPLENUMADDRESSTYPESCALLBACK, REFGUID, LPVOID, DWORD) PURE;
|
||||
STDMETHOD(EnumLocalApplications)(THIS_ LPDPLENUMLOCALAPPLICATIONSCALLBACK, LPVOID, DWORD) PURE;
|
||||
STDMETHOD(GetConnectionSettings)(THIS_ DWORD, LPVOID, LPDWORD) PURE;
|
||||
STDMETHOD(ReceiveLobbyMessage) (THIS_ DWORD, DWORD, LPDWORD, LPVOID, LPDWORD) PURE;
|
||||
STDMETHOD(RunApplication) (THIS_ DWORD, LPDWORD, LPDPLCONNECTION, HANDLE) PURE;
|
||||
STDMETHOD(SendLobbyMessage) (THIS_ DWORD, DWORD, LPVOID, DWORD) PURE;
|
||||
STDMETHOD(SetConnectionSettings)(THIS_ DWORD, DWORD, LPDPLCONNECTION) PURE;
|
||||
STDMETHOD(SetLobbyMessageEvent) (THIS_ DWORD, DWORD, HANDLE) PURE;
|
||||
|
||||
/* IDirectPlayLobby2 Methods */
|
||||
STDMETHOD(CreateCompoundAddress)(THIS_ LPCDPCOMPOUNDADDRESSELEMENT,DWORD,LPVOID,LPDWORD) PURE;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* IDirectPlayLobby interface macros
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
|
||||
#define IDirectPlayLobby_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IDirectPlayLobby_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IDirectPlayLobby_Release(p) (p)->lpVtbl->Release(p)
|
||||
#define IDirectPlayLobby_Connect(p,a,b,c) (p)->lpVtbl->Connect(p,a,b,c)
|
||||
#define IDirectPlayLobby_CreateAddress(p,a,b,c,d,e,f) (p)->lpVtbl->CreateAddress(p,a,b,c,d,e,f)
|
||||
#define IDirectPlayLobby_CreateCompoundAddress(p,a,b,c,d) (p)->lpVtbl->CreateCompoundAddress(p,a,b,c,d)
|
||||
#define IDirectPlayLobby_EnumAddress(p,a,b,c,d) (p)->lpVtbl->EnumAddress(p,a,b,c,d)
|
||||
#define IDirectPlayLobby_EnumAddressTypes(p,a,b,c,d) (p)->lpVtbl->EnumAddressTypes(p,a,b,c,d)
|
||||
#define IDirectPlayLobby_EnumLocalApplications(p,a,b,c) (p)->lpVtbl->EnumLocalApplications(p,a,b,c)
|
||||
#define IDirectPlayLobby_GetConnectionSettings(p,a,b,c) (p)->lpVtbl->GetConnectionSettings(p,a,b,c)
|
||||
#define IDirectPlayLobby_ReceiveLobbyMessage(p,a,b,c,d,e) (p)->lpVtbl->ReceiveLobbyMessage(p,a,b,c,d,e)
|
||||
#define IDirectPlayLobby_RunApplication(p,a,b,c,d) (p)->lpVtbl->RunApplication(p,a,b,c,d)
|
||||
#define IDirectPlayLobby_SendLobbyMessage(p,a,b,c,d) (p)->lpVtbl->SendLobbyMessage(p,a,b,c,d)
|
||||
#define IDirectPlayLobby_SetConnectionSettings(p,a,b,c) (p)->lpVtbl->SetConnectionSettings(p,a,b,c)
|
||||
#define IDirectPlayLobby_SetLobbyMessageEvent(p,a,b,c) (p)->lpVtbl->SetLobbyMessageEvent(p,a,b,c)
|
||||
|
||||
#else /* C++ */
|
||||
|
||||
#define IDirectPlayLobby_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
|
||||
#define IDirectPlayLobby_AddRef(p) (p)->AddRef()
|
||||
#define IDirectPlayLobby_Release(p) (p)->Release()
|
||||
#define IDirectPlayLobby_Connect(p,a,b,c) (p)->Connect(a,b,c)
|
||||
#define IDirectPlayLobby_CreateAddress(p,a,b,c,d,e,f) (p)->CreateAddress(a,b,c,d,e,f)
|
||||
#define IDirectPlayLobby_CreateCompoundAddress(p,a,b,c,d) (p)->lpVtbl->CreateCompoundAddress(a,b,c,d)
|
||||
#define IDirectPlayLobby_EnumAddress(p,a,b,c,d) (p)->EnumAddress(a,b,c,d)
|
||||
#define IDirectPlayLobby_EnumAddressTypes(p,a,b,c,d) (p)->EnumAddressTypes(a,b,c,d)
|
||||
#define IDirectPlayLobby_EnumLocalApplications(p,a,b,c) (p)->EnumLocalApplications(a,b,c)
|
||||
#define IDirectPlayLobby_GetConnectionSettings(p,a,b,c) (p)->GetConnectionSettings(a,b,c)
|
||||
#define IDirectPlayLobby_ReceiveLobbyMessage(p,a,b,c,d,e) (p)->ReceiveLobbyMessage(a,b,c,d,e)
|
||||
#define IDirectPlayLobby_RunApplication(p,a,b,c,d) (p)->RunApplication(a,b,c,d)
|
||||
#define IDirectPlayLobby_SendLobbyMessage(p,a,b,c,d) (p)->SendLobbyMessage(a,b,c,d)
|
||||
#define IDirectPlayLobby_SetConnectionSettings(p,a,b,c) (p)->SetConnectionSettings(a,b,c)
|
||||
#define IDirectPlayLobby_SetLobbyMessageEvent(p,a,b,c) (p)->SetLobbyMessageEvent(a,b,c)
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DirectPlayLobby Flags
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* This is a message flag used by ReceiveLobbyMessage. It can be
|
||||
* returned in the dwMessageFlags parameter to indicate a message from
|
||||
* the system.
|
||||
*/
|
||||
#define DPLMSG_SYSTEM 0x00000001
|
||||
|
||||
/*
|
||||
* This is a message flag used by ReceiveLobbyMessage and SendLobbyMessage.
|
||||
* It is used to indicate that the message is a standard lobby message.
|
||||
* DPLMSG_SETPROPERTY, DPLMSG_SETPROPERTYRESPONSE, DPLMSG_GETPROPERTY,
|
||||
* DPLMSG_GETPROPERTYRESPONSE
|
||||
*/
|
||||
#define DPLMSG_STANDARD 0x00000002
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DirectPlayLobby messages and message data structures
|
||||
*
|
||||
* All system messages have a dwMessageFlags value of DPLMSG_SYSTEM returned
|
||||
* from a call to ReceiveLobbyMessage.
|
||||
*
|
||||
* All standard messages have a dwMessageFlags value of DPLMSG_STANDARD returned
|
||||
* from a call to ReceiveLobbyMessage.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* DPLMSG_GENERIC
|
||||
* Generic message structure used to identify the message type.
|
||||
*/
|
||||
typedef struct _DPLMSG_GENERIC
|
||||
{
|
||||
DWORD dwType; // Message type
|
||||
} DPLMSG_GENERIC, FAR *LPDPLMSG_GENERIC;
|
||||
|
||||
/*
|
||||
* DPLMSG_SETPROPERTY
|
||||
* Standard message sent by an application to a lobby to set a
|
||||
* property
|
||||
*/
|
||||
typedef struct _DPLMSG_SETPROPERTY
|
||||
{
|
||||
DWORD dwType; // Message type
|
||||
DWORD dwRequestID; // Request ID (DPL_NOCONFIRMATION if no confirmation desired)
|
||||
GUID guidPlayer; // Player GUID
|
||||
GUID guidPropertyTag; // Property GUID
|
||||
DWORD dwDataSize; // Size of data
|
||||
DWORD dwPropertyData[1]; // Buffer containing data
|
||||
} DPLMSG_SETPROPERTY, FAR *LPDPLMSG_SETPROPERTY;
|
||||
|
||||
#define DPL_NOCONFIRMATION 0
|
||||
|
||||
/*
|
||||
* DPLMSG_SETPROPERTYRESPONSE
|
||||
* Standard message returned by a lobby to confirm a
|
||||
* DPLMSG_SETPROPERTY message.
|
||||
*/
|
||||
typedef struct _DPLMSG_SETPROPERTYRESPONSE
|
||||
{
|
||||
DWORD dwType; // Message type
|
||||
DWORD dwRequestID; // Request ID
|
||||
GUID guidPlayer; // Player GUID
|
||||
GUID guidPropertyTag; // Property GUID
|
||||
HRESULT hr; // Return Code
|
||||
} DPLMSG_SETPROPERTYRESPONSE, FAR *LPDPLMSG_SETPROPERTYRESPONSE;
|
||||
|
||||
/*
|
||||
* DPLMSG_GETPROPERTY
|
||||
* Standard message sent by an application to a lobby to request
|
||||
* the current value of a property
|
||||
*/
|
||||
typedef struct _DPLMSG_GETPROPERTY
|
||||
{
|
||||
DWORD dwType; // Message type
|
||||
DWORD dwRequestID; // Request ID
|
||||
GUID guidPlayer; // Player GUID
|
||||
GUID guidPropertyTag; // Property GUID
|
||||
} DPLMSG_GETPROPERTY, FAR *LPDPLMSG_GETPROPERTY;
|
||||
|
||||
/*
|
||||
* DPLMSG_GETPROPERTYRESPONSE
|
||||
* Standard message returned by a lobby in response to a
|
||||
* DPLMSG_GETPROPERTY message.
|
||||
*/
|
||||
typedef struct _DPLMSG_GETPROPERTYRESPONSE
|
||||
{
|
||||
DWORD dwType; // Message type
|
||||
DWORD dwRequestID; // Request ID
|
||||
GUID guidPlayer; // Player GUID
|
||||
GUID guidPropertyTag; // Property GUID
|
||||
HRESULT hr; // Return Code
|
||||
DWORD dwDataSize; // Size of data
|
||||
DWORD dwPropertyData[1]; // Buffer containing data
|
||||
} DPLMSG_GETPROPERTYRESPONSE, FAR *LPDPLMSG_GETPROPERTYRESPONSE;
|
||||
|
||||
|
||||
/******************************************
|
||||
*
|
||||
* DirectPlay Lobby message dwType values
|
||||
*
|
||||
*****************************************/
|
||||
|
||||
/*
|
||||
* The application has read the connection settings.
|
||||
* It is now O.K. for the lobby client to release
|
||||
* its IDirectPlayLobby interface.
|
||||
*/
|
||||
#define DPLSYS_CONNECTIONSETTINGSREAD 0x00000001
|
||||
|
||||
/*
|
||||
* The application's call to DirectPlayConnect failed
|
||||
*/
|
||||
#define DPLSYS_DPLAYCONNECTFAILED 0x00000002
|
||||
|
||||
/*
|
||||
* The application has created a DirectPlay session.
|
||||
*/
|
||||
#define DPLSYS_DPLAYCONNECTSUCCEEDED 0x00000003
|
||||
|
||||
/*
|
||||
* The application has terminated.
|
||||
*/
|
||||
#define DPLSYS_APPTERMINATED 0x00000004
|
||||
|
||||
/*
|
||||
* The message is a DPLMSG_SETPROPERTY message.
|
||||
*/
|
||||
#define DPLSYS_SETPROPERTY 0x00000005
|
||||
|
||||
/*
|
||||
* The message is a DPLMSG_SETPROPERTYRESPONSE message.
|
||||
*/
|
||||
#define DPLSYS_SETPROPERTYRESPONSE 0x00000006
|
||||
|
||||
/*
|
||||
* The message is a DPLMSG_GETPROPERTY message.
|
||||
*/
|
||||
#define DPLSYS_GETPROPERTY 0x00000007
|
||||
|
||||
/*
|
||||
* The message is a DPLMSG_GETPROPERTYRESPONSE message.
|
||||
*/
|
||||
#define DPLSYS_GETPROPERTYRESPONSE 0x00000008
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DirectPlay defined property GUIDs and associated data structures
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* DPLPROPERTY_MessagesSupported
|
||||
*
|
||||
* Request whether the lobby supports standard. Lobby with respond with either
|
||||
* TRUE or FALSE or may not respond at all.
|
||||
*
|
||||
* Property data is a single BOOL with TRUE or FALSE
|
||||
*/
|
||||
// {762CCDA1-D916-11d0-BA39-00C04FD7ED67}
|
||||
DEFINE_GUID(DPLPROPERTY_MessagesSupported,
|
||||
0x762ccda1, 0xd916, 0x11d0, 0xba, 0x39, 0x0, 0xc0, 0x4f, 0xd7, 0xed, 0x67);
|
||||
|
||||
/*
|
||||
* DPLPROPERTY_LobbyGuid
|
||||
*
|
||||
* Request the GUID that identifies the lobby software that the application
|
||||
* is communicating with.
|
||||
*
|
||||
* Property data is a single GUID.
|
||||
*/
|
||||
// {F56920A0-D218-11d0-BA39-00C04FD7ED67}
|
||||
DEFINE_GUID(DPLPROPERTY_LobbyGuid,
|
||||
0xf56920a0, 0xd218, 0x11d0, 0xba, 0x39, 0x0, 0xc0, 0x4f, 0xd7, 0xed, 0x67);
|
||||
|
||||
/*
|
||||
* DPLPROPERTY_PlayerGuid
|
||||
*
|
||||
* Request the GUID that identifies the player on this machine for sending
|
||||
* property data back to the lobby.
|
||||
*
|
||||
* Property data is the DPLDATA_PLAYERDATA structure
|
||||
*/
|
||||
// {B4319322-D20D-11d0-BA39-00C04FD7ED67}
|
||||
DEFINE_GUID(DPLPROPERTY_PlayerGuid,
|
||||
0xb4319322, 0xd20d, 0x11d0, 0xba, 0x39, 0x0, 0xc0, 0x4f, 0xd7, 0xed, 0x67);
|
||||
|
||||
/*
|
||||
* DPLDATA_PLAYERGUID
|
||||
*
|
||||
* Data structure to hold the GUID of the player and player creation flags
|
||||
* from the lobby.
|
||||
*/
|
||||
typedef struct _DPLDATA_PLAYERGUID
|
||||
{
|
||||
GUID guidPlayer;
|
||||
DWORD dwPlayerFlags;
|
||||
} DPLDATA_PLAYERGUID, FAR *LPDPLDATA_PLAYERGUID;
|
||||
|
||||
/*
|
||||
* DPLPROPERTY_PlayerScore
|
||||
*
|
||||
* Used to send an array of long integers to the lobby indicating the
|
||||
* score of a player.
|
||||
*
|
||||
* Property data is the DPLDATA_PLAYERSCORE structure.
|
||||
*/
|
||||
// {48784000-D219-11d0-BA39-00C04FD7ED67}
|
||||
DEFINE_GUID(DPLPROPERTY_PlayerScore,
|
||||
0x48784000, 0xd219, 0x11d0, 0xba, 0x39, 0x0, 0xc0, 0x4f, 0xd7, 0xed, 0x67);
|
||||
|
||||
/*
|
||||
* DPLDATA_PLAYERSCORE
|
||||
*
|
||||
* Data structure to hold an array of long integers representing a player score.
|
||||
* Application must allocate enough memory to hold all the scores.
|
||||
*/
|
||||
typedef struct _DPLDATA_PLAYERSCORE
|
||||
{
|
||||
DWORD dwScoreCount;
|
||||
LONG Score[1];
|
||||
} DPLDATA_PLAYERSCORE, FAR *LPDPLDATA_PLAYERSCORE;
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DirectPlay Address ID's
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* DirectPlay Address
|
||||
*
|
||||
* A DirectPlay address consists of multiple chunks of data, each tagged
|
||||
* with a GUID signifying the type of data in the chunk. The chunk also
|
||||
* has a length so that unknown chunk types can be skipped.
|
||||
*
|
||||
* The EnumAddress() function is used to parse these address data chunks.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DPADDRESS
|
||||
*
|
||||
* Header for block of address data elements
|
||||
*/
|
||||
typedef struct _DPADDRESS
|
||||
{
|
||||
GUID guidDataType;
|
||||
DWORD dwDataSize;
|
||||
} DPADDRESS;
|
||||
|
||||
typedef DPADDRESS FAR *LPDPADDRESS;
|
||||
|
||||
/*
|
||||
* DPAID_TotalSize
|
||||
*
|
||||
* Chunk is a DWORD containing size of entire DPADDRESS structure
|
||||
*/
|
||||
|
||||
// {1318F560-912C-11d0-9DAA-00A0C90A43CB}
|
||||
DEFINE_GUID(DPAID_TotalSize,
|
||||
0x1318f560, 0x912c, 0x11d0, 0x9d, 0xaa, 0x0, 0xa0, 0xc9, 0xa, 0x43, 0xcb);
|
||||
|
||||
/*
|
||||
* DPAID_ServiceProvider
|
||||
*
|
||||
* Chunk is a GUID describing the service provider that created the chunk.
|
||||
* All addresses must contain this chunk.
|
||||
*/
|
||||
|
||||
// {07D916C0-E0AF-11cf-9C4E-00A0C905425E}
|
||||
DEFINE_GUID(DPAID_ServiceProvider,
|
||||
0x7d916c0, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
|
||||
/*
|
||||
* DPAID_LobbyProvider
|
||||
*
|
||||
* Chunk is a GUID describing the lobby provider that created the chunk.
|
||||
* All addresses must contain this chunk.
|
||||
*/
|
||||
|
||||
// {59B95640-9667-11d0-A77D-0000F803ABFC}
|
||||
DEFINE_GUID(DPAID_LobbyProvider,
|
||||
0x59b95640, 0x9667, 0x11d0, 0xa7, 0x7d, 0x0, 0x0, 0xf8, 0x3, 0xab, 0xfc);
|
||||
|
||||
/*
|
||||
* DPAID_Phone and DPAID_PhoneW
|
||||
*
|
||||
* Chunk is a string containing a phone number (i.e. "1-800-555-1212")
|
||||
* in ANSI or UNICODE format
|
||||
*/
|
||||
|
||||
// {78EC89A0-E0AF-11cf-9C4E-00A0C905425E}
|
||||
DEFINE_GUID(DPAID_Phone,
|
||||
0x78ec89a0, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
|
||||
// {BA5A7A70-9DBF-11d0-9CC1-00A0C905425E}
|
||||
DEFINE_GUID(DPAID_PhoneW,
|
||||
0xba5a7a70, 0x9dbf, 0x11d0, 0x9c, 0xc1, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
|
||||
/*
|
||||
* DPAID_Modem and DPAID_ModemW
|
||||
*
|
||||
* Chunk is a string containing a modem name registered with TAPI
|
||||
* in ANSI or UNICODE format
|
||||
*/
|
||||
|
||||
// {F6DCC200-A2FE-11d0-9C4F-00A0C905425E}
|
||||
DEFINE_GUID(DPAID_Modem,
|
||||
0xf6dcc200, 0xa2fe, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
|
||||
// {01FD92E0-A2FF-11d0-9C4F-00A0C905425E}
|
||||
DEFINE_GUID(DPAID_ModemW,
|
||||
0x1fd92e0, 0xa2ff, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
|
||||
/*
|
||||
* DPAID_Inet and DPAID_InetW
|
||||
*
|
||||
* Chunk is a string containing a TCP/IP host name or an IP address
|
||||
* (i.e. "dplay.microsoft.com" or "137.55.100.173") in ANSI or UNICODE format
|
||||
*/
|
||||
|
||||
// {C4A54DA0-E0AF-11cf-9C4E-00A0C905425E}
|
||||
DEFINE_GUID(DPAID_INet,
|
||||
0xc4a54da0, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
|
||||
// {E63232A0-9DBF-11d0-9CC1-00A0C905425E}
|
||||
DEFINE_GUID(DPAID_INetW,
|
||||
0xe63232a0, 0x9dbf, 0x11d0, 0x9c, 0xc1, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
|
||||
/*
|
||||
* DPCOMPORTADDRESS
|
||||
*
|
||||
* Used to specify com port settings. The constants that define baud rate,
|
||||
* stop bits and parity are defined in WINBASE.H. The constants for flow
|
||||
* control are given below.
|
||||
*/
|
||||
|
||||
#define DPCPA_NOFLOW 0 // no flow control
|
||||
#define DPCPA_XONXOFFFLOW 1 // software flow control
|
||||
#define DPCPA_RTSFLOW 2 // hardware flow control with RTS
|
||||
#define DPCPA_DTRFLOW 3 // hardware flow control with DTR
|
||||
#define DPCPA_RTSDTRFLOW 4 // hardware flow control with RTS and DTR
|
||||
|
||||
typedef struct _DPCOMPORTADDRESS
|
||||
{
|
||||
DWORD dwComPort; // COM port to use (1-4)
|
||||
DWORD dwBaudRate; // baud rate (100-256k)
|
||||
DWORD dwStopBits; // no. stop bits (1-2)
|
||||
DWORD dwParity; // parity (none, odd, even, mark)
|
||||
DWORD dwFlowControl; // flow control (none, xon/xoff, rts, dtr)
|
||||
} DPCOMPORTADDRESS;
|
||||
|
||||
typedef DPCOMPORTADDRESS FAR *LPDPCOMPORTADDRESS;
|
||||
|
||||
/*
|
||||
* DPAID_ComPort
|
||||
*
|
||||
* Chunk contains a DPCOMPORTADDRESS structure defining the serial port.
|
||||
*/
|
||||
|
||||
// {F2F0CE00-E0AF-11cf-9C4E-00A0C905425E}
|
||||
DEFINE_GUID(DPAID_ComPort,
|
||||
0xf2f0ce00, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* dplobby 1.0 obsolete definitions
|
||||
* Included for compatibility only.
|
||||
*
|
||||
****************************************************************************/
|
||||
#define DPLAD_SYSTEM DPLMSG_SYSTEM
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __DPLOBBY_INCLUDED__ */
|
||||
@@ -1,268 +0,0 @@
|
||||
/*==========================================================================
|
||||
*
|
||||
* Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
|
||||
*
|
||||
* File: dsetup.h
|
||||
* Content: DirectXSetup, error codes and flags
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __DSETUP_H__
|
||||
#define __DSETUP_H__
|
||||
|
||||
#include <windows.h> // windows stuff
|
||||
|
||||
#ifdef _WIN32
|
||||
#define COM_NO_WINDOWS_H
|
||||
#include <objbase.h>
|
||||
#else
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// DSETUP Error Codes, must remain compatible with previous setup.
|
||||
#define DSETUPERR_SUCCESS_RESTART 1
|
||||
#define DSETUPERR_SUCCESS 0
|
||||
#define DSETUPERR_BADWINDOWSVERSION -1
|
||||
#define DSETUPERR_SOURCEFILENOTFOUND -2
|
||||
#define DSETUPERR_BADSOURCESIZE -3
|
||||
#define DSETUPERR_BADSOURCETIME -4
|
||||
#define DSETUPERR_NOCOPY -5
|
||||
#define DSETUPERR_OUTOFDISKSPACE -6
|
||||
#define DSETUPERR_CANTFINDINF -7
|
||||
#define DSETUPERR_CANTFINDDIR -8
|
||||
#define DSETUPERR_INTERNAL -9
|
||||
#define DSETUPERR_NTWITHNO3D -10 /* REM: obsolete, you'll never see this */
|
||||
#define DSETUPERR_UNKNOWNOS -11
|
||||
#define DSETUPERR_USERHITCANCEL -12
|
||||
#define DSETUPERR_NOTPREINSTALLEDONNT -13
|
||||
|
||||
// DSETUP flags. DirectX 5.0 apps should use these flags only.
|
||||
#define DSETUP_DDRAWDRV 0x00000008 /* install DirectDraw Drivers */
|
||||
#define DSETUP_DSOUNDDRV 0x00000010 /* install DirectSound Drivers */
|
||||
#define DSETUP_DXCORE 0x00010000 /* install DirectX runtime */
|
||||
#define DSETUP_DIRECTX (DSETUP_DXCORE|DSETUP_DDRAWDRV|DSETUP_DSOUNDDRV)
|
||||
#define DSETUP_TESTINSTALL 0x00020000 /* just test install, don't do anything */
|
||||
|
||||
// These OBSOLETE flags are here for compatibility with pre-DX5 apps only.
|
||||
// They are present to allow DX3 apps to be recompiled with DX5 and still work.
|
||||
// DO NOT USE THEM for DX5. They will go away in future DX releases.
|
||||
#define DSETUP_DDRAW 0x00000001 /* OBSOLETE. install DirectDraw */
|
||||
#define DSETUP_DSOUND 0x00000002 /* OBSOLETE. install DirectSound */
|
||||
#define DSETUP_DPLAY 0x00000004 /* OBSOLETE. install DirectPlay */
|
||||
#define DSETUP_DPLAYSP 0x00000020 /* OBSOLETE. install DirectPlay Providers */
|
||||
#define DSETUP_DVIDEO 0x00000040 /* OBSOLETE. install DirectVideo */
|
||||
#define DSETUP_D3D 0x00000200 /* OBSOLETE. install Direct3D */
|
||||
#define DSETUP_DINPUT 0x00000800 /* OBSOLETE. install DirectInput */
|
||||
#define DSETUP_DIRECTXSETUP 0x00001000 /* OBSOLETE. install DirectXSetup DLL's */
|
||||
#define DSETUP_NOUI 0x00002000 /* OBSOLETE. install DirectX with NO UI */
|
||||
#define DSETUP_PROMPTFORDRIVERS 0x10000000 /* OBSOLETE. prompt when replacing display/audio drivers */
|
||||
#define DSETUP_RESTOREDRIVERS 0x20000000 /* OBSOLETE. restore display/audio drivers */
|
||||
|
||||
|
||||
|
||||
//******************************************************************
|
||||
// DirectX Setup Callback mechanism
|
||||
//******************************************************************
|
||||
|
||||
// DSETUP Message Info Codes, passed to callback as Reason parameter.
|
||||
#define DSETUP_CB_MSG_NOMESSAGE 0
|
||||
#define DSETUP_CB_MSG_CANTINSTALL_UNKNOWNOS 1
|
||||
#define DSETUP_CB_MSG_CANTINSTALL_NT 2
|
||||
#define DSETUP_CB_MSG_CANTINSTALL_BETA 3
|
||||
#define DSETUP_CB_MSG_CANTINSTALL_NOTWIN32 4
|
||||
#define DSETUP_CB_MSG_CANTINSTALL_WRONGLANGUAGE 5
|
||||
#define DSETUP_CB_MSG_CANTINSTALL_WRONGPLATFORM 6
|
||||
#define DSETUP_CB_MSG_PREINSTALL_NT 7
|
||||
#define DSETUP_CB_MSG_NOTPREINSTALLEDONNT 8
|
||||
#define DSETUP_CB_MSG_SETUP_INIT_FAILED 9
|
||||
#define DSETUP_CB_MSG_INTERNAL_ERROR 10
|
||||
#define DSETUP_CB_MSG_CHECK_DRIVER_UPGRADE 11
|
||||
#define DSETUP_CB_MSG_OUTOFDISKSPACE 12
|
||||
#define DSETUP_CB_MSG_BEGIN_INSTALL 13
|
||||
#define DSETUP_CB_MSG_BEGIN_INSTALL_RUNTIME 14
|
||||
#define DSETUP_CB_MSG_BEGIN_INSTALL_DRIVERS 15
|
||||
#define DSETUP_CB_MSG_BEGIN_RESTORE_DRIVERS 16
|
||||
#define DSETUP_CB_MSG_FILECOPYERROR 17
|
||||
|
||||
|
||||
#define DSETUP_CB_UPGRADE_TYPE_MASK 0x000F
|
||||
#define DSETUP_CB_UPGRADE_KEEP 0x0001
|
||||
#define DSETUP_CB_UPGRADE_SAFE 0x0002
|
||||
#define DSETUP_CB_UPGRADE_FORCE 0x0004
|
||||
#define DSETUP_CB_UPGRADE_UNKNOWN 0x0008
|
||||
|
||||
#define DSETUP_CB_UPGRADE_HASWARNINGS 0x0100
|
||||
#define DSETUP_CB_UPGRADE_CANTBACKUP 0x0200
|
||||
|
||||
#define DSETUP_CB_UPGRADE_DEVICE_ACTIVE 0x0800
|
||||
|
||||
#define DSETUP_CB_UPGRADE_DEVICE_DISPLAY 0x1000
|
||||
#define DSETUP_CB_UPGRADE_DEVICE_MEDIA 0x2000
|
||||
|
||||
|
||||
typedef struct _DSETUP_CB_UPGRADEINFO
|
||||
{
|
||||
DWORD UpgradeFlags;
|
||||
} DSETUP_CB_UPGRADEINFO;
|
||||
|
||||
typedef struct _DSETUP_CB_FILECOPYERROR
|
||||
{
|
||||
DWORD dwError;
|
||||
} DSETUP_CB_FILECOPYERROR;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Data Structures
|
||||
//
|
||||
#ifndef UNICODE_ONLY
|
||||
typedef struct _DIRECTXREGISTERAPPA {
|
||||
DWORD dwSize;
|
||||
DWORD dwFlags;
|
||||
LPSTR lpszApplicationName;
|
||||
LPGUID lpGUID;
|
||||
LPSTR lpszFilename;
|
||||
LPSTR lpszCommandLine;
|
||||
LPSTR lpszPath;
|
||||
LPSTR lpszCurrentDirectory;
|
||||
} DIRECTXREGISTERAPPA, *PDIRECTXREGISTERAPPA, *LPDIRECTXREGISTERAPPA;
|
||||
#endif //!UNICODE_ONLY
|
||||
#ifndef ANSI_ONLY
|
||||
typedef struct _DIRECTXREGISTERAPPW {
|
||||
DWORD dwSize;
|
||||
DWORD dwFlags;
|
||||
LPWSTR lpszApplicationName;
|
||||
LPGUID lpGUID;
|
||||
LPWSTR lpszFilename;
|
||||
LPWSTR lpszCommandLine;
|
||||
LPWSTR lpszPath;
|
||||
LPWSTR lpszCurrentDirectory;
|
||||
} DIRECTXREGISTERAPPW, *PDIRECTXREGISTERAPPW, *LPDIRECTXREGISTERAPPW;
|
||||
#endif //!ANSI_ONLY
|
||||
#ifdef UNICODE
|
||||
typedef DIRECTXREGISTERAPPW DIRECTXREGISTERAPP;
|
||||
typedef PDIRECTXREGISTERAPPW PDIRECTXREGISTERAPP;
|
||||
typedef LPDIRECTXREGISTERAPPW LPDIRECTXREGISTERAPP;
|
||||
#else
|
||||
typedef DIRECTXREGISTERAPPA DIRECTXREGISTERAPP;
|
||||
typedef PDIRECTXREGISTERAPPA PDIRECTXREGISTERAPP;
|
||||
typedef LPDIRECTXREGISTERAPPA LPDIRECTXREGISTERAPP;
|
||||
#endif // UNICODE
|
||||
|
||||
|
||||
//
|
||||
// API
|
||||
//
|
||||
#ifndef UNICODE_ONLY
|
||||
INT
|
||||
WINAPI
|
||||
DirectXSetupA(
|
||||
HWND hWnd,
|
||||
LPSTR lpszRootPath,
|
||||
DWORD dwFlags
|
||||
);
|
||||
#endif //!UNICODE_ONLY
|
||||
#ifndef ANSI_ONLY
|
||||
INT
|
||||
WINAPI
|
||||
DirectXSetupW(
|
||||
HWND hWnd,
|
||||
LPWSTR lpszRootPath,
|
||||
DWORD dwFlags
|
||||
);
|
||||
#endif //!ANSI_ONLY
|
||||
#ifdef UNICODE
|
||||
#define DirectXSetup DirectXSetupW
|
||||
#else
|
||||
#define DirectXSetup DirectXSetupA
|
||||
#endif // !UNICODE
|
||||
|
||||
#ifndef UNICODE_ONLY
|
||||
INT
|
||||
WINAPI
|
||||
DirectXDeviceDriverSetupA(
|
||||
HWND hWnd,
|
||||
LPSTR lpszDriverClass,
|
||||
LPSTR lpszDriverPath,
|
||||
DWORD dwFlags
|
||||
);
|
||||
#endif //!UNICODE_ONLY
|
||||
#ifndef ANSI_ONLY
|
||||
INT
|
||||
WINAPI
|
||||
DirectXDeviceDriverSetupW(
|
||||
HWND hWnd,
|
||||
LPWSTR lpszDriverClass,
|
||||
LPWSTR lpszDriverPath,
|
||||
DWORD dwFlags
|
||||
);
|
||||
#endif //!ANSI_ONLY
|
||||
#ifdef UNICODE
|
||||
#define DirectXDeviceDriverSetup DirectXDeviceDriverSetupW
|
||||
#else
|
||||
#define DirectXDeviceDriverSetup DirectXDeviceDriverSetupA
|
||||
#endif // !UNICODE
|
||||
|
||||
#ifndef UNICODE_ONLY
|
||||
INT
|
||||
WINAPI
|
||||
DirectXRegisterApplicationA(
|
||||
HWND hWnd,
|
||||
LPDIRECTXREGISTERAPPA lpDXRegApp
|
||||
);
|
||||
#endif //!UNICODE_ONLY
|
||||
#ifndef ANSI_ONLY
|
||||
INT
|
||||
WINAPI
|
||||
DirectXRegisterApplicationW(
|
||||
HWND hWnd,
|
||||
LPDIRECTXREGISTERAPPW lpDXRegApp
|
||||
);
|
||||
#endif //!ANSI_ONLY
|
||||
#ifdef UNICODE
|
||||
#define DirectXRegisterApplication DirectXRegisterApplicationW
|
||||
#else
|
||||
#define DirectXRegisterApplication DirectXRegisterApplicationA
|
||||
#endif // !UNICODE
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
DirectXUnRegisterApplication(
|
||||
HWND hWnd,
|
||||
LPGUID lpGUID
|
||||
);
|
||||
|
||||
//
|
||||
// Function Pointers
|
||||
//
|
||||
#ifdef UNICODE
|
||||
typedef INT (WINAPI * LPDIRECTXSETUP)(HWND, LPWSTR, DWORD);
|
||||
typedef INT (WINAPI * LPDIRECTXDEVICEDRIVERSETUP)(HWND, LPWSTR, LPSTR, DWORD);
|
||||
typedef INT (WINAPI * LPDIRECTXREGISTERAPPLICATION)(HWND, LPDIRECTXREGISTERAPPW);
|
||||
#else
|
||||
typedef INT (WINAPI * LPDIRECTXSETUP)(HWND, LPSTR, DWORD);
|
||||
typedef INT (WINAPI * LPDIRECTXDEVICEDRIVERSETUP)(HWND, LPSTR, LPSTR, DWORD);
|
||||
typedef INT (WINAPI * LPDIRECTXREGISTERAPPLICATION)(HWND, LPDIRECTXREGISTERAPPA);
|
||||
#endif // UNICODE
|
||||
|
||||
typedef DWORD (FAR PASCAL * DSETUP_CALLBACK)(DWORD Reason,
|
||||
DWORD MsgType, /* Same as flags to MessageBox */
|
||||
LPSTR szMessage,
|
||||
LPSTR szName,
|
||||
void *pInfo);
|
||||
|
||||
INT WINAPI DirectXSetupSetCallback(DSETUP_CALLBACK Callback);
|
||||
INT WINAPI DirectXSetupGetVersion(DWORD *lpdwVersion, DWORD *lpdwMinorVersion);
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,832 +0,0 @@
|
||||
/*==========================================================================;
|
||||
*
|
||||
* Copyright (C) 1996-1997 Microsoft Corporation. All Rights Reserved.
|
||||
*
|
||||
* File: dvp.h
|
||||
* Content: DirectDrawVideoPort include file
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __DVP_INCLUDED__
|
||||
#define __DVP_INCLUDED__
|
||||
#if defined( _WIN32 ) && !defined( _NO_COM )
|
||||
#define COM_NO_WINDOWS_H
|
||||
#include <objbase.h>
|
||||
#else
|
||||
#define IUnknown void
|
||||
#undef CO_E_NOTINITIALIZED
|
||||
#define CO_E_NOTINITIALIZED 0x800401F0L
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GUIDS used by DirectDrawVideoPort objects
|
||||
*/
|
||||
#if defined( _WIN32 ) && !defined( _NO_COM )
|
||||
DEFINE_GUID( IID_IDDVideoPortContainer, 0x6C142760,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
|
||||
DEFINE_GUID( IID_IDirectDrawVideoPort, 0xB36D93E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 );
|
||||
|
||||
DEFINE_GUID( DDVPTYPE_E_HREFH_VREFH, 0x54F39980L,0xDA60,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
|
||||
DEFINE_GUID( DDVPTYPE_E_HREFH_VREFL, 0x92783220L,0xDA60,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
|
||||
DEFINE_GUID( DDVPTYPE_E_HREFL_VREFH, 0xA07A02E0L,0xDA60,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
|
||||
DEFINE_GUID( DDVPTYPE_E_HREFL_VREFL, 0xE09C77E0L,0xDA60,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
|
||||
DEFINE_GUID( DDVPTYPE_CCIR656, 0xFCA326A0L,0xDA60,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
|
||||
DEFINE_GUID( DDVPTYPE_BROOKTREE, 0x1352A560L,0xDA61,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
|
||||
DEFINE_GUID( DDVPTYPE_PHILIPS, 0x332CF160L,0xDA61,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
|
||||
|
||||
/*
|
||||
* GUIDS used to describe connections
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*============================================================================
|
||||
*
|
||||
* DirectDraw Structures
|
||||
*
|
||||
* Various structures used to invoke DirectDraw.
|
||||
*
|
||||
*==========================================================================*/
|
||||
|
||||
struct IDirectDraw;
|
||||
struct IDirectDrawSurface;
|
||||
struct IDirectDrawPalette;
|
||||
struct IDirectDrawClipper;
|
||||
|
||||
typedef struct IDDVideoPortContainer FAR *LPDDVIDEOPORTCONTAINER;
|
||||
typedef struct IDirectDrawVideoPort FAR *LPDIRECTDRAWVIDEOPORT;
|
||||
|
||||
typedef struct _DDVIDEOPORTCONNECT FAR *LPDDVIDEOPORTCONNECT;
|
||||
typedef struct _DDVIDEOPORTCAPS FAR *LPDDVIDEOPORTCAPS;
|
||||
typedef struct _DDVIDEOPORTDESC FAR *LPDDVIDEOPORTDESC;
|
||||
typedef struct _DDVIDEOPORTINFO FAR *LPDDVIDEOPORTINFO;
|
||||
typedef struct _DDVIDEOPORTBANDWIDTH FAR *LPDDVIDEOPORTBANDWIDTH;
|
||||
typedef struct _DDVIDEOPORTSTATUS FAR *LPDDVIDEOPORTSTATUS;
|
||||
|
||||
typedef struct IDDVideoPortContainerVtbl DDVIDEOPORTCONTAINERCALLBACKS;
|
||||
typedef struct IDirectDrawVideoPortVtbl DIRECTDRAWVIDEOPORTCALLBACKS;
|
||||
|
||||
|
||||
/*
|
||||
* API's
|
||||
*/
|
||||
typedef HRESULT (FAR PASCAL * LPDDENUMVIDEOCALLBACK)(LPDDVIDEOPORTCAPS, LPVOID);
|
||||
|
||||
|
||||
/*
|
||||
* INTERACES FOLLOW:
|
||||
* IDirectDrawVideoPort
|
||||
* IVideoPort
|
||||
*/
|
||||
|
||||
/*
|
||||
* IDirectDrawVideoPortContainer
|
||||
*/
|
||||
#if defined( _WIN32 ) && !defined( _NO_COM )
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IDDVideoPortContainer
|
||||
DECLARE_INTERFACE_( IDDVideoPortContainer, IUnknown )
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
/*** IDirectDrawVideoPort methods ***/
|
||||
STDMETHOD(CreateVideoPort)(THIS_ DWORD, LPDDVIDEOPORTDESC, LPDIRECTDRAWVIDEOPORT FAR *, IUnknown FAR *) PURE;
|
||||
STDMETHOD(EnumVideoPorts)(THIS_ DWORD, LPDDVIDEOPORTCAPS, LPVOID,LPDDENUMVIDEOCALLBACK ) PURE;
|
||||
STDMETHOD(GetVideoPortConnectInfo)(THIS_ DWORD, LPDWORD, LPDDVIDEOPORTCONNECT ) PURE;
|
||||
STDMETHOD(QueryVideoPortStatus)(THIS_ DWORD, LPDDVIDEOPORTSTATUS ) PURE;
|
||||
};
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
#define IVideoPortContainer_QueryInterface(p, a, b) (p)->lpVtbl->QueryInterface(p, a, b)
|
||||
#define IVideoPortContainer_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IVideoPortContainer_Release(p) (p)->lpVtbl->Release(p)
|
||||
#define IVideoPortContainer_CreateVideoPort(p, a, b, c, d) (p)->lpVtbl->CreateVideoPort(p, a, b, c, d)
|
||||
#define IVideoPortContainer_EnumVideoPorts(p, a, b, c, d) (p)->lpVtbl->EnumVideoPorts(p, a, b, c, d)
|
||||
#define IVideoPortContainer_GetVideoPortConnectInfo(p, a, b, c) (p)->lpVtbl->GetVideoPortConnectInfo(p, a, b, c)
|
||||
#define IVideoPortContainer_QueryVideoPortStatus(p, a, b) (p)->lpVtbl->QueryVideoPortStatus(p, a, b)
|
||||
#else
|
||||
#define IVideoPortContainer_QueryInterface(p, a, b) (p)->QueryInterface(a, b)
|
||||
#define IVideoPortContainer_AddRef(p) (p)->AddRef()
|
||||
#define IVideoPortContainer_Release(p) (p)->Release()
|
||||
#define IVideoPortContainer_CreateVideoPort(p, a, b, c, d) (p)->CreateVideoPort(a, b, c, d)
|
||||
#define IVideoPortContainer_EnumVideoPorts(p, a, b, c, d) (p)->EnumVideoPorts(a, b, c, d)
|
||||
#define IVideoPortContainer_GetVideoPortConnectInfo(p, a, b, c) (p)->GetVideoPortConnectInfo(a, b, c)
|
||||
#define IVideoPortContainer_QueryVideoPortStatus(p, a, b) (p)->QueryVideoPortStatus(a, b)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* IDirectDrawVideoPort
|
||||
*/
|
||||
#if defined( _WIN32 ) && !defined( _NO_COM )
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IDirectDrawVideoPort
|
||||
DECLARE_INTERFACE_( IDirectDrawVideoPort, IUnknown )
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
/*** IVideoPort methods ***/
|
||||
STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE;
|
||||
STDMETHOD(GetBandwidthInfo)(THIS_ LPDDPIXELFORMAT, DWORD, DWORD, DWORD, LPDDVIDEOPORTBANDWIDTH) PURE;
|
||||
STDMETHOD(GetColorControls)(THIS_ LPDDCOLORCONTROL) PURE;
|
||||
STDMETHOD(GetInputFormats)(THIS_ LPDWORD, LPDDPIXELFORMAT, DWORD) PURE;
|
||||
STDMETHOD(GetOutputFormats)(THIS_ LPDDPIXELFORMAT, LPDWORD, LPDDPIXELFORMAT, DWORD) PURE;
|
||||
STDMETHOD(GetFieldPolarity)(THIS_ LPBOOL) PURE;
|
||||
STDMETHOD(GetVideoLine)(THIS_ LPDWORD) PURE;
|
||||
STDMETHOD(GetVideoSignalStatus)(THIS_ LPDWORD) PURE;
|
||||
STDMETHOD(SetColorControls)(THIS_ LPDDCOLORCONTROL) PURE;
|
||||
STDMETHOD(SetTargetSurface)(THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE;
|
||||
STDMETHOD(StartVideo)(THIS_ LPDDVIDEOPORTINFO) PURE;
|
||||
STDMETHOD(StopVideo)(THIS) PURE;
|
||||
STDMETHOD(UpdateVideo)(THIS_ LPDDVIDEOPORTINFO) PURE;
|
||||
STDMETHOD(WaitForSync)(THIS_ DWORD, DWORD, DWORD) PURE;
|
||||
};
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
#define IVideoPort_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IVideoPort_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IVideoPort_Release(p) (p)->lpVtbl->Release(p)
|
||||
#define IVideoPort_SetTargetSurface(p,a,b) (p)->lpVtbl->SetTargetSurface(p,a,b)
|
||||
#define IVideoPort_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b)
|
||||
#define IVideoPort_GetBandwidthInfo(p,a,b,c,d,e) (p)->lpVtbl->GetBandwidthInfo(p,a,b,c,d,e)
|
||||
#define IVideoPort_GetColorControls(p,a) (p)->lpVtbl->GetColorControls(p,a)
|
||||
#define IVideoPort_GetInputFormats(p,a,b,c) (p)->lpVtbl->GetInputFormats(p,a,b,c)
|
||||
#define IVideoPort_GetOutputFormats(p,a,b,c,d) (p)->lpVtbl->GetOutputFormats(p,a,b,c,d)
|
||||
#define IVideoPort_GetFieldPolarity(p,a) (p)->lpVtbl->GetFieldPolarity(p,a)
|
||||
#define IVideoPort_GetVideoLine(p,a) (p)->lpVtbl->GetVideoLine(p,a)
|
||||
#define IVideoPort_GetVideoSignalStatus(p,a) (p)->lpVtbl->GetVideoSignalStatus(p,a)
|
||||
#define IVideoPort_SetColorControls(p,a) (p)->lpVtbl->SetColorControls(p,a)
|
||||
#define IVideoPort_StartVideo(p,a) (p)->lpVtbl->StartVideo(p,a)
|
||||
#define IVideoPort_StopVideo(p) (p)->lpVtbl->StopVideo(p)
|
||||
#define IVideoPort_UpdateVideo(p,a) (p)->lpVtbl->UpdateVideo(p,a)
|
||||
#define IVideoPort_WaitForSync(p,a,b,c) (p)->lpVtbl->WaitForSync(p,a,b,c)
|
||||
#else
|
||||
#define IVideoPort_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
|
||||
#define IVideoPort_AddRef(p) (p)->AddRef()
|
||||
#define IVideoPort_Release(p) (p)->Release()
|
||||
#define IVideoPort_SetTargetSurface(p,a,b) (p)->SetTargetSurface(a,b)
|
||||
#define IVideoPort_Flip(p,a,b) (p)->Flip(a,b)
|
||||
#define IVideoPort_GetBandwidthInfo(p,a,b,c,d,e) (p)->GetBandwidthInfo(a,b,c,d,e)
|
||||
#define IVideoPort_GetColorControls(p,a) (p)->GetColorControls(a)
|
||||
#define IVideoPort_GetInputFormats(p,a,b,c) (p)->GetInputFormats(a,b,c)
|
||||
#define IVideoPort_GetOutputFormats(p,a,b,c,d) (p)->GetOutputFormats(a,b,c,d)
|
||||
#define IVideoPort_GetFieldPolarity(p,a) (p)->GetFieldPolarity(a)
|
||||
#define IVideoPort_GetVideoLine(p,a) (p)->GetVideoLine(a)
|
||||
#define IVideoPort_GetVideoSignalStatus(p,a) (p)->GetVideoSignalStatus(a)
|
||||
#define IVideoPort_SetColorControls(p,a) (p)->SetColorControls(a)
|
||||
#define IVideoPort_StartVideo(p,a) (p)->StartVideo(a)
|
||||
#define IVideoPort_StopVideo(p) (p)->StopVideo()
|
||||
#define IVideoPort_UpdateVideo(p,a) (p)->UpdateVideo(a)
|
||||
#define IVideoPort_WaitForSync(p,a,b,c) (p)->WaitForSync(a,b,c)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* DDVIDEOPORTCONNECT
|
||||
*/
|
||||
typedef struct _DDVIDEOPORTCONNECT
|
||||
{
|
||||
DWORD dwSize; // size of the DDVIDEOPORTCONNECT structure
|
||||
DWORD dwPortWidth; // Width of the video port
|
||||
GUID guidTypeID; // Description of video port connection
|
||||
DWORD dwFlags; // Connection flags
|
||||
DWORD dwReserved1; // Reserved, set to zero.
|
||||
} DDVIDEOPORTCONNECT;
|
||||
|
||||
|
||||
/*
|
||||
* DDVIDEOPORTCAPS
|
||||
*/
|
||||
typedef struct _DDVIDEOPORTCAPS
|
||||
{
|
||||
DWORD dwSize; // size of the DDVIDEOPORTCAPS structure
|
||||
DWORD dwFlags; // indicates which fields contain data
|
||||
DWORD dwMaxWidth; // max width of the video port field
|
||||
DWORD dwMaxVBIWidth; // max width of the VBI data
|
||||
DWORD dwMaxHeight; // max height of the video port field
|
||||
DWORD dwVideoPortID; // Video port ID (0 - (dwMaxVideoPorts -1))
|
||||
DWORD dwCaps; // Video port capabilities
|
||||
DWORD dwFX; // More video port capabilities
|
||||
DWORD dwNumAutoFlipSurfaces; // Number of autoflippable surfaces
|
||||
DWORD dwAlignVideoPortBoundary; // Byte restriction of placement within the surface
|
||||
DWORD dwAlignVideoPortPrescaleWidth;// Byte restriction of width after prescaling
|
||||
DWORD dwAlignVideoPortCropBoundary; // Byte restriction of left cropping
|
||||
DWORD dwAlignVideoPortCropWidth; // Byte restriction of cropping width
|
||||
DWORD dwPreshrinkXStep; // Width can be shrunk in steps of 1/x
|
||||
DWORD dwPreshrinkYStep; // Height can be shrunk in steps of 1/x
|
||||
DWORD dwNumVBIAutoFlipSurfaces; // Number of VBI autoflippable surfaces
|
||||
DWORD dwReserved1; // Reserved for future use
|
||||
DWORD dwReserved2; // Reserved for future use
|
||||
} DDVIDEOPORTCAPS;
|
||||
|
||||
/*
|
||||
* The dwMaxWidth and dwMaxVBIWidth members are valid
|
||||
*/
|
||||
#define DDVPD_WIDTH 0x00000001l
|
||||
|
||||
/*
|
||||
* The dwMaxHeight member is valid
|
||||
*/
|
||||
#define DDVPD_HEIGHT 0x00000002l
|
||||
|
||||
/*
|
||||
* The dwVideoPortID member is valid
|
||||
*/
|
||||
#define DDVPD_ID 0x00000004l
|
||||
|
||||
/*
|
||||
* The dwCaps member is valid
|
||||
*/
|
||||
#define DDVPD_CAPS 0x00000008l
|
||||
|
||||
/*
|
||||
* The dwFX member is valid
|
||||
*/
|
||||
#define DDVPD_FX 0x00000010l
|
||||
|
||||
/*
|
||||
* The dwNumAutoFlipSurfaces member is valid
|
||||
*/
|
||||
#define DDVPD_AUTOFLIP 0x00000020l
|
||||
|
||||
/*
|
||||
* All of the alignment members are valid
|
||||
*/
|
||||
#define DDVPD_ALIGN 0x00000040l
|
||||
|
||||
|
||||
/*
|
||||
* DDVIDEOPORTDESC
|
||||
*/
|
||||
typedef struct _DDVIDEOPORTDESC
|
||||
{
|
||||
DWORD dwSize; // size of the DDVIDEOPORTDESC structure
|
||||
DWORD dwFieldWidth; // width of the video port field
|
||||
DWORD dwVBIWidth; // width of the VBI data
|
||||
DWORD dwFieldHeight; // height of the video port field
|
||||
DWORD dwMicrosecondsPerField; // Microseconds per video field
|
||||
DWORD dwMaxPixelsPerSecond; // Maximum pixel rate per second
|
||||
DWORD dwVideoPortID; // Video port ID (0 - (dwMaxVideoPorts -1))
|
||||
DWORD dwReserved1; // Reserved for future use - set to zero
|
||||
DDVIDEOPORTCONNECT VideoPortType; // Description of video port connection
|
||||
DWORD dwReserved2; // Reserved for future use - set to zero
|
||||
DWORD dwReserved3; // Reserved for future use - set to zero
|
||||
} DDVIDEOPORTDESC;
|
||||
|
||||
|
||||
/*
|
||||
* DDVIDEOPORTINFO
|
||||
*/
|
||||
typedef struct _DDVIDEOPORTINFO
|
||||
{
|
||||
DWORD dwSize; // Size of the structure
|
||||
DWORD dwOriginX; // Placement of the video data within the surface.
|
||||
DWORD dwOriginY; // Placement of the video data within the surface.
|
||||
DWORD dwVPFlags; // Video port options
|
||||
RECT rCrop; // Cropping rectangle (optional).
|
||||
DWORD dwPrescaleWidth; // Determines pre-scaling/zooming in the X direction (optional).
|
||||
DWORD dwPrescaleHeight; // Determines pre-scaling/zooming in the Y direction (optional).
|
||||
LPDDPIXELFORMAT lpddpfInputFormat; // Video format written to the video port
|
||||
LPDDPIXELFORMAT lpddpfVBIInputFormat; // Input format of the VBI data
|
||||
LPDDPIXELFORMAT lpddpfVBIOutputFormat;// Output format of the data
|
||||
DWORD dwVBIHeight; // Specifies the number of lines of data within the vertical blanking interval.
|
||||
DWORD dwReserved1; // Reserved for future use - set to zero
|
||||
DWORD dwReserved2; // Reserved for future use - set to zero
|
||||
} DDVIDEOPORTINFO;
|
||||
|
||||
|
||||
/*
|
||||
* DDVIDEOPORTBANDWIDTH
|
||||
*/
|
||||
typedef struct _DDVIDEOPORTBANDWIDTH
|
||||
{
|
||||
DWORD dwSize; // Size of the structure
|
||||
DWORD dwCaps;
|
||||
DWORD dwOverlay; // Zoom factor at which overlay is supported
|
||||
DWORD dwColorkey; // Zoom factor at which overlay w/ colorkey is supported
|
||||
DWORD dwYInterpolate; // Zoom factor at which overlay w/ Y interpolation is supported
|
||||
DWORD dwYInterpAndColorkey; // Zoom factor at which ovelray w/ Y interpolation and colorkeying is supported
|
||||
DWORD dwReserved1; // Reserved for future use - set to zero
|
||||
DWORD dwReserved2; // Reserved for future use - set to zero
|
||||
} DDVIDEOPORTBANDWIDTH;
|
||||
|
||||
|
||||
/*
|
||||
* DDVIDEOPORTSTATUS
|
||||
*/
|
||||
typedef struct _DDVIDEOPORTSTATUS
|
||||
{
|
||||
DWORD dwSize; // Size of the structure
|
||||
BOOL bInUse; // TRUE if video port is currently being used
|
||||
DWORD dwFlags; // Currently not used
|
||||
DWORD dwReserved1; // Reserved for future use
|
||||
DDVIDEOPORTCONNECT VideoPortType; // Information about the connection
|
||||
DWORD dwReserved2; // Reserved for future use
|
||||
DWORD dwReserved3; // Reserved for future use
|
||||
} DDVIDEOPORTSTATUS;
|
||||
|
||||
/*============================================================================
|
||||
*
|
||||
* Video Port Flags
|
||||
*
|
||||
* All flags are bit flags.
|
||||
*
|
||||
*==========================================================================*/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* VIDEOPORT DDVIDEOPORTCONNECT FLAGS
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* When this is set by the driver and passed to the client, this
|
||||
* indicates that the video port is capable of double clocking the data.
|
||||
* When this is set by the client, this indicates that the video port
|
||||
* should enable double clocking. This flag is only valid with external
|
||||
* syncs.
|
||||
*/
|
||||
#define DDVPCONNECT_DOUBLECLOCK 0x00000001l
|
||||
|
||||
/*
|
||||
* When this is set by the driver and passed to the client, this
|
||||
* indicates that the video port is capable of using an external VACT
|
||||
* signal. When this is set by the client, this indicates that the
|
||||
* video port should use the external VACT signal.
|
||||
*/
|
||||
#define DDVPCONNECT_VACT 0x00000002l
|
||||
|
||||
/*
|
||||
* When this is set by the driver and passed to the client, this
|
||||
* indicates that the video port is capable of treating even fields
|
||||
* like odd fields and visa versa. When this is set by the client,
|
||||
* this indicates that the video port should treat even fields like odd
|
||||
* fields.
|
||||
*/
|
||||
#define DDVPCONNECT_INVERTPOLARITY 0x00000004l
|
||||
|
||||
/*
|
||||
* Indicates that any data written to the video port during the VREF
|
||||
* period will not be written into the frame buffer. This flag is read only.
|
||||
*/
|
||||
#define DDVPCONNECT_DISCARDSVREFDATA 0x00000008l
|
||||
|
||||
/*
|
||||
* Device will write half lines into the frame buffer, sometimes causing
|
||||
* the data to not be displayed correctly.
|
||||
*/
|
||||
#define DDVPCONNECT_HALFLINE 0x00000010l
|
||||
|
||||
/*
|
||||
* Indicates that the signal is interlaced. This flag is only
|
||||
* set by the client.
|
||||
*/
|
||||
#define DDVPCONNECT_INTERLACED 0x00000020l
|
||||
|
||||
/*
|
||||
* Indicates that video port is shareable and that this video port
|
||||
* will use the even fields. This flag is only set by the client.
|
||||
*/
|
||||
#define DDVPCONNECT_SHAREEVEN 0x00000040l
|
||||
|
||||
/*
|
||||
* Indicates that video port is shareable and that this video port
|
||||
* will use the odd fields. This flag is only set by the client.
|
||||
*/
|
||||
#define DDVPCONNECT_SHAREODD 0x00000080l
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* VIDEOPORT DDVIDEOPORTDESC CAPS
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Flip can be performed automatically to avoid tearing.
|
||||
*/
|
||||
#define DDVPCAPS_AUTOFLIP 0x00000001l
|
||||
|
||||
/*
|
||||
* Supports interlaced video
|
||||
*/
|
||||
#define DDVPCAPS_INTERLACED 0x00000002l
|
||||
|
||||
/*
|
||||
* Supports non-interlaced video
|
||||
*/
|
||||
#define DDVPCAPS_NONINTERLACED 0x00000004l
|
||||
|
||||
/*
|
||||
* Indicates that the device can return whether the current field
|
||||
* of an interlaced signal is even or odd.
|
||||
*/
|
||||
#define DDVPCAPS_READBACKFIELD 0x00000008l
|
||||
|
||||
/*
|
||||
* Indicates that the device can return the current line of video
|
||||
* being written into the frame buffer.
|
||||
*/
|
||||
#define DDVPCAPS_READBACKLINE 0x00000010l
|
||||
|
||||
/*
|
||||
* Allows two gen-locked video streams to share a single video port,
|
||||
* where one stream uses the even fields and the other uses the odd
|
||||
* fields. Separate parameters (including address, scaling,
|
||||
* cropping, etc.) are maintained for both fields.)
|
||||
*/
|
||||
#define DDVPCAPS_SHAREABLE 0x00000020l
|
||||
|
||||
/*
|
||||
* Even fields of video can be automatically discarded.
|
||||
*/
|
||||
#define DDVPCAPS_SKIPEVENFIELDS 0x00000040l
|
||||
|
||||
/*
|
||||
* Odd fields of video can be automatically discarded.
|
||||
*/
|
||||
#define DDVPCAPS_SKIPODDFIELDS 0x00000080l
|
||||
|
||||
/*
|
||||
* Indicates that the device is capable of driving the graphics
|
||||
* VSYNC with the video port VSYNC.
|
||||
*/
|
||||
#define DDVPCAPS_SYNCMASTER 0x00000100l
|
||||
|
||||
/*
|
||||
* Indicates that data within the vertical blanking interval can
|
||||
* be written to a different surface.
|
||||
*/
|
||||
#define DDVPCAPS_VBISURFACE 0x00000200l
|
||||
|
||||
/*
|
||||
* Indicates that the video port can perform color operations
|
||||
* on the incoming data before it is written to the frame buffer.
|
||||
*/
|
||||
#define DDVPCAPS_COLORCONTROL 0x00000400l
|
||||
|
||||
/*
|
||||
* Indicates that the video port can accept VBI data in a different
|
||||
* width or format than the regular video data.
|
||||
*/
|
||||
#define DDVPCAPS_OVERSAMPLEDVBI 0x00000800l
|
||||
|
||||
/*
|
||||
* Indicates that the video port can write data directly to system memory
|
||||
*/
|
||||
#define DDVPCAPS_SYSTEMMEMORY 0x00001000l
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* VIDEOPORT DDVIDEOPORTDESC FX
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Limited cropping is available to crop out the vertical interval data.
|
||||
*/
|
||||
#define DDVPFX_CROPTOPDATA 0x00000001l
|
||||
|
||||
/*
|
||||
* Incoming data can be cropped in the X direction before it is written
|
||||
* to the surface.
|
||||
*/
|
||||
#define DDVPFX_CROPX 0x00000002l
|
||||
|
||||
/*
|
||||
* Incoming data can be cropped in the Y direction before it is written
|
||||
* to the surface.
|
||||
*/
|
||||
#define DDVPFX_CROPY 0x00000004l
|
||||
|
||||
/*
|
||||
* Supports interleaving interlaced fields in memory.
|
||||
*/
|
||||
#define DDVPFX_INTERLEAVE 0x00000008l
|
||||
|
||||
/*
|
||||
* Supports mirroring left to right as the video data is written
|
||||
* into the frame buffer.
|
||||
*/
|
||||
#define DDVPFX_MIRRORLEFTRIGHT 0x00000010l
|
||||
|
||||
/*
|
||||
* Supports mirroring top to bottom as the video data is written
|
||||
* into the frame buffer.
|
||||
*/
|
||||
#define DDVPFX_MIRRORUPDOWN 0x00000020l
|
||||
|
||||
/*
|
||||
* Data can be arbitrarily shrunk in the X direction before it
|
||||
* is written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESHRINKX 0x00000040l
|
||||
|
||||
/*
|
||||
* Data can be arbitrarily shrunk in the Y direction before it
|
||||
* is written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESHRINKY 0x00000080l
|
||||
|
||||
/*
|
||||
* Data can be binary shrunk (1/2, 1/4, 1/8, etc.) in the X
|
||||
* direction before it is written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESHRINKXB 0x00000100l
|
||||
|
||||
/*
|
||||
* Data can be binary shrunk (1/2, 1/4, 1/8, etc.) in the Y
|
||||
* direction before it is written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESHRINKYB 0x00000200l
|
||||
|
||||
/*
|
||||
* Data can be shrunk in increments of 1/x in the X direction
|
||||
* (where X is specified in the DDVIDEOPORTCAPS.dwPreshrinkXStep)
|
||||
* before it is written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESHRINKXS 0x00000400l
|
||||
|
||||
/*
|
||||
* Data can be shrunk in increments of 1/x in the Y direction
|
||||
* (where X is specified in the DDVIDEOPORTCAPS.dwPreshrinkYStep)
|
||||
* before it is written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESHRINKYS 0x00000800l
|
||||
|
||||
/*
|
||||
* Data can be arbitrarily stretched in the X direction before
|
||||
* it is written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESTRETCHX 0x00001000l
|
||||
|
||||
/*
|
||||
* Data can be arbitrarily stretched in the Y direction before
|
||||
* it is written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESTRETCHY 0x00002000l
|
||||
|
||||
/*
|
||||
* Data can be integer stretched in the X direction before it is
|
||||
* written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESTRETCHXN 0x00004000l
|
||||
|
||||
/*
|
||||
* Data can be integer stretched in the Y direction before it is
|
||||
* written to the surface.
|
||||
*/
|
||||
#define DDVPFX_PRESTRETCHYN 0x00008000l
|
||||
|
||||
/*
|
||||
* Indicates that data within the vertical blanking interval can
|
||||
* be converted independently of the remaining video data.
|
||||
*/
|
||||
#define DDVPFX_VBICONVERT 0x00010000l
|
||||
|
||||
/*
|
||||
* Indicates that scaling can be disabled for data within the
|
||||
* vertical blanking interval.
|
||||
*/
|
||||
#define DDVPFX_VBINOSCALE 0x00020000l
|
||||
|
||||
/*
|
||||
* Indicates that the video data can ignore the left and right
|
||||
* cropping coordinates when cropping oversampled VBI data.
|
||||
*/
|
||||
#define DDVPFX_IGNOREVBIXCROP 0x00040000l
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* VIDEOPORT DDVIDEOPORTINFO FLAGS
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Perform automatic flipping. Auto-flipping is performed between
|
||||
* the overlay surface that was attached to the video port using
|
||||
* IDirectDrawVideoPort::AttachSurface and the overlay surfaces that
|
||||
* are attached to the surface via the IDirectDrawSurface::AttachSurface
|
||||
* method. The flip order is the order in which the overlay surfaces
|
||||
* were. attached.
|
||||
*/
|
||||
#define DDVP_AUTOFLIP 0x00000001l
|
||||
|
||||
/*
|
||||
* Perform conversion using the ddpfOutputFormat information.
|
||||
*/
|
||||
#define DDVP_CONVERT 0x00000002l
|
||||
|
||||
/*
|
||||
* Perform cropping using the specified rectangle.
|
||||
*/
|
||||
#define DDVP_CROP 0x00000004l
|
||||
|
||||
/*
|
||||
* Indicates that interlaced fields should be interleaved in memory.
|
||||
*/
|
||||
#define DDVP_INTERLEAVE 0x00000008l
|
||||
|
||||
/*
|
||||
* Indicates that the data should be mirrored left to right as it's
|
||||
* written into the frame buffer.
|
||||
*/
|
||||
#define DDVP_MIRRORLEFTRIGHT 0x00000010l
|
||||
|
||||
/*
|
||||
* Indicates that the data should be mirrored top to bottom as it's
|
||||
* written into the frame buffer.
|
||||
*/
|
||||
#define DDVP_MIRRORUPDOWN 0x00000020l
|
||||
|
||||
/*
|
||||
* Perform pre-scaling/zooming based on the pre-scale parameters.
|
||||
*/
|
||||
#define DDVP_PRESCALE 0x00000040l
|
||||
|
||||
/*
|
||||
* Ignore input of even fields.
|
||||
*/
|
||||
#define DDVP_SKIPEVENFIELDS 0x00000080l
|
||||
|
||||
/*
|
||||
* Ignore input of odd fields.
|
||||
*/
|
||||
#define DDVP_SKIPODDFIELDS 0x00000100l
|
||||
|
||||
/*
|
||||
* Drive the graphics VSYNCs using the video port VYSNCs.
|
||||
*/
|
||||
#define DDVP_SYNCMASTER 0x00000200l
|
||||
|
||||
/*
|
||||
* The ddpfVBIOutputFormatFormat member contains data that should be used
|
||||
* to convert the data within the vertical blanking interval.
|
||||
*/
|
||||
#define DDVP_VBICONVERT 0x00000400l
|
||||
|
||||
/*
|
||||
* Indicates that data within the vertical blanking interval
|
||||
* should not be scaled.
|
||||
*/
|
||||
#define DDVP_VBINOSCALE 0x00000800l
|
||||
|
||||
/*
|
||||
* Indicates that these bob/weave decisions should not be
|
||||
* overriden by other interfaces.
|
||||
*/
|
||||
#define DDVP_OVERRIDEBOBWEAVE 0x00001000l
|
||||
|
||||
/*
|
||||
* Indicates that the video data should ignore the left and right
|
||||
* cropping coordinates when cropping the VBI data.
|
||||
*/
|
||||
#define DDVP_IGNOREVBIXCROP 0x00002000l
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DIRIRECTDRAWVIDEOPORT GETINPUTFORMAT/GETOUTPUTFORMAT FLAGS
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Return formats for the video data
|
||||
*/
|
||||
#define DDVPFORMAT_VIDEO 0x00000001l
|
||||
|
||||
/*
|
||||
* Return formats for the VBI data
|
||||
*/
|
||||
#define DDVPFORMAT_VBI 0x00000002l
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DIRIRECTDRAWVIDEOPORT SETTARGETSURFACE FLAGS
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Surface should receive video data (and VBI data if a surface
|
||||
* is not explicitly attached for that purpose)
|
||||
*/
|
||||
#define DDVPTARGET_VIDEO 0x00000001l
|
||||
|
||||
/*
|
||||
* Surface should receive VBI data
|
||||
*/
|
||||
#define DDVPTARGET_VBI 0x00000002l
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DIRIRECTDRAWVIDEOPORT WAITFORSYNC FLAGS
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Waits until the beginning of the next VSYNC
|
||||
*/
|
||||
#define DDVPWAIT_BEGIN 0x00000001l
|
||||
|
||||
/*
|
||||
* Waits until the end of the next/current VSYNC
|
||||
*/
|
||||
#define DDVPWAIT_END 0x00000002l
|
||||
|
||||
/*
|
||||
* Waits until the beginning of the specified line
|
||||
*/
|
||||
#define DDVPWAIT_LINE 0x00000003l
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DIRECTDRAWVIDEOPORT FLIP FLAGS
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Flips the normal video surface
|
||||
*/
|
||||
#define DDVPFLIP_VIDEO 0x00000001l
|
||||
|
||||
/*
|
||||
* Flips the VBI surface
|
||||
*/
|
||||
#define DDVPFLIP_VBI 0x00000002l
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* DIRIRECTDRAWVIDEOPORT GETVIDEOSIGNALSTATUS VALUES
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* No video signal is present at the video port
|
||||
*/
|
||||
#define DDVPSQ_NOSIGNAL 0x00000001l
|
||||
|
||||
/*
|
||||
* A valid video signal is present at the video port
|
||||
*/
|
||||
#define DDVPSQ_SIGNALOK 0x00000002l
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* VIDEOPORTBANDWIDTH Flags
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* The specified height/width refer to the size of the video port data
|
||||
* written into memory, after prescaling has occured.
|
||||
*/
|
||||
#define DDVPB_VIDEOPORT 0x00000001l
|
||||
|
||||
/*
|
||||
* The specified height/width refer to the source size of the overlay.
|
||||
*/
|
||||
#define DDVPB_OVERLAY 0x00000002l
|
||||
|
||||
/*
|
||||
* This is a query for the device to return which caps this device requires.
|
||||
*/
|
||||
#define DDVPB_TYPE 0x00000004l
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* VIDEOPORTBANDWIDTH Caps
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* The bandwidth for this device is dependant on the overlay source size.
|
||||
*/
|
||||
#define DDVPBCAPS_SOURCE 0x00000001l
|
||||
|
||||
/*
|
||||
* The bandwidth for this device is dependant on the overlay destination
|
||||
* size.
|
||||
*/
|
||||
#define DDVPBCAPS_DESTINATION 0x00000002l
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,512 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Copyright © 1998 Bruce Dawson.
|
||||
/*
|
||||
This source file contains the exception handler for recording error
|
||||
information after crashes. See exceptionhandler.h for information
|
||||
on how to hook it in.
|
||||
*/
|
||||
|
||||
#ifdef GAME_ERRORLOG_TXT
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
// --------------------
|
||||
#define ONEK 1024
|
||||
#define SIXTYFOURK (64*ONEK)
|
||||
#define ONEM (ONEK*ONEK)
|
||||
#define ONEG (ONEK*ONEK*ONEK)
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Enumerated Types
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Structures
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Classes
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Local Variables
|
||||
//
|
||||
// --------------------
|
||||
|
||||
const int NumCodeBytes = 16; // Number of code bytes to record.
|
||||
const int MaxStackDump = 2048; // Maximum number of DWORDS in stack dumps.
|
||||
const int StackColumns = 8; // Number of columns in stack dump.
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Internal Functions
|
||||
//
|
||||
// --------------------
|
||||
|
||||
// hprintf behaves similarly to printf, with a few vital differences.
|
||||
// It uses wvsprintf to do the formatting, which is a system routine,
|
||||
// thus avoiding C run time interactions. For similar reasons it
|
||||
// uses WriteFile rather than fwrite.
|
||||
// The one limitation that this imposes is that wvsprintf, and
|
||||
// therefore hprintf, cannot handle floating point numbers.
|
||||
static void hprintf(HANDLE LogFile, char* Format, ...)
|
||||
{
|
||||
char buffer[2000]; // wvsprintf never prints more than one K.
|
||||
|
||||
va_list arglist;
|
||||
va_start( arglist, Format);
|
||||
wvsprintf(buffer, Format, arglist);
|
||||
va_end( arglist);
|
||||
|
||||
DWORD NumBytes;
|
||||
WriteFile(LogFile, buffer, lstrlen(buffer), &NumBytes, 0);
|
||||
}
|
||||
|
||||
// Print the specified FILETIME to output in a human readable format,
|
||||
// without using the C run time.
|
||||
static void PrintTime(char *output, FILETIME TimeToPrint)
|
||||
{
|
||||
WORD Date, Time;
|
||||
if (FileTimeToLocalFileTime(&TimeToPrint, &TimeToPrint) &&
|
||||
FileTimeToDosDateTime(&TimeToPrint, &Date, &Time))
|
||||
{
|
||||
// What a silly way to print out the file date/time. Oh well,
|
||||
// it works, and I'm not aware of a cleaner way to do it.
|
||||
wsprintf(output, "%d/%d/%d %02d:%02d:%02d",
|
||||
(Date / 32) & 15, Date & 31, (Date / 512) + 1980,
|
||||
(Time / 2048), (Time / 32) & 63, (Time & 31) * 2);
|
||||
} else {
|
||||
output[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Print information about a code module (DLL or EXE) such as its size,
|
||||
// location, time stamp, etc.
|
||||
static void ShowModuleInfo(HANDLE LogFile, HINSTANCE ModuleHandle)
|
||||
{
|
||||
char ModName[MAX_PATH];
|
||||
#ifdef _MSC_VER
|
||||
__try {
|
||||
#endif
|
||||
if (GetModuleFileName(ModuleHandle, ModName, sizeof(ModName)) > 0) {
|
||||
// If GetModuleFileName returns greater than zero then this must
|
||||
// be a valid code module address. Therefore we can try to walk
|
||||
// our way through its structures to find the link time stamp.
|
||||
IMAGE_DOS_HEADER *DosHeader = (IMAGE_DOS_HEADER*)ModuleHandle;
|
||||
if (IMAGE_DOS_SIGNATURE != DosHeader->e_magic) {
|
||||
return;
|
||||
}
|
||||
|
||||
IMAGE_NT_HEADERS *NTHeader = (IMAGE_NT_HEADERS*)((char *)DosHeader + DosHeader->e_lfanew);
|
||||
if (IMAGE_NT_SIGNATURE != NTHeader->Signature) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Open the code module file so that we can get its file date
|
||||
// and size.
|
||||
HANDLE ModuleFile = CreateFile(ModName, GENERIC_READ,
|
||||
FILE_SHARE_READ, 0, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, 0);
|
||||
char TimeBuffer[100] = "";
|
||||
DWORD FileSize = 0;
|
||||
if (ModuleFile != INVALID_HANDLE_VALUE) {
|
||||
FileSize = GetFileSize(ModuleFile, 0);
|
||||
FILETIME LastWriteTime;
|
||||
if (GetFileTime(ModuleFile, 0, 0, &LastWriteTime)) {
|
||||
wsprintf(TimeBuffer, " - file date is ");
|
||||
PrintTime(TimeBuffer + lstrlen(TimeBuffer), LastWriteTime);
|
||||
}
|
||||
CloseHandle(ModuleFile);
|
||||
}
|
||||
hprintf(LogFile, "%s, loaded at 0x%08x - %d bytes - %08x%s\r\n",
|
||||
ModName, ModuleHandle, FileSize,
|
||||
NTHeader->FileHeader.TimeDateStamp, TimeBuffer);
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
}
|
||||
// Handle any exceptions by continuing from this point.
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Scan memory looking for code modules (DLLs or EXEs). VirtualQuery is used
|
||||
// to find all the blocks of address space that were reserved or committed,
|
||||
// and ShowModuleInfo will display module information if they are code
|
||||
// modules.
|
||||
|
||||
static void RecordModuleList(HANDLE LogFile)
|
||||
{
|
||||
hprintf(LogFile, "\r\n"
|
||||
"\tModule list: names, addresses, sizes, time stamps "
|
||||
"and file times:\r\n");
|
||||
SYSTEM_INFO SystemInfo;
|
||||
GetSystemInfo(&SystemInfo);
|
||||
const size_t PageSize = SystemInfo.dwPageSize;
|
||||
// Set NumPages to the number of pages in the 4GByte address space,
|
||||
// while being careful to avoid overflowing ints.
|
||||
const size_t NumPages = 4 * size_t(ONEG / PageSize);
|
||||
size_t pageNum = 0;
|
||||
void *LastAllocationBase = 0;
|
||||
while (pageNum < NumPages) {
|
||||
MEMORY_BASIC_INFORMATION MemInfo;
|
||||
if (VirtualQuery((void *)(pageNum * PageSize), &MemInfo, sizeof(MemInfo))) {
|
||||
if (MemInfo.RegionSize > 0) {
|
||||
|
||||
// Adjust the page number to skip over this block of memory.
|
||||
pageNum += MemInfo.RegionSize / PageSize;
|
||||
if (MemInfo.State == MEM_COMMIT && MemInfo.AllocationBase > LastAllocationBase) {
|
||||
// Look for new blocks of committed memory, and try
|
||||
// recording their module names - this will fail
|
||||
// gracefully if they aren't code modules.
|
||||
LastAllocationBase = MemInfo.AllocationBase;
|
||||
ShowModuleInfo(LogFile, (HINSTANCE)LastAllocationBase);
|
||||
}
|
||||
} else {
|
||||
pageNum += SIXTYFOURK / PageSize;
|
||||
}
|
||||
} else {
|
||||
// If VirtualQuery fails we advance by 64K because that is the
|
||||
// granularity of address space doled out by VirtualAlloc().
|
||||
pageNum += SIXTYFOURK / PageSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Record information about the user's system, such as processor type, amount
|
||||
// of memory, etc.
|
||||
|
||||
static void RecordSystemInformation(HANDLE LogFile)
|
||||
{
|
||||
FILETIME CurrentTime;
|
||||
GetSystemTimeAsFileTime(&CurrentTime);
|
||||
char TimeBuffer[100];
|
||||
PrintTime(TimeBuffer, CurrentTime);
|
||||
hprintf(LogFile, "Error occurred at %s.\r\n", TimeBuffer);
|
||||
char ModuleName[MAX_PATH];
|
||||
if (GetModuleFileName(0, ModuleName, sizeof(ModuleName)) <= 0) {
|
||||
lstrcpy(ModuleName, "Unknown");
|
||||
}
|
||||
char UserName[200];
|
||||
DWORD UserNameSize = sizeof(UserName);
|
||||
if (!GetUserName(UserName, &UserNameSize)) {
|
||||
lstrcpy(UserName, "Unknown");
|
||||
}
|
||||
hprintf(LogFile, "%s, run by %s.\r\n", ModuleName, UserName);
|
||||
|
||||
SYSTEM_INFO SystemInfo;
|
||||
GetSystemInfo(&SystemInfo);
|
||||
hprintf(LogFile, "%d processor(s), type %d.\r\n",
|
||||
SystemInfo.dwNumberOfProcessors, SystemInfo.dwProcessorType);
|
||||
|
||||
MEMORYSTATUS MemInfo;
|
||||
MemInfo.dwLength = sizeof(MemInfo);
|
||||
GlobalMemoryStatus(&MemInfo);
|
||||
// Print out the amount of physical memory, rounded up.
|
||||
hprintf(LogFile, "%d MBytes physical memory.\r\n", (MemInfo.dwTotalPhys +
|
||||
ONEM - 1) / ONEM);
|
||||
}
|
||||
|
||||
// Translate the exception code into something human readable.
|
||||
|
||||
static const char *GetExceptionDescription(DWORD ExceptionCode)
|
||||
{
|
||||
struct ExceptionNames
|
||||
{
|
||||
DWORD ExceptionCode;
|
||||
char* ExceptionName;
|
||||
};
|
||||
|
||||
ExceptionNames ExceptionMap[] =
|
||||
{
|
||||
{0x40010005, "a Control-C"},
|
||||
{0x40010008, "a Control-Break"},
|
||||
{0x80000002, "a Datatype Misalignment"},
|
||||
{0x80000003, "a Breakpoint"},
|
||||
{0xc0000005, "an Access Violation"},
|
||||
{0xc0000006, "an In Page Error"},
|
||||
{0xc0000017, "a No Memory"},
|
||||
{0xc000001d, "an Illegal Instruction"},
|
||||
{0xc0000025, "a Noncontinuable Exception"},
|
||||
{0xc0000026, "an Invalid Disposition"},
|
||||
{0xc000008c, "a Array Bounds Exceeded"},
|
||||
{0xc000008d, "a Float Denormal Operand"},
|
||||
{0xc000008e, "a Float Divide by Zero"},
|
||||
{0xc000008f, "a Float Inexact Result"},
|
||||
{0xc0000090, "a Float Invalid Operation"},
|
||||
{0xc0000091, "a Float Overflow"},
|
||||
{0xc0000092, "a Float Stack Check"},
|
||||
{0xc0000093, "a Float Underflow"},
|
||||
{0xc0000094, "an Integer Divide by Zero"},
|
||||
{0xc0000095, "an Integer Overflow"},
|
||||
{0xc0000096, "a Privileged Instruction"},
|
||||
{0xc00000fD, "a Stack Overflow"},
|
||||
{0xc0000142, "a DLL Initialization Failed"},
|
||||
{0xe06d7363, "a Microsoft C++ Exception"},
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(ExceptionMap) / sizeof(ExceptionMap[0]); i++) {
|
||||
if (ExceptionCode == ExceptionMap[i].ExceptionCode) {
|
||||
return ExceptionMap[i].ExceptionName;
|
||||
}
|
||||
}
|
||||
|
||||
return "Unknown exception type";
|
||||
}
|
||||
|
||||
static char* GetFilePart(char *source)
|
||||
{
|
||||
char *result = strrchr(source, '\\');
|
||||
if (result) {
|
||||
result++;
|
||||
} else {
|
||||
result = source;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// External Functions
|
||||
//
|
||||
// --------------------
|
||||
|
||||
extern char safe_string[512];
|
||||
|
||||
// Entry point into the main exception handling routine. This routine is put into an except()
|
||||
// statment at the beginning of a thread and is called anytime that there is a program exception
|
||||
// The data is stored in a file called ErrorLog.txt in the data directory.
|
||||
//
|
||||
// data: pointer to the exception data
|
||||
// Message: Any message that should be printed out in the error log file
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS data, const char *Message)
|
||||
{
|
||||
static bool BeenHere = false;
|
||||
|
||||
// Going recursive! That must mean this routine crashed!
|
||||
if (BeenHere) {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
BeenHere = true;
|
||||
|
||||
char ModuleName[MAX_PATH];
|
||||
char FileName[MAX_PATH] = "Unknown";
|
||||
// Create a filename to record the error information to.
|
||||
// Storing it in the executable directory works well.
|
||||
if (GetModuleFileName(0, ModuleName, sizeof(ModuleName)) <= 0) {
|
||||
ModuleName[0] = 0;
|
||||
}
|
||||
|
||||
char *FilePart = GetFilePart(ModuleName);
|
||||
|
||||
// Extract the file name portion and remove it's file extension. We'll
|
||||
// use that name shortly.
|
||||
lstrcpy(FileName, FilePart);
|
||||
char *lastperiod = strrchr(FileName, '.');
|
||||
if (lastperiod) {
|
||||
lastperiod[0] = 0;
|
||||
}
|
||||
|
||||
// Replace the executable filename with our error log file name.
|
||||
lstrcpy(FilePart, "errorlog.txt");
|
||||
HANDLE LogFile = CreateFile(ModuleName, GENERIC_WRITE, 0, 0,
|
||||
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, 0);
|
||||
if (LogFile == INVALID_HANDLE_VALUE) {
|
||||
OutputDebugString("Error creating exception report");
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// Append to the error log.
|
||||
SetFilePointer(LogFile, 0, 0, FILE_END);
|
||||
// Print out some blank lines to separate this error log from any previous ones.
|
||||
hprintf(LogFile, "\r\n\r\n\r\n\r\n");
|
||||
PEXCEPTION_RECORD Exception = data->ExceptionRecord;
|
||||
PCONTEXT Context = data->ContextRecord;
|
||||
|
||||
char CrashModulePathName[MAX_PATH];
|
||||
char *CrashModuleFileName = "Unknown";
|
||||
MEMORY_BASIC_INFORMATION MemInfo;
|
||||
// VirtualQuery can be used to get the allocation base associated with a
|
||||
// code address, which is the same as the ModuleHandle. This can be used
|
||||
// to get the filename of the module that the crash happened in.
|
||||
if (VirtualQuery((void*)Context->Eip, &MemInfo, sizeof(MemInfo)) && GetModuleFileName((HINSTANCE)MemInfo.AllocationBase, CrashModulePathName, sizeof(CrashModulePathName)) > 0) {
|
||||
CrashModuleFileName = GetFilePart(CrashModulePathName);
|
||||
}
|
||||
|
||||
// Print out the beginning of the error log in a Win95 error window
|
||||
// compatible format.
|
||||
hprintf(LogFile, "%s caused %s in module %s at %04x:%08x.\r\n",
|
||||
FileName, GetExceptionDescription(Exception->ExceptionCode),
|
||||
CrashModuleFileName, Context->SegCs, Context->Eip);
|
||||
hprintf(LogFile, "Exception handler called in %s.\r\n", Message);
|
||||
RecordSystemInformation(LogFile);
|
||||
// If the exception was an access violation, print out some additional
|
||||
// information, to the error log and the debugger.
|
||||
if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION && Exception->NumberParameters >= 2) {
|
||||
char DebugMessage[1000];
|
||||
const char* readwrite = "Read from";
|
||||
if (Exception->ExceptionInformation[0]) {
|
||||
readwrite = "Write to";
|
||||
}
|
||||
|
||||
wsprintf(DebugMessage, "%s location %08x caused an access violation.\r\n", readwrite, Exception->ExceptionInformation[1]);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// The VisualC++ debugger doesn't actually tell you whether a read
|
||||
// or a write caused the access violation, nor does it tell what
|
||||
// address was being read or written. So I fixed that.
|
||||
OutputDebugString("Exception handler: ");
|
||||
OutputDebugString(DebugMessage);
|
||||
#endif
|
||||
|
||||
hprintf(LogFile, "%s", DebugMessage);
|
||||
}
|
||||
|
||||
// Print out the register values in a Win95 error window compatible format.
|
||||
hprintf(LogFile, "\r\n");
|
||||
hprintf(LogFile, "Registers:\r\n");
|
||||
hprintf(LogFile, "EAX=%08x CS=%04x EIP=%08x EFLGS=%08x\r\n",
|
||||
Context->Eax, Context->SegCs, Context->Eip, Context->EFlags);
|
||||
hprintf(LogFile, "EBX=%08x SS=%04x ESP=%08x EBP=%08x\r\n",
|
||||
Context->Ebx, Context->SegSs, Context->Esp, Context->Ebp);
|
||||
hprintf(LogFile, "ECX=%08x DS=%04x ESI=%08x FS=%04x\r\n",
|
||||
Context->Ecx, Context->SegDs, Context->Esi, Context->SegFs);
|
||||
hprintf(LogFile, "EDX=%08x ES=%04x EDI=%08x GS=%04x\r\n",
|
||||
Context->Edx, Context->SegEs, Context->Edi, Context->SegGs);
|
||||
hprintf(LogFile, "Bytes at CS:EIP:\r\n");
|
||||
|
||||
// Print out the bytes of code at the instruction pointer. Since the
|
||||
// crash may have been caused by an instruction pointer that was bad,
|
||||
// this code needs to be wrapped in an exception handler, in case there
|
||||
// is no memory to read. If the dereferencing of code[] fails, the
|
||||
// exception handler will print '??'.
|
||||
unsigned char *code = (unsigned char*)Context->Eip;
|
||||
for (int codebyte = 0; codebyte < NumCodeBytes; codebyte++) {
|
||||
#ifdef _MSC_VER
|
||||
__try {
|
||||
#endif
|
||||
hprintf(LogFile, "%02x ", code[codebyte]);
|
||||
#ifdef _MSC_VER
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
hprintf(LogFile, "?? ");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Time to print part or all of the stack to the error log. This allows
|
||||
// us to figure out the call stack, parameters, local variables, etc.
|
||||
hprintf(LogFile, "\r\n"
|
||||
"Stack dump:\r\n");
|
||||
__try {
|
||||
// Esp contains the bottom of the stack, or at least the bottom of
|
||||
// the currently used area.
|
||||
DWORD* pStack = (DWORD *)Context->Esp;
|
||||
DWORD* pStackTop;
|
||||
__asm
|
||||
{
|
||||
// Load the top (highest address) of the stack from the
|
||||
// thread information block. It will be found there in
|
||||
// Win9x and Windows NT.
|
||||
mov eax, fs:[4]
|
||||
mov pStackTop, eax
|
||||
}
|
||||
if (pStackTop > pStack + MaxStackDump) {
|
||||
pStackTop = pStack + MaxStackDump;
|
||||
}
|
||||
|
||||
int Count = 0;
|
||||
// Too many calls to WriteFile can take a long time, causing
|
||||
// confusing delays when programs crash. Therefore I implemented
|
||||
// simple buffering for the stack dumping code instead of calling
|
||||
// hprintf directly.
|
||||
char buffer[1000] = "";
|
||||
const int safetyzone = 50;
|
||||
char* nearend = buffer + sizeof(buffer) - safetyzone;
|
||||
char* output = buffer;
|
||||
while (pStack + 1 <= pStackTop) {
|
||||
if ((Count % StackColumns) == 0) {
|
||||
output += wsprintf(output, "%08x: ", pStack);
|
||||
}
|
||||
|
||||
char *Suffix = " ";
|
||||
if ((++Count % StackColumns) == 0 || pStack + 2 > pStackTop) {
|
||||
Suffix = "\r\n";
|
||||
}
|
||||
|
||||
output += wsprintf(output, "%08x%s", *pStack, Suffix);
|
||||
pStack++;
|
||||
// Check for when the buffer is almost full, and flush it to disk.
|
||||
if (output > nearend) {
|
||||
hprintf(LogFile, "%s", buffer);
|
||||
buffer[0] = 0;
|
||||
output = buffer;
|
||||
}
|
||||
}
|
||||
// Print out any final characters from the cache.
|
||||
hprintf(LogFile, "%s", buffer);
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
hprintf(LogFile, "Exception encountered during stack dump.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (safe_string[0])
|
||||
hprintf(LogFile, "Last safe point: %s\r\n", safe_string);
|
||||
#endif
|
||||
|
||||
RecordModuleList(LogFile);
|
||||
|
||||
CloseHandle(LogFile);
|
||||
// Return the magic value which tells Win32 that this handler didn't
|
||||
// actually handle the exception - so that things will proceed as per
|
||||
// normal.
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef GAME_ERRORLOG_TXT
|
||||
|
||||
#ifndef __EXCEPTION_HANDLER_H
|
||||
#define __EXCEPTION_HANDLER_H
|
||||
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Enumerated types
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Structures
|
||||
//
|
||||
// --------------------
|
||||
|
||||
// this is a forward declaration so we don't need to include windows.h
|
||||
|
||||
typedef struct _EXCEPTION_POINTERS EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Classes
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Prototypes
|
||||
//
|
||||
// --------------------
|
||||
|
||||
int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS data, const char *Message);
|
||||
|
||||
// --------------------
|
||||
//
|
||||
// Helper Macros
|
||||
//
|
||||
// --------------------
|
||||
|
||||
|
||||
#endif // __EXCEPTION_HANDLER_H
|
||||
#endif
|
||||
@@ -1,106 +0,0 @@
|
||||
#ifndef EXTERNALCODE_H_INCLUDED_
|
||||
#define EXTERNALCODE_H_INCLUDED_
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
/* We must have windows.h anywhere SCP_ExternalCode is used under windows */
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/* This class loads external libraries for FSO use.
|
||||
* Different platforms have different ways of doing this, so use your ifdefs!
|
||||
*/
|
||||
class SCP_ExternalCode
|
||||
{
|
||||
public:
|
||||
SCP_ExternalCode( )
|
||||
#ifdef _WIN32
|
||||
: m_dll( NULL )
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SCP_ExternalCode( )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( m_dll )
|
||||
::FreeLibrary( m_dll );
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
BOOL LoadExternal( const char* externlib )
|
||||
{
|
||||
if ( !externlib )
|
||||
return FALSE;
|
||||
|
||||
#ifdef _WIN32
|
||||
m_dll = ::LoadLibrary( externlib );
|
||||
|
||||
if ( m_dll )
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void* LoadFunction( const char* functionname )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( m_dll != NULL && functionname != NULL )
|
||||
return ::GetProcAddress( m_dll, functionname );
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
HMODULE m_dll;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* These are available if you're compiling an external DLL
|
||||
* So far we have trackir, and speech is on the way
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
# define SCP_EXT_CALLCONV __cdecl
|
||||
# ifdef SCPDLL_EXTERNAL_LIB
|
||||
# define SCPDLL_EXTERNAL __declspec( dllexport )
|
||||
# else
|
||||
# define SCPDLL_EXTERNAL __declspec( dllimport )
|
||||
# endif
|
||||
/* Must be in a CPP file in your DLL code
|
||||
* If you want to write your own, you shouldn't.
|
||||
*/
|
||||
# define SCPDLL_DLLMAIN( ) \
|
||||
SCP_EXTERN_C BOOL APIENTRY DllMain( HANDLE, DWORD, LPVOID ) { return TRUE; }
|
||||
#else
|
||||
# define SCP_EXT_CALLCONV
|
||||
# define SCPDLL_EXTERNAL
|
||||
# define SCPDLL_DLLMAIN( )
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define SCP_EXTERN_C extern "C"
|
||||
#else
|
||||
# define SCP_EXTERN_C
|
||||
#endif
|
||||
|
||||
/* Version information */
|
||||
typedef struct _SCPDLL_Version
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
} SCPDLL_Version;
|
||||
|
||||
typedef int ( SCP_EXT_CALLCONV *SCPDLL_PFVERSION )( SCPDLL_Version* );
|
||||
|
||||
/* Must be in a CPP file in your DLL code */
|
||||
#define SCPDLL_VERSION_FUNCTION( Major, Minor, Patch ) \
|
||||
SCP_EXTERN_C int SCPDLL_EXTERNAL SCPDLL_GetVersion( SCPDLL_Version* v ) { \
|
||||
if ( !v ) return -1;\
|
||||
v->major = Major; v->minor = Minor; v->patch = Patch;\
|
||||
return 0; }
|
||||
|
||||
#endif /* EXTERNALCODE_H_INCLUDED_ */
|
||||
@@ -1,4 +0,0 @@
|
||||
#include "trackirpublic.h"
|
||||
|
||||
/* The TrackIR Interface */
|
||||
TrackIRDLL gTirDll_TrackIR;
|
||||
@@ -1,170 +0,0 @@
|
||||
#ifndef TRACKIRPUBLIC_H_INCLUDED_
|
||||
#define TRACKIRPUBLIC_H_INCLUDED_
|
||||
|
||||
#include "external_dll/externalcode.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#define TRACKIRBRIDGEDLLNAME "scptrackir.dll"
|
||||
|
||||
#define SCP_INITRESULT_SUCCESS 0
|
||||
#define SCP_INITRESULT_BADKEY 1
|
||||
#define SCP_INITRESULT_BADPATH 2
|
||||
#define SCP_INITRESULT_PATHTOOLONG 3
|
||||
#define SCP_INITRESULT_NODLL 4
|
||||
#define SCP_INITRESULT_BADSIGNATURE 5
|
||||
#define SCP_INITRESULT_UNABLETOREGISTER 6
|
||||
#define SCP_INITRESULT_BADDATAFIELDS 7
|
||||
#define SCP_INITRESULT_BADREGISTRATION 8
|
||||
#define SCP_INITRESULT_BADTRANSMISSION 9
|
||||
|
||||
/* Exported functions */
|
||||
/* HWND comes from externalcode.h */
|
||||
/* These are function pointer prototypes provided for library loading */
|
||||
|
||||
/* Only one function doesn't return an int or a float */
|
||||
typedef int ( SCP_EXT_CALLCONV *SCPTRACKIR_PFINIT )( HWND );
|
||||
|
||||
/* All other trackir functions return an int or a float
|
||||
* and take no parameters
|
||||
*/
|
||||
typedef int ( SCP_EXT_CALLCONV *SCPTRACKIR_PFINTVOID )( );
|
||||
typedef float ( SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID )( );
|
||||
|
||||
class TrackIRDLL : public SCP_ExternalCode
|
||||
{
|
||||
public:
|
||||
TrackIRDLL( )
|
||||
{
|
||||
/* Load the DLL and functions
|
||||
* If this is done globally, we'll be found by MSPDBDEBUGGING :)
|
||||
*/
|
||||
|
||||
Reset( );
|
||||
|
||||
if ( !LoadExternal( TRACKIRBRIDGEDLLNAME ) )
|
||||
return;
|
||||
|
||||
m_Init = (SCPTRACKIR_PFINIT)LoadFunction( "SCPTIR_Init" );
|
||||
m_Close = (SCPTRACKIR_PFINTVOID)LoadFunction( "SCPTIR_Close" );
|
||||
m_Query = (SCPTRACKIR_PFINTVOID)LoadFunction( "SCPTIR_Query" );
|
||||
|
||||
m_GetX = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetX" );
|
||||
m_GetY = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetY" );
|
||||
m_GetZ = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetZ" );
|
||||
m_GetRoll = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetRoll" );
|
||||
m_GetPitch = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetPitch" );
|
||||
m_GetYaw = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetYaw" );
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
bool Enabled( )
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
virtual ~TrackIRDLL( )
|
||||
{
|
||||
/* Prevent further use of the DLL */
|
||||
Reset( );
|
||||
}
|
||||
|
||||
void Reset( )
|
||||
{
|
||||
m_Init = NULL;
|
||||
m_Close = NULL;
|
||||
m_Query = NULL;
|
||||
m_GetX = NULL;
|
||||
m_GetY = NULL;
|
||||
m_GetZ = NULL;
|
||||
m_GetPitch = NULL;
|
||||
m_GetRoll = NULL;
|
||||
m_GetYaw = NULL;
|
||||
m_enabled = false;
|
||||
}
|
||||
|
||||
/* Returns 0 on success */
|
||||
int Init( HWND hwnd )
|
||||
{
|
||||
if ( m_Init )
|
||||
return m_Init( hwnd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Close( )
|
||||
{
|
||||
if ( m_Close )
|
||||
return m_Close( );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Query( )
|
||||
{
|
||||
if ( m_Query )
|
||||
return m_Query( );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
float GetX( )
|
||||
{
|
||||
if ( m_GetX )
|
||||
return m_GetX( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetY( )
|
||||
{
|
||||
if ( m_GetY )
|
||||
return m_GetY( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetZ( )
|
||||
{
|
||||
if ( m_GetZ )
|
||||
return m_GetZ( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetPitch( )
|
||||
{
|
||||
if ( m_GetPitch )
|
||||
return m_GetPitch( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetRoll( )
|
||||
{
|
||||
if ( m_GetRoll )
|
||||
return m_GetRoll( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetYaw( )
|
||||
{
|
||||
if ( m_GetYaw )
|
||||
return m_GetYaw( );
|
||||
return 0.0f;
|
||||
}
|
||||
private:
|
||||
/* Functions */
|
||||
SCPTRACKIR_PFINIT m_Init;
|
||||
SCPTRACKIR_PFINTVOID m_Close;
|
||||
SCPTRACKIR_PFINTVOID m_Query;
|
||||
|
||||
SCPTRACKIR_PFFLOATVOID m_GetX;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetY;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetZ;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetPitch;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetRoll;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetYaw;
|
||||
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
/* Added to trackirpublic.h */
|
||||
#ifndef SCPDLL_EXTERNAL_LIB
|
||||
extern TrackIRDLL gTirDll_TrackIR;
|
||||
#endif
|
||||
|
||||
#endif /* TRACKIRPUBLIC_H_INCLUDED_ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _FIREBALLS_H
|
||||
#define _FIREBALLS_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct object;
|
||||
struct ship_info;
|
||||
|
||||
// values correspond to the fireball render types
|
||||
#define FIREBALL_MEDIUM_EXPLOSION 0
|
||||
#define FIREBALL_LARGE_EXPLOSION 1
|
||||
#define FIREBALL_WARP_EFFECT 2
|
||||
|
||||
// these values correspond to the fireball.tbl default entries
|
||||
#define FIREBALL_EXPLOSION_MEDIUM 0 // Used for the 4 little explosions before a ship explodes
|
||||
#define FIREBALL_WARP 1 // Used for the warp in / warp out effect
|
||||
#define FIREBALL_KNOSSOS 2 // Used for the KNOSSOS warp in / warp out effect
|
||||
#define FIREBALL_ASTEROID 3
|
||||
#define FIREBALL_EXPLOSION_LARGE1 4 // Used for the big explosion when a ship breaks into pieces
|
||||
#define FIREBALL_EXPLOSION_LARGE2 5 // Used for the big explosion when a ship breaks into pieces
|
||||
|
||||
#define MAX_FIREBALL_TYPES 32 // The maximum number of fireballs that can be defined
|
||||
#define NUM_DEFAULT_FIREBALLS 6
|
||||
|
||||
#define FIREBALL_NUM_LARGE_EXPLOSIONS 2
|
||||
|
||||
extern int fireball_used[MAX_FIREBALL_TYPES];
|
||||
extern int Num_fireball_types;
|
||||
|
||||
// all this moved here by Goober5000 because it makes more sense in the H file
|
||||
typedef struct fireball_lod {
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
int bitmap_id;
|
||||
int num_frames;
|
||||
int fps;
|
||||
} fireball_lod;
|
||||
|
||||
typedef struct fireball_info {
|
||||
int lod_count;
|
||||
float exp_color[3];
|
||||
fireball_lod lod[4];
|
||||
} fireball_info;
|
||||
|
||||
// flag values for fireball struct flags member
|
||||
#define FBF_WARP_CLOSE_SOUND_PLAYED (1<<0)
|
||||
#define FBF_WARP_CAPITAL_SIZE (1<<1)
|
||||
#define FBF_WARP_CRUISER_SIZE (1<<2)
|
||||
#define FBF_WARP_3D (1<<3) // Goober5000
|
||||
#define FBF_WARP_VIA_SEXP (1<<4) // Goober5000
|
||||
|
||||
typedef struct fireball {
|
||||
int objnum; // If -1 this object is unused
|
||||
int fireball_info_index; // Index into Fireball_info array
|
||||
int fireball_render_type;
|
||||
int current_bitmap;
|
||||
int orient; // For fireballs, which orientation. For warps, 0 is warpin, 1 is warpout
|
||||
int flags; // see #define FBF_*
|
||||
char lod; // current LOD
|
||||
float time_elapsed; // in seconds
|
||||
float total_time; // total lifetime of animation in seconds
|
||||
int warp_open_sound_index; // for warp-effect - Goober5000
|
||||
int warp_close_sound_index; // for warp-effect - Goober5000
|
||||
} fireball;
|
||||
// end move
|
||||
|
||||
void fireball_init();
|
||||
void fireball_render(object * obj);
|
||||
void fireball_delete( object * obj );
|
||||
void fireball_process_pre(object * obj, float frame_time);
|
||||
void fireball_process_post(object * obj, float frame_time);
|
||||
|
||||
// reversed is for warp_in/out effects
|
||||
// Velocity: If not NULL, the fireball will move at a constant velocity.
|
||||
// warp_lifetime: If warp_lifetime > 0.0f then makes the explosion loop so it lasts this long. Only works for warp effect
|
||||
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reversed=0, vec3d *velocity=NULL, float warp_lifetime=0.0f, int ship_class=-1, matrix *orient=NULL, int low_res=0, int extra_flags=0, int warp_open_sound=-1, int warp_close_sound=-1);
|
||||
void fireball_render_plane(int plane);
|
||||
void fireball_close();
|
||||
void fireball_level_close();
|
||||
void fireball_preload(); // page in warpout effect data
|
||||
|
||||
// Returns 1 if you can remove this fireball
|
||||
int fireball_is_perishable(object * obj);
|
||||
|
||||
// Returns 1 if this fireball is a warp
|
||||
int fireball_is_warp(object * obj);
|
||||
|
||||
// Returns life left of a fireball in seconds
|
||||
float fireball_lifeleft( object *obj );
|
||||
|
||||
// Returns life left of a fireball in percent
|
||||
float fireball_lifeleft_percent( object *obj );
|
||||
|
||||
// returns the lighting color (in [0...1] range) to use for explosion
|
||||
void fireball_get_color(int idx, float *red, float *green, float *blue);
|
||||
|
||||
// returns the index of the fireball bitmap for this ship. -1 if there is none.
|
||||
int fireball_ship_explosion_type(ship_info *sip);
|
||||
|
||||
// internal function to draw warp grid.
|
||||
extern void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d = 0 );
|
||||
|
||||
extern int Warp_model;
|
||||
|
||||
// Goober5000
|
||||
extern int Knossos_warp_ani_used;
|
||||
|
||||
#endif /* _FIREBALLS_H */
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "math/vecmat.h"
|
||||
#include "graphics/tmapper.h"
|
||||
#include "render/3d.h"
|
||||
#include "fireball/fireballs.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "model/model.h"
|
||||
#include "ship/ship.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
|
||||
|
||||
extern int Warp_model;
|
||||
extern int Warp_glow_bitmap;
|
||||
extern int Warp_ball_bitmap;
|
||||
|
||||
|
||||
void draw_face( vertex *v1, vertex *v2, vertex *v3 )
|
||||
{
|
||||
vec3d norm;
|
||||
vertex *vertlist[3];
|
||||
|
||||
vm_vec_perp(&norm,(vec3d *)&v1->x, (vec3d *)&v2->x, (vec3d *)&v3->x);
|
||||
if ( vm_vec_dot(&norm, (vec3d *)&v1->x ) >= 0.0 ) {
|
||||
vertlist[0] = v3;
|
||||
vertlist[1] = v2;
|
||||
vertlist[2] = v1;
|
||||
} else {
|
||||
vertlist[0] = v1;
|
||||
vertlist[1] = v2;
|
||||
vertlist[2] = v3;
|
||||
}
|
||||
|
||||
g3_draw_poly( 3, vertlist, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
||||
|
||||
}
|
||||
|
||||
void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
|
||||
{
|
||||
vec3d center;
|
||||
vec3d vecs[5];
|
||||
vertex verts[5];
|
||||
int saved_gr_zbuffering = gr_zbuffer_get();
|
||||
|
||||
gr_zbuffer_set(GR_ZBUFF_READ);
|
||||
|
||||
vm_vec_scale_add( ¢er, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
|
||||
|
||||
|
||||
if (Warp_glow_bitmap >= 0) {
|
||||
float r = radius;
|
||||
bool render_it = true;
|
||||
|
||||
#define OUT_PERCENT1 0.80f
|
||||
#define OUT_PERCENT2 0.90f
|
||||
|
||||
#define IN_PERCENT1 0.10f
|
||||
#define IN_PERCENT2 0.20f
|
||||
|
||||
if (Cmdline_warp_flash)
|
||||
{
|
||||
if ( (life_percent >= IN_PERCENT1) && (life_percent < IN_PERCENT2) ) {
|
||||
r *= (life_percent - IN_PERCENT1) / (IN_PERCENT2 - IN_PERCENT1);
|
||||
//render_it = true;
|
||||
} else if ( (life_percent >= OUT_PERCENT1) && (life_percent < OUT_PERCENT2) ) {
|
||||
r *= (OUT_PERCENT2 - life_percent) / (OUT_PERCENT2 - OUT_PERCENT1);
|
||||
//render_it = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (render_it) {
|
||||
// Add in noise
|
||||
int noise_frame = fl2i(Missiontime/15.0f) % NOISE_NUM_FRAMES;
|
||||
|
||||
r *= (0.40f + Noise[noise_frame] * 0.30f);
|
||||
|
||||
// Bobboau's warp thingie, toggled by cmdline
|
||||
if (Cmdline_warp_flash) {
|
||||
r += powf((2.0f * life_percent) - 1.0f, 24.0f) * max_radius * 1.5f;
|
||||
}
|
||||
|
||||
vecs[4] = center;
|
||||
verts[4].u = 0.5f; verts[4].v = 0.5f;
|
||||
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[4], &vecs[4] );
|
||||
} else {
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
}
|
||||
|
||||
float alpha = (The_mission.flags & MISSION_FLAG_FULLNEB) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
|
||||
gr_set_bitmap( Warp_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha );
|
||||
|
||||
g3_draw_bitmap( &verts[4], 0, r, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
||||
}
|
||||
}
|
||||
|
||||
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
float scale = radius / 25.0f;
|
||||
model_set_warp_globals(scale, scale, scale, texture_bitmap_num, (radius/max_radius) );
|
||||
|
||||
float dist = vm_vec_dist_quick( pos, &Eye_position );
|
||||
model_set_detail_level((int)(dist / (radius * 10.0f)));
|
||||
|
||||
model_render( Warp_model, orient, pos, MR_LOCK_DETAIL | MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL );
|
||||
|
||||
model_set_warp_globals();
|
||||
} else {
|
||||
float Grid_depth = radius/2.5f;
|
||||
|
||||
gr_set_bitmap( texture_bitmap_num, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
|
||||
|
||||
vm_vec_scale_add( &vecs[0], ¢er, &orient->vec.uvec, radius );
|
||||
vm_vec_scale_add2( &vecs[0], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[0], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[1], ¢er, &orient->vec.uvec, radius );
|
||||
vm_vec_scale_add2( &vecs[1], &orient->vec.rvec, radius );
|
||||
vm_vec_scale_add2( &vecs[1], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[2], ¢er, &orient->vec.uvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[2], &orient->vec.rvec, radius );
|
||||
vm_vec_scale_add2( &vecs[2], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[3], ¢er, &orient->vec.uvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
|
||||
vecs[4] = center;
|
||||
|
||||
verts[0].u = 0.01f; verts[0].v = 0.01f;
|
||||
verts[1].u = 0.99f; verts[1].v = 0.01f;
|
||||
verts[2].u = 0.99f; verts[2].v = 0.99f;
|
||||
verts[3].u = 0.01f; verts[3].v = 0.99f;
|
||||
verts[4].u = 0.5f; verts[4].v = 0.5f;
|
||||
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[0], &vecs[0] );
|
||||
g3_rotate_vertex( &verts[1], &vecs[1] );
|
||||
g3_rotate_vertex( &verts[2], &vecs[2] );
|
||||
g3_rotate_vertex( &verts[3], &vecs[3] );
|
||||
g3_rotate_vertex( &verts[4], &vecs[4] );
|
||||
} else {
|
||||
g3_transfer_vertex( &verts[0], &vecs[0] );
|
||||
g3_transfer_vertex( &verts[1], &vecs[1] );
|
||||
g3_transfer_vertex( &verts[2], &vecs[2] );
|
||||
g3_transfer_vertex( &verts[3], &vecs[3] );
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
}
|
||||
|
||||
int cull = gr_set_cull(0); // fixes rendering problem in D3D - taylor
|
||||
draw_face( &verts[0], &verts[4], &verts[1] );
|
||||
draw_face( &verts[1], &verts[4], &verts[2] );
|
||||
draw_face( &verts[4], &verts[3], &verts[2] );
|
||||
draw_face( &verts[0], &verts[3], &verts[4] );
|
||||
gr_set_cull(cull);
|
||||
}
|
||||
|
||||
if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
|
||||
flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
|
||||
float adg = (2.0f * life_percent) - 1.0f;
|
||||
float pct = (powf(adg, 4.0f) - powf(adg, 128.0f)) * 4.0f;
|
||||
|
||||
if (pct > 0.00001f) {
|
||||
g3_start_instance_matrix(pos, orient, true);
|
||||
|
||||
gr_set_bitmap(Warp_ball_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
|
||||
|
||||
warp_ball.render(max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
|
||||
|
||||
g3_done_instance(true);
|
||||
}
|
||||
}
|
||||
|
||||
gr_zbuffer_set( saved_gr_zbuffering );
|
||||
}
|
||||
@@ -1,405 +0,0 @@
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
// AltShipClassDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "AltShipClassDlg.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
|
||||
AltShipClassDlg::AltShipClassDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(AltShipClassDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AltShipClassDlg)
|
||||
m_selected_variable = -1;
|
||||
m_selected_class = -1;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
multi_edit = false;
|
||||
player_ships_only = true;
|
||||
num_string_variables = 0;
|
||||
|
||||
memset(string_variable_indices, -1, sizeof (int)*MAX_SEXP_VARIABLES);
|
||||
memset(ship_class_indices, -1, sizeof (int)*MAX_SHIP_CLASSES);
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AltShipClassDlg)
|
||||
DDX_Control(pDX, IDC_DEFAULT_TO_CLASS, m_default_to_class);
|
||||
DDX_Control(pDX, IDC_ALT_CLASS_LIST, m_alt_class_list);
|
||||
DDX_Control(pDX, IDC_SET_FROM_SHIP_CLASS, m_set_from_ship_class);
|
||||
DDX_Control(pDX, IDC_SET_FROM_VARIABLES, m_set_from_variables);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_VARIABLES, m_selected_variable);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_SHIP_CLASS, m_selected_class);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AltShipClassDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(AltShipClassDlg)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_ADD, OnAltClassAdd)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_INSERT, OnAltClassInsert)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DELETE, OnAltClassDelete)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_UP, OnMoveUp)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DOWN, OnMoveDown)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_SHIP_CLASS, OnSelendokSetFromShipClass)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_VARIABLES, OnSelendokSetFromVariables)
|
||||
ON_LBN_SELCHANGE(IDC_ALT_CLASS_LIST, OnSelchangeAltClassList)
|
||||
ON_BN_CLICKED(IDC_DEFAULT_TO_CLASS, OnDefaultToClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg message handlers
|
||||
|
||||
|
||||
BOOL AltShipClassDlg::OnInitDialog()
|
||||
{
|
||||
int i, count;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// have we got multiple selected ships?
|
||||
num_selected_ships = 0;
|
||||
object *objp;
|
||||
|
||||
objp = GET_FIRST(&obj_used_list);
|
||||
while (objp != END_OF_LIST(&obj_used_list)) {
|
||||
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
|
||||
if (objp->flags & OF_MARKED) {
|
||||
m_selected_ships[num_selected_ships++] = objp->instance;
|
||||
}
|
||||
}
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
Assert (num_selected_ships > 0);
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
|
||||
if (num_selected_ships > 1)
|
||||
{
|
||||
multi_edit = true;
|
||||
}
|
||||
|
||||
// Fill the variable combo box
|
||||
m_set_from_variables.ResetContent();
|
||||
m_set_from_variables.AddString("Set From Ship Class");
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[i].variable_name, Sexp_variables[i].text);
|
||||
m_set_from_variables.AddString(buff);
|
||||
string_variable_indices[num_string_variables++] = i;
|
||||
}
|
||||
}
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
if (!num_string_variables) {
|
||||
m_set_from_variables.EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
// Fill the ship classes combo box
|
||||
m_set_from_ship_class.ResetContent();
|
||||
// Add the default entry if we need one followed by all the ship classes
|
||||
if (num_string_variables) {
|
||||
m_set_from_ship_class.AddString("Set From Variable");
|
||||
}
|
||||
count = 0;
|
||||
for (i=0; i<Num_ship_classes; i++)
|
||||
{
|
||||
if (player_ships_only && !(Ship_info[i].flags & SIF_PLAYER_SHIP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ship_class_indices[count++] = i;
|
||||
m_set_from_ship_class.AddString(Ship_info[i].name);
|
||||
}
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables?1:0); // Set to the first ship class
|
||||
|
||||
// Set up the actual list of alt classes
|
||||
alt_class_pool.clear();
|
||||
alt_class_pool = Ships[Objects[cur_object_index].instance].s_alt_classes;
|
||||
alt_class_list_rebuild();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild()
|
||||
{
|
||||
int i, j;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
j = m_alt_class_list.GetCount();
|
||||
for ( i=0; i < j ; i++) {
|
||||
m_alt_class_list.DeleteString(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)alt_class_pool.size() ; i++) {
|
||||
// Default classes should be at the end of the list
|
||||
if(alt_class_pool[i].default_to_this_class && (i < (int)alt_class_pool.size() - 1) ) {
|
||||
// Int3();
|
||||
// TO DO : we should fix this.
|
||||
}
|
||||
|
||||
if (alt_class_pool[i].variable_index != -1) {
|
||||
Assert (alt_class_pool[i].variable_index > -1 && alt_class_pool[i].variable_index < MAX_SEXP_VARIABLES);
|
||||
Assert (Sexp_variables[alt_class_pool[i].variable_index].type & SEXP_VARIABLE_STRING);
|
||||
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[alt_class_pool[i].variable_index].variable_name, Sexp_variables[alt_class_pool[i].variable_index].text);
|
||||
|
||||
// add it to the list
|
||||
m_alt_class_list.AddString(buff);
|
||||
}
|
||||
else {
|
||||
if (alt_class_pool[i].ship_class >= 0 && alt_class_pool[i].ship_class < MAX_SHIP_CLASSES) {
|
||||
m_alt_class_list.AddString(Ship_info[alt_class_pool[i].ship_class].name);
|
||||
}
|
||||
else {
|
||||
m_alt_class_list.AddString("Invalid Ship Class");
|
||||
Int3();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
|
||||
for (int i=0; i < num_selected_ships; i++) {
|
||||
Ships[m_selected_ships[i]].s_alt_classes = alt_class_pool;
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassAdd()
|
||||
{
|
||||
alt_class new_list_item;
|
||||
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassInsert()
|
||||
{
|
||||
int index;
|
||||
alt_class new_list_item;
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// If nothing is selected just add it
|
||||
if ( index == -1) {
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
}
|
||||
// Stick it in front of the current selection
|
||||
else {
|
||||
alt_class_pool.insert(alt_class_pool.begin() + index, new_list_item );
|
||||
}
|
||||
|
||||
alt_class_list_rebuild();
|
||||
|
||||
// If we inserted the user will probably want to edit the selection
|
||||
if (index > -1) {
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the currently selected list entry
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item)
|
||||
{
|
||||
int index;
|
||||
|
||||
// Add a string variable to the list
|
||||
if (num_string_variables && m_set_from_variables.GetCurSel() > 0) {
|
||||
index = string_variable_indices[m_set_from_variables.GetCurSel() -1];
|
||||
|
||||
Assert (index >= 0);
|
||||
list_item.variable_index = index;
|
||||
list_item.ship_class = ship_info_lookup(Sexp_variables[index].text);
|
||||
}
|
||||
// Add a ship class to the list
|
||||
else {
|
||||
index = m_set_from_ship_class.GetCurSel();
|
||||
|
||||
// Correct the index if the first entry isn't actually a ship class
|
||||
if (num_string_variables) {
|
||||
Assert (index > 0);
|
||||
index--;
|
||||
}
|
||||
|
||||
list_item.variable_index = -1;
|
||||
list_item.ship_class = ship_class_indices[index];
|
||||
}
|
||||
|
||||
// check the default tickbox
|
||||
list_item.default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassDelete()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert (index < (int) alt_class_pool.size());
|
||||
alt_class_pool.erase(alt_class_pool.begin()+index);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveUp()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected or already at the top
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[index-1]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index-1);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveDown()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected or already at the bottom
|
||||
if (index == -1 || (index >= m_alt_class_list.GetCount() - 1) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[index++]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromShipClass()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_ship_class.GetCurSel() == 0 && num_string_variables) {
|
||||
m_set_from_variables.SetCurSel(1);
|
||||
}
|
||||
else {
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromVariables()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_variables.GetCurSel() == 0) {
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
m_set_from_ship_class.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelchangeAltClassList()
|
||||
{
|
||||
int i;
|
||||
int variable_selection = 0;
|
||||
int ship_selection = 0;
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Selected nothing
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have a variable selected
|
||||
if (alt_class_pool[index].variable_index != -1) {
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (string_variable_indices[i] == alt_class_pool[index].variable_index) {
|
||||
variable_selection = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ship selected
|
||||
else {
|
||||
for (i=0; i < MAX_SHIP_CLASSES; i++) {
|
||||
if (ship_class_indices[i] == alt_class_pool[index].ship_class) {
|
||||
ship_selection = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have string variables in the mission the first entry on the list won't be a ship
|
||||
if (num_string_variables) {
|
||||
ship_selection++;
|
||||
}
|
||||
}
|
||||
|
||||
m_set_from_variables.SetCurSel(variable_selection);
|
||||
m_set_from_ship_class.SetCurSel(ship_selection);
|
||||
m_default_to_class.SetCheck(alt_class_pool[index].default_to_this_class ? 1:0);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnDefaultToClass()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
alt_class_pool[index].default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
#define AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AltShipClassDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
class AltShipClassDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
AltShipClassDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(AltShipClassDlg)
|
||||
enum { IDD = IDD_ALT_SHIP_CLASS };
|
||||
CButton m_default_to_class;
|
||||
CListBox m_alt_class_list;
|
||||
CComboBox m_set_from_ship_class;
|
||||
CComboBox m_set_from_variables;
|
||||
int m_selected_variable;
|
||||
int m_selected_class;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(AltShipClassDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(AltShipClassDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnCancel();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnAltClassAdd();
|
||||
afx_msg void OnAltClassInsert();
|
||||
afx_msg void OnAltClassDelete();
|
||||
afx_msg void OnMoveUp();
|
||||
afx_msg void OnMoveDown();
|
||||
afx_msg void OnSelendokSetFromShipClass();
|
||||
afx_msg void OnSelendokSetFromVariables();
|
||||
afx_msg void OnSelchangeAltClassList();
|
||||
afx_msg void OnDefaultToClass();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
|
||||
bool player_ships_only; // Whether we only add player ships to the alt classes or if we can add any ship
|
||||
|
||||
SCP_vector<alt_class> alt_class_pool;
|
||||
int num_string_variables; // Number of string variables in the mission
|
||||
int string_variable_indices[MAX_SEXP_VARIABLES]; // maps string variables to their index in Sexp_variables
|
||||
int ship_class_indices[MAX_SHIP_CLASSES]; // maps ships in the ships combobox to their index in Ship_info
|
||||
|
||||
|
||||
// variables to handle selection of multiple ships
|
||||
bool multi_edit;
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild();
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item);
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
@@ -1,115 +0,0 @@
|
||||
// FictionViewerDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "FictionViewerDlg.h"
|
||||
#include "missionui/fictionviewer.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
|
||||
FictionViewerDlg::FictionViewerDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(FictionViewerDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(FictionViewerDlg)
|
||||
m_story_file = _T("");
|
||||
m_font_file = _T("");
|
||||
m_fiction_music = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void FictionViewerDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(FictionViewerDlg)
|
||||
DDX_Text(pDX, IDC_STORY_FILE, m_story_file);
|
||||
DDX_Text(pDX, IDC_FONT_FILE, m_font_file);
|
||||
DDX_CBIndex(pDX, IDC_FICTION_MUSIC, m_fiction_music);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(FictionViewerDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(FictionViewerDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg message handlers
|
||||
|
||||
BOOL FictionViewerDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
CComboBox *box;
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_FICTION_MUSIC);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++){
|
||||
box->AddString(Spooled_music[i].name);
|
||||
}
|
||||
|
||||
// init variables
|
||||
m_story_file = _T(fiction_file());
|
||||
m_font_file = _T(fiction_font());
|
||||
m_fiction_music = Mission_music[SCORE_FICTION_VIEWER] + 1;
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
// load it up
|
||||
fiction_viewer_reset();
|
||||
fiction_viewer_load((char *)(LPCSTR) m_story_file, (char *)(LPCSTR) m_font_file);
|
||||
|
||||
// set music
|
||||
Mission_music[SCORE_FICTION_VIEWER] = m_fiction_music - 1;
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnClose()
|
||||
{
|
||||
int z;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
if (query_modified()) {
|
||||
z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
|
||||
if (z == IDCANCEL){
|
||||
return;
|
||||
}
|
||||
|
||||
if (z == IDYES) {
|
||||
OnOK();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
int FictionViewerDlg::query_modified()
|
||||
{
|
||||
return strcmp(m_story_file, fiction_file()) || strcmp(m_font_file, fiction_font()) || m_fiction_music != (Mission_music[SCORE_FICTION_VIEWER] + 1);
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#if !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
#define AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// FictionViewerDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
class FictionViewerDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
FictionViewerDlg(CWnd* pParent = NULL); // standard constructor
|
||||
int query_modified();
|
||||
void OnOK();
|
||||
void OnCancel();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(FictionViewerDlg)
|
||||
enum { IDD = IDD_FICTION_VIEWER };
|
||||
CString m_story_file;
|
||||
CString m_font_file;
|
||||
int m_fiction_music;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(FictionViewerDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(FictionViewerDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
Loaded 100 of 1120 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user