Compare commits

..
141 Commits
Author SHA1 Message Date
karajorma f475ae983e Sync with Trunk (Part IV) 2010-09-20 08:21:41 +00:00
karajorma 3be57f609e Sync with Trunk (Part III) 2010-09-20 08:06:39 +00:00
karajorma fc66e2f78b Sync with Trunk (Part II) - I knew I'd miss something. 2010-09-20 07:17:50 +00:00
karajorma 1afadaa142 Sync with Trunk (Part I) 2010-09-20 05:49:34 +00:00
karajorma 1583b74c9d Missed that somehow. 2010-03-04 09:53:05 +00:00
karajorma e8ba07ee43 Sync with trunk 2010-03-02 05:25:56 +00:00
karajorma 7f706d398f Revert the Toggle Behaviour When Crippled flag as it's not good enough really. I'll add a better solution later. 2010-03-01 14:57:43 +00:00
karajorma 7b50be4afb Sync with trunk 2010-02-24 03:27:01 +00:00
karajorma f690e124d0 These should have been removed. 2010-02-23 13:50:27 +00:00
karajorma df6e87f552 As promised, a much better fix for the issue of ships losing orders/getting protected as soon as something has disarm/disable orders. 2010-02-23 13:49:15 +00:00
karajorma 45305bf78f Sync with trunk 2010-02-19 04:44:25 +00:00
karajorma e6f640c53d Sync with trunk 2009-11-02 07:12:36 +00:00
karajorma 4f1d39ed0e Sync with trunk 2009-07-19 09:42:46 +00:00
karajorma a7570926c9 Some minor changes which appear to have slipped into one codebase but not the other. 2009-07-18 17:48:22 +00:00
karajorma aa481d7463 Sync with trunk 2009-07-18 17:26:06 +00:00
karajorma e79afa5b65 Fix a couple of typos other people made. One minor, one not so minor. 2009-07-15 21:50:23 +00:00
karajorma b69a80db90 Sync with trunk 2009-07-15 21:29:08 +00:00
karajorma 5f64b680f5 Sync with trunk 2009-07-10 17:20:11 +00:00
karajorma a3508be54a Sync with the right branch this time! 2009-07-05 20:55:42 +00:00
karajorma 0fede5f475 Revert last sync 2009-07-05 20:47:25 +00:00
karajorma a8c36b9654 Sync with trunk 2009-07-05 20:30:57 +00:00
karajorma 8c98287b39 Sync with trunk 2009-07-02 17:21:49 +00:00
karajorma 345fa9c3ac Sync with trunk again 2009-06-30 22:09:08 +00:00
karajorma cf483e0237 Sync with trunk 2009-06-30 07:20:30 +00:00
karajorma f40710f500 Mark Selected Ships via information in FRED too as this is more likely to still be used rather than the slow wireframe marking. 2009-06-27 12:34:25 +00:00
karajorma 9f162d813f Sync with trunk 2009-06-22 20:17:00 +00:00
karajorma 3edee14eea Sync with trunk 2009-06-14 16:09:49 +00:00
karajorma 82757763e6 Sync with trunk 2009-06-06 10:51:02 +00:00
karajorma 91346a814d Sync with trunk 2009-05-24 22:01:10 +00:00
karajorma 5f013ad41d Allow lua to send variable changes from client to server. 2009-05-24 15:42:19 +00:00
karajorma 00cd5490c4 Sync with trunk 2009-05-21 14:59:36 +00:00
karajorma a4542cf71b Fix a newline issue with skybox flags. 2009-05-21 14:02:40 +00:00
karajorma f4521da771 Sync with trunk 2009-05-21 13:50:06 +00:00
karajorma 6ba0f3622a Fix Mantis 1926 (Piranha submunitions home in on the ship that fired them in dogfight mode) 2009-05-18 21:41:20 +00:00
karajorma e3765e24e1 Sync with trunk 2009-05-17 12:08:06 +00:00
karajorma 7171bf1005 Sync with trunk 2009-05-16 12:36:06 +00:00
karajorma b85ee3217d A couple of minor corrections. 2009-05-15 20:31:01 +00:00
karajorma 12f137c645 Version Bump 2009-05-10 09:54:14 +00:00
karajorma f0eb798f7e Add the High Praise and Primaries Low builtin message types 2009-05-09 18:37:18 +00:00
karajorma 5c60351288 Sync with Trunk 2009-05-09 17:40:14 +00:00
karajorma 5895aca2c5 Warning level bump 2009-05-09 09:34:05 +00:00
karajorma cfd2469f8b Fix some minor warnings 2009-05-09 09:30:34 +00:00
karajorma 0094a5dba4 Sync with trunk 2009-05-08 17:19:10 +00:00
karajorma 94e84fc9b8 Switch a couple of Asserts to Assertions. 2009-05-08 17:18:46 +00:00
karajorma 35ad2c5cdc Add support for multiple builtins of the same type. 2009-05-08 17:17:40 +00:00
karajorma af7e0a700b Add support for new builtin message types 2009-05-08 17:08:01 +00:00
karajorma 8943449825 Switch network variables over to the SEXP packet except for when called from lua 2009-05-08 17:05:43 +00:00
karajorma 555488e0bb Add the Assertion Macro as an alternative to Assert. 2009-05-05 10:09:15 +00:00
karajorma c6cf9da861 Add the set-ambient-light SEXP 2009-05-05 10:07:00 +00:00
karajorma f11e9253b2 Allow multi-docking in multiplayer. 2009-05-04 12:19:34 +00:00
karajorma fac68e4838 Maybe fix a crash with voice recognition. 2009-05-01 17:01:29 +00:00
karajorma 17d8105c38 Fix an issue with calling up the options menu while waiting for popupdead to appear. 2009-05-01 09:54:26 +00:00
karajorma a31eed376c This one too. 2009-04-30 11:22:01 +00:00
karajorma e8abd881d2 Forgot to commit that. 2009-04-30 10:43:57 +00:00
karajorma 136b5c936d Add a ship and parse flag to lock all turrets initially. Fix the Lock Primary/Secondary checkboxes to work for multi-selection. Add a checkbox for lock afterburner. 2009-04-28 13:13:47 +00:00
karajorma 34855d000e Break up the status SEXPs into sub-categories. 2009-04-26 22:13:03 +00:00
karajorma b6eed01e41 Auto-expand branches after pasting, add-pasting or replacing SEXPs. I really don't know why someone didn't get rid of that petty annoyance years ago. 2009-04-26 21:56:59 +00:00
karajorma 9616fb4cd7 Fix an assertion that crops up when you have no selected message but click on delete message. Has the side effect of making the message editor much less annoying too. 2009-04-26 21:51:53 +00:00
karajorma 344d8ba217 Fix a bug where the order of SEXP arguments was reversed. 2009-04-25 18:21:28 +00:00
karajorma 7e5239aff0 An ounce of prevention with the multiplayer SEXP packet code. 2009-04-24 21:56:09 +00:00
karajorma 09d5225883 Fix Mantis 1371 (Can target target's target even if it is stealthed or hidden from sensors). 2009-04-24 21:54:12 +00:00
karajorma 7f3ba14cec Fix Mantis 1538 (special hitpoints not updated properly on deletion) 2009-04-24 21:17:10 +00:00
karajorma 850414b358 Fix Mantis 1909 (Can't paste variables in FRED) 2009-04-24 19:58:29 +00:00
karajorma f18fa672f2 Fix (part of) Mantis 1677 (cap-subsys-cargo-known-delay doesn't list the correct ships) 2009-04-24 16:43:09 +00:00
karajorma fcb62348b9 Fix Mantis 1813 (Negative number constants could be added in FRED for SEXPs which expected OPF_POSITIVE, often resulting in crashes). 2009-04-24 15:54:44 +00:00
karajorma fbbb31bc49 Previous fix makes this code unnecessary so it might as well be removed. 2009-04-24 13:08:29 +00:00
karajorma 4d0e574ba4 Fix Mantis 1911 (Add Data doesn't show the <argument> option) 2009-04-24 13:05:24 +00:00
karajorma ce5b56fdf7 Don't need to set that flag. 2009-04-24 10:33:17 +00:00
karajorma 04de7f7498 Fix Mantis 1913 (Characters after # are visible in the wings and reinforcements comms menu) 2009-04-23 18:46:29 +00:00
karajorma 46b2165312 Sync with trunk 2009-04-23 18:43:02 +00:00
karajorma 4182951b19 Fix Mantis 1884 (Entering the name of an invalid operator in any dialog other than events editor would crash FRED)
Fix a typo in disable-builtin-messages
2009-04-22 20:39:32 +00:00
karajorma cbd6f247d9 Fix Mantis 1916 (Can't change the dockpoint a ship is initial docked to without undocking it) 2009-04-21 18:00:03 +00:00
karajorma 73facc313e Fix Mantis 1907 (Error in the get-damage-caused description) 2009-04-21 08:18:02 +00:00
karajorma d2e3094544 Add SEXPs to set weapon, shield and afterburner energy. 2009-04-15 19:34:12 +00:00
karajorma 61512d5b8f First commit of the SEXP packet code. 2009-04-15 19:32:56 +00:00
karajorma 2b42038c09 Fix Mantis 1910 (Assist Percentage resets itself when ships are multi selected) 2009-04-09 14:36:48 +00:00
karajorma ad8f6ccda3 Some minor changes to the way the game uses the scoring features I added earlier. 2009-04-08 15:56:22 +00:00
karajorma a201c9b3f3 Move the repair penalty to an AI profile setting. 2009-04-05 16:55:08 +00:00
karajorma 7edde650a1 Add the validate-argument SEXP.
Fix a minor initialisation error with the ship-tag SEXP.
2009-04-05 16:48:07 +00:00
karajorma ae3b88f23b Sync with trunk 2009-04-02 17:37:42 +00:00
karajorma c86e58e5e8 Fix Mantis 1883 (spaces at the end of ship and wing names can cause errors) 2009-04-02 17:33:29 +00:00
karajorma f441432d57 Fix a bug which was causing FRED to choke on the ; and " replacement fix. 2009-04-02 17:30:10 +00:00
karajorma 417982862e Fix an issue with homing capship missiles not tracking correctly. 2009-04-01 11:17:48 +00:00
karajorma 158733df8f Apparently even the null terminator needs to be coloured. 2009-03-31 18:38:13 +00:00
karajorma 4b75870857 Sync with trunk 2009-03-29 21:31:50 +00:00
karajorma dbfe86f018 Allow wireframe for the targetbox to be set from hud_gauges.tbl. 2009-03-29 21:03:24 +00:00
karajorma f7d95acec8 Fix Mantis 1753 (Using " or ; in briefings and messages causes them to either vanish or truncate the message)
Fix a bug that prevented lcl_replace_stuff() working properly when a message had two or more replacements of the same type.
2009-03-29 17:56:32 +00:00
karajorma 506686cfb7 Fix Mantis 1859 (FRED crashes if an unknown ship type is detected in the loadout.) 2009-03-29 12:39:01 +00:00
karajorma 8415a591e1 Allow the boilerplate traitor debrief to be turned off even if the player did turn traitor. 2009-03-24 15:22:57 +00:00
karajorma 1f8644f059 Fix Mantis 1620 (Replace Number/String don't work in FRED) 2009-03-21 21:48:20 +00:00
karajorma f32f947b62 Sync with trunk 2009-03-20 14:01:12 +00:00
karajorma 99ce717f7e Allow beams on any player ship to count for kills. Not just fighters and bombers. 2009-03-20 13:49:14 +00:00
karajorma 28f32a2f6d Fix the FictionViewer truncating anything with more than 70 lines. 2009-03-17 18:01:59 +00:00
karajorma 3d5d730306 Sync with trunk. 2009-03-05 22:19:24 +00:00
karajorma 96426de56f Fix Mantis 1661 (Ships leaving via the fighter bay don't disappear on multiplayer clients). 2009-03-05 22:12:34 +00:00
karajorma b14b5e3622 Fix multiplayer for Inferno builds. 2009-03-02 09:28:08 +00:00
karajorma 35cd6ea336 Various fixes needed to allow multiplayer to use over 255 weapons. 2009-02-27 20:04:44 +00:00
karajorma 3332870e9e Bobboau's Skybox flags code (via Wanderer then me) 2009-02-27 11:53:20 +00:00
karajorma 944c4bb2f2 Add new sexps to determine the amount of afterburner and weapon energy remaining. Add a missing resource file. 2009-02-26 13:17:00 +00:00
karajorma 705faf4a78 Sync up project files with Trunk 2009-02-25 20:02:18 +00:00
karajorma 614eda3b08 Sync with Trunk 2009-02-25 19:56:10 +00:00
karajorma 593cf6a533 Sync with trunk 2009-02-14 23:38:11 +00:00
karajorma 17ddae5db4 Fix Mantis 1486 (Pressing F4 locks multiplayer). Since this fix breaks compatibility I'll save up a few similar breaks and commit them all to trunk at the same time. 2009-02-14 21:47:53 +00:00
karajorma d1b1eb65b6 Add Wanderer's Salvo Mode. Sync the 2008 project files up with Trunk. 2009-01-27 20:25:00 +00:00
karajorma 43ee74a2e0 Patch in Wanderer's subsystem flag 2009-01-13 17:43:09 +00:00
karajorma 20d33ac699 Sync with trunk 2009-01-09 18:29:01 +00:00
karajorma 1609e9211f Sync with Trunk 2008-12-15 19:08:07 +00:00
karajorma c8c05e9d0b Add support for cutscenes before the various briefing and debriefing sections (FRED support for this feature will come later.) 2008-12-15 18:43:43 +00:00
karajorma 35130122e4 Sync up with trunk 2008-12-14 18:44:06 +00:00
karajorma c1b549867a Sync with Trunk. 2008-11-17 18:27:02 +00:00
karajorma efea823ef1 Fix a bug where the log displays incorrect percentages for kills. 2008-11-17 15:12:41 +00:00
karajorma 91e375693c Sync with Trunk. 2008-10-15 19:28:40 +00:00
karajorma 022aa38ad1 KeldorKatarn's afterburner lock SEXPs 2008-09-12 21:54:57 +00:00
karajorma 40419fb891 Allow players to filter who they send messages to when using the chatbox 2008-09-10 17:36:09 +00:00
karajorma 25d4a3b439 Update branch to latest SVN 2008-09-10 15:10:32 +00:00
karajorma 968e8d3d66 Sync with trunk 2008-08-20 20:58:15 +00:00
karajorma 6610938b80 Sync with trunk 2008-08-04 19:18:47 +00:00
karajorma 4b2691f572 Might as well update the project files too 2008-07-25 17:43:21 +00:00
karajorma 0ac2532fe5 Metge branch with trunk 2008-07-25 17:40:17 +00:00
karajorma e42892cb90 Change the project file to add the new alt classes file. 2008-06-17 19:39:02 +00:00
karajorma 0d14a559eb FRED changes for team loadout. 2008-06-17 19:36:16 +00:00
karajorma 2a65fcb388 Commit the actual team loadout code. 2008-06-17 19:20:34 +00:00
karajorma a02b9d953a Get-Damage-Caused SEXP and a couple of functions for counting the number of variables of a certain type. 2008-06-17 19:17:55 +00:00
karajorma 53f8c36587 Changes to allow more data to be used from exited_ship. Make ship_exited dynamic too. 2008-06-17 19:10:28 +00:00
karajorma 8323f5b4ad A couple of new parsing functions for dealing with variables in fields that previously only accepted integers or strings. 2008-06-17 18:49:11 +00:00
Goober5000 6ef349a6d4 made a copy 2008-06-17 02:52:56 +00:00
phreak 5b45bf9029 Fix for mantis #1691: Ships disappear at stage 2 of knossos warpout. 2008-06-15 21:02:18 +00:00
Wanderer 6f67df5835 fix for the detail box parsing (issue reported by Water) 2008-06-13 13:18:43 +00:00
WMCoolmon 380b3e658e Move gr_reset_clip into draw_model_rotating, and don't assume that if a NULL closeup pos is passed that it's a missile. 2008-06-11 22:38:28 +00:00
phreak ece785dee7 fix mantis #1682 - weapon ship collisions not applying to ships beyond the warpout clip plane. 2008-06-10 01:14:32 +00:00
phreak db2e91478b Shoudln't forgetting a return statement be an error and not a warning? 2008-06-10 01:13:48 +00:00
phreak 90238d4e69 Mantis #1676 - Prevent particles from appearing during warpout and the particle emitter is beyond the clip plane. 2008-06-09 22:27:21 +00:00
Wanderer 939dcaa849 Fix for mantis #1687 (corkscrew missiles and turrets) 2008-06-09 08:11:27 +00:00
phreak 25c0d647bd Added SSE/SSE2 build configurations. These builds are are optional versions of the release builds with SSE/SSE2 instruction support. 2008-06-09 01:10:43 +00:00
phreak b99f4d98a2 Added additional compiler optimizations for release builds. 2008-06-08 23:53:12 +00:00
phreak 81b3aad776 Add Visual Studio 2008 project files.
The release builds have been configured to use Multi-processor support (/MP) when compiling.
2008-06-07 23:59:05 +00:00
phreak 43407479d5 Alpha blending and line widths for radar orb rings when in HTL mode. 2008-06-03 00:18:58 +00:00
Wanderer 2661893a44 fix for cutscene jerkyness (part of mantis #1697) 2008-06-02 20:51:50 +00:00
Wanderer b909ada973 fix for the Mantis #1703 (debris and alt names) 2008-06-02 06:28:13 +00:00
phreak cdffd39097 Render the radar orb using HTL. It still wasn't doing that after all these years. The original rendering method is still in place. 2008-06-01 17:54:02 +00:00
Wanderer 15209a2a5f Fixes beams have migrating firing points (Mantis #1688)
Prevents simultaneously fired weapons from sharing firing points.
2008-06-01 10:50:28 +00:00
647 changed files with 132964 additions and 143489 deletions

No files matched your search

+14 -2
View File
@@ -32,7 +32,7 @@ EXTRA_DIST = \
AM_CXXFLAGS = -I./code @D_CFLAGS@
AM_LDFLAGS = @D_LDFLAGS@
EXTRA_PROGRAMS = cfilearchiver cfileextractor
EXTRA_PROGRAMS = cfilearchiver cfileextractor cryptstring scramble
###############################################################################
##
@@ -47,8 +47,20 @@ cfilearchiver_SOURCES = \
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
tools: cfilearchiver cfileextractor cryptstring scramble
# cleaning
clean-tools:
+1 -4
View File
@@ -1,10 +1,7 @@
The "projects" directory contains ready projects for:
Microsoft Visual C++ 6
Microsoft Visual C++ 2005
Microsoft Visual C++ 2008
Micrsofot Visual C++ 2010
Apple Xcode
Code::Blocks
Anjuta 1 (please see README with project before using)
See the ChangeLog to see what's new.
-175
View File
@@ -712,178 +712,3 @@ int main ()
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)
])
-2
View File
@@ -128,8 +128,6 @@ done
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
# to not run configure, call autogen.sh as,
# NOCONFIGURE=1 ./autogen.sh
if test x$NOCONFIGURE = x; then
echo Running $srcdir/configure $conf_flags "$@" ...
$srcdir/configure $conf_flags "$@" \
+10 -4
View File
@@ -258,6 +258,10 @@ FS2_SOURCES = \
debugconsole/dbugfile.h \
debugconsole/timerbar.cpp \
debugconsole/timerbar.h \
decals/decals.cpp \
decals/decals.h \
demo/demo.cpp \
demo/demo.h \
exceptionhandler/exceptionhandler.cpp \
exceptionhandler/exceptionhandler.h \
external_dll/externalcode.h \
@@ -285,10 +289,10 @@ FS2_SOURCES = \
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 \
@@ -355,6 +359,7 @@ FS2_SOURCES = \
hud/hudobserver.h \
hud/hudparse.cpp \
hud/hudparse.h \
hud/hudresource.h \
hud/hudreticle.cpp \
hud/hudreticle.h \
hud/hudshield.cpp \
@@ -523,6 +528,7 @@ FS2_SOURCES = \
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 \
@@ -548,6 +554,8 @@ FS2_SOURCES = \
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 \
@@ -607,8 +615,6 @@ FS2_SOURCES = \
popup/popupdead.h \
radar/radar.cpp \
radar/radar.h \
radar/radardradis.cpp \
radar/radardradis.h \
radar/radarorb.cpp \
radar/radarorb.h \
radar/radarsetup.cpp \
+19 -26
View File
@@ -7,26 +7,23 @@
*
*/
/**
* @file
* The code in here is just for bookeeping, allocating AI slots and linking them to ships.
* See AiCode.cpp for the actual AI code.
*/
// 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_target_names = 0;
char Goal_target_names[MAX_GOAL_TARGET_NAMES][NAME_LENGTH];
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;
/**
* @brief Returns index of free AI slot.
* @return Return -1 if no free slot.
*/
// Return index of free AI slot.
// Return -1 if no free slot.
int ai_get_slot(int shipnum)
{
int i;
@@ -43,10 +40,8 @@ int ai_get_slot(int shipnum)
return -1;
}
/**
* @brief Frees a currently used AI slot.
* @details Only modifies in ::Ai_info struct. Does not modify hook in ship.
*/
// 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) );
@@ -82,22 +77,20 @@ void set_wingnum(int objnum, int wingnum)
Ai_info[ai_index].wing = wingnum;
}
char *ai_get_goal_target_name(char *name, int *index)
char *ai_get_goal_ship_name(char *name, int *index)
{
Assert(name != NULL);
Assert(index != NULL);
int i;
for (i=0; i < Total_goal_target_names; i++)
if (!stricmp(name, Goal_target_names[i])) {
for (i=0; i < Total_goal_ship_names; i++)
if (!stricmp(name, Goal_ship_names[i])) {
*index = i;
return Goal_target_names[i];
return Goal_ship_names[i];
}
Assert(Total_goal_target_names < MAX_GOAL_TARGET_NAMES);
Assertion(strlen(name) <= NAME_LENGTH - 1, "Goal target name %s is too long. Needs to be 31 characters or less.", name);
i = Total_goal_target_names++;
strcpy_s(Goal_target_names[i], name);
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_target_names[i];
return Goal_ship_names[i];
}
+42 -56
View File
@@ -17,7 +17,6 @@
#include "globalincs/systemvars.h"
#include "ai/ai_profiles.h"
#include "physics/physics.h"
#include "object/waypoint.h"
struct ship_weapon;
struct ship_subsys;
@@ -33,11 +32,11 @@ struct ship_info;
#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_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_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.
@@ -49,7 +48,7 @@ struct ship_info;
#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
#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!
@@ -60,7 +59,7 @@ struct ship_info;
// 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_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.
@@ -74,7 +73,7 @@ struct ship_info;
// 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_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
@@ -83,8 +82,8 @@ struct ship_info;
// 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_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
@@ -97,7 +96,7 @@ struct ship_info;
#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_DEPART_SOUND_PLAYED (1<<7) // Goober5000 - replacement for AL's hack ;)
#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)
@@ -127,12 +126,10 @@ typedef struct ai_goal {
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 *target_name; // name of the thing that this goal acts upon
int target_name_index; // index of goal_target_name in Goal_target_names[][]
waypoint_list *wp_list; // waypoints that this ship might fly.
int target_instance; // instance of thing this ship might be chasing (currently only used for weapons; note, not the same as objnum!)
int target_signature; // signature of object this ship might be chasing (currently only used for weapons; paired with above value to confirm target)
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)
@@ -149,7 +146,7 @@ typedef struct ai_goal {
} ai_goal;
#define MAX_GOAL_TARGET_NAMES 100
#define MAX_GOAL_SHIP_NAMES 100
#define AIM_CHASE 0
#define AIM_EVADE 1
@@ -159,25 +156,25 @@ typedef struct ai_goal {
#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_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_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_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_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 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_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 MAX_ENEMY_DISTANCE 2500.0f // maximum distance from which a ship will pursue an enemy.
#define AI_GOAL_NONE -1
@@ -254,12 +251,13 @@ typedef struct ai_class {
#define AIS_CHASE_CIRCLESTRAFE 19 // Attempt a circle-strafe on the target
// Submodes for docking behavior
#define AIS_DOCK_0 20
#define AIS_DOCK_1 21
#define AIS_DOCK_2 22
#define AIS_DOCK_3 23
#define AIS_DOCK_4 24 // Only for rearm/repair.
#define AIS_DOCK_4A 25 // Only for not rearm/repair. MK, 7/15/97
#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
@@ -357,9 +355,10 @@ typedef struct ai_info {
int ai_class; // Class. Might be override of default.
// Probably become obsolete, to be replaced by path_start, path_cur, etc.
waypoint_list *wp_list; // waypoint list being followed
SCP_list<waypoint>::iterator wp_index; // waypoint index in list
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
@@ -377,7 +376,6 @@ typedef struct ai_info {
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
vec3d path_depart_orient; //Rotational orientation associated with the path
int submode;
int previous_submode; // previous submode, get it?
@@ -463,6 +461,9 @@ typedef struct ai_info {
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
@@ -508,7 +509,7 @@ typedef struct ai_info {
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.
int kamikaze_damage; // some damage value used to produce a shockwave from a kamikaze ship
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.
@@ -538,17 +539,6 @@ typedef struct ai_info {
int ai_override_timestamp; // mark for when to end the current override
} ai_info;
// Goober5000
typedef struct {
vec3d docker_point;
vec3d dockee_point;
int dock_mode;
int submodel;
vec3d submodel_pos;
float submodel_r;
float submodel_w;
} rotating_dockpoint_info;
#define MAX_AI_INFO MAX_SHIPS
// SUBSYS_PATH_DIST is used as the distance that a subsystem path should terminate from the actual
@@ -561,8 +551,8 @@ typedef struct {
#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_target_names;
extern char Goal_target_names[MAX_GOAL_TARGET_NAMES][NAME_LENGTH];
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);
@@ -604,7 +594,7 @@ 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_target_name(char *name, int *index);
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);
@@ -615,7 +605,7 @@ extern void ai_dock_with_object(object *docker, int docker_index, object *dockee
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, waypoint_list *wp_list, int wp_flags);
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);
@@ -691,10 +681,6 @@ extern void ai_do_objects_docked_stuff(object *docker, int docker_point, object
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 );
// Goober5000
// Move to a position relative to a dock bay using thrusters.
extern float dock_orient_and_approach(object *docker_objp, int docker_index, object *dockee_objp, int dockee_index, int dock_mode, rotating_dockpoint_info *rdinfo = NULL);
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);
+8 -102
View File
@@ -12,8 +12,6 @@
#include "ai/ai_profiles.h"
#include "parse/parselo.h"
#include "localization/localize.h"
#include "weapon/weapon.h"
#include "ship/ship.h"
// global stuff
@@ -48,32 +46,12 @@ void set_flag(ai_profile_t *profile, char *name, int flag, int type)
}
}
char *AI_path_types[] = {
"normal",
"alt1",
};
int Num_ai_path_types = sizeof(AI_path_types)/sizeof(char*);
int ai_path_type_match(char *p)
{
int i;
for(i = 0; i < Num_ai_path_types; i++)
{
if(!stricmp(AI_path_types[i], p))
return i;
}
return -1;
}
void parse_ai_profiles_tbl(char *filename)
{
int i, rval;
char profile_name[NAME_LENGTH];
ai_profile_t dummy_profile;
char *saved_Mp = NULL;
char buf[NAME_LENGTH];
// open localization
lcl_ext_open();
@@ -260,10 +238,10 @@ void parse_ai_profiles_tbl(char *filename)
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 (i = 0; i < NUM_SKILL_LEVELS; i++) {
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.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] = 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;
}
@@ -273,10 +251,10 @@ void parse_ai_profiles_tbl(char *filename)
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 (i = 0; i < NUM_SKILL_LEVELS; i++) {
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.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] = 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;
}
@@ -286,10 +264,10 @@ void parse_ai_profiles_tbl(char *filename)
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 (i = 0; i < NUM_SKILL_LEVELS; i++) {
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.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] = 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;
}
@@ -299,10 +277,10 @@ void parse_ai_profiles_tbl(char *filename)
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 (i = 0; i < NUM_SKILL_LEVELS; i++) {
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.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] = 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;
}
@@ -347,27 +325,6 @@ void parse_ai_profiles_tbl(char *filename)
if (optional_string("$Turret Max Aim Update Delay:"))
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
if (optional_string("$Player Autoaim FOV:"))
{
float fov_list[NUM_SKILL_LEVELS];
parse_float_list(fov_list, NUM_SKILL_LEVELS);
for (i = 0; i < NUM_SKILL_LEVELS; i++)
{
//Enforce range
if (fov_list[i] < 0.0f || fov_list[i] >= 360.0f)
{
Warning(LOCATION, "$Player Autoaim FOV should be >= 0 and < 360.0 (read %f). Setting to 0.", fov_list[i]);
fov_list[i] = 0.0f;
}
//Convert units
profile->player_autoaim_fov[i] = fov_list[i] * PI / 180.0f;
}
}
if (optional_string("$Detail Distance Multiplier:"))
parse_float_list(profile->detail_distance_mult, 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);
@@ -436,62 +393,11 @@ void parse_ai_profiles_tbl(char *filename)
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);
set_flag(profile, "$ai aims from ship center:", AIPF2_AI_AIMS_FROM_SHIP_CENTER, AIP_FLAG2);
set_flag(profile, "$allow primary link delay:", AIPF2_ALLOW_PRIMARY_LINK_DELAY, AIP_FLAG2);
set_flag(profile, "$allow beams to damage bombs:", AIPF2_BEAMS_DAMAGE_WEAPONS, AIP_FLAG2);
set_flag(profile, "$disable weapon damage scaling for player:", AIPF2_PLAYER_WEAPON_SCALE_FIX, AIP_FLAG2);
profile->ai_path_mode = AI_PATH_MODE_NORMAL;
if(optional_string("$ai path mode:"))
{
stuff_string(buf, F_NAME, NAME_LENGTH);
int j = ai_path_type_match(buf);
if(j >= 0) {
profile->ai_path_mode = j;
} else {
Warning(LOCATION, "Invalid ai path mode '%s' specified", buf);
}
}
if (optional_string("$Default weapon select effect:")) {
char effect[NAME_LENGTH];
stuff_string(effect, F_NAME, NAME_LENGTH);
if (!stricmp(effect, "FS1"))
Default_weapon_select_effect = 1;
if (!stricmp(effect, "off"))
Default_weapon_select_effect = 0;
}
if (optional_string("$Default ship select effect:")) {
char effect[NAME_LENGTH];
stuff_string(effect, F_NAME, NAME_LENGTH);
if (!stricmp(effect, "FS1"))
Default_ship_select_effect = 1;
if (!stricmp(effect, "off"))
Default_ship_select_effect = 0;
}
set_flag(profile, "$no warp camera:", AIPF2_NO_WARP_CAMERA, AIP_FLAG2);
// if we've been through once already and are at the same place, force a move
if ( saved_Mp && (saved_Mp == Mp) )
{
char buf[60];
memset(buf, 0, 60);
strncpy(buf, Mp, 59);
mprintf(("WARNING: Unrecognized parameter in ai_profiles: %s\n", buf));
Mp++;
}
// find next valid option
skip_to_start_of_string_either("$", "#");
+1 -18
View File
@@ -54,19 +54,8 @@
#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 AIPF2_AI_AIMS_FROM_SHIP_CENTER (1 << 6)
#define AIPF2_ALLOW_PRIMARY_LINK_DELAY (1 << 7)
#define AIPF2_BEAMS_DAMAGE_WEAPONS (1 << 8)
#define AIPF2_PLAYER_WEAPON_SCALE_FIX (1 << 9)
#define AIPF2_NO_WARP_CAMERA (1 << 10)
#define AIPF2_ALL_SHIPS_MANAGE_SHIELDS (1 << 3)
// AI Path types
#define AI_PATH_MODE_NORMAL 0
#define AI_PATH_MODE_ALT1 1
#define MAX_AI_PROFILES 5
typedef struct ai_profile_t {
@@ -140,12 +129,6 @@ typedef struct ai_profile_t {
// the chance (x/7) that ship is allowed to fire missiles at player ship.
int chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
// Player-specific autoaim FOV override
float player_autoaim_fov[NUM_SKILL_LEVELS];
float detail_distance_mult[MAX_DETAIL_LEVEL + 1]; //MAX_DETAIL_LEVEL really needs to be 4
int ai_path_mode;
} ai_profile_t;
+15 -13
View File
@@ -173,7 +173,6 @@ done_1:
}
mc_info mc;
mc.model_instance_num = Ships[objp->instance].model_instance_num;
mc.model_num = sip->model_num;
mc.orient = &objp->orient;
mc.pos = &objp->pos;
@@ -377,12 +376,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
float dist;
pm = model_get( Ship_info[Ships[Pl_objp->instance].ship_info_index].model_num );
//Necessary sanity check
polymodel *pm_t;
pm_t = model_get(Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].model_num);
Assertion(aip->targeted_subsys->system_info->path_num <= pm_t->n_paths, "Invalid Path number %d for subsystem %s on ship %s (Model: %s)\n", aip->targeted_subsys->system_info->path_num, aip->targeted_subsys->system_info->name, Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].name, pm_t->filename );
if (aip->targeted_subsys->system_info->path_num > pm_t->n_paths)
return 0;
// If attacking a subsystem, ensure that we have an unobstructed line of sight... if not, then move
// towards path linked to subsystem
subsys_in_sight = 0; // assume Pl_objp doesn't have line of sight to subys
@@ -426,7 +420,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
aip->path_goal_dist = 5;
subsys_path_num = aip->targeted_subsys->system_info->path_num;
if ( ((aip->path_start) == -1 || (aip->mp_index != subsys_path_num)) && subsys_path_num <= pm->n_paths ) {
if ( (aip->path_start) == -1 || (aip->mp_index != subsys_path_num) ) {
// maybe create a new path
if ( subsys_path_num >= 0 ) {
Assert(aip->target_objnum >= 0);
@@ -472,6 +466,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
// for now, only follow the path to the first point
if ( aip->path_cur < (aip->path_start+aip->path_length-1) ) {
if ( aip->goal_objnum != aip->target_objnum ) {
//Int3(); // what is going on here? - Get Alan
aip->previous_mode = aip->mode;
aip->mode = AIM_NONE;
aip->submode = -1;
@@ -552,7 +547,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
object *objp;
for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
if ((objp->type == OBJ_WEAPON) && (iff_x_attacks_y(Ships[Pl_objp->instance].team, Weapons[objp->instance].team)))
if (Weapon_info[Weapons[objp->instance].weapon_info_index].subtype == WP_LASER) {
if (Weapon_info[objp->instance].subtype == WP_LASER) {
vec3d in_vec;
float dist;
@@ -826,12 +821,15 @@ void ai_big_chase()
ship_info *sip = &Ship_info[Ships[Pl_objp->instance].ship_info_index];
ship *shipp = &Ships[Pl_objp->instance];
ai_info *aip = &Ai_info[shipp->ai_index];
int enemy_ship_type;
vec3d predicted_enemy_pos;
Assert(aip->mode == AIM_CHASE);
maybe_cheat_fire_synaptic(Pl_objp, aip);
enemy_ship_type = Ship_info[Ships[En_objp->instance].ship_info_index].flags;
ai_set_positions(Pl_objp, En_objp, aip, &player_pos, &enemy_pos);
player_pos = Pl_objp->pos;
@@ -1163,13 +1161,12 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
float weapon_speed;
// Compute position of gun in absolute space and use that as fire position.
if (po->n_guns > 0 && !(The_mission.ai_profile->flags2 & AIPF2_AI_AIMS_FROM_SHIP_CENTER)) {
if (po->n_guns > 0) {
pnt = po->gun_banks[0].pnt[0];
vm_vec_unrotate(&gun_pos, &pnt, &Pl_objp->orient);
vm_vec_add2(&gun_pos, &Pl_objp->pos);
} else {
//Use the convergence offset, if there is one
vm_vec_copy_scale(&pnt, &Ship_info[shipp->ship_info_index].convergence_offset, 1.0f);
gun_pos = Pl_objp->pos;
}
weapon_speed = ai_get_weapon_speed(&shipp->weapons);
@@ -1248,6 +1245,7 @@ void ai_big_strafe_attack()
vec3d target_pos;
vec3d rand_vec;
float target_dist, target_dot, accel, t;
object *target_objp;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -1259,8 +1257,11 @@ void ai_big_strafe_attack()
if ( ai_big_strafe_maybe_retreat(target_dist, &target_pos) )
return;
target_objp = &Objects[aip->target_objnum];
if (aip->ai_flags & AIF_KAMIKAZE) {
if (target_dist < 1200.0f) {
//nprintf(("AI", "Kamikaze: %7.3f %7.3f\n", target_dot, target_dist));
ai_turn_towards_vector(&target_pos, Pl_objp, flFrametime, Ship_info[Ships[Pl_objp->instance].ship_info_index].srotation_time, NULL, NULL, 0.0f, 0);
accelerate_ship(aip, 1.0f);
if ((target_dist < 400.0f) && ai_maybe_fire_afterburner(Pl_objp, aip)) {
@@ -1296,6 +1297,7 @@ void ai_big_strafe_attack()
aip->submode = AIS_STRAFE_AVOID;
aip->submode_start_time = Missiontime;
// nprintf(("Alan","Ship %s entering AIS_STRAFE_AVOID at frame %d\n", Ships[aip->shipnum].ship_name, Framecount));
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
afterburners_start(Pl_objp);
@@ -1765,7 +1767,7 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
// Approx 1/4 chance we'll go after the other ship's beam.
bool attack_turret_on_different_ship = (aip->ai_profile_flags & AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS)
&& (Weapon_info[Weapons[weapon_objp->instance].weapon_info_index].wi_flags & WIF_BEAM) && (frand()*100 < 25.0f);
&& (Weapon_info[weapon_objp->instance].wi_flags & WIF_BEAM) && (frand()*100 < 25.0f);
// unless we're making an exception, we should only attack a turret if it sits on the current target
if ( !attack_turret_on_different_ship )
+1612 -1166
View File
File diff suppressed because it is too large. Load diff
+116 -116
View File
@@ -329,7 +329,7 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
mode = remove_goalp->ai_mode;
submode = remove_goalp->ai_submode;
priority = remove_goalp->priority;
name = remove_goalp->target_name;
name = remove_goalp->ship_name;
Assert ( name ); // should not be NULL!!!!
@@ -345,10 +345,10 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
aigp = &(aip->goals[j]);
// don't need to worry about these types of goals since they can't possibly be a goal we are looking for.
if ( (aigp->ai_mode == AI_GOAL_NONE) || !aigp->target_name )
if ( (aigp->ai_mode == AI_GOAL_NONE) || !aigp->ship_name )
continue;
if ( (aigp->ai_mode == mode) && (aigp->ai_submode == submode) && (aigp->priority == priority) && !stricmp(name, aigp->target_name) ) {
if ( (aigp->ai_mode == mode) && (aigp->ai_submode == submode) && (aigp->priority == priority) && !stricmp(name, aigp->ship_name) ) {
ai_remove_ship_goal( aip, j );
ai_do_default_behavior( &Objects[Ships[aip->shipnum].objnum] ); // do the default behavior
break; // we are all done
@@ -359,10 +359,10 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
// now remove the goal from the wing
for (i = 0; i < MAX_AI_GOALS; i++ ) {
aigp = &(wingp->ai_goals[i]);
if ( (aigp->ai_mode == AI_GOAL_NONE) || !aigp->target_name )
if ( (aigp->ai_mode == AI_GOAL_NONE) || !aigp->ship_name )
continue;
if ( (aigp->ai_mode == mode) && (aigp->ai_submode == submode) && (aigp->priority == priority) && !stricmp(name, aigp->target_name) ) {
if ( (aigp->ai_mode == mode) && (aigp->ai_submode == submode) && (aigp->priority == priority) && !stricmp(name, aigp->ship_name) ) {
wingp->ai_goals[i].ai_mode = AI_GOAL_NONE;
wingp->ai_goals[i].signature = -1;
wingp->ai_goals[i].priority = -1;
@@ -401,7 +401,7 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list, ai_info *ai
int mode, ship_index, wingnum;
// get locals for easer access
name = aigp->target_name;
name = aigp->ship_name;
mode = aigp->ai_mode;
// these goals cannot be associated to wings, but can to a ship in a wing. So, we should find out
@@ -424,17 +424,17 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list, ai_info *ai
continue;
// goals must operate on something to be purged.
if ( purge_goal->target_name == NULL )
if ( purge_goal->ship_name == NULL )
continue;
// determine if the purge goal is acting either on the ship or the ship's wing.
purge_wing = wing_name_lookup( purge_goal->target_name, 1 );
purge_wing = wing_name_lookup( purge_goal->ship_name, 1 );
// if the target of the purge goal is a ship (purge_wing will be -1), then if the names
// don't match, we can continue; if the wing is valid, don't process if the wing numbers
// are different.
if ( purge_wing == -1 ) {
if ( stricmp(purge_goal->target_name, name ) )
if ( stricmp(purge_goal->ship_name, name ) )
continue;
} else if ( purge_wing != wingnum )
continue;
@@ -560,7 +560,7 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
int shipnum, docker_index, dockee_index;
Assert ( aip->shipnum != -1 );
shipnum = ship_name_lookup( aigp->target_name );
shipnum = ship_name_lookup( aigp->ship_name );
docker_index = -1;
dockee_index = -1;
@@ -626,36 +626,27 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
// from the mission goals (i.e. those goals which come from events) in that we don't
// use sexpressions for goals from the player...so we enumerate all the parameters
void ai_add_goal_sub_player(int type, int mode, int submode, char *target_name, ai_goal *aigp )
void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
{
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
aigp->time = Missiontime;
aigp->type = type; // from player for sure -- could be to ship or to wing
aigp->ai_mode = mode; // major mode for this goal
aigp->type = type; // from player for sure -- could be to ship or to wing
aigp->ai_mode = mode; // major mode for this goal
aigp->ai_submode = submode; // could mean different things depending on mode
if ( mode == AI_GOAL_WARP ) {
if (submode >= 0) {
aigp->wp_list = find_waypoint_list_at_index(submode);
Assert(aigp->wp_list != NULL);
} else {
aigp->wp_list = NULL;
}
}
if ( mode == AI_GOAL_WARP )
aigp->wp_index = submode;
if ( mode == AI_GOAL_CHASE_WEAPON ) {
aigp->target_instance = submode; // submode contains the instance of the weapon
aigp->target_signature = Objects[Weapons[submode].objnum].signature;
} else {
aigp->target_instance = -1;
aigp->target_signature = -1;
aigp->wp_index = submode; // submode contains the instance of the weapon
aigp->weapon_signature = Objects[Weapons[submode].objnum].signature;
}
if ( target_name != NULL )
aigp->target_name = ai_get_goal_target_name( target_name, &aigp->target_name_index );
if ( shipname != NULL )
aigp->ship_name = ai_get_goal_ship_name( shipname, &aigp->ship_name_index );
else
aigp->target_name = NULL;
aigp->ship_name = NULL;
// special case certain orders from player so that ships continue to do the right thing
@@ -720,7 +711,7 @@ int ai_goal_num(ai_goal *goals)
}
void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, char *target_name, ai_goal *aigp )
void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, char *shipname, ai_goal *aigp )
{
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
@@ -730,17 +721,17 @@ void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, ch
aigp->ai_submode = submode; // could mean different things depending on mode
if ( mode == AI_GOAL_WARP )
aigp->wp_list = NULL;
aigp->wp_index = submode;
if ( mode == AI_GOAL_CHASE_WEAPON ) {
aigp->target_instance = submode; // submode contains the instance of the weapon
aigp->target_signature = Objects[Weapons[submode].objnum].signature;
aigp->wp_index = submode; // submode contains the instance of the weapon
aigp->weapon_signature = Objects[Weapons[submode].objnum].signature;
}
if ( target_name != NULL )
aigp->target_name = ai_get_goal_target_name( target_name, &aigp->target_name_index );
if ( shipname != NULL )
aigp->ship_name = ai_get_goal_ship_name( shipname, &aigp->ship_name_index );
else
aigp->target_name = NULL;
aigp->ship_name = NULL;
aigp->priority = priority;
}
@@ -833,7 +824,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
aigp->signature = Ai_goal_signature++;
aigp->target_name = NULL;
aigp->ship_name = NULL;
aigp->time = Missiontime;
aigp->type = type;
aigp->flags = 0;
@@ -848,10 +839,10 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
ref_type = Sexp_nodes[CDR(node)].subtype;
if (ref_type == SEXP_ATOM_STRING) { // referenced by name
// save the waypoint path name -- the list will get resolved when the goal is checked
// for achievability.
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index); // waypoint path name;
aigp->wp_list = NULL;
// save the waypoint path name -- the index will get resolved when the goal is checked
// for acheivability.
aigp->ship_name = ai_get_goal_ship_name(CTEXT(CDR(node)), &aigp->ship_name_index); // waypoint path name;
aigp->wp_index = -1;
} else
Int3();
@@ -865,24 +856,24 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
case OP_AI_DESTROY_SUBSYS:
aigp->ai_mode = AI_GOAL_DESTROY_SUBSYSTEM;
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
// store the name of the subsystem in the docker.name field for now -- this field must get
// fixed up when the goal is valid since we need to locate the subsystem on the ship's model
aigp->docker.name = ai_get_goal_target_name(CTEXT(CDR(CDR(node))), &dummy);
aigp->docker.name = ai_get_goal_ship_name(CTEXT(CDR(CDR(node))), &dummy);
aigp->flags |= AIGF_SUBSYS_NEEDS_FIXUP;
aigp->priority = atoi( CTEXT(CDR(CDR(CDR(node)))) );
break;
case OP_AI_DISABLE_SHIP:
aigp->ai_mode = AI_GOAL_DISABLE_SHIP;
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
aigp->ai_submode = -SUBSYSTEM_ENGINE;
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
break;
case OP_AI_DISARM_SHIP:
aigp->ai_mode = AI_GOAL_DISARM_SHIP;
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
aigp->ai_submode = -SUBSYSTEM_TURRET;
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
break;
@@ -895,8 +886,9 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
// the following goal is obsolete, but here for compatibility
case OP_AI_WARP:
aigp->ai_mode = AI_GOAL_WARP;
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index); // waypoint path name;
aigp->wp_list = NULL;
aigp->ship_name = ai_get_goal_ship_name(CTEXT(CDR(node)), &aigp->ship_name_index); // waypoint path name;
//aigp->wp_index = atoi( CTEXT(CDR(node)) ); // this is the index into the warp points
aigp->wp_index = -1;
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
break;
@@ -905,9 +897,9 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
// Goober5000 - optional undock with something
if (CDR(CDR(node)) != -1)
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(CDR(node))), &aigp->target_name_index );
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(CDR(node))), &aigp->ship_name_index );
else
aigp->target_name = NULL;
aigp->ship_name = NULL;
aigp->ai_mode = AI_GOAL_UNDOCK;
aigp->ai_submode = AIS_UNDOCK_0;
@@ -915,12 +907,12 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
case OP_AI_STAY_STILL:
aigp->ai_mode = AI_GOAL_STAY_STILL;
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index); // waypoint path name;
aigp->ship_name = ai_get_goal_ship_name(CTEXT(CDR(node)), &aigp->ship_name_index); // waypoint path name;
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
break;
case OP_AI_DOCK:
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
aigp->docker.name = ai_add_dock_name(CTEXT(CDR(CDR(node))));
aigp->dockee.name = ai_add_dock_name(CTEXT(CDR(CDR(CDR(node)))));
aigp->flags &= ~AIGF_DOCK_INDEXES_VALID;
@@ -945,12 +937,6 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
aigp->ai_mode = AI_GOAL_KEEP_SAFE_DISTANCE;
break;
case OP_AI_FORM_ON_WING:
aigp->priority = 99;
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index);
aigp->ai_mode = AI_GOAL_FORM_ON_WING;
break;
case OP_AI_CHASE:
case OP_AI_GUARD:
case OP_AI_GUARD_WING:
@@ -959,7 +945,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
case OP_AI_STAY_NEAR_SHIP:
case OP_AI_IGNORE:
case OP_AI_IGNORE_NEW:
aigp->target_name = ai_get_goal_target_name( CTEXT(CDR(node)), &aigp->target_name_index );
aigp->ship_name = ai_get_goal_ship_name( CTEXT(CDR(node)), &aigp->ship_name_index );
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
if ( op == OP_AI_CHASE ) {
@@ -968,12 +954,12 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
// in the case of ai_chase (and ai_guard) we must do a wing_name_lookup on the name
// passed here to see if we could be chasing a wing. Hoffoss and I have consolidated
// sexpression operators which makes this step necessary
if ( wing_name_lookup(aigp->target_name, 1) != -1 )
if ( wing_name_lookup(aigp->ship_name, 1) != -1 )
aigp->ai_mode = AI_GOAL_CHASE_WING;
} else if ( op == OP_AI_GUARD ) {
aigp->ai_mode = AI_GOAL_GUARD;
if ( wing_name_lookup(aigp->target_name, 1) != -1 )
if ( wing_name_lookup(aigp->ship_name, 1) != -1 )
aigp->ai_mode = AI_GOAL_GUARD_WING;
} else if ( op == OP_AI_EVADE_SHIP ) {
@@ -1005,7 +991,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
// Goober5000 - since none of the goals act on the actor,
// don't assign the goal if the actor's goal target is itself
if (aigp->target_name != NULL && !strcmp(aigp->target_name, actor_name))
if (aigp->ship_name != NULL && !strcmp(aigp->ship_name, actor_name))
{
// based on ai_remove_ship_goal, these seem to be the only statements
// necessary to cause this goal to "never have been assigned"
@@ -1289,7 +1275,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int doc
*/
case AI_GOAL_UNDOCK:
aigp->target_name = name;
aigp->ship_name = name;
aigp->priority = MAX_GOAL_PRIORITY;
aigp->ai_mode = AI_GOAL_UNDOCK;
aigp->ai_submode = AIS_UNDOCK_0;
@@ -1308,7 +1294,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int doc
case AI_GOAL_REARM_REPAIR:
aigp->ai_mode = AI_GOAL_REARM_REPAIR;
aigp->ai_submode = 0;
aigp->target_name = name;
aigp->ship_name = name;
aigp->priority = PLAYER_PRIORITY_MIN-1; // make the priority always less than what the player's is
aigp->flags &= ~AIGF_GOAL_OVERRIDE; // don't override this goal. rearm repair requests should happen in order
ai_goal_fixup_dockpoints( aip, aigp );
@@ -1373,6 +1359,7 @@ void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
{
int status;
char *ai_shipname;
int return_val;
object *objp;
ai_info *aip;
@@ -1381,6 +1368,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
objp = &Objects[objnum];
Assert( objp->instance != -1 );
ai_shipname = Ships[objp->instance].ship_name;
aip = &Ai_info[Ships[objp->instance].ai_index];
// these orders are always achievable.
@@ -1412,7 +1400,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// if the wing target is valid then be sure to set the override bit so that it always
// gets executed next
if ( aigp->ai_mode == AI_GOAL_FORM_ON_WING ) {
sindex = ship_name_lookup( aigp->target_name );
sindex = ship_name_lookup( aigp->ship_name );
if (sindex < 0)
return AI_GOAL_NOT_ACHIEVABLE;
@@ -1421,14 +1409,20 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
return AI_GOAL_ACHIEVABLE;
}
// check to see if we have a valid list. If not, then try to set one up. If that
// check to see if we have a valid index. If not, then try to set one up. If that
// fails, then we must pitch this order
if ( (aigp->ai_mode == AI_GOAL_WAYPOINTS_ONCE) || (aigp->ai_mode == AI_GOAL_WAYPOINTS) ) {
if ( aigp->wp_list == NULL ) {
aigp->wp_list = find_matching_waypoint_list(aigp->target_name);
if ( aigp->wp_index == -1 ) {
int i;
if ( aigp->wp_list == NULL ) {
Warning(LOCATION, "Unknown waypoint list %s - not found in mission file. Killing ai goal", aigp->target_name );
for (i = 0; i < Num_waypoint_lists; i++) {
if (!stricmp(aigp->ship_name, Waypoint_lists[i].name)) {
aigp->wp_index = i;
break;
}
}
if ( i == Num_waypoint_lists ) {
Warning(LOCATION, "Unknown waypoint %s. not found in mission file. Killing ai goal", aigp->ship_name );
return AI_GOAL_NOT_ACHIEVABLE;
}
}
@@ -1443,6 +1437,8 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
{
case AI_GOAL_DOCK:
case AI_GOAL_UNDOCK:
//status = mission_log_get_time( LOG_SHIP_DOCK, ai_shipname, aigp->ship_name, NULL );
//status = mission_log_get_time( LOG_SHIP_UNDOCK, ai_shipname, aigp->ship_name, NULL );
//MWA 3/20/97 -- cannot short circuit a dock or undock goal already succeeded -- we must
// rely on the goal removal code to just remove this goal. This is because docking/undock
// can happen > 1 time per mission per pair of ships. The above checks will find only
@@ -1456,7 +1452,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// shipnum could be -1 depending on if the ship hasn't arrived or died. only look for subsystem
// destroyed when shipnum is valid
sindex = ship_name_lookup( aigp->target_name );
sindex = ship_name_lookup( aigp->ship_name );
// can't determine the status of this goal if ship not valid
// or we haven't found a valid subsystem index yet
@@ -1470,17 +1466,17 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// for this goal to be valid).
Assert ( aigp->ai_submode >= 0 );
ssp = ship_get_indexed_subsys( &Ships[sindex], aigp->ai_submode );
status = mission_log_get_time( LOG_SHIP_SUBSYS_DESTROYED, aigp->target_name, ssp->system_info->subobj_name, NULL );
status = mission_log_get_time( LOG_SHIP_SUBSYS_DESTROYED, aigp->ship_name, ssp->system_info->subobj_name, NULL );
break;
}
case AI_GOAL_DISABLE_SHIP:
status = mission_log_get_time( LOG_SHIP_DISABLED, aigp->target_name, NULL, NULL );
status = mission_log_get_time( LOG_SHIP_DISABLED, aigp->ship_name, NULL, NULL );
break;
case AI_GOAL_DISARM_SHIP:
status = mission_log_get_time( LOG_SHIP_DISARMED, aigp->target_name, NULL, NULL );
status = mission_log_get_time( LOG_SHIP_DISARMED, aigp->ship_name, NULL, NULL );
break;
// to guard or ignore a ship, the goal cannot continue if the ship being guarded is either destroyed
@@ -1497,11 +1493,11 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// MWA -- 4/22/98. Check for the ship actually being in the mission before
// checking departure and destroyed. In multiplayer, since ships can respawn,
// they get log entries for being destroyed even though they have respawned.
sindex = ship_name_lookup( aigp->target_name );
sindex = ship_name_lookup( aigp->ship_name );
if ( sindex == -1 ) {
status = mission_log_get_time( LOG_SHIP_DEPARTED, aigp->target_name, NULL, NULL);
status = mission_log_get_time( LOG_SHIP_DEPARTED, aigp->ship_name, NULL, NULL);
if ( !status ) {
status = mission_log_get_time( LOG_SHIP_DESTROYED, aigp->target_name, NULL, NULL);
status = mission_log_get_time( LOG_SHIP_DESTROYED, aigp->ship_name, NULL, NULL);
if ( status )
return_val = AI_GOAL_NOT_ACHIEVABLE;
}
@@ -1515,9 +1511,9 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
case AI_GOAL_CHASE_WING:
case AI_GOAL_GUARD_WING:
{
status = mission_log_get_time( LOG_WING_DEPARTED, aigp->target_name, NULL, NULL );
status = mission_log_get_time( LOG_WING_DEPARTED, aigp->ship_name, NULL, NULL );
if ( !status ) {
status = mission_log_get_time( LOG_WING_DESTROYED, aigp->target_name, NULL, NULL);
status = mission_log_get_time( LOG_WING_DESTROYED, aigp->ship_name, NULL, NULL);
if ( status )
return_val = AI_GOAL_NOT_ACHIEVABLE;
}
@@ -1530,13 +1526,13 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
{
// for chase weapon, we simply need to look at the weapon instance that we are trying to
// attack and see if the object still exists, and has the same signature that we expect.
Assert( aigp->target_instance >= 0 );
Assert( aigp->wp_index >= 0 );
if ( Weapons[aigp->target_instance].objnum == -1 )
if ( Weapons[aigp->wp_index].objnum == -1 )
return AI_GOAL_NOT_ACHIEVABLE;
// if the signatures don't match, then goal isn't achievable.
if ( Objects[Weapons[aigp->target_instance].objnum].signature != aigp->target_signature )
if ( Objects[Weapons[aigp->wp_index].objnum].signature != aigp->weapon_signature )
return AI_GOAL_NOT_ACHIEVABLE;
// otherwise, we should be good to go
@@ -1561,7 +1557,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// the if statement.
if ( (aigp->ai_mode == AI_GOAL_CHASE_WING) || (aigp->ai_mode == AI_GOAL_GUARD_WING) )
{
sindex = wing_name_lookup( aigp->target_name );
sindex = wing_name_lookup( aigp->ship_name );
if (sindex < 0)
return AI_GOAL_NOT_KNOWN;
@@ -1577,24 +1573,24 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
}
// Goober5000 - undocking from an unspecified object is always achievable;
// undocking from a specified object is handled below
else if ( (aigp->ai_mode == AI_GOAL_UNDOCK) && (aigp->target_name == NULL) )
else if ( (aigp->ai_mode == AI_GOAL_UNDOCK) && (aigp->ship_name == NULL) )
{
return AI_GOAL_ACHIEVABLE;
}
else
{
// goal ship is currently in mission
if ( ship_name_lookup( aigp->target_name ) != -1 )
if ( ship_name_lookup( aigp->ship_name ) != -1 )
{
status = SHIP_STATUS_ARRIVED;
}
// goal ship is still on the arrival list
else if ( mission_parse_get_arrival_ship(aigp->target_name) )
else if ( mission_parse_get_arrival_ship(aigp->ship_name) )
{
status = SHIP_STATUS_NOT_ARRIVED;
}
// goal ship has left the area
else if ( ship_find_exited_ship_by_name(aigp->target_name) != -1 )
else if ( ship_find_exited_ship_by_name(aigp->ship_name) != -1 )
{
status = SHIP_STATUS_GONE;
}
@@ -1609,7 +1605,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
if ((status == SHIP_STATUS_ARRIVED) && (aigp->ai_mode == AI_GOAL_DISARM_SHIP))
{
// if the ship has no turrets, we can't disarm it!
if (Ships[ship_name_lookup(aigp->target_name)].subsys_info[SUBSYSTEM_TURRET].type_count == 0)
if (Ships[ship_name_lookup(aigp->ship_name)].subsys_info[SUBSYSTEM_TURRET].num == 0)
return AI_GOAL_NOT_ACHIEVABLE;
}
@@ -1640,7 +1636,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
}
if (!(aigp->flags & AIGF_DOCKEE_INDEX_VALID)) {
sindex = ship_name_lookup(aigp->target_name);
sindex = ship_name_lookup(aigp->ship_name);
if ( sindex != -1 ) {
modelnum = Ship_info[Ships[sindex].ship_info_index].model_num;
index = model_find_dock_name_index(modelnum, aigp->dockee.name);
@@ -1660,7 +1656,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
return AI_GOAL_NOT_KNOWN;
// we must also determine if we're prevented from docking for any reason
sindex = ship_name_lookup(aigp->target_name);
sindex = ship_name_lookup(aigp->ship_name);
Assert( sindex >= 0 );
object *goal_objp = &Objects[Ships[sindex].objnum];
@@ -1712,7 +1708,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
if ((aip->mode == AIM_DOCK) && (aip->submode >= AIS_UNDOCK_0))
{
// only put it on hold if it's someone other than the guy we're undocking from right now!!
if (aip->goal_objnum != Ships[ship_name_lookup(aigp->target_name)].objnum)
if (aip->goal_objnum != Ships[ship_name_lookup(aigp->ship_name)].objnum)
return AI_GOAL_NOT_KNOWN;
}
@@ -1721,7 +1717,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// have fixed up the subsystem name (of the subsystem to destroy) into an index into
// the ship's subsystem list
if ( aigp->flags & AIGF_SUBSYS_NEEDS_FIXUP ) {
sindex = ship_name_lookup( aigp->target_name );
sindex = ship_name_lookup( aigp->ship_name );
if ( sindex != -1 ) {
aigp->ai_submode = ship_get_subsys_index( &Ships[sindex], aigp->docker.name );
@@ -1735,7 +1731,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
object *ignored;
// for ignoring a ship, call the ai_ignore object function, then declare the goal satisfied
sindex = ship_name_lookup( aigp->target_name );
sindex = ship_name_lookup( aigp->ship_name );
Assert( sindex != -1 ); // should be true because of above status
ignored = &Objects[Ships[sindex].objnum];
@@ -1789,7 +1785,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
if ( status == SHIP_STATUS_GONE )
return AI_GOAL_NOT_ACHIEVABLE;
sindex = ship_name_lookup( aigp->target_name );
sindex = ship_name_lookup( aigp->ship_name );
if ( sindex < 0 ) {
Int3();
@@ -1815,6 +1811,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// test code!!!
if ( aip->goal_objnum == -1 ) {
// -- MK, 11/9/97 -- I was always hitting this: Int3();
return AI_GOAL_ACHIEVABLE;
}
@@ -2048,8 +2045,8 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
switch ( current_goal->ai_mode ) {
case AI_GOAL_CHASE:
if ( current_goal->target_name ) {
shipnum = ship_name_lookup( current_goal->target_name );
if ( current_goal->ship_name ) {
shipnum = ship_name_lookup( current_goal->ship_name );
Assert (shipnum != -1 ); // shouldn't get here if this is false!!!!
other_obj = &Objects[Ships[shipnum].objnum];
} else
@@ -2061,14 +2058,13 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
break;
case AI_GOAL_CHASE_WEAPON:
Assert( Weapons[current_goal->target_instance].objnum >= 0 );
other_obj = &Objects[Weapons[current_goal->target_instance].objnum];
Assert( other_obj->signature == current_goal->target_signature );
Assert( Weapons[current_goal->wp_index].objnum != -1 );
other_obj = &Objects[Weapons[current_goal->wp_index].objnum];
ai_attack_object( objp, other_obj, NULL );
break;
case AI_GOAL_GUARD:
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
Assert (shipnum != -1 ); // shouldn't get here if this is false!!!!
other_obj = &Objects[Ships[shipnum].objnum];
// shipnum and other_obj are the shipnumber and object pointer of the object that you should
@@ -2083,7 +2079,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
break;
case AI_GOAL_GUARD_WING:
wingnum = wing_name_lookup( current_goal->target_name );
wingnum = wing_name_lookup( current_goal->ship_name );
Assert (wingnum != -1 ); // shouldn't get here if this is false!!!!
ai_set_guard_wing(objp, wingnum);
aip->submode_start_time = Missiontime;
@@ -2095,18 +2091,18 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
if ( current_goal->ai_mode == AI_GOAL_WAYPOINTS)
flags |= WPF_REPEAT;
ai_start_waypoints(objp, current_goal->wp_list, flags);
ai_start_waypoints(objp, current_goal->wp_index, flags);
break;
}
case AI_GOAL_FLY_TO_SHIP:
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
Assert (shipnum != -1 ); // shouldn't get here if this is false!!!!
ai_start_fly_to_ship(objp, shipnum);
break;
case AI_GOAL_DOCK: {
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
Assert (shipnum != -1 ); // shouldn't get here if this is false!!!!
other_obj = &Objects[Ships[shipnum].objnum];
@@ -2123,9 +2119,9 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
// goal cannot continue. Spit out a warning and remove the goal.
// Goober5000 - do we have a specific ship to undock from?
if ( current_goal->target_name != NULL )
if ( current_goal->ship_name != NULL )
{
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
// hmm, perhaps he was destroyed
if (shipnum == -1)
@@ -2148,7 +2144,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
other_obj = dock_get_first_docked_object( objp );
// and add the ship name so it displays on the HUD
current_goal->target_name = Ships[other_obj->instance].ship_name;
current_goal->ship_name = Ships[other_obj->instance].ship_name;
}
// hmm, nobody exists that we can undock from
else
@@ -2158,6 +2154,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
}
if ( other_obj == NULL ) {
//Int3();
// assume that the guy he was docked with doesn't exist anymore. (i.e. a cargo containuer
// can get destroyed while docked with a freighter.) We should just remove this goal and
// let this ship pick up it's next goal.
@@ -2186,7 +2183,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
case AI_GOAL_DESTROY_SUBSYSTEM:
case AI_GOAL_DISABLE_SHIP:
case AI_GOAL_DISARM_SHIP: {
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
Assert( shipnum >= 0 );
other_obj = &Objects[Ships[shipnum].objnum];
ai_attack_object( objp, other_obj, NULL);
@@ -2205,7 +2202,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
}
case AI_GOAL_CHASE_WING:
wingnum = wing_name_lookup( current_goal->target_name );
wingnum = wing_name_lookup( current_goal->ship_name );
Assert( wingnum >= 0 );
ai_attack_wing(objp, wingnum);
break;
@@ -2215,12 +2212,15 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
break;
case AI_GOAL_WARP: {
int index;
index = current_goal->wp_index;
mission_do_departure( objp );
break;
}
case AI_GOAL_EVADE_SHIP:
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
Assert( shipnum >= 0 );
other_obj = &Objects[Ships[shipnum].objnum];
ai_evade_object( objp, other_obj);
@@ -2249,7 +2249,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
// on wing AI code
// clearing out goals is okay here since we are now what mode to set this AI object to.
ai_clear_ship_goals( aip );
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
Assert( shipnum >= 0 );
other_obj = &Objects[Ships[shipnum].objnum];
ai_form_on_wing( objp, other_obj );
@@ -2258,7 +2258,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
// labels for support ship commands
case AI_GOAL_STAY_NEAR_SHIP: {
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
Assert( shipnum >= 0 );
other_obj = &Objects[Ships[shipnum].objnum];
// todo MK: hook to keep support ship near other_obj -- other_obj could be the player object!!!
@@ -2275,7 +2275,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
break;
case AI_GOAL_REARM_REPAIR:
shipnum = ship_name_lookup( current_goal->target_name );
shipnum = ship_name_lookup( current_goal->ship_name );
Assert( shipnum >= 0 );
other_obj = &Objects[Ships[shipnum].objnum];
ai_rearm_repair( objp, current_goal->docker.index, other_obj, current_goal->dockee.index );
@@ -2346,11 +2346,11 @@ void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *n
}
if (flag) // is this a valid goal to parse for this conversion?
if (!stricmp(goals[i].target_name, old_name)) {
if (!stricmp(goals[i].ship_name, old_name)) {
if (*new_name == '<') // target was just deleted..
goals[i].ai_mode = AI_GOAL_NONE;
else
goals[i].target_name = ai_get_goal_target_name(new_name, &dummy);
goals[i].ship_name = ai_get_goal_ship_name(new_name, &dummy);
}
}
}
@@ -2412,7 +2412,7 @@ int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
if (flag) // is this a valid goal to parse for this conversion?
{
if (!stricmp(goals[i].target_name, name))
if (!stricmp(goals[i].ship_name, name))
return 1;
}
}
@@ -2425,7 +2425,7 @@ char *ai_add_dock_name(char *str)
char *ptr;
int i;
Assert(strlen(str) <= NAME_LENGTH - 1);
Assert(strlen(str) < NAME_LENGTH - 1);
for (i=0; i<Num_ai_dock_names; i++)
if (!stricmp(Ai_dock_names[i], str))
return Ai_dock_names[i];
+55 -351
View File
@@ -21,7 +21,6 @@
#include "ai/aiinternal.h" //Included last, so less includes are needed
#include "iff_defs/iff_defs.h"
#include "weapon/muzzleflash.h"
#include "parse/scripting.h"
#include <limits.h>
@@ -53,21 +52,15 @@ char *Turret_target_order_names[NUM_TURRET_ORDER_TYPES] = {
"Asteroids",
};
#define EEOF_BIG_ONLY (1<<0) // turret fires only at big and huge ships
#define EEOF_SMALL_ONLY (1<<1) // turret fires only at small ships
#define EEOF_TAGGED_ONLY (1<<2) // turret fires only at tagged ships
#define EEOF_BEAM (1<<3) // turret is a beam
#define EEOF_FLAK (1<<4) // turret is flak
#define EEOF_LASER (1<<5) // turret is a laser
#define EEOF_MISSILE (1<<6) // turret is a missile
typedef struct eval_enemy_obj_struct {
int turret_parent_objnum; // parent of turret
float weapon_travel_dist; // max targeting range of turret weapon
int enemy_team_mask;
int weapon_system_ok; // is the weapon subsystem of turret ship ok
int eeo_flags;
bool big_only_flag; // turret fires only at big and huge ships
bool small_only_flag; // turret fires only at small ships
bool tagged_only_flag; // turret fires only at tagged ships
bool beam_flag; // turret is a beam
vec3d *tpos;
vec3d *tvec;
ship_subsys *turret_subsys;
@@ -107,101 +100,6 @@ int object_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos
return 0;
}
bool is_object_radius_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, vec3d *v2e, vec3d *predicted_pos, float distance)
{
float target_dist = distance;
if (distance == 0.0f)
target_dist = vm_vec_dist(predicted_pos,tpos);
if (object_in_turret_fov(objp, ss, tvec, tpos, target_dist + objp->radius)) {
// so the targeted spot in not in fov but the enemy + radius is
// lets align the darn gun and try shooting there
vec3d temp_vec;
float multiplier = 0;
model_subsystem *tp = ss->system_info;
// project v2e_from_turret to turret normal
// substract resultant vector from the temp_vec (v2e_from_turret)
// adjust z component as necessary
// calculate multiplier for the resultant vector
// use multiplier and the z component and compose a new vector
float dot = vm_vec_dot(v2e, tvec);
vm_vec_scale_add(&temp_vec, v2e, tvec, -dot);
if (IS_VEC_NULL_SQ_SAFE(&temp_vec)) {
// return false, target is perfectly aligned over or below the turret
// safe bet is to allow turret to reacquire better target
return false;
}
// normalize the vec, it needs to be done regardless
vm_vec_normalize(&temp_vec);
bool fix_elevation = false;
bool fix_base_rot = false;
if (dot < tp->turret_fov) {
dot = tp->turret_fov;
fix_elevation = true;
}
if (dot > tp->turret_max_fov) {
dot = tp->turret_max_fov;
fix_elevation = true;
}
if (tp->flags & MSS_FLAG_TURRET_ALT_MATH) {
vec3d temp_vec2;
vm_vec_rotate(&temp_vec2, &temp_vec, &ss->world_to_turret_matrix);
// now in turrets frame of reference
// check if math is actually possible
if (!((temp_vec2.xyz.x == 0) && (temp_vec2.xyz.y == 0))) {
float temp_z = temp_vec2.xyz.z;
temp_vec2.xyz.z = 0.0f;
// make sure null vecs wont happen
if (!IS_VEC_NULL_SQ_SAFE(&temp_vec2)) {
vm_vec_normalize(&temp_vec2);
// only do this if it actually is required
if (-temp_vec2.xyz.y < tp->turret_y_fov) {
float check_pos = 1;
fix_base_rot = true;
temp_vec2.xyz.y = -tp->turret_y_fov;
if (temp_vec2.xyz.x < 0)
check_pos = -1;
temp_vec2.xyz.x = check_pos * sqrtf(1 - (temp_vec2.xyz.y*temp_vec2.xyz.y));
// restore z component
float scaler = sqrtf(1 - (temp_z*temp_z));
vm_vec_scale(&temp_vec2,scaler);
temp_vec2.xyz.z = temp_z;
// back to world frame
vm_vec_unrotate(&temp_vec, &temp_vec2, &ss->world_to_turret_matrix);
}
}
}
}
if (fix_elevation || fix_base_rot) {
if (fix_elevation) {
multiplier = sqrtf(1 - (dot*dot));
// keep the temp_vec scaled with the tweaked vector
vm_vec_scale(&temp_vec, multiplier);
}
vm_vec_scale_add(v2e, &temp_vec, tvec, dot);
// and we are done with v2e...
vm_vec_scale_add(predicted_pos, tpos, v2e, target_dist);
// and we are done with predicted position
return true;
} else {
mprintf(("Warning: Function 'is_object_radius_in_turret_fov' was called\nwithout need to fix turret alignments\n"));
return false;
}
}
// outside of the expanded radii, unable to align, return false
return false;
}
// return 1 if bomb_objp is headed towards ship_objp
int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
{
@@ -402,7 +300,7 @@ int valid_turret_enemy(object *objp, object *turret_parent)
return 1;
}
if ( objp->type == OBJ_SHIP ) {
if ( (objp->type == OBJ_SHIP) ) {
Assert( objp->instance >= 0 );
ship *shipp;
ship_info *sip;
@@ -459,10 +357,9 @@ extern int Player_attacking_enabled;
void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
{
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
ship *shipp;
ship *shipp;
ship_subsys *ss = eeo->turret_subsys;
float dist, dist_comp;
bool turret_has_no_target = false;
// Don't look for bombs when weapon system is not ok
if (objp->type == OBJ_WEAPON && !eeo->weapon_system_ok) {
@@ -493,49 +390,28 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
}
// check if beam protected
if (eeo->eeo_flags & EEOF_BEAM) {
if (eeo->beam_flag) {
if (objp->flags & OF_BEAM_PROTECTED) {
return;
}
}
// check if flak protected
if (eeo->eeo_flags & EEOF_FLAK) {
if (objp->flags & OF_FLAK_PROTECTED) {
return;
}
}
// check if laser protected
if (eeo->eeo_flags & EEOF_LASER) {
if (objp->flags & OF_LASER_PROTECTED) {
return;
}
}
// check if missile protected
if (eeo->eeo_flags & EEOF_MISSILE) {
if (objp->flags & OF_MISSILE_PROTECTED) {
return;
}
}
// don't shoot at small ships if we shouldn't
if (eeo->eeo_flags & EEOF_BIG_ONLY) {
if (eeo->big_only_flag) {
if (!(Ship_info[shipp->ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
return;
}
}
// don't shoot at big ships if we shouldn't
if (eeo->eeo_flags & EEOF_SMALL_ONLY) {
if (eeo->small_only_flag) {
if ((Ship_info[shipp->ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
return;
}
}
// check if turret flagged to only target tagged ships
if (eeo->eeo_flags & EEOF_TAGGED_ONLY) {
if (eeo->tagged_only_flag) {
if (!ship_is_tagged(objp)) {
return;
}
@@ -598,20 +474,9 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
}
if ((objp->type == OBJ_WEAPON) && check_weapon) {
//Maybe restrict the number of turrets attacking this bomb
if (ss->turret_max_bomb_ownage != -1) {
int num_att_turrets = num_turrets_attacking(turret_parent_obj, OBJ_INDEX(objp));
if (num_att_turrets > ss->system_info->turret_max_bomb_ownage) {
return;
}
}
if ( Weapons[objp->instance].homing_object == &Objects[eeo->turret_parent_objnum] ) {
if ( dist_comp < eeo->nearest_homing_bomb_dist ) {
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
turret_has_no_target = true;
}
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
eeo->nearest_homing_bomb_dist = dist_comp;
eeo->nearest_homing_bomb_objnum = OBJ_INDEX(objp);
}
@@ -619,10 +484,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
// if not homing, check if bomb is flying towards ship
} else if ( bomb_headed_towards_ship(objp, &Objects[eeo->turret_parent_objnum]) ) {
if ( dist_comp < eeo->nearest_bomb_dist ) {
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
turret_has_no_target = true;
}
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
eeo->nearest_bomb_dist = dist_comp;
eeo->nearest_bomb_objnum = OBJ_INDEX(objp);
}
@@ -651,10 +513,6 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
if (objp->flags & OF_PLAYER_SHIP) {
max_turrets = The_mission.ai_profile->max_turret_ownage_player[Game_skill_level];
}
// Apply the per-turret limit, if there is one
if (ss->turret_max_target_ownage != -1) {
max_turrets = MIN(max_turrets, ss->system_info->turret_max_target_ownage);
}
if (num_att_turrets > max_turrets) {
return;
}
@@ -682,10 +540,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
// maybe update nearest attacker
if ( dist_comp < eeo->nearest_attacker_dist ) {
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
turret_has_no_target = true;
}
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
// nprintf(("AI", "Nearest enemy = %s, dist = %7.3f, dot = %6.3f, fov = %6.3f\n", Ships[objp->instance].ship_name, dist, vm_vec_dot(&v2e, tvec), tp->turret_fov));
eeo->nearest_attacker_dist = dist_comp;
eeo->nearest_attacker_objnum = OBJ_INDEX(objp);
@@ -700,10 +555,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
dist_comp *= 0.9f + (0.01f * asteroid_time_to_impact(objp));
if (dist_comp < eeo->nearest_dist ) {
if (!(ss->flags & SSF_FOV_REQUIRED) && (eeo->current_enemy == -1)) {
turret_has_no_target = true;
}
if ( (turret_has_no_target) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, ss, eeo->tvec, eeo->tpos, dist + objp->radius) ) {
eeo->nearest_dist = dist_comp;
eeo->nearest_objnum = OBJ_INDEX(objp);
}
@@ -740,7 +592,7 @@ int is_target_beam_valid(ship_weapon *swp, object *objp)
// tpos => position of turret (world coords)
// tvec => forward vector of turret (world coords)
// current_enemy => objnum of current turret target
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag, bool flak_flag, bool laser_flag, bool missile_flag)
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
{
//float weapon_travel_dist;
int weapon_system_ok;
@@ -768,26 +620,10 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
eeo.turret_parent_objnum = turret_parent_objnum;
eeo.weapon_system_ok = weapon_system_ok;
eeo.weapon_travel_dist = longest_turret_weapon_range(swp);
// set flags
eeo.eeo_flags = 0;
if (big_only_flag)
eeo.eeo_flags |= EEOF_BIG_ONLY;
if (small_only_flag)
eeo.eeo_flags |= EEOF_SMALL_ONLY;
if (tagged_only_flag)
eeo.eeo_flags |= EEOF_TAGGED_ONLY;
// flags for weapon types
if (beam_flag)
eeo.eeo_flags |= EEOF_BEAM;
else if (flak_flag)
eeo.eeo_flags |= EEOF_FLAK;
else if (laser_flag)
eeo.eeo_flags |= EEOF_LASER;
else if (missile_flag)
eeo.eeo_flags |= EEOF_MISSILE;
eeo.big_only_flag = big_only_flag;
eeo.small_only_flag = small_only_flag;
eeo.tagged_only_flag = tagged_only_flag;
eeo.beam_flag = beam_flag;
eeo.enemy_team_mask = enemy_team_mask;
eeo.current_enemy = current_enemy;
eeo.tpos = tpos;
@@ -836,9 +672,9 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
else
tt = &Ai_tp_list[Weapon_info[priority_weapon_idx].targeting_priorities[i]];
int n_types = (int)tt->ship_type.size();
int n_s_classes = (int)tt->ship_class.size();
int n_w_classes = (int)tt->weapon_class.size();
int n_types = tt->ship_type.size();
int n_s_classes = tt->ship_class.size();
int n_w_classes = tt->weapon_class.size();
bool found_something;
object *ptr = GET_FIRST(&obj_used_list);
@@ -1058,15 +894,10 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
tp = turret_subsys->system_info;
enemy_team_mask = iff_get_attackee_mask(obj_team(&Objects[objnum]));
bool big_only_flag = all_turret_weapons_have_flags(&turret_subsys->weapons, WIF_HUGE);
bool small_only_flag = all_turret_weapons_have_flags2(&turret_subsys->weapons, WIF2_SMALL_ONLY);
bool tagged_only_flag = all_turret_weapons_have_flags2(&turret_subsys->weapons, WIF2_TAGGED_ONLY) || (turret_subsys->weapons.flags & SW_FLAG_TAGGED_ONLY);
bool beam_flag = turret_weapon_has_flags(&turret_subsys->weapons, WIF_BEAM);
bool flak_flag = turret_weapon_has_flags(&turret_subsys->weapons, WIF_FLAK);
bool laser_flag = turret_weapon_has_subtype(&turret_subsys->weapons, WP_LASER);
bool missile_flag = turret_weapon_has_subtype(&turret_subsys->weapons, WP_MISSILE);
bool beam_flag = all_turret_weapons_have_flags(&turret_subsys->weapons, WIF_BEAM);
// If a small ship and target_objnum != -1, use that as goal.
ai_info *aip = &Ai_info[Ships[Objects[objnum].instance].ai_index];
@@ -1100,14 +931,8 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
}
// maybe use ship target_objnum if valid for turret
// check for beam weapon and beam protected, etc.
bool skip = false;
if ( (target_flags & OF_BEAM_PROTECTED) && beam_flag ) skip = true;
else if ( (target_flags & OF_FLAK_PROTECTED) && flak_flag ) skip = true;
else if ( (target_flags & OF_LASER_PROTECTED) && laser_flag ) skip = true;
else if ( (target_flags & OF_MISSILE_PROTECTED) && missile_flag ) skip = true;
if (!skip) {
// check for beam weapon and beam protected
if ( !((target_flags & OF_BEAM_PROTECTED) && (beam_flag)) ) {
if ( Objects[aip->target_objnum].type == OBJ_SHIP ) {
// check for huge weapon and huge ship
if ( !big_only_flag || (Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].flags & (SIF_BIG_SHIP|SIF_HUGE_SHIP)) ) {
@@ -1120,13 +945,7 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
dist = vm_vec_normalized_dir(&v2e, &Objects[aip->target_objnum].pos, tpos);
in_fov = turret_fov_test(turret_subsys, tvec, &v2e);
if (turret_subsys->flags & SSF_FOV_EDGE_CHECK) {
if (in_fov == false)
if (object_in_turret_fov(&Objects[aip->target_objnum], turret_subsys, tvec, tpos, dist + Objects[aip->target_objnum].radius))
in_fov = true;
}
// MODIFY FOR ATTACKING BIG SHIP
// MODIFY FOR ATTACKING BIG SHIP
// dot += (0.5f * Objects[aip->target_objnum].radius / dist);
if (in_fov) {
return aip->target_objnum;
@@ -1138,13 +957,9 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
}
}
enemy_objnum = get_nearest_turret_objnum(objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag, flak_flag, laser_flag, missile_flag);
enemy_objnum = get_nearest_turret_objnum(objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag);
if ( enemy_objnum >= 0 ) {
Assert( !((Objects[enemy_objnum].flags & OF_BEAM_PROTECTED) && beam_flag) );
Assert( !((Objects[enemy_objnum].flags & OF_FLAK_PROTECTED) && flak_flag) );
Assert( !((Objects[enemy_objnum].flags & OF_LASER_PROTECTED) && laser_flag) );
Assert( !((Objects[enemy_objnum].flags & OF_MISSILE_PROTECTED) && missile_flag) );
if ( Objects[enemy_objnum].flags & OF_PROTECTED ) {
Int3();
enemy_objnum = aip->target_objnum;
@@ -1179,22 +994,21 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
vec3d * gun_pos;
model_subsystem *tp = ssp->system_info;
//ship_model_start(objp);
ship_model_start(objp);
gun_pos = &tp->turret_firing_point[ssp->turret_next_fire_pos % tp->turret_num_firing_points];
//model_find_world_point(gpos, gun_pos, tp->model_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
model_instance_find_world_point(gpos, gun_pos, tp->model_num, Ships[objp->instance].model_instance_num, tp->turret_gun_sobj, &objp->orient, &objp->pos);
model_find_world_point(gpos, gun_pos, tp->model_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
if (use_angles)
model_instance_find_world_dir(gvec, &tp->turret_norm, tp->model_num, Ships[objp->instance].model_instance_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
model_find_world_dir(gvec, &tp->turret_norm, tp->model_num, tp->turret_gun_sobj, &objp->orient, &objp->pos );
else {
//vector gun_pos2;
//vm_vec_add(&gun_pos2, gpos, gun_pos);
vm_vec_normalized_dir(gvec, targetp, gpos);
}
//ship_model_stop(objp);
ship_model_stop(objp);
// per firingpoint based changes go here for turrets
}
@@ -1292,11 +1106,6 @@ int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object
in_fov = turret_fov_test(ss, gvec, &v2e);
if (ss->flags & SSF_FOV_EDGE_CHECK) {
if (in_fov == false)
in_fov = is_object_radius_in_turret_fov(&Objects[ss->turret_enemy_objnum], ss, gvec, &gun_pos, &v2e, predicted_enemy_pos, 0.0f);
}
if (in_fov) {
ret_val = model_rotate_gun(Ship_info[shipp->ship_info_index].model_num,
tp, &Objects[parent_objnum].orient,
@@ -1572,16 +1381,13 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
wait *= frand_range(0.9f, 1.1f);
}
if(turret->rof_scaler != 1.0f)
wait /= get_adjusted_turret_rof(turret);
(*fs_dest) = timestamp((int)wait);
}
// Decide if a turret should launch an aspect seeking missile
int turret_should_fire_aspect(ship_subsys *turret, weapon_info *wip, bool in_sight)
int turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
{
if ( in_sight && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
if ( (dot > AICODE_TURRET_DUMBFIRE_ANGLE) && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
return 1;
}
@@ -1636,34 +1442,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
wip = get_turret_weapon_wip(&turret->weapons, weapon_num);
int turret_weapon_class = WEAPON_INFO_INDEX(wip);
#ifndef NDEBUG
// moved here from check_ok_to_fire
if (turret->turret_enemy_objnum >= 0) {
object *tobjp = &Objects[turret->turret_enemy_objnum];
// should not get this far. check if ship is protected from beam and weapon is type beam
if ( (wip->wi_flags & WIF_BEAM) && (tobjp->flags & OF_BEAM_PROTECTED) ) {
Int3();
return 0;
}
// should not get this far. check if ship is protected from flak and weapon is type flak
else if ( (wip->wi_flags & WIF_FLAK) && (tobjp->flags & OF_FLAK_PROTECTED) ) {
Int3();
return 0;
}
// should not get this far. check if ship is protected from laser and weapon is type laser
else if ( (wip->subtype == WP_LASER) && (tobjp->flags & OF_LASER_PROTECTED) ) {
Int3();
return 0;
}
// should not get this far. check if ship is protected from missile and weapon is type missile
else if ( (wip->subtype == WP_MISSILE) && (tobjp->flags & OF_MISSILE_PROTECTED) ) {
Int3();
return 0;
}
}
#endif
if (check_ok_to_fire(parent_objnum, turret->turret_enemy_objnum, wip)) {
vm_vector_2_matrix(&turret_orient, turret_fvec, NULL, NULL);
turret->turret_last_fire_direction = *turret_fvec;
@@ -1676,6 +1454,8 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
if (wip->wi_flags & WIF_BEAM) {
// if this beam isn't free to fire
if (!(turret->weapons.flags & SW_FLAG_BEAM_FREE)) {
//WMC - remove this
//Int3(); // should never get this far
return false;
}
beam_fire_info fire_info;
@@ -1689,6 +1469,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
fire_info.target = &Objects[turret->turret_enemy_objnum];
fire_info.target_subsys = NULL;
fire_info.turret = turret;
fire_info.fighter_beam = false;
// fire a beam weapon
beam_fire(&fire_info);
@@ -1706,11 +1487,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
// now do anything else
else {
for (int i=0; i < wip->shots; i++)
{
// zookeeper - Firepoints should cycle normally between shots,
// so we need to get the position info separately for each shot
ship_get_global_turret_gun_info(&Objects[parent_objnum], turret, turret_pos, turret_fvec, 1, NULL);
{
weapon_objnum = weapon_create( turret_pos, &turret_orient, turret_weapon_class, parent_objnum, -1, 1);
weapon_set_tracking_info(weapon_objnum, parent_objnum, turret->turret_enemy_objnum, 1, turret->targeted_subsys);
@@ -1718,12 +1495,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
objp=&Objects[weapon_objnum];
wp=&Weapons[objp->instance];
parent_ship->last_fired_turret = turret;
turret->last_fired_weapon_info_index = wp->weapon_info_index;
Script_system.SetHookObjects(3, "Ship", &Objects[parent_objnum], "Weapon", objp, "Target", &Objects[turret->turret_enemy_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[parent_objnum]);
//nprintf(("AI", "Turret_time_enemy_in_range = %7.3f\n", ss->turret_time_enemy_in_range));
if (weapon_objnum != -1) {
wp->target_num = turret->turret_enemy_objnum;
@@ -1766,14 +1537,13 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
if ( wip->launch_snd != -1 ) {
// Don't play turret firing sound if turret sits on player ship... it gets annoying.
if ( parent_objnum != OBJ_INDEX(Player_obj) || (turret->flags & SSF_PLAY_SOUND_FOR_PLAYER) ) {
if ( parent_objnum != OBJ_INDEX(Player_obj) ) {
snd_play_3d( &Snds[wip->launch_snd], turret_pos, &View_position );
}
}
}
turret->turret_next_fire_pos++;
}
turret->turret_next_fire_pos--;
// reset any animations if we need to
// (I'm not sure how accurate this timestamp would be in practice - taylor)
if (turret->turret_animation_position == MA_POS_READY)
@@ -1920,6 +1690,14 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
return;
}
// starting animation checks
if (ss->turret_animation_position == MA_POS_NOT_SET) {
if ( model_anim_start_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num, 1) ) {
ss->turret_animation_done_time = model_anim_get_time_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num);
ss->turret_animation_position = MA_POS_SET;
}
}
if (ss->turret_animation_position == MA_POS_SET) {
if ( timestamp_elapsed(ss->turret_animation_done_time) ) {
ss->turret_animation_position = MA_POS_READY;
@@ -2091,12 +1869,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
}
}
if ( wip->wi_flags2 & WIF2_SMALL_ONLY ) {
if ( (lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) ) {
continue;
}
}
if (lep->type == OBJ_SHIP) {
// Check if we're targeting a protected ship
if (lep->flags & OF_PROTECTED) {
@@ -2111,24 +1883,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
ss->turret_time_enemy_in_range = 0.0f;
continue;
}
// Check if we're targeting a flak protected ship with a flak weapon
else if ( (lep->flags & OF_FLAK_PROTECTED) && (wip->wi_flags & WIF_FLAK) ) {
ss->turret_enemy_objnum = -1;
ss->turret_time_enemy_in_range = 0.0f;
continue;
}
// Check if we're targeting a laser protected ship with a laser weapon
else if ( (lep->flags & OF_LASER_PROTECTED) && (wip->subtype == WP_LASER) ) {
ss->turret_enemy_objnum = -1;
ss->turret_time_enemy_in_range = 0.0f;
continue;
}
// Check if we're targeting a missile protected ship with a missile weapon
else if ( (lep->flags & OF_MISSILE_PROTECTED) && (wip->subtype == WP_MISSILE) ) {
ss->turret_enemy_objnum = -1;
ss->turret_time_enemy_in_range = 0.0f;
continue;
}
}
else
{
@@ -2152,7 +1906,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
ss->turret_enemy_objnum = -1;
// Maybe pick a new enemy, unless targeting has been taken over by scripting
if ( turret_should_pick_new_target(ss) && !ss->scripting_target_override ) {
if ( turret_should_pick_new_target(ss) && !ss->scripting_target_override) {
Num_find_turret_enemy++;
int objnum = find_turret_enemy(ss, parent_objnum, &gpos, &gvec, ss->turret_enemy_objnum);
//Assert(objnum < 0 || is_target_beam_valid(tp, objnum));
@@ -2338,7 +2092,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
{
turret_update_enemy_in_range(ss, 2*wip->fire_wait);
}
if ( turret_should_fire_aspect(ss, wip, in_sight) )
if ( turret_should_fire_aspect(ss, dot, wip) )
{
ok_to_fire = true;
}
@@ -2351,7 +2105,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
}
// Check if turret should fire and enemy's engines are
// in line of sight
if (turret_should_fire_aspect(ss, wip, in_sight) &&
if (turret_should_fire_aspect(ss, dot, wip) &&
ship_get_closest_subsys_in_sight(&Ships[lep->signature], SUBSYSTEM_ENGINE, &gpos))
{
ok_to_fire = true;
@@ -2365,7 +2119,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
vm_vec_scale_add(&end, &gpos, &gvec, model_get_radius(model_num));
hull_check.model_instance_num = shipp->model_instance_num;
hull_check.model_num = model_num;
hull_check.orient = &objp->orient;
hull_check.pos = &objp->pos;
@@ -2378,28 +2131,11 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
}
}
if ( ok_to_fire )
{
// starting animation checks
if (ss->turret_animation_position == MA_POS_NOT_SET) {
if ( model_anim_start_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num, 1) ) {
ss->turret_animation_done_time = model_anim_get_time_type(shipp, TRIGGER_TYPE_TURRET_FIRING, ss->system_info->subobj_num);
ss->turret_animation_position = MA_POS_SET;
}
}
//Wait until the animation is done to actually fire
if (tp->flags & MSS_FLAG_TURRET_ANIM_WAIT && (ss->turret_animation_position != MA_POS_READY))
{
ok_to_fire = false;
}
}
if ( ok_to_fire )
{
something_was_ok_to_fire = true;
Num_turrets_fired++;
//Pass along which gun we are using
if (tp->flags & MSS_FLAG_TURRET_SALVO)
turret_fire_weapon(valid_weapons[0], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
@@ -2412,6 +2148,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
turret_set_next_fire_timestamp(valid_weapons[0], wip, ss, parent_aip);
}
}
// moved this here so we increment the fire pos only after we have fired and not during it
ss->turret_next_fire_pos++;
}
@@ -2421,14 +2158,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
//Impose a penalty on turret accuracy for losing site of its goal, or just not being able to fire.
turret_update_enemy_in_range(ss, -4*Weapon_info[ss->turret_best_weapon].fire_wait);
ss->turret_next_fire_stamp = timestamp(500);
// If nothing is OK to fire (lost track of the target?)
// reset the target (so we don't continue to track what we can't hit)
if (tp->flags2 & MSS_FLAG2_TURRET_ONLY_TARGET_IF_CAN_FIRE)
{
ss->turret_enemy_objnum = -1; // Reset enemy objnum, find a new one next frame.
ss->turret_time_enemy_in_range = 0.0f;
}
}
else
{
@@ -2477,7 +2206,7 @@ bool turret_std_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
{
model_subsystem *tp = ss->system_info;
float dot = vm_vec_dot(v2e, gvec);
if (((dot + size_mod) >= tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov))
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov))
return true;
return false;
@@ -2487,7 +2216,7 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
{
model_subsystem *tp = ss->system_info;
float dot = vm_vec_dot(v2e, gvec);
if (((dot + size_mod) >= tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
vec3d of_dst;
vm_vec_rotate( &of_dst, v2e, &ss->world_to_turret_matrix );
if ((of_dst.xyz.x == 0) && (of_dst.xyz.y == 0)) {
@@ -2497,7 +2226,7 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
if (!IS_VEC_NULL_SQ_SAFE(&of_dst)) {
vm_vec_normalize(&of_dst);
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
if ((-of_dst.xyz.y + size_mod) >= tp->turret_y_fov)
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
return true;
}
}
@@ -2515,28 +2244,3 @@ bool turret_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
return in_fov;
}
float get_adjusted_turret_rof(ship_subsys *ss)
{
float tempf = ss->rof_scaler;
// optional reset switch (negative value)
if (tempf < 0) {
ss->rof_scaler = 1.0f;
return 1.0f;
}
if (tempf == 0) {
// special case returning the number of firingpoints
ss->rof_scaler = (float) ss->system_info->turret_num_firing_points;
tempf = ss->rof_scaler;
// safety check to avoid div/0 issues
if (tempf == 0) {
ss->rof_scaler = 1.0f;
return 1.0f;
}
}
return tempf;
}
+176 -107
View File
@@ -31,17 +31,16 @@ anim_instance anim_render_list;
#define MAX_ANIM_INSTANCES 25
anim_instance anim_render_instance[MAX_ANIM_INSTANCES];
int Anim_paused; /// Global variable to pause the playing back of anims
int Anim_paused; // global variable to pause the playing back of anims
int Anim_inited = FALSE;
fix t1,t2;
int Anim_ignore_frametime=0; // flag used to ignore frametime... useful when need to avoid saturated frametimes
/**
* @brief Initialise animation
* @details Queue all the ::anim_render_instance[] elements onto the ::anim_free_list
*/
// -------------------------------------------------------------------------------------------------
// anim_init() will queue all the anim_render_instance[] elements onto the anim_free_list
//
void anim_init()
{
int i;
@@ -61,9 +60,9 @@ void anim_init()
Anim_inited = TRUE;
}
/**
* @brief Display the frames for the currently playing anims
*/
// -------------------------------------------------------------------------------------------------
// anim_render_all() will display the frames for the currently playing anims
//
void anim_render_all(int screen_id, float frametime)
{
anim_instance* A;
@@ -86,10 +85,10 @@ void anim_render_all(int screen_id, float frametime)
}
}
/**
* @brief Display the frames for the passed animation
* @details It will ignore animations which do not have the same id as the passed screen_id
*/
// -------------------------------------------------------------------------------------------------
// anim_render_one() will display the frames for the passed animation, it will ignore animations which
// do not have the same id as the passed screen_id
//
void anim_render_one(int screen_id, anim_instance *ani, float frametime)
{
// make sure this guy's screen id matches the passed one
@@ -110,17 +109,14 @@ void anim_render_one(int screen_id, anim_instance *ani, float frametime)
MONITOR(NumANIPlayed)
/**
* @brief Setup an anim_play_struct for passing into ::anim_play().
* @details Will fill in default values, which you can then change before calling ::anim_play().
*/
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int base_w, int base_h)
// Setup an anim_play_struct for passing into anim_play(). Will fill in default values, which you
// can then change before calling anim_play().
//
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y)
{
aps->anim_info = a_info;
aps->x = x;
aps->y = y;
aps->base_w = base_w;
aps->base_h = base_h;
aps->start_at = 0;
aps->stop_at = a_info->total_frames - 1;
aps->screen_id = 0;
@@ -133,21 +129,49 @@ void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int base_
aps->ping_pong = 0;
}
/**
* @brief Will add an anim instance to the anim_render_list.
* This will cause the anim to be played at the x,y position specified in the parameter list.
*
* @param aps Compressed animation that we should make an instance from
* @return If success pointer to instance, NULL if anim anim could not be played
*/
// -------------------------------------------------------------------------------------------------
// anim_play() will add an anim instance to the anim_render_list. This will cause the
// anim to be played at the x,y position specified in the parameter list.
//
// input:
//
// anim_info => the compressed animation that we should make an instance from
// x => x position of animation to play at (top left corner)
// y => y position of animation to play at ( top left corner)
// start_at => frame number to start at (note: numbering is from 0->num_frames-1)
// stop_at => frame number to stop at (note: numbering is from 0->num_frames-1)
// screen_id => OPTIONAL (default value 0): screen signature so animation only plays when
// anim_render_all() called with that same signature
// world_pos => OPTIONAL (default value NULL): only give a world pos when you want to
// play the animation at a 3D location. You must specify radius when
// this is non-null.
// radius => OPTIONAL (default value 0): only needed when the animation is playing
// as a 3D animation (this is only when world_pos in not NULL).
// fi => OPTIONAL (default value 0): framerate indepentdent flag, when set TRUE
// the animation will skip frames if necessary to maintain the fps value
// associated with the animation
// color => OPTIONAL (default value NULL) address of an alpha color struct. Only
// required when the animation should be drawn with an alpha color.
// skip_frames => OPTIONAL (default value 1) should anim skip frames when doing framerate
// independent playback
// looped => OPTIONAL (default value 0) should anim play looped (ie forever)
//
// returns:
//
// pointer to instance => success
// NULL => if anim anim could not be played
//
anim_instance *anim_play(anim_play_struct *aps)
{
Assert( aps->anim_info != NULL );
Assert( aps->start_at >= 0 );
Assert( aps->stop_at < aps->anim_info->total_frames );
// Assert( aps->stop_at >= aps->start_at );
Assert( !(aps->looped && aps->ping_pong) ); // shouldn't have these both set at once
MONITOR_INC(NumANIPlayed, 1);
// if (aps->ping_pong && !(aps->anim_info->flags & ANF_ALL_KEYFRAMES));
anim_instance *instance;
@@ -195,14 +219,6 @@ anim_instance *anim_play(anim_play_struct *aps)
instance->xlate_pal = 0;
}
if(aps->base_w < 0 || aps->base_h < 0) {
instance->base_w = gr_screen.max_w_unscaled;
instance->base_h = gr_screen.max_h_unscaled;
} else {
instance->base_w = aps->base_w;
instance->base_h = aps->base_h;
}
// determining the start_at frame is more complicated, since it must be a key-frame.
// Futhermore, need to subtract 1 from key-frame number, since frame number is always
// incremented the first time anim_show_next_frame() is called
@@ -227,6 +243,16 @@ anim_instance *anim_play(anim_play_struct *aps)
idx++;
}
/*while (keyp) {
if (( (keyp->frame_num-1) <= frame_num) && ( (keyp->frame_num-1) > key)) { // find closest key
key = keyp->frame_num-1;
offset = keyp->offset;
if ( key == frame_num )
break;
}
keyp = keyp->next;
}*/
if (key > instance->frame_num) { // best key is closer than current position
instance->frame_num = key;
@@ -244,17 +270,20 @@ anim_instance *anim_play(anim_play_struct *aps)
return instance;
}
/**
* @brief This function is called to blit the next frame of an anim instance to the screen.
* This is normally called by the anim_render_all() function.
*
* @param instance Pointer to animation instance
* @param frametime Time elapsed since last call, in seconds
*/
// -----------------------------------------------------------------------------
// anim_show_next_frame()
//
// This function is called to blit the next frame of an anim instance to the
// screen. This is normally called by the anim_render_all() function.
//
// input: instance => pointer to animation instance
// frametime => time elapsed since last call, in seconds
//
int anim_show_next_frame(anim_instance *instance, float frametime)
{
int bitmap_id, bitmap_flags=0, new_frame_num, frame_diff=0, i, n_frames=0,frame_save;
float percent_through, decompress_time, render_time, time;
int bitmap_id, bitmap_flags=0, new_frame_num, frame_diff=0, i, n_frames=0,frame_save;
float percent_through, decompress_time, render_time, time;
vertex image_vertex;
int aabitmap = 0;
int bpp = 16;
@@ -336,6 +365,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
instance->time_elapsed = 0.0f;
} else if(instance->ping_pong) { // pingponged animations
instance->frame_num = instance->stop_at;
// instance->time_elapsed = 0.0f;
anim_reverse_direction(instance);
} else { // one-shot animations
instance->frame_num = instance->stop_at;
@@ -350,6 +380,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
instance->time_elapsed = 0.0f;
} else if(instance->ping_pong) { // pingponged animations
instance->frame_num = instance->stop_at;
// instance->time_elapsed = 0.0f;
anim_reverse_direction(instance);
} else { // one-shot animations
instance->frame_num = instance->stop_at+1;
@@ -373,6 +404,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
}
}
Assert(frame_diff >= 0);
// nprintf(("Alan","FRAME DIFF: %d\n",frame_diff));
Assert( instance->frame_num >= 0 && instance->frame_num < instance->parent->total_frames );
// if the anim is paused, ignore all the above changes and still display this frame
@@ -383,6 +415,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
}
if (instance->parent->flags & ANF_XPARENT){
// bitmap_flags = BMP_XPARENT;
bitmap_flags = 0;
}
bpp = 16;
@@ -488,8 +521,6 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
// determine x,y to display the bitmap at
if ( instance->world_pos == NULL ) {
gr_set_screen_scale(instance->base_w, instance->base_h);
gr_set_clip(0, 0, instance->base_w, instance->base_h, false);
if ( instance->aa_color == NULL ) {
gr_bitmap(instance->x, instance->y);
}
@@ -497,8 +528,6 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
gr_set_color_fast( (color*)instance->aa_color );
gr_aabitmap(instance->x, instance->y);
}
gr_reset_screen_scale();
gr_reset_clip();
}
else {
g3_rotate_vertex(&image_vertex,instance->world_pos);
@@ -506,18 +535,23 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
g3_draw_bitmap(&image_vertex, 0, instance->radius*1.5f, TMAP_FLAG_TEXTURED | TMAP_HTL_2D);
}
//bm_release(bitmap_id);
instance->last_bitmap = bitmap_id;
}
t2 = timer_get_fixed_seconds();
render_time = f2fl(t2-t1);
// nprintf(("Alan","DECOMPRESS: %.3fms RENDER: %.3fms\n", decompress_time*1000, render_time*1000));
return 0;
}
/**
* @brief Stop an anim instance that is on the anim_render_list from playing
*/
// -----------------------------------------------------------------------------
// anim_stop_playing()
//
// Stop an anim instance that is on the anim_render_list from playing
//
int anim_stop_playing(anim_instance* instance)
{
Assert(instance != NULL);
@@ -528,12 +562,14 @@ int anim_stop_playing(anim_instance* instance)
return 0;
}
/**
* @brief Free a particular animation instance that is on the anim_render_list.
* Do not call this function to free an animation instance in general (use
* free_anim_instance() for that), only when you want to free an instance
* that is on the anim_render_list
*/
// -----------------------------------------------------------------------------
// anim_release_render_instance()
//
// Free a particular animation instance that is on the anim_render_list. Do
// not call this function to free an animation instance in general (use
// free_anim_instance() for that), only when you want to free an instance
// that is on the anim_render_list
//
void anim_release_render_instance(anim_instance* instance)
{
Assert( instance != NULL );
@@ -556,13 +592,16 @@ void anim_release_render_instance(anim_instance* instance)
list_append( &anim_free_list, instance );
}
/**
* @brief Free all anim instances that are on the anim_render_list.
*
* @param screen_id Optional parameter that lets you only free a subset of the anim instances.
* A screen_id of 0 is the default value, and this is used for animations that always play when
* they are placed on the aim_render_list.
*/
// -----------------------------------------------------------------------------
// anim_release_all_instances()
//
// Free all anim instances that are on the anim_render_list.
//
// input: screen_id => optional parameter that lets you only free a subset
// of the anim instances. A screen_id of 0 is the default
// value, and this is used for animations that always play
// when they are placed on the aim_render_list.
//
void anim_release_all_instances(int screen_id)
{
anim_instance* A;
@@ -586,18 +625,18 @@ void anim_release_all_instances(int screen_id)
//
// Read the header of a .ani file. Below is the format of a .ani header
//
// #bytes | description
// #bytes | description
// 2 | obsolete, kept for compatibility with old versions
// 2 | version number
// 2 | fps
// 1 | transparent red value
// 1 | transparent green value
// 1 | transparent green value
// 1 | transparent blue value
// 2 | width
// 2 | height
// 2 | number of frames
// 1 | packer code
// 763 | palette
// 763 | palette
// 2 | number of key frames
// 2 | key frame number } repeats
// 4 | key frame offset } repeats
@@ -607,7 +646,7 @@ void anim_read_header(anim *ptr, CFILE *fp)
{
ptr->width = cfread_short(fp);
// If first 2 bytes are zero, this means we are using a new format, which includes
// a version, and fps values. This is only done since a version number was not included
// a version, and fps values. This is only done since a version number was not included
// in the original header.
// default
@@ -672,17 +711,20 @@ void anim_read_header(anim *ptr, CFILE *fp)
}
}
/**
* @brief Load an animation. This stores the compressed data, which instances of the animation can reference.
* Must be free'ed later with anim_free().
*
* @param real_filename Filename of animation
* @param cf_dir_type
* @param file_mapped Whether to use memory-mapped file or not.
*
* @details Memory-mapped files will page in the animation from disk as it is needed, but performance is not as good.
* @return Pointer to anim that is loaded if sucess, NULL if failure.
*/
// -----------------------------------------------------------------------------
// anim_load()
//
// Load an animation. This stores the compressed data, which instances
// of the animation can reference. Must be free'ed later with anim_free()
//
// input: name => filename of animation
// file_mapped => boolean, whether to use memory-mapped file or not.
// Memory-mapped files will page in the animation from disk
// as it is needed, but performance is not as good
//
// returns: pointer to anim that is loaded => sucess
// NULL => failure
//
anim *anim_load(char *real_filename, int cf_dir_type, int file_mapped)
{
anim *ptr;
@@ -690,7 +732,7 @@ anim *anim_load(char *real_filename, int cf_dir_type, int file_mapped)
int count,idx;
char name[_MAX_PATH];
Assert( real_filename != NULL );
Assert ( real_filename != NULL );
strcpy_s( name, real_filename );
char *p = strchr( name, '.' );
@@ -741,10 +783,22 @@ anim *anim_load(char *real_filename, int cf_dir_type, int file_mapped)
ptr->keys[idx].frame_num = 0;
cfread(&ptr->keys[idx].frame_num, 2, 1, fp);
cfread(&ptr->keys[idx].offset, 4, 1, fp);
ptr->keys[idx].frame_num = INTEL_INT( ptr->keys[idx].frame_num ); //-V570
ptr->keys[idx].offset = INTEL_INT( ptr->keys[idx].offset ); //-V570
ptr->keys[idx].frame_num = INTEL_INT( ptr->keys[idx].frame_num );
ptr->keys[idx].offset = INTEL_INT( ptr->keys[idx].offset );
}
/*prev_keyp = &ptr->keys;
count = ptr->num_keys;
while (count--) {
keyp = (key_frame *) vm_malloc(sizeof(key_frame));
keyp->next = *prev_keyp;
*prev_keyp = keyp;
prev_keyp = &keyp->next;
keyp->frame_num = 0;
cfread(&keyp->frame_num, 2, 1, fp);
cfread(&keyp->offset, 4, 1, fp);
}*/
cfread(&count, 4, 1, fp); // size of compressed data
count = INTEL_INT( count );
@@ -805,10 +859,12 @@ anim *anim_load(char *real_filename, int cf_dir_type, int file_mapped)
return ptr;
}
/**
* @brief Free an animation that was loaded with anim_load().
* @details All instances referencing this animation must be free'ed or get an assert.
*/
// ---------------------------------------------------
// anim_free()
//
// Free an animation that was loaded with anim_load(). All instances
// referencing this animation must be free'ed or get an assert.
//
int anim_free(anim *ptr)
{
Assert ( ptr != NULL );
@@ -840,14 +896,14 @@ int anim_free(anim *ptr)
if ( ptr->flags & (ANF_MEM_MAPPED|ANF_STREAMED) ) {
cfclose(ptr->cfile_ptr);
if (ptr->cache != NULL) {
if ( ptr->cache ) {
vm_free(ptr->cache);
ptr->cache = NULL;
}
}
else {
Assert(ptr->data);
if (ptr->data != NULL) {
if ( ptr->data ) {
vm_free(ptr->data);
ptr->data = NULL;
}
@@ -859,9 +915,11 @@ int anim_free(anim *ptr)
}
/**
* @brief Return if an anim is playing or not.
*/
// ---------------------------------------------------------------------
// anim_playing()
//
// Return if an anim is playing or not.
//
int anim_playing(anim_instance *ai)
{
Assert(ai != NULL);
@@ -872,28 +930,36 @@ int anim_playing(anim_instance *ai)
}
/**
* @brief Called at the beginning of a mission to initialize any mission dependent anim data.
* @todo Redundant?
*/
// ---------------------------------------------------------------------
// anim_level_init()
//
// Called at the beginning of a mission to initialize any mission dependent
// anim data.
//
void anim_level_init()
{
}
/**
* @brief Called after the end of a mission to clean up any mission dependent anim data.
*/
// ---------------------------------------------------------------------
// anim_level_close()
//
// Called after the end of a mission to clean up any mission dependent
// anim data.
//
void anim_level_close()
{
anim_release_all_instances();
}
/**
* @brief Write the frames of a .ani file out to disk as .pcx files.
* @details Use naming convention: filename0000.pcx, filename0001.pcx etc.
*
* @return If success 0, or if failed -1
*/
// ---------------------------------------------------
// anim_write_frames_out()
//
// Write the frames of a .ani file out to disk as .pcx files.
// Use naming convention: filename0000.pcx, filename0001.pcx etc.
//
// return: 0 => success
// -1 => failed
//
int anim_write_frames_out(char *filename)
{
anim *source_anim;
@@ -939,10 +1005,12 @@ int anim_write_frames_out(char *filename)
return 0;
}
/**
* @brief Display information and statistics about a .ani file.
* @details This is called when -i switch is on when running ac.exe
*/
// ---------------------------------------------------
// anim_display_info()
//
// Display information and statistics about a .ani file.
// This is called when -i switch is on when running ac.exe
//
void anim_display_info(char *real_filename)
{
CFILE *fp;
@@ -972,6 +1040,7 @@ void anim_display_info(char *real_filename)
key_frame_nums[i] = 0;
cfread(&key_frame_nums[i], 2, 1, fp);
cfread(&tmp, 4, 1, fp);
//printf("key frame num: %d,%d\n", key_frame_nums[i],tmp);
}
cfread(&compressed, 4, 1, fp);
+1 -3
View File
@@ -24,8 +24,6 @@ typedef struct {
anim *anim_info;
int x;
int y;
int base_w;
int base_h;
int start_at;
int stop_at;
int screen_id;
@@ -52,7 +50,7 @@ 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);
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y);
anim_instance *anim_play(anim_play_struct *aps);
void anim_ignore_next_frametime();
int anim_stop_playing(anim_instance* anim_instance);
+54 -65
View File
@@ -15,6 +15,8 @@
#include "anim/animplay.h"
const int packer_code = PACKER_CODE;
const int transparent_code = 254;
@@ -49,7 +51,6 @@ anim_instance *init_anim_instance(anim *ptr, int bpp)
ptr->instance_count++;
inst = (anim_instance *) vm_malloc(sizeof(anim_instance));
Assert(inst);
memset(inst, 0, sizeof(anim_instance));
inst->frame_num = -1;
inst->last_frame_num = -1;
inst->parent = ptr;
@@ -100,7 +101,12 @@ int anim_get_next_frame(anim_instance *inst)
return -1;
}
bitmap_flags = 0;
if (inst->parent->flags & ANF_XPARENT) {
// bitmap_flags = BMP_XPARENT;
bitmap_flags = 0;
} else {
bitmap_flags = 0;
}
bpp = 16;
if(inst->aa_color != NULL){
@@ -162,16 +168,11 @@ ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap
return inst->frame;
}
/**
* @brief Pack key frame
*
* @param frame Frame pixel data to pack
* @param save Memory to store packed data to
* @param size Number of bytes to pack
* @param max Maximum number of packed bytes (size of buffer)
* @param compress_type Compress type
* @return Actual number of bytes data packed to or -1 if error
*/
// frame = frame pixel data to pack
// save = memory to store packed data to
// size = number of bytes to pack
// max = maximum number of packed bytes (size of buffer)
// returns: actual number of bytes data packed to or -1 if error
int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type)
{
int last = -32768, count = 0;
@@ -256,12 +257,14 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
*save++ = (ubyte)last;
packed_size++;
Assert( last != STD_RLE_CODE );
// printf("Just packed %d 1 times, since pixel change, no count included\n",last);
}
else {
count |= STD_RLE_CODE;
*save++ = (ubyte)count;
*save++ = (ubyte)last;
packed_size += 2;
// printf("Just packed %d %d times, since pixel change\n",last,count);
}
}
@@ -278,6 +281,8 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
*save++ = (ubyte)last;
packed_size += 2;
count = 0;
// printf("Just packed %d %d times, since count overflow\n",last,count);
}
} // end for
@@ -289,6 +294,7 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
*save++ = (ubyte)last;
packed_size++;
// printf("Just packed %d 1 times, at end since single pixel, no count\n",last);
Assert( last != STD_RLE_CODE );
}
else {
@@ -296,6 +302,7 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
*save++ = (ubyte)count;
*save++ = (ubyte)last;
packed_size += 2;
// printf("Just packed %d %d times, at end since pixel change\n",last,count);
}
}
@@ -313,17 +320,12 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
return packed_size;
}
/**
* @brief Pack frame
*
* @param frame Frame pixel data to pack
* @param frame2 Previous frame's pixel data
* @param save Memory to store packed data to
* @param size Number of bytes to pack
* @param max Maximum number of packed bytes (size of buffer)
* @param compress_type Compress type
* @return Actual number of bytes data packed to or -1 if error
*/
// frame = frame pixel data to pack
// frame2 = previous frame's pixel data
// save = memory to store packed data to
// size = number of bytes to pack
// max = maximum number of packed bytes (size of buffer)
// returns: actual number of bytes data packed to or -1 if error
int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
{
int pixel, last = -32768, count = 0, i;
@@ -479,11 +481,7 @@ int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, in
return packed_size;
}
/**
* @brief Convert a 24 bit value to a 16 bit value
* @param bit_24 24 bit value
* @param bit_16 16 bit value (output)
*/
// convert a 24 bit value to a 16 bit value
void convert_24_to_16(int bit_24, ushort *bit_16)
{
ubyte *pixel = (ubyte*)&bit_24;
@@ -492,10 +490,7 @@ void convert_24_to_16(int bit_24, ushort *bit_16)
bm_set_components((ubyte*)bit_16, (ubyte*)&pixel[0], (ubyte*)&pixel[1], (ubyte*)&pixel[2], &alpha);
}
/**
* @brief Unpack a pixel given the passed index and the anim_instance's palette
* @return Bytes stuffed
*/
// unpack a pixel given the passed index and the anim_instance's palette, return bytes stuffed
int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
{
int bit_24;
@@ -544,7 +539,7 @@ int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bp
}
} else {
// stuff the 24 bit value
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3);
// convert to 16 bit
convert_24_to_16(bit_24, &bit_16);
@@ -575,10 +570,7 @@ int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bp
return pixel_size;
}
/**
* @brief Unpack a pixel given the passed index and the anim_instance's palette
* @return Bytes stuffed
*/
// unpack a pixel given the passed index and the anim_instance's palette, return bytes stuffed
int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0, int aabitmap = 0, int bpp = 8)
{
int bit_24;
@@ -628,7 +620,7 @@ int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0,
}
} else {
// stuff the 24 bit value
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3);
// convert to 16 bit
convert_24_to_16(bit_24, &bit_16);
@@ -657,17 +649,10 @@ int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0,
return (pixel_size * count);
}
/**
* @brief Unpack frame
*
* @param ai Animation instance
* @param ptr Packed data to unpack
* @param frame Where to store unpacked data to
* @param size Total number of unpacked pixels requested
* @param pal_translate Color translation lookup table (NULL if no palette translation desired)
* @param aabitmap
* @param bpp
*/
// ptr = packed data to unpack
// frame = where to store unpacked data to
// size = total number of unpacked pixels requested
// pal_translate = color translation lookup table (NULL if no palette translation desired)
ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
{
int xlate_pal, value, count = 0;
@@ -750,6 +735,9 @@ ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte
}
}
else if (*ptr == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
// test code, to show unused pixels
// memset(frame, 255, size);
ptr++;
while (size > 0) {
@@ -840,23 +828,17 @@ ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte
}
}
else {
// unknown packing method
// Assert(0); // unknown packing method
return NULL;
}
return ptr;
}
/**
* @brief Unpack frame from file
*
* @param ai Animation instance
* @param frame Where to store unpacked data to
* @param size Total number of unpacked pixels requested
* @param pal_translate Color translation lookup table (NULL if no palette translation desired)
* @param aabitmap
* @param bpp
*/
// ptr = packed data to unpack
// frame = where to store unpacked data to
// size = total number of unpacked pixels requested
// pal_translate = color translation lookup table (NULL if no palette translation desired)
int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
{
int xlate_pal, value, count = 0;
@@ -946,6 +928,9 @@ int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal
}
}
else if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
// test code, to show unused pixels
// memset(frame, 255, size);
offset++;
while (size > 0) {
@@ -1048,17 +1033,21 @@ int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal
}
/**
* @brief Set animation palette
* @todo Actually convert the frame data to correct palette at this point
*/
// TODO: actually convert the frame data to correct palette at this point
void anim_set_palette(anim *ptr)
{
int i, xparent_found = 0;
// create the palette translation look-up table
for ( i = 0; i < 256; i++ ) {
ptr->palette_translation[i] = (ubyte)i;
//if ( (ptr->palette[i*3] == ptr->xparent_r) && (ptr->palette[i*3+1] == ptr->xparent_g) && (ptr->palette[i*3+2] == ptr->xparent_b) ) {
// ptr->palette_translation[i] = 255;
// xparent_found = 1;
//} else {
// ptr->palette_translation[i] = (ubyte)palette_find( ptr->palette[i*3], ptr->palette[i*3+1], ptr->palette[i*3+2] );
ptr->palette_translation[i] = (ubyte)i;
//}
}
if ( xparent_found ) {
+5 -6
View File
@@ -18,11 +18,11 @@ struct CFILE;
#define ANI_STREAM_CACHE_SIZE 4096
#define PACKER_CODE 0xEE /// Used 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 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
@@ -71,7 +71,6 @@ typedef struct anim {
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)
+214 -319
View File
File diff suppressed because it is too large. Load diff
+35 -43
View File
@@ -22,13 +22,18 @@ 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 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
@@ -44,39 +49,26 @@ typedef struct asteroid_obj {
extern asteroid_obj Asteroid_obj_list;
// Data structure for determining a type and amount of other asteroids an
// asteroid will split to when destroyed.
typedef struct asteroid_split_info {
int asteroid_type;
int min;
int max;
} asteroid_split_info;
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
int damage_type_idx_sav; // stored value from table used to reset damage_type_idx
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
SCP_vector< asteroid_split_info > split_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];
SCP_vector<int> explosion_bitmap_anims;
float fireball_radius_multiplier; // the model radius is multiplied by this to determine the fireball size
asteroid_info( )
: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx( 0 ),
damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
fireball_radius_multiplier( -1 )
{
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 ) );
@@ -86,20 +78,20 @@ typedef struct asteroid_info {
} asteroid_info;
#define AF_USED (1<<0) // Set means used.
#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_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 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().
vec3d death_hit_pos; // hit pos that caused death
int target_objnum; // Yes, hah! Asteroids can have targets. See asteroid_aim_at_target().
} asteroid;
@@ -116,15 +108,15 @@ typedef enum {
} field_type_t;
typedef struct asteroid_field {
vec3d min_bound; // Minimum range of field.
vec3d max_bound; // Maximum range of 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
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;
@@ -136,7 +128,7 @@ extern asteroid_field Asteroid_field;
extern int Num_asteroids;
extern int Asteroids_enabled;
void asteroid_init();
void asteroid_init();
void asteroid_level_init();
void asteroid_level_close();
void asteroid_create_all();
+41 -27
View File
@@ -54,7 +54,7 @@ int camMovingTime;
//float CameraSpeed;
bool CinematicStarted, CameraMoving;
vec3d cameraPos, cameraTarget;
SCP_map<int,int> autopilot_wings;
std::map<int,int> autopilot_wings;
int AutopilotMinEnemyDistance;
int AutopilotMinAsteroidDistance;
@@ -67,7 +67,14 @@ int start_dist;
void autopilot_ai_waypoint_goal_fixup(ai_goal* aigp)
{
// this function sets wp_index properly;
aigp->wp_list = find_matching_waypoint_list(aigp->target_name);
for (int i = 0; i < Num_waypoint_lists; i++)
{
if (!stricmp(aigp->ship_name, Waypoint_lists[i].name))
{
aigp->wp_index = i;
return;
}
}
}
@@ -112,9 +119,7 @@ vec3d *NavPoint::GetPosition()
{
if (flags & NP_WAYPOINT)
{
waypoint *wpt = find_waypoint_at_index((waypoint_list*) target_obj, waypoint_num-1);
Assert(wpt != NULL);
return wpt->get_pos();
return &((waypoint_list*) target_obj)->waypoints[waypoint_num-1];
}
else
{
@@ -122,16 +127,16 @@ vec3d *NavPoint::GetPosition()
}
}
char* NavPoint::GetInternalName()
char* NavPoint::GetInteralName()
{
char *NavName;
char strtmp[33];
if (flags & NP_WAYPOINT)
{
NavName = new char[strlen(((waypoint_list*)target_obj)->get_name())+5];
memset(NavName, 0, strlen(((waypoint_list*)target_obj)->get_name())+5);
strcpy(NavName, ((waypoint_list*)target_obj)->get_name());
NavName = new char[strlen(((waypoint_list*)target_obj)->name)+5];
memset(NavName, 0, strlen(((waypoint_list*)target_obj)->name)+5);
strcpy(NavName, ((waypoint_list*)target_obj)->name);
strcat(NavName, ":");
sprintf(strtmp, "%d", waypoint_num);
@@ -367,7 +372,8 @@ bool StartAutopilot()
{
capshipPresent = true;
capIndexes.push_back(i);
capIndexes.resize(capIndexes.size()+1);
capIndexes[capIndexes.size()-1] = i;
// ok.. what size class
if (Ship_info[Ships[i].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
@@ -472,7 +478,7 @@ bool StartAutopilot()
{
if (Navs[CurrentNav].flags & NP_WAYPOINT)
{
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name(), &Ai_info[Ships[i].ai_index] );
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->name, &Ai_info[Ships[i].ai_index] );
//fixup has to wait until after wing goals
}
else
@@ -501,7 +507,7 @@ bool StartAutopilot()
if (Navs[CurrentNav].flags & NP_WAYPOINT)
{
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name(), i );
ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->name, i );
// "fix up" the goal
for (j = 0; j < MAX_AI_GOALS; j++)
@@ -553,13 +559,13 @@ bool StartAutopilot()
// position capships
vec3d right, front, up, offset;
for (SCP_vector<int>::iterator idx = capIndexes.begin(); idx != capIndexes.end(); ++idx)
for (i = 0; i < (int)capIndexes.size(); i++)
{
vm_vec_add(&right, &Autopilot_flight_leader->orient.vec.rvec, &zero);
vm_vec_add(&front, &Autopilot_flight_leader->orient.vec.fvec, &zero);
vm_vec_add(&up, &Autopilot_flight_leader->orient.vec.uvec, &zero);
vm_vec_add(&offset, &zero, &zero);
if (Ship_info[Ships[*idx].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
if (Ship_info[Ships[capIndexes[i]].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
{
//0 - below - three lines of position
@@ -593,7 +599,7 @@ bool StartAutopilot()
capship_placed[0]++;
}
else if (Ship_info[Ships[*idx].ship_info_index].flags & SIF_CORVETTE)
else if (Ship_info[Ships[capIndexes[i]].ship_info_index].flags & SIF_CORVETTE)
{
//1 above - 3 lines of position
// front/back to zero
@@ -702,7 +708,7 @@ bool StartAutopilot()
// global scale the position by 50%
//vm_vec_scale(&offset, 1.5);
vm_vec_add(&Objects[Ships[*idx].objnum].pos, &Autopilot_flight_leader->pos, &offset);
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Autopilot_flight_leader->pos, &offset);
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
{
@@ -884,7 +890,7 @@ void EndAutoPilot()
if (Navs[CurrentNav].flags & NP_WAYPOINT)
{
goal = AI_GOAL_WAYPOINTS_ONCE;
goal_name = ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name();
goal_name = ((waypoint_list*)Navs[CurrentNav].target_obj)->name;
}
else
{
@@ -917,7 +923,7 @@ void EndAutoPilot()
{
ai_goal *aigp = &Ai_info[Ships[i].ai_index].goals[j];
if ( ((aigp->target_name != NULL) && !stricmp(aigp->target_name, goal_name))
if ( ((aigp->ship_name != NULL) && !stricmp(aigp->ship_name, goal_name))
&& (aigp->ai_mode == goal) )
{
ai_remove_ship_goal(&Ai_info[Ships[i].ai_index], j);
@@ -930,7 +936,7 @@ void EndAutoPilot()
{
ai_goal *aigp = &Wings[Ships[i].wingnum].ai_goals[j];
if ( ((aigp->target_name != NULL) && !stricmp(aigp->target_name, goal_name))
if ( ((aigp->ship_name != NULL) && !stricmp(aigp->ship_name, goal_name))
&& (aigp->ai_mode == goal) )
{
aigp->ai_mode = AI_GOAL_NONE;
@@ -954,7 +960,7 @@ void EndAutoPilot()
{
ai_goal *aigp = &Wings[i].ai_goals[j];
if ( ((aigp->target_name != NULL) && !stricmp(aigp->target_name, goal_name))
if ( ((aigp->ship_name != NULL) && !stricmp(aigp->ship_name, goal_name))
&& (aigp->ai_mode == goal) )
{
aigp->ai_mode = AI_GOAL_NONE;
@@ -1213,11 +1219,11 @@ void send_autopilot_msg(char *msg, char *snd)
audio_handle = -1;
}
if (msg[0] != '\0' && strcmp(msg, "none"))
if (strlen(msg) != 0 && strcmp(msg, "none"))
change_message("autopilot builtin message", msg, -1, 0);
// load sound
if ((snd != NULL) && (snd[0] != '\0' && !strcmp(snd, "none")))
if (snd != NULL || strlen(snd) == 0 || !strcmp(snd, "none"))
{
audio_handle = audiostream_open(snd, ASF_MENUMUSIC );
}
@@ -1228,7 +1234,7 @@ void send_autopilot_msg(char *msg, char *snd)
audiostream_play(audio_handle, (Master_event_music_volume * aav_music_volume), 0);
}
if (msg[0] != '\0' && strcmp(msg, "none"))
if (strlen(msg) != 0 && strcmp(msg, "none"))
message_training_queue("autopilot builtin message", timestamp(0), 5); // display message for five seconds
}
@@ -1255,7 +1261,7 @@ void NavSystem_Init()
void parse_autopilot_table(char *filename)
{
int rval;
SCP_vector<SCP_string> lines;
SCP_vector<std::string> lines;
// open localization
lcl_ext_open();
@@ -1448,7 +1454,15 @@ bool AddNav_Waypoint(char *Nav, char *WP_Path, int node, int flags)
Assert(!(tnav.flags & NP_SHIP));
tnav.target_obj = find_matching_waypoint_list(WP_Path);
for (i = 0; i < Num_waypoint_lists; i++)
{
if (!stricmp(WP_Path, Waypoint_lists[i].name))
{
tnav.target_obj = (void *)&Waypoint_lists[i];
}
}
tnav.waypoint_num = node;
// copy it into it's location
@@ -1580,7 +1594,7 @@ unsigned int DistanceTo(char *nav)
unsigned int DistanceTo(int nav)
{
if (nav >= MAX_NAVPOINTS || nav < 0)
if (nav >= MAX_NAVPOINTS && nav < 0)
return 0xFFFFFFFF;
return (uint)vm_vec_dist_quick(&Player_obj->pos, Navs[nav].GetPosition());
@@ -1597,7 +1611,7 @@ bool IsVisited(char *nav)
bool IsVisited(int nav)
{
if (nav >= MAX_NAVPOINTS || nav < 0)
if (nav >= MAX_NAVPOINTS && nav < 0)
return 0;
if (Navs[nav].flags & NP_VISITED)
+4 -4
View File
@@ -16,8 +16,8 @@
#define MAX_NAVPOINTS 8
#define NP_WAYPOINT 0x0001 // Nav Point is bound to the position of a single node of a waypoint path
#define NP_SHIP 0x0002 // Nav Point is bound to the position of a certain ship
#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
@@ -34,7 +34,7 @@ struct NavPoint
int waypoint_num; //only used when flags & NP_WAYPOINT
vec3d *GetPosition();
char* GetInternalName();
char* GetInteralName();
};
@@ -59,7 +59,7 @@ extern int CurrentNav;
extern NavPoint Navs[MAX_NAVPOINTS];
extern NavMessage NavMsgs[NP_NUM_MESSAGES];
extern int LockAPConv;
extern SCP_map<int,int> autopilot_wings;
extern std::map<int,int> autopilot_wings;
// Cycles through the NavPoint List
bool Sel_NextNav();
+2 -2
View File
@@ -53,9 +53,9 @@ 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
int keyframe; // used for animation -- keyframe info
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
+165 -213
View File
@@ -17,8 +17,6 @@
#include <windows.h> // for MAX_PATH
#endif
#include <limits.h> // for MAX_INT
#include "bmpman/bmpman.h"
#include "pcxutils/pcxutils.h"
#include "palman/palman.h"
@@ -62,7 +60,7 @@ int Bm_paging = 0;
// locals
static unsigned int Bm_next_signature = 0x1234;
static int bm_next_handle = 1;
static int bm_next_handle = 0;
int Bm_low_mem = 0;
// Bm_max_ram - How much RAM bmpman can use for textures.
// Set to <1 to make it use all it wants.
@@ -80,33 +78,23 @@ static int Bm_ignore_load_count = 0;
// 2 = Debug low memory ( only use first frame of each ani )
void bm_set_low_mem( int mode )
{
Assert( (mode >= 0) && (mode<=2) );
CLAMP(mode, 0, 2);
Assert( (mode >= 0) && (mode<=2 ));
Bm_low_mem = mode;
}
int bm_get_next_handle()
{
//bm_next_handle used to wrap around to 1 if it was over 30000. Now, believe it or not, but that is actually not uncommon;
//as bitmaps get allocated and released, bm_next_handle could get there far more often than you'd think.
//The check introduced below is intended to replace this behaviour with one that ensures we won't be seeing handle collisions
//for a very long time.
int n = bm_next_handle;
bm_next_handle++;
//Due to the way bm_next_handle is used to generate the /actual/ bitmap handles ( (bm_next_handle * MAX_BITMAPS) + free slot index in bm_bitmaps[]),
//this check is necessary to ensure we don't start giving out negative handles all of a sudden.
if (( (bm_next_handle + 1) * MAX_BITMAPS) > INT_MAX)
if ( bm_next_handle > 30000 ) {
bm_next_handle = 1;
return bm_next_handle;
}
return n;
}
/**
* Frees a bitmaps data if it can
*/
// Frees a bitmaps data if it should, and
// Returns true if bitmap n can free it's data.
static void bm_free_data(int n, bool release = false)
{
bitmap_entry *be;
@@ -121,12 +109,12 @@ static void bm_free_data(int n, bool release = false)
// If there isn't a bitmap in this structure, don't
// do anything but clear out the bitmap info
if (be->type==BM_TYPE_NONE)
if ( be->type==BM_TYPE_NONE)
goto SkipFree;
// Don't free up memory for user defined bitmaps, since
// BmpMan isn't the one in charge of allocating/deallocing them.
if (be->type==BM_TYPE_USER) {
if ( ( be->type==BM_TYPE_USER ) ) {
#ifdef BMPMAN_NDEBUG
if ( be->data_size != 0 )
bm_texture_ram -= be->data_size;
@@ -136,7 +124,7 @@ static void bm_free_data(int n, bool release = false)
// If this bitmap doesn't have any data to free, skip
// the freeing it part of this.
if (bmp->data == 0) {
if ( (bmp->data == 0) ) {
#ifdef BMPMAN_NDEBUG
if ( be->data_size != 0 )
bm_texture_ram -= be->data_size;
@@ -145,6 +133,8 @@ static void bm_free_data(int n, bool release = false)
}
// Free up the data now!
// mprintf(( "Bitmap %d freed %d bytes\n", n, bm_bitmaps[n].data_size ));
#ifdef BMPMAN_NDEBUG
bm_texture_ram -= be->data_size;
#endif
@@ -164,16 +154,13 @@ SkipFree:
#ifdef BMPMAN_NDEBUG
be->data_size = 0;
#endif
be->signature = Bm_next_signature++;
be->signature = Bm_next_signature++;
}
/**
* A special version of bm_free_data() that can be safely used in gr_*_texture
* to save system memory once textures have been transfered to API memory
* it doesn't restore the slot to a pristine state, it only releases the data
*
* NOTE: THIS SHOULD ONLY BE USED FROM bm_unload_fast()!!!
*/
// a special version of bm_free_data() that can be safely used in gr_*_texture
// to save system memory once textures have been transfered to API memory
// it doesn't restore the slot to a pristine state, it only releases the data
// NOTE: THIS SHOULD ONLY BE USED FROM bm_unload_fast()!!!
static void bm_free_data_fast(int n)
{
bitmap_entry *be;
@@ -186,12 +173,12 @@ static void bm_free_data_fast(int n)
// If there isn't a bitmap in this structure, don't
// do anything but clear out the bitmap info
if (be->type == BM_TYPE_NONE)
if ( be->type == BM_TYPE_NONE)
return;
// Don't free up memory for user defined bitmaps, since
// BmpMan isn't the one in charge of allocating/deallocing them.
if (be->type == BM_TYPE_USER) {
if ( ( be->type == BM_TYPE_USER ) ) {
#ifdef BMPMAN_NDEBUG
if ( be->data_size != 0 )
bm_texture_ram -= be->data_size;
@@ -201,7 +188,7 @@ static void bm_free_data_fast(int n)
// If this bitmap doesn't have any data to free, skip
// the freeing it part of this.
if (bmp->data == 0) {
if ( (bmp->data == 0) ) {
#ifdef BMPMAN_NDEBUG
if ( be->data_size != 0 ) {
bm_texture_ram -= be->data_size;
@@ -212,6 +199,8 @@ static void bm_free_data_fast(int n)
}
// Free up the data now!
// mprintf(( "Bitmap %d freed %d bytes\n", n, bm_bitmaps[n].data_size ));
#ifdef BMPMAN_NDEBUG
bm_texture_ram -= be->data_size;
be->data_size = 0;
@@ -240,12 +229,11 @@ void *bm_malloc( int n, int size )
bm_texture_ram += size;
#endif
// mprintf(( "Bitmap %d allocated %d bytes\n", n, size ));
return vm_malloc(size);
}
/**
* Like bm_malloc but only keeps track of how much memory is getting used
*/
// kinda like bm_malloc but only keeps track of how much memory is getting used
void bm_update_memory_used( int n, int size )
{
Assert( (n >= 0) && (n < MAX_BITMAPS) );
@@ -306,11 +294,9 @@ void bm_init()
}
}
/**
* Returns number of bytes of bitmaps locked this frame
* @param ntotal number of bytes of bitmaps locked this frame
* @param nnew number of bytes of bitmaps locked this frame that weren't locked last frame
*/
// 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)
{
#ifdef BMPMAN_NDEBUG
@@ -332,17 +318,12 @@ void bm_get_frame_usage(int *ntotal, int *nnew)
#endif
}
/**
* Creates a bitmap that exists in RAM somewhere, instead
* of coming from a disk file.
*
* You pass in a pointer to a block of 32 (or 8)-bit-per-pixel data.
* Right now, the only bpp you can pass in is 32 or 8.
*
* On success, it returns the bitmap number.
*
* You cannot free that RAM until bm_release is called on that bitmap.
*/
// Creates a bitmap that exists in RAM somewhere, instead
// of coming from a disk file. You pass in a pointer to a
// block of 32 (or 8)-bit-per-pixel data. Right now, the only
// bpp you can pass in is 32 or 8. On success, it returns the
// bitmap number. You cannot free that RAM until bm_release
// is called on that bitmap.
int bm_create( int bpp, int w, int h, void *data, int flags )
{
if (bpp == 8) {
@@ -408,12 +389,10 @@ int bm_create( int bpp, int w, int h, void *data, int flags )
return bm_bitmaps[n].handle;
}
/**
* Given a raw filename and an extension set, try and find the bitmap
* that isn't already loaded and may exist somewhere on the disk
*
* @return -1 if it could not be found index into ext_list[] if it was found as a file, fills img_cfg if available
*/
// slow sub helper function. Given a raw filename and an extension set, try and find the bitmap
// that isn't already loaded and may exist somewhere on the disk
// returns -1 if it could not be found
// index into ext_list[] if it was found as a file, fills img_cfg if available
int bm_load_sub_slow(char *real_filename, const int num_ext, const char **ext_list, CFILE **img_cfp = NULL, int dir_type = CF_TYPE_ANY)
{
char full_path[MAX_PATH];
@@ -439,10 +418,10 @@ int bm_load_sub_slow(char *real_filename, const int num_ext, const char **ext_li
return -1;
}
/**
* Given a raw filename, try and find a bitmap that's already loaded
* @return 0 if it could not be found, 1 if it already exists, fills in handle
*/
// fast sub helper function. Given a raw filename, try and find a bitmap
// that's already loaded
// returns 0 if it could not be found
// 1 if it already exists, fills in handle
int bm_load_sub_fast(char *real_filename, int *handle, int dir_type = CF_TYPE_ANY, bool animated_type = false)
{
if (Bm_ignore_duplicates)
@@ -476,13 +455,11 @@ int bm_load_sub_fast(char *real_filename, int *handle, int dir_type = CF_TYPE_AN
return 0;
}
/**
* Loads a bitmap so we can draw with it later.
* Function doesn't actually load the data, only width, height, and possibly flags.
*
* @return A negative number if it couldn't load the bitmap.
* @return On success, it returns the bitmap number.
*/
// 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. Function doesn't actually load the data, only
// width, height, and possibly flags.
int bm_load( char *real_filename )
{
int i, free_slot = -1;
@@ -508,6 +485,7 @@ int bm_load( char *real_filename )
char *p = strrchr( filename, '.' );
if ( p ) {
mprintf(( "Someone passed an extension to bm_load for file '%s'\n", real_filename ));
//Int3();
*p = 0;
}
@@ -604,20 +582,9 @@ Done:
return handle;
}
/**
* Same as bm_load above, just with an SCP_string
*/
int bm_load(const SCP_string& filename)
{
return bm_load(const_cast<char*> (filename.c_str()));
}
/**
* 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
*/
// 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)
{
int ret;
@@ -701,6 +668,7 @@ static int find_block_of(int n)
return nstart;
}
// Error( LOCATION, "Couldn't find block of %d frames\n", n );
return -1;
}
@@ -709,8 +677,8 @@ int bm_load_and_parse_eff(char *filename, int dir_type, int *nframes, int *nfps,
int frames = 0, fps = 30, keyframe = 0, rval;
char ext[8];
ubyte c_type = BM_TYPE_NONE;
char file_text[1024];
char file_text_raw[1024];
char file_text[50];
char file_text_raw[50];
memset( ext, 0, sizeof(ext) );
memset( file_text, 0, sizeof(file_text) );
@@ -780,18 +748,15 @@ int bm_load_and_parse_eff(char *filename, int dir_type, int *nframes, int *nfps,
return 0;
}
/**
* Load animation
*
* @param real_filename filename of animation
* @param nframes OUTPUT parameter: number of frames in the animation
* @param fps OUTPUT/OPTIONAL parameter: intended fps for the animation
* @param keyframe Keyframe number
* @param can_drop_frames Toggle to allow dropped frames
* @param dir_type Directory type
*
* @returns Bitmap number of first frame in the animation
*/
// ------------------------------------------------------------------
// bm_load_animation()
//
// input: filename => filename of animation
// nframes => OUTPUT parameter: number of frames in the animation
// fps => OUTPUT/OPTIONAL parameter: intended fps for the animation
//
// returns: bitmap number of first frame in the animation
//
int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type)
{
int i, n;
@@ -826,6 +791,7 @@ int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyfram
char *p = strchr( filename, '.' );
if ( p ) {
mprintf(( "Someone passed an extension to bm_load_animation for file '%s'\n", real_filename ));
//Int3();
*p = 0;
}
@@ -921,8 +887,8 @@ int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyfram
the_anim.keys[i].frame_num = 0;
cfread(&the_anim.keys[i].frame_num, 2, 1, img_cfp);
cfread(&the_anim.keys[i].offset, 4, 1, img_cfp);
the_anim.keys[i].frame_num = INTEL_INT( the_anim.keys[i].frame_num ); //-V570
the_anim.keys[i].offset = INTEL_INT( the_anim.keys[i].offset ); //-V570
the_anim.keys[i].frame_num = INTEL_INT( the_anim.keys[i].frame_num );
the_anim.keys[i].offset = INTEL_INT( the_anim.keys[i].offset );
}
//some retail anis have their keyframes reversed
key = MAX(the_anim.keys[0].frame_num, the_anim.keys[1].frame_num);
@@ -979,8 +945,8 @@ int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyfram
anim_frames = i;
// update all previous frames with the new count
for (int j=0; j<anim_frames; j++)
bm_bitmaps[n+j].info.ani.num_frames = anim_frames;
for (i=0; i<anim_frames; i++)
bm_bitmaps[n+i].info.ani.num_frames = anim_frames;
break;
}
@@ -1065,10 +1031,7 @@ int bm_is_valid(int handle)
return (bm_bitmaps[handle % MAX_BITMAPS].handle == handle);
}
/**
* Gets info.
* w,h,flags,nframes or fps can be NULL if you don't care.
*/
// Gets info. w,h,or flags,nframes or fps can be NULL if you don't care.
int bm_get_info( int handle, int *w, int * h, ubyte * flags, int *nframes, int *fps)
{
bitmap * bmp;
@@ -1131,9 +1094,7 @@ unsigned int bm_get_signature(int handle)
return bm_bitmaps[bitmapnum].signature;
}
/**
* Gets the image type
*/
//gets the image type
ubyte bm_get_type(int handle)
{
if ( !bm_inited ) bm_init();
@@ -1144,6 +1105,7 @@ ubyte bm_get_type(int handle)
return bm_bitmaps[bitmapnum].type;
}
extern int palman_is_nondarkening(int r,int g, int b);
static void bm_convert_format( int bitmapnum, bitmap *bmp, ubyte bpp, ubyte flags )
{
int idx;
@@ -1239,14 +1201,12 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
nframes = bm_bitmaps[first_frame].info.ani.num_frames;
if ( (the_anim = anim_load(bm_bitmaps[first_frame].filename, bm_bitmaps[first_frame].dir_type)) == NULL ) {
nprintf(("BMPMAN", "Error opening %s in bm_lock\n", be->filename));
return;
// Error(LOCATION, "Error opening %s in bm_lock\n", be->filename);
}
if ( (the_anim_instance = init_anim_instance(the_anim, bpp)) == NULL ) {
nprintf(("BMPMAN", "Error opening %s in bm_lock\n", be->filename));
// Error(LOCATION, "Error opening %s in bm_lock\n", be->filename);
anim_free(the_anim);
return;
}
int can_drop_frames = 0;
@@ -1275,7 +1235,11 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
bm->data = (ptr_u)bm_malloc(first_frame + i, size);
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0 ,flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0 ,flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
if ( frame_data == NULL ) {
// Error(LOCATION,"Fatal error locking .ani file: %s\n", be->filename);
}
ubyte *dptr, *sptr;
@@ -1284,6 +1248,8 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
if ( (bm->w!=the_anim->width) || (bm->h!=the_anim->height) ) {
// Scale it down
// Int3(); // not ready yet - should only be ingame
// 8 bit
if(bpp == 8){
int w,h;
@@ -1341,6 +1307,8 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
if ( (i < nframes-1) && can_drop_frames ) {
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0, flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
}
//mprintf(( "Checksum = %d\n", be->palette_checksum ));
}
free_anim_instance(the_anim_instance);
@@ -1383,8 +1351,9 @@ void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, uby
break;
default:
Error( LOCATION, "Unhandled user bitmap conversion from %d to %d bpp", be->info.user.bpp, bmp->bpp );
Int3();
break;
// Error( LOCATION, "Unhandled user bitmap conversion from %d to %d bpp", be->info.user.bpp, bmp->bpp );
}
bm_convert_format( bitmapnum, bmp, bpp, flags );
@@ -1407,6 +1376,9 @@ void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
Assert( (bpp == 16) || (bpp == 24 ) || (bpp == 32) );
}
// should never try to make an aabitmap out of a targa
Assert(!(flags & BMP_AABITMAP));
// allocate bitmap data
byte_size = (bpp >> 3);
@@ -1449,9 +1421,7 @@ void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
bm_convert_format( bitmapnum, bmp, bpp, flags );
}
/**
* Lock a DDS file
*/
//lock a dds file
void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
{
ubyte *data = NULL;
@@ -1515,9 +1485,7 @@ void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
#endif
}
/**
* Lock a PNG file
*/
// lock a PNG file
void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
{
ubyte *data = NULL;
@@ -1525,10 +1493,14 @@ void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
int d_size;
int png_error = PNG_ERROR_INVALID;
char filename[MAX_FILENAME_LEN];
//int size = bmp->w * bmp->h * d_size;
// Unload any existing data
bm_free_data( bitmapnum );
// should never try to make an aabitmap out of a png
Assert(!(flags & BMP_AABITMAP));
// allocate bitmap data
Assert( bmp->w * bmp->h > 0 );
@@ -1562,9 +1534,7 @@ void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
#endif
}
/**
* Lock a JPEG file
*/
// lock a JPEG file
void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
{
ubyte *data = NULL;
@@ -1575,6 +1545,9 @@ void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
// Unload any existing data
bm_free_data( bitmapnum );
// should never try to make an aabitmap out of a jpeg
Assert(!(flags & BMP_AABITMAP));
d_size = (bpp >> 3);
// allocate bitmap data
@@ -1611,11 +1584,10 @@ void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
MONITOR( NumBitmapPage )
MONITOR( SizeBitmapPage )
/**
* 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.
*/
// 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.
bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
{
bitmap *bmp;
@@ -1627,6 +1599,8 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid handle %d passed to bm_lock. This might be due to an animation elsewhere in the code being too short.\n", handle ); // INVALID BITMAP HANDLE
// flags &= (~BMP_RLE);
// to fix a couple of OGL bpp passes, force 8bit on AABITMAP - taylor
if (flags & BMP_AABITMAP)
bpp = 8;
@@ -1715,12 +1689,11 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
return bmp;
}
/**
* Unlocks a bitmap
*
* Decrements the ref_count member of the bitmap_entry struct. A bitmap can only be unloaded
* when the ref_count is 0.
*/
// Unlocks a bitmap
//
// Decrements the ref_count member of the bitmap_entry struct. A bitmap can only be unloaded
// when the ref_count is 0.
//
void bm_unlock( int handle )
{
bitmap_entry *be;
@@ -1747,6 +1720,11 @@ void bm_unlock( int handle )
Assert(be->ref_count >= 0); // Trying to unlock data more times than lock was called!!!
}
void bm_update()
{
}
char *bm_get_filename(int handle)
{
int n;
@@ -1776,19 +1754,16 @@ void bm_get_palette(int handle, ubyte *pal, char *name)
}
}
/**
* Unloads the bitmap's data and entire slot, so bitmap 'handle' won't be valid anymore
* NOTE: this releases the slot of EVERY frame in an ANI so don't pass any frame but the first
*
* @param handle index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
* @param clear_render_targets Whether to release a render target
*
* @return 1 on successful release, 0 otherwise
*/
// --------------------------------------------------------------------------------------
// bm_release() - unloads the bitmap's data and entire slot, so bitmap 'n' won't be valid anymore
// NOTE: this releases the slot of EVERY frame in an ANI so don't pass any frame but the first
//
// parameters: n => index into bm_bitmaps ( index returned from bm_load() or bm_create() )
//
// returns: 1 on successful release, 0 otherwise
int bm_release(int handle, int clear_render_targets)
{
Assert(handle >= 0);
bitmap_entry *be;
int n = handle % MAX_BITMAPS;
@@ -1882,14 +1857,14 @@ int bm_release(int handle, int clear_render_targets)
return 1;
}
/**
* Unloads the data, but not the bitmap info.
*
* @param handle index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
* @param clear_render_targets Whether to release a render target
*
* @return 1 on successful release, 0 otherwise
*/
// --------------------------------------------------------------------------------------
// bm_unload() - unloads the data, but not the bitmap info.
//
// parameters: n => index into bm_bitmaps ( index returned from bm_load() or bm_create() )
//
// returns: 0 => unload failed
// 1 => unload successful
//
int bm_unload( int handle, int clear_render_targets )
{
bitmap_entry *be;
@@ -1951,12 +1926,9 @@ int bm_unload( int handle, int clear_render_targets )
return 1;
}
/**
* Just like bm_unload() except that it doesn't care about what load_count is
* and will just plow through and release the data anyway
*
* NOTE: that bm_free_data_fast() is used here and NOT bm_free_data()!
*/
// just like bm_unload() except that it doesn't care about what load_count is
// and will just plow through and release the data anyway
// (NOTE that bm_free_data_fast() is used here and NOT bm_free_data()!)
int bm_unload_fast( int handle, int clear_render_targets )
{
bitmap_entry *be;
@@ -1964,6 +1936,7 @@ int bm_unload_fast( int handle, int clear_render_targets )
int n = handle % MAX_BITMAPS;
Assert( (n >= 0) && (n < MAX_BITMAPS) );
be = &bm_bitmaps[n];
bmp = &be->bm;
@@ -1995,9 +1968,7 @@ int bm_unload_fast( int handle, int clear_render_targets )
return 1;
}
/**
* Unload all used bitmaps
*/
// unload all used bitmaps
void bm_unload_all()
{
int i;
@@ -2063,9 +2034,7 @@ DCF(bmpman,"Shows/changes bitmap caching parameters and usage")
}
}
/**
* Marks a texture as being used for this level
*/
// Marks a texture as being used for this level
void bm_page_in_texture( int bitmapnum, int nframes )
{
int i;
@@ -2117,12 +2086,9 @@ void bm_page_in_texture( int bitmapnum, int nframes )
}
}
/**
* Marks a texture as being a transparent texture used for this level
*
* @param bitmapnum Index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
* @param nframes Animation number of frames
*/
// 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 nframes)
{
int i;
@@ -2167,12 +2133,7 @@ void bm_page_in_xparent_texture( int bitmapnum, int nframes)
}
}
/**
* Marks an aabitmap as being used for this level
*
* @param bitmapnum Index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
* @param nframes Animation number of frames
*/
// Marks an aabitmap as being used for this level
void bm_page_in_aabitmap( int bitmapnum, int nframes )
{
int i;
@@ -2192,9 +2153,9 @@ void bm_page_in_aabitmap( int bitmapnum, int nframes )
}
}
/**
* Tell the bitmap manager to start keeping track of what bitmaps are used where.
*/
// Tell the bitmap manager to start keeping track of what bitmaps are used where.
void bm_page_in_start()
{
int i;
@@ -2292,13 +2253,12 @@ void bm_page_in_stop()
}
mprintf(( "Bmpman: %d/%d bitmap slots in use.\n", total_bitmaps, MAX_BITMAPS ));
//mprintf(( "Bmpman: Usage went from %d KB to %d KB.\n", usage_before/1024, usage_after/1024 ));
Bm_paging = 0;
}
/**
* For unloading bitmaps while a mission is going
*/
// for unloading bitmaps while a mission is going
int bm_page_out( int bitmap_id )
{
int n = bitmap_id % MAX_BITMAPS;
@@ -2309,6 +2269,7 @@ int bm_page_out( int bitmap_id )
if ( bm_bitmaps[n].type == BM_TYPE_NONE )
return 0;
Assert( bm_bitmaps[n].handle == bitmap_id ); // INVALID BITMAP HANDLE
// it's possible to hit < 0 here when model_page_out_textures() is called from
@@ -2394,9 +2355,7 @@ void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv
*((unsigned int*)pixel) |= (unsigned int)(Gr_current_alpha->mask);
}
/**
* For selecting pixel formats
*/
// for selecting pixel formats
void BM_SELECT_SCREEN_FORMAT()
{
Gr_current_red = &Gr_red;
@@ -2436,9 +2395,7 @@ void BM_SELECT_ALPHA_TEX_FORMAT()
bm_set_components = bm_set_components_argb_16_tex;
}
/**
* Get the rgba components of a pixel, any of the parameters can be NULL
*/
// 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)
{
int bit_32 = 0;
@@ -2447,6 +2404,7 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
bit_32 = 1;
}
if(r != NULL){
if(bit_32){
*r = ubyte(( (*((unsigned int*)pixel) & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale);
@@ -2454,7 +2412,6 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
*r = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale);
}
}
if(g != NULL){
if(bit_32){
*g = ubyte(( (*((unsigned int*)pixel) & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale);
@@ -2462,7 +2419,6 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
*g = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale);
}
}
if(b != NULL){
if(bit_32){
*b = ubyte(( (*((unsigned int*)pixel) & Gr_current_blue->mask)>>Gr_current_blue->shift)*Gr_current_blue->scale);
@@ -2482,9 +2438,7 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
}
}
/**
* Get filename
*/
// get filename
void bm_get_filename(int bitmapnum, char *filename)
{
if(!bm_is_valid(bitmapnum))
@@ -2499,9 +2453,7 @@ void bm_get_filename(int bitmapnum, char *filename)
strcpy(filename, bm_bitmaps[n].filename);
}
/**
* Needed only for compressed bitmaps
*/
// needed only for compressed bitmaps
int bm_is_compressed(int num)
{
int n = num % MAX_BITMAPS;
@@ -2557,17 +2509,17 @@ int bm_has_alpha_channel(int handle)
return (bm_bitmaps[n].bm.true_bpp == 32);
}
/**
* Purpose for this is to return the correct TCACHE_TYPE for compressed graphics,
* uncompressed graphics are assumed to be of type NORMAL.
*
* The only other real format to check for is TCACHE_TYPE_SECTIONED - taylor
*/
// the only real purpose for this is to return the correct TCACHE_TYPE for compressed graphics,
// uncompressed graphics are assumed to be of type NORMAL. The only other real format to check
// for is TCACHE_TYPE_SECTIONED - taylor
int bm_get_tcache_type(int num)
{
if ( bm_is_compressed(num) )
return TCACHE_TYPE_COMPRESSED;
// if ( bm_is_render_target(num) )
// return TCACHE_TYPE_RENDER_TARGET;
return TCACHE_TYPE_NORMAL;
}
@@ -2594,9 +2546,7 @@ int bm_get_num_mipmaps(int num)
return bm_bitmaps[n].num_mipmaps;
}
/**
* Convert an 8-bit (256 color) image to a 24-bit BGR image sending new bitmap data to "out_data"
*/
// convert an 8-bit (256 color) image to a 24-bit BGR image sending new bitmap data to "out_data"
int bm_convert_color_index_to_BGR(int num, ubyte **out_data)
{
int n = num % MAX_BITMAPS;
@@ -2679,10 +2629,8 @@ int bm_convert_color_index_to_BGR(int num, ubyte **out_data)
return 0;
}
/**
* List of all bitmaps loaded, but not necessarily in memory
* used to debug bmpman after a mission load
*/
// list of all bitmaps loaded, but not necessarily in memory
// used to debug bmpman after a mission load
void bm_print_bitmaps()
{
#ifdef BMPMAN_NDEBUG
@@ -2701,11 +2649,12 @@ void bm_print_bitmaps()
#endif
}
// this will create a render target as close to the desired resolution as possable of the following base types:
// this will create a render target as close to the desiered resolution as posable of the following base types:
// - BMP_FLAG_RENDER_TARGET_STATIC
// static render targets are ones that you intend to draw to once or not very often in game
// - BMP_FLAG_RENDER_TARGET_DYNAMIC
// dynamic render targets are ones that you will be drawing to all the time (like once per frame)
int bm_make_render_target( int width, int height, int flags )
{
int i, n;
@@ -2730,9 +2679,11 @@ int bm_make_render_target( int width, int height, int flags )
if ( n == -1 )
return -1;
if ( !gr_bm_make_render_target(n, &w, &h, &bpp, &mm_lvl, flags) )
return -1;
Assert( mm_lvl > 0 );
if (flags & BMP_FLAG_RENDER_TARGET_STATIC) {
@@ -2775,6 +2726,7 @@ int bm_make_render_target( int width, int height, int flags )
if (bm_bitmaps[n].mem_taken) {
bm_bitmaps[n].bm.data = (ptr_u) bm_malloc(n, bm_bitmaps[n].mem_taken);
}
// bm_update_memory_used( n, bm_bitmaps[n].mem_taken );
return bm_bitmaps[n].handle;
}
@@ -2808,7 +2760,7 @@ int bm_set_render_target(int handle, int face)
if ( gr_bm_set_render_target(n, face) ) {
if (gr_screen.rendering_to_texture == -1) {
//if we are moving from the back buffer to a texture save whatever the current settings are
//if we are moveing from the back buffer to a texture save whatever the current settings are
gr_screen.save_max_w = gr_screen.max_w;
gr_screen.save_max_h = gr_screen.max_h;
}
+8 -1
View File
@@ -19,6 +19,11 @@
#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
@@ -89,7 +94,6 @@ extern int bm_texture_ram;
// the bitmap. On success, it returns the bitmap
// number.
int bm_load(char * filename);
int bm_load(const SCP_string& 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
@@ -156,6 +160,9 @@ int bm_get_info( int bitmapnum, int *w=NULL, int * h=NULL, ubyte * flags=NULL, i
// 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();
+217 -37
View File
@@ -24,12 +24,16 @@ SCP_vector<camera*> Cameras;
camid Current_camera;
camid Main_camera;
//*************************INTERNAL FUNCS*************************
//static avd_camera *cam_upgrade_to_avd(camera *cam);
//*************************CLASS: camera*************************
//This is where the camera class beings! :D
camera::camera(char *in_name, int in_signature)
{
set_name(in_name);
sig = in_signature;
// flags = CAM_DEFAULT_FLAGS;
reset();
}
@@ -71,11 +75,31 @@ void camera::reset()
pos_y.clear();
pos_z.clear();
/*
ori_p.clear();
ori_b.clear();
ori_h.clear();
*/
/*
ori_progress.clear();
ori_initial = ori_final = vmd_identity_matrix;
*/
for(int i = 0; i < 9; i++)
{
ori[i].clear();
ori[i].set(vmd_identity_matrix.a1d[i]);
}
/*
flags = CAM_DEFAULT_FLAGS;
desired_position = position = vmd_zero_vector;
translation_velocity = translation_vel_limit = translation_acc_limit = vmd_zero_vector;
vm_set_identity(&orientation);
vm_set_identity(&desired_orientation);
rotation_rate = rotation_vel_limit = rotation_acc_limit = vmd_zero_vector;
*/
}
void camera::set_name(char *in_name)
@@ -120,19 +144,15 @@ void camera::set_object_target(object *objp, int n_object_target_submodel)
object_target_submodel = n_object_target_submodel;
}
/**
* Custom function receives the already-modified current position value.
* It should be replaced or added to as the custom function modifier sees fit.
*/
//Custom function receives the already-modified current position value.
//It should be replaced or added to as the custom function modifier sees fit.
void camera::set_custom_position_function(void (*n_func_custom_position)(camera *cam, vec3d *camera_pos))
{
func_custom_position = n_func_custom_position;
}
/**
* Custom function receives the already-modified current orientation value.
* It should be replaced or added to as the custom function modifier sees fit.
*/
//Custom function receives the already-modified current orientation value.
//It should be replaced or added to as the custom function modifier sees fit.
void camera::set_custom_orientation_function(void (*n_func_custom_orientation)(camera *cam, matrix *camera_ori))
{
func_custom_orientation = n_func_custom_orientation;
@@ -192,6 +212,26 @@ void camera::set_rotation(matrix *in_orientation, float in_rotation_time, float
for(int i = 0; i < 9; i++)
ori[i].setAVD(in_orientation->a1d[i], in_rotation_time, in_rotation_acceleration_time, in_rotation_deceleration_time, 0.0f);
//WMC - This stationary check is here because it's a lot more
//accurate to directly save the matrix, if we've been provided one.
//IMPORTANT: Without this chunk, the HUD and view waves around with
// the main camera.
/*
angles a;
vm_extract_angles_matrix(&a, in_orientation);
if(in_rotation_time == 0.0f && in_rotation_acceleration_time == 0.0f)
{
c_ori = *in_orientation;
ori_p.set(a.p);
ori_b.set(a.b);
ori_h.set(a.h);
flags |= CAM_STATIONARY_ORI;
return;
}
//Continue on
this->set_rotation(&a, in_rotation_time, in_rotation_acceleration_time);
*/
}
void camera::set_rotation(angles *in_angles, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
@@ -199,6 +239,33 @@ void camera::set_rotation(angles *in_angles, float in_rotation_time, float in_ro
matrix mtx = IDENTITY_MATRIX;
vm_rotate_matrix_by_angles(&mtx, in_angles);
this->set_rotation(&mtx, in_rotation_time, in_rotation_acceleration_time, in_rotation_deceleration_time);
/*
if(in_rotation_time == 0.0f && in_rotation_acceleration_time == 0.0f)
{
ori_p.set(in_angles->p);
ori_b.set(in_angles->b);
ori_h.set(in_angles->h);
c_ori = vmd_identity_matrix;
vm_rotate_matrix_by_angles(&c_ori, in_angles);
flags |= CAM_STATIONARY_ORI;
return;
}
flags &= ~CAM_STATIONARY_ORI;
if(in_angles == NULL)
{
ori_p.setVD(in_rotation_time, in_rotation_acceleration_time, 0.0f);
ori_b.setVD(in_rotation_time, in_rotation_acceleration_time, 0.0f);
ori_h.setVD(in_rotation_time, in_rotation_acceleration_time, 0.0f);
return;
}
ori_p.setAVD(in_angles->p, in_rotation_time, in_rotation_acceleration_time, in_rotation_acceleration_time, 0.0f);
ori_b.setAVD(in_angles->b, in_rotation_time, in_rotation_acceleration_time, in_rotation_acceleration_time, 0.0f);
ori_h.setAVD(in_angles->h, in_rotation_time, in_rotation_acceleration_time, in_rotation_acceleration_time, 0.0f);
*/
}
void camera::set_rotation_facing(vec3d *in_target, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
@@ -227,6 +294,27 @@ void camera::set_rotation_facing(vec3d *in_target, float in_rotation_time, float
void camera::set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time)
{
Error(LOCATION, "This function is disabled until further notice.");
/*
ori_p.setVD(in_acceleration_time, in_acceleration_time, in_rotation_rate->p);
ori_b.setVD(in_acceleration_time, in_acceleration_time, in_rotation_rate->b);
ori_h.setVD(in_acceleration_time, in_acceleration_time, in_rotation_rate->h);
*/
/*if(in_rotation_rate == NULL)
{
rotation_rate.p = rotation_rate.b = rotation_rate.h = 0.0f;
rotation_rate_delta_time = rotation_rate_delta_time_left = in_rotation_acceleration_time = 0.0f;
rotation_rate_decel_time_til = -1.0f;
return;
}
rotation_rate_delta_time = rotation_rate_delta_time_left = in_rotation_acceleration_time;
rotation_rate_decel_time_til = -1.0f;
rotation_rate_delta.p = in_rotation_rate->p / in_rotation_acceleration_time;
rotation_rate_delta.b = in_rotation_rate->b / in_rotation_acceleration_time;
rotation_rate_delta.h = in_rotation_rate->h / in_rotation_acceleration_time;*/
}
void camera::do_frame(float in_frametime)
@@ -272,6 +360,7 @@ float camera::get_fov()
void camera::get_info(vec3d *position, matrix *orientation)
{
//WTF?
if(position == NULL && orientation == NULL)
return;
@@ -363,6 +452,17 @@ void camera::get_info(vec3d *position, matrix *orientation)
c_ori = vmd_identity_matrix;
}
//Do human interaction
//WMC - Nevermind for now, maybe toggleable later.
/*
if ( Viewer_obj == object_host.objp || Viewer_mode & VM_CHASE ) {
if ( Viewer_mode & VM_PADLOCK_ANY ) {
player_get_padlock_orient(&c_ori);
} else {
compute_slew_matrix(&c_ori, &Viewer_slew_angles);
}
}*/
matrix mtxA = c_ori;
matrix mtxB = IDENTITY_MATRIX;
float pos = 0.0f;
@@ -374,6 +474,15 @@ void camera::get_info(vec3d *position, matrix *orientation)
vm_matrix_x_matrix(&c_ori, &mtxA, &mtxB);
vm_orthogonalize_matrix(&c_ori);
/*
angles a;
ori_p.get(&a.p, NULL);
ori_b.get(&a.b, NULL);
ori_h.get(&a.h, NULL);
vm_rotate_matrix_by_angles(&c_ori, &a);
*/
//vm_angles_2_matrix(&c_ori, &a);
}
//Do custom orientation stuff, if needed
if(func_custom_orientation != NULL)
@@ -383,7 +492,6 @@ void camera::get_info(vec3d *position, matrix *orientation)
*orientation = c_ori;
}
}
//*************************warp_camera*************************
warp_camera::warp_camera()
{
@@ -396,7 +504,16 @@ warp_camera::warp_camera(object *objp)
vec3d object_pos = objp->pos;
matrix tmp;
ship_get_eye(&object_pos, &tmp, objp);
/*
//matrix tmp_m = vmd_identity_matrix;
camid cid = ship_get_eye( objp );
if(cid.isValid())
{
camera *cam = cid.getCamera();
cam->get_info(&player_pos, NULL);
//tmp_m = *cam->get_orientation();
}
*/
vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.rvec, 0.0f );
vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.uvec, 0.952f );
vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.fvec, -1.782f );
@@ -442,6 +559,7 @@ void warp_camera::set_velocity( vec3d *in_vel, bool instantaneous )
}
//
void warp_camera::do_frame(float in_frametime)
{
vec3d new_vel, delta_pos;
@@ -452,6 +570,8 @@ void warp_camera::do_frame(float in_frametime)
c_vel = new_vel;
// mprintf(( "Camera velocity = %.1f,%.1f, %.1f\n", Camera_velocity.xyz.x, Camera_velocity.xyz.y, Camera_velocity.xyz.z ));
vm_vec_add2( &c_pos, &delta_pos );
float ot = c_time+0.0f;
@@ -471,6 +591,9 @@ void warp_camera::do_frame(float in_frametime)
tmp.xyz.x = 22.0f * (float)sin(tmp_angle);
tmp.xyz.y = -22.0f * (float)cos(tmp_angle);
//mprintf(( "Angle = %.1f, vx=%.1f, vy=%.1f\n", tmp_angle, tmp.xyz.x, tmp.xyz.y ));
//mprintf(( "Changing velocity!\n" ));
this->set_velocity( &tmp, 0 );
}
@@ -505,9 +628,9 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim
return;
char text_buf[256];
if (in_text != NULL && in_text[0] != '\0')
if (in_text != NULL && strlen(in_text) > 0)
{
strcpy_s(text_buf, in_text);
strcpy(text_buf, in_text);
sexp_replace_variable_names_with_values(text_buf, 256);
in_text = text_buf;
}
@@ -518,11 +641,11 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim
int text_line_lens[MAX_SUBTITLE_LINES];
//Setup text
if ( (in_text != NULL) && (in_text[0] != '\0') ) {
if ( (in_text != NULL) && (strlen(in_text) > 0) ) {
int split_width = (in_width > 0) ? in_width : 200;
num_text_lines = split_str(in_text, split_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
SCP_string temp_str;
std::string temp_str;
for(int i = 0; i < num_text_lines; i++)
{
temp_str.assign(text_line_ptrs[i], text_line_lens[i]);
@@ -542,7 +665,7 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim
fade_time = fl_abs(in_fade_time);
//Setup image
if ( (in_imageanim != NULL) && (in_imageanim[0] != '\0') )
if ( (in_imageanim != NULL) && (strlen(in_imageanim) > 0) )
{
image_id = bm_load(in_imageanim);
@@ -668,10 +791,9 @@ void subtitle::do_frame(float frametime)
int x = text_pos.x;
int y = text_pos.y;
for(SCP_vector<SCP_string>::iterator line = text_lines.begin(); line != text_lines.end(); ++line)
for(unsigned int i = 0; i < text_lines.size(); i++)
{
gr_string(x, y, (char*)line->c_str(), false);
gr_string(x, y, (char*)text_lines[i].c_str(), false);
y += font_height;
}
@@ -721,8 +843,11 @@ subtitle::~subtitle()
void subtitle::clone(const subtitle &sub)
{
uint i = 0;
text_lines = sub.text_lines;
for (i = 0; i < sub.text_lines.size(); i++) {
text_lines.push_back(sub.text_lines[i]);
}
text_fontnum = sub.text_fontnum;
// copy the structs
@@ -796,7 +921,7 @@ int camid::getSignature()
bool camid::isValid()
{
if(idx >= Cameras.size())
if(idx < 0 || idx >= Cameras.size())
return false;
if(Cameras[idx] == NULL)
@@ -819,6 +944,14 @@ void cam_close()
{
//Set Current_camera to nothing
Current_camera = camid();
for(unsigned int i = 0; i < Cameras.size(); i++)
{
if(Cameras[i] != NULL)
{
delete Cameras[i];
Cameras[i] = NULL;
}
}
Cameras.clear();
}
@@ -851,9 +984,29 @@ camid cam_create(char *n_name, vec3d *n_pos, matrix *n_ori, object *n_object, in
strncpy(buf, n_name, NAME_LENGTH-1);
//Find a free slot
cam = new camera(buf, sig);
cid = camid(Cameras.size(), sig);
Cameras.push_back(cam);
for(uint i = 0; i < Cameras.size(); i++)
{
if(Cameras[i] == NULL)
{
cam = new camera(buf, sig);
cid = camid(i, sig);
Cameras[i] = cam;
break;
}
else if(Cameras[i]->is_empty())
{
delete Cameras[i];
cam = new camera(buf, sig);
cid = camid(i, sig);
Cameras[i] = cam;
}
}
if(cam == NULL)
{
cam = new camera(buf, sig);
cid = camid(Cameras.size(), sig);
Cameras.push_back(cam);
}
//Set attributes
if(n_pos != NULL)
@@ -876,7 +1029,7 @@ void cam_delete(camid cid)
void cam_do_frame(float frametime)
{
size_t i,size=Cameras.size();
unsigned int i,size=Cameras.size();
for(i = 0; i < size; i++)
{
if(Cameras[i] != NULL)
@@ -886,7 +1039,7 @@ void cam_do_frame(float frametime)
camid cam_get_camera(uint idx)
{
if(idx >= Cameras.size())
if(idx < 0 || idx >= Cameras.size())
return camid();
return camid(idx, Cameras[idx]->get_signature());
@@ -902,12 +1055,10 @@ uint cam_get_num()
return Cameras.size();
}
/**
* Looks up camera by name, returns -1 on failure
*/
//Looks up camera by name, returns -1 on failure
camid cam_lookup(char *name)
{
size_t i, size=Cameras.size();
unsigned int i,size=Cameras.size();
for(i = 0; i < size; i++)
{
if(Cameras[i] != NULL && !stricmp(Cameras[i]->get_name(), name))
@@ -947,6 +1098,35 @@ void cam_reset_camera()
Camera_hud_draw_saved = false;
}
//Functions must delete the original camera after calling this function.
//Note that due to the esoteric nature of this function, it should not
//be used outside camera.cpp
/*
static avd_camera *cam_upgrade_to_avd(camera *cam)
{
for(uint i = 0; i < Cameras.size(); i++)
{
if(Cameras[i] == cam)
break;
}
if(i == Cameras.size())
return NULL;
avd_camera *avdcam = new avd_camera(cam);
//Make the switch
Cameras[i] = avdcam;
return avdcam;
}
*/
void subtitles_init()
{
//Do nothing!!
}
void subtitles_close()
{
Subtitles.clear();
@@ -954,20 +1134,20 @@ void subtitles_close()
void subtitles_do_frame(float frametime)
{
SCP_vector<subtitle>::iterator sub;
for(sub = Subtitles.begin(); sub != Subtitles.end(); ++sub)
unsigned int i,size=Subtitles.size();
for(i = 0; i < size; i++)
{
if ( !sub->is_post_shaded( ) )
sub->do_frame(frametime);
if ( !Subtitles[i].is_post_shaded( ) )
Subtitles[i].do_frame(frametime);
}
}
void subtitles_do_frame_post_shaded(float frametime)
{
SCP_vector<subtitle>::iterator sub;
for(sub = Subtitles.begin(); sub != Subtitles.end(); ++sub)
unsigned int i,size=Subtitles.size();
for(i = 0; i < size; i++)
{
if ( sub->is_post_shaded( ) )
sub->do_frame(frametime);
if ( Subtitles[i].is_post_shaded( ) )
Subtitles[i].do_frame(frametime);
}
}
+10 -1
View File
@@ -33,9 +33,17 @@ protected:
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
@@ -116,7 +124,7 @@ class subtitle
private:
void clone(const subtitle &sub);
SCP_vector<SCP_string> text_lines;
SCP_vector<std::string> text_lines;
struct { int x; int y; } text_pos;
float display_time;
@@ -168,6 +176,7 @@ 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);
+14 -46
View File
@@ -52,7 +52,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_INVALID, NULL, NULL, CF_TYPE_INVALID },
// Root must be index 1!!
{ CF_TYPE_ROOT, "", ".mve .ogg", CF_TYPE_ROOT },
{ CF_TYPE_DATA, "data", ".cfg .txt", CF_TYPE_ROOT },
{ CF_TYPE_DATA, "data", ".cfg .log .txt", CF_TYPE_ROOT },
{ CF_TYPE_MAPS, "data" DIR_SEPARATOR_STR "maps", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
{ CF_TYPE_TEXT, "data" DIR_SEPARATOR_STR "text", ".txt .net", CF_TYPE_DATA },
{ CF_TYPE_MODELS, "data" DIR_SEPARATOR_STR "models", ".pof", CF_TYPE_DATA },
@@ -78,7 +78,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .png .dds", CF_TYPE_PLAYERS },
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css", CF_TYPE_PLAYERS },
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr", CF_TYPE_PLAYERS },
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .bx", CF_TYPE_DATA }, //clr=cached color
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .ibx .tsb", CF_TYPE_DATA }, //clr=cached color
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .png .dds .fs2 .txt", CF_TYPE_DATA },
{ CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA },
{ CF_TYPE_CONFIG, "data" DIR_SEPARATOR_STR "config", ".cfg", CF_TYPE_DATA },
@@ -961,7 +961,6 @@ CFILE *cf_open_fill_cfblock(FILE *fp, int type)
cfbp->data = NULL;
cfbp->fp = fp;
cfbp->dir_type = type;
cfbp->max_read_len = 0;
int pos = ftell(fp);
if(pos == -1L)
@@ -999,7 +998,6 @@ CFILE *cf_open_packed_cfblock(FILE *fp, int type, int offset, int size)
cfbp->data = NULL;
cfbp->fp = fp;
cfbp->dir_type = type;
cfbp->max_read_len = 0;
cf_init_lowlevel_read_code(cfp,offset, size, 0 );
@@ -1037,8 +1035,6 @@ CFILE *cf_open_mapped_fill_cfblock(FILE *fp, int type)
cfp = &Cfile_list[cfile_block_index];
cfp->id = cfile_block_index;
cfp->version = 0;
cfbp->max_read_len = 0;
cfbp->fp = NULL;
#if defined _WIN32
cfbp->hInFile = hFile;
@@ -1102,22 +1098,6 @@ void cf_set_version( CFILE * cfile, int version )
cfile->version = version;
}
// cutoff point where cfread() will throw an error when it hits this limit
// if 'len' is 0 then this check will be disabled
void cf_set_max_read_len( CFILE * cfile, size_t len )
{
Assert( cfile != NULL );
Assert( (cfile->id >= 0) && (cfile->id < MAX_CFILE_BLOCKS) );
Cfile_block *cb = &Cfile_block_list[cfile->id];
if (len) {
cb->max_read_len = cb->raw_position + len;
} else {
cb->max_read_len = 0;
}
}
// routines to read basic data types from CFILE's. Put here to
// simplify mac/pc reading from cfiles.
@@ -1266,7 +1246,7 @@ void cfread_string_len(char *buf,int n, CFILE *file)
{
int len;
len = cfread_int(file);
Assertion( (len < n), "len: %i, n: %i", len, n );
Assert( len < n );
if (len)
cfread(buf, len, 1, file);
@@ -1349,7 +1329,7 @@ int cfwrite_string(char *buf, CFILE *file)
return cfwrite_char(0, file); // write out NULL termination
}
int cfwrite_string_len(const char *buf, CFILE *file)
int cfwrite_string_len(char *buf, CFILE *file)
{
int len = strlen(buf);
@@ -1385,7 +1365,7 @@ int cfilelength( CFILE * cfile )
// returns: number of full elements actually written
//
//
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
int cfwrite(void *buf, int elsize, int nelem, CFILE *cfile)
{
if(!cf_is_valid(cfile))
return 0;
@@ -1407,22 +1387,18 @@ int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
return EOF;
}
size_t bytes_written = 0;
size_t size = elsize * nelem;
int result = 0;
bytes_written = fwrite(buf, 1, size, cb->fp);
result = fwrite(buf, elsize, nelem, cb->fp);
//WMC - update filesize and position
if (bytes_written > 0) {
cb->size += bytes_written;
cb->raw_position += bytes_written;
if(result > 0)
{
cb->size = filelength(fileno(cb->fp));
cb->raw_position += result;
}
#if defined(CHECK_SIZE) && !defined(NDEBUG)
Assert( cb->size == filelength(fileno(cb->fp)) );
#endif
return ((int)bytes_written / elsize);
return result;
}
@@ -1458,14 +1434,10 @@ int cfputc(int c, CFILE *cfile)
//WMC - update filesize and position
if(result != EOF)
{
cb->size += 1;
cb->size = filelength(fileno(cb->fp));
cb->raw_position += 1;
}
#if defined(CHECK_SIZE) && !defined(NDEBUG)
Assert( cb->size == filelength(fileno(cb->fp)) );
#endif
return result;
}
@@ -1502,14 +1474,10 @@ int cfputs(char *str, CFILE *cfile)
//WMC - update filesize and position
if(result != EOF)
{
cb->size += strlen(str);
cb->size = filelength(fileno(cb->fp));
cb->raw_position += strlen(str);
}
#if defined(CHECK_SIZE) && !defined(NDEBUG)
Assert( cb->size == filelength(fileno(cb->fp)) );
#endif
return result;
}
+6 -72
View File
@@ -16,9 +16,6 @@
#include <time.h>
#include "globalincs/pstypes.h"
#include <stdexcept>
#define CF_EOF (-1)
#define CF_SEEK_SET (0)
@@ -101,11 +98,6 @@ typedef struct {
// to add file to list, or 0 to not add it.
extern int (*Get_file_list_filter)(char *filename);
// extra check for child directory under CF_TYPE_*
// NOTE: if specified cf_get_file_list() will not search pack files!
// NOTE: specified string must not contain ':' or spaces or begin with DIR_SEPARATOR!
extern const char *Get_file_list_child;
// cfile directory. valid after cfile_init() returns successfully
#define CFILE_ROOT_DIRECTORY_LEN 256
extern char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN];
@@ -143,11 +135,6 @@ int cflush(CFILE *cfile);
// open a file. Once set, you can use minimum version numbers with the read functions.
void cf_set_version( CFILE * cfile, int version );
// will throw an error if cfread*() functions read past this mark
// converted to raw offsets when used, but gets passed actual length from current position
// setting 'len' to zero will disable the check
void cf_set_max_read_len(CFILE *cfile, size_t len);
// Deletes a file. Returns 0 on error, 1 if successful
int cf_delete(char *filename, int dir_type);
@@ -181,7 +168,7 @@ int cfilelength(CFILE *fp);
int cfread(void *buf, int elsize, int nelem, CFILE *fp);
// cfwrite() writes to the file
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile);
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);
@@ -271,15 +258,8 @@ 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);
/**
* @brief Read a fixed length string that is not null-terminated, with the length stored in file
*
* @param buf Pre-allocated array to store string
* @param n Size of pre-allocated array
* @param file File to read from
*
* @note Appends NULL character to string (buf)
*/
// 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
@@ -296,19 +276,13 @@ int cfwrite_angles(angles *ang, CFILE *file);
// writes variable length, null-termined string.
int cfwrite_string(char *buf, CFILE *file);
/**
* @brief Write a fixed length string (not including its null terminator), with the length stored in file
*
* @param buf String to write to file
* @param file File to write to
*/
int cfwrite_string_len(const 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( SCP_vector<SCP_string> &list, int pathtype, char *filter, int sort = CF_SORT_NONE, SCP_vector<file_list_info> *info = NULL );
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 );
void cf_sort_filenames( SCP_vector<SCP_string> &list, int sort, SCP_vector<file_list_info> *info = NULL );
// Searches for a file. Follows all rules and precedence and searches
// CD's and pack files.
@@ -348,45 +322,5 @@ int cfile_push_chdir(int type);
// restore directory on top of the stack
int cfile_pop_dir();
namespace cfile
{
// exceptions and other errors
class cfile_error : public std::exception
{
public:
cfile_error() : m_excuse("CFILE Exception")
{
}
cfile_error(const std::string &excuse) : m_excuse(excuse)
{
}
~cfile_error() throw()
{
}
virtual const char *what() const throw()
{
return m_excuse.c_str();
}
private:
std::string m_excuse;
};
class max_read_length : public cfile_error
{
public:
max_read_length(const std::string &excuse) : cfile_error(excuse)
{
}
max_read_length() : cfile_error("Attempted to read beyond length limit")
{
}
};
};
#endif /* __CFILE_H__ */
-11
View File
@@ -26,8 +26,6 @@
#include "cfile/cfilearchive.h"
#include "luaconf.h"
#include <sstream>
#define CHECK_POSITION
@@ -207,15 +205,6 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
//mprintf(( "CFILE: EOF encountered in file\n" ));
}
if (cb->max_read_len) {
if ( (size_t)(cb->raw_position+size) > cb->max_read_len ) {
std::ostringstream s_buf;
s_buf << "Attempted to read " << size << "-byte(s) beyond length limit";
throw cfile::max_read_length(s_buf.str());
}
}
int bytes_read = fread( buf, 1, size, cb->fp );
if ( bytes_read > 0 ) {
cb->raw_position += bytes_read;
+1 -2
View File
@@ -37,8 +37,7 @@ typedef struct Cfile_block {
int lib_offset;
int raw_position;
int size; // for packed files
size_t max_read_len; // max read offset, for special error handling
} Cfile_block;
#define MAX_CFILE_BLOCKS 64
-79
View File
@@ -12,8 +12,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include <algorithm>
#ifdef _WIN32
#include <io.h>
@@ -26,84 +24,7 @@
#include "cfile/cfile.h"
void cf_sort_filenames( SCP_vector<SCP_string> &list, int sort, SCP_vector<file_list_info> *info )
{
// NOTE: This really needs to be updated to C++ style sorting at some point
int i, j, incr;
SCP_string t;
file_list_info tt;
int n = (int)list.size();
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].c_str(), list[j + incr].c_str()) > 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) {
std::reverse( list.begin(), list.end() );
if (info) {
std::reverse( info->begin(), info->end() );
}
return;
}
nprintf(("Error", "Unknown sorting method %d passed to cf_sort_filenames()\n", sort));
}
// Sorts a list of filenames using the specified sorting method (CF_SORT_*).
// n = number of filenames in list to sort
+71 -364
View File
@@ -15,7 +15,6 @@
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sstream>
#ifdef _WIN32
#include <io.h>
@@ -86,14 +85,14 @@ typedef struct cf_file {
int pack_offset; // For pack files, where it is at. 0 if not in a pack file. This can be used to tell if in a pack file.
} cf_file;
#define CF_NUM_FILES_PER_BLOCK 512
#define CF_MAX_FILE_BLOCKS 128 // Can store 512*128 = 65536 files
#define CF_NUM_FILES_PER_BLOCK 256
#define CF_MAX_FILE_BLOCKS 128 // Can store 256*128 = 32768 files
typedef struct cf_file_block {
cf_file files[CF_NUM_FILES_PER_BLOCK];
} cf_file_block;
static uint Num_files = 0;
static int Num_files = 0;
static cf_file_block *File_blocks[CF_MAX_FILE_BLOCKS];
@@ -109,10 +108,8 @@ cf_file *cf_get_file(int index)
// Create a new file and return a pointer to it.
cf_file *cf_create_file()
{
Assertion(Num_files < CF_NUM_FILES_PER_BLOCK * CF_MAX_FILE_BLOCKS, "Too many files found. CFile cannot handle more than %d files.\n", CF_NUM_FILES_PER_BLOCK * CF_MAX_FILE_BLOCKS);
uint block = Num_files / CF_NUM_FILES_PER_BLOCK;
uint offset = Num_files % CF_NUM_FILES_PER_BLOCK;
int block = Num_files / CF_NUM_FILES_PER_BLOCK;
int offset = Num_files % CF_NUM_FILES_PER_BLOCK;
if ( File_blocks[block] == NULL ) {
File_blocks[block] = (cf_file_block *)vm_malloc( sizeof(cf_file_block) );
@@ -373,7 +370,6 @@ void cf_build_root_list(char *cdrom_dir)
cf_root *root;
char str_temp[CF_MAX_PATHNAME_LENGTH], *cur_pos;
int path_len;
#ifdef SCP_UNIX
// =========================================================================
@@ -430,7 +426,8 @@ void cf_build_root_list(char *cdrom_dir)
if(Cmdline_mod) {
// stackable Mod support -- Kazan
for (cur_pos=Cmdline_mod; *cur_pos != '\0'; cur_pos+= (strlen(cur_pos)+1))
//This for statement is a work of art :D
for (cur_pos=Cmdline_mod; strlen(cur_pos) != 0; cur_pos+= (strlen(cur_pos)+1))
{
memset(str_temp, 0, CF_MAX_PATHNAME_LENGTH);
strncpy(str_temp, cur_pos, CF_MAX_PATHNAME_LENGTH-1);
@@ -447,15 +444,12 @@ void cf_build_root_list(char *cdrom_dir)
Int3();
}
path_len = strlen(root->path);
// do we already have a slash? as in the case of a root directory install
if ( (path_len < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[path_len-1] != DIR_SEPARATOR_CHAR) ) {
if ( (strlen(root->path) < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[strlen(root->path)-1] != DIR_SEPARATOR_CHAR) ) {
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
path_len++;
}
strncat(root->path, str_temp, (CF_MAX_PATHNAME_LENGTH - path_len - 1));
strncat(root->path, str_temp, (CF_MAX_PATHNAME_LENGTH - strlen(root->path) - 1));
root->roottype = CF_ROOTTYPE_PATH;
cf_build_pack_list(root);
}
@@ -467,10 +461,8 @@ void cf_build_root_list(char *cdrom_dir)
Error(LOCATION, "Can't get current working directory -- %d", errno );
}
path_len = strlen(root->path);
// do we already have a slash? as in the case of a root directory install
if ( (path_len < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[path_len-1] != DIR_SEPARATOR_CHAR) ) {
if ( (strlen(root->path) < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[strlen(root->path)-1] != DIR_SEPARATOR_CHAR) ) {
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
}
@@ -672,9 +664,9 @@ void cf_search_root_pack(int root_index)
Assert( sizeof(VP_header) == 16 );
fread(&VP_header, 1, sizeof(VP_header), fp);
VP_header.version = INTEL_INT( VP_header.version ); //-V570
VP_header.index_offset = INTEL_INT( VP_header.index_offset ); //-V570
VP_header.num_files = INTEL_INT( VP_header.num_files ); //-V570
VP_header.version = INTEL_INT( VP_header.version );
VP_header.index_offset = INTEL_INT( VP_header.index_offset );
VP_header.num_files = INTEL_INT( VP_header.num_files );
mprintf(( "Searching root pack '%s' ... ", root->path ));
@@ -692,21 +684,21 @@ void cf_search_root_pack(int root_index)
fread( &find, sizeof(VP_FILE), 1, fp );
find.offset = INTEL_INT( find.offset ); //-V570
find.size = INTEL_INT( find.size ); //-V570
find.write_time = INTEL_INT( find.write_time ); //-V570
find.offset = INTEL_INT( find.offset );
find.size = INTEL_INT( find.size );
find.write_time = INTEL_INT( find.write_time );
if ( find.size == 0 ) {
int search_path_len = strlen(search_path);
if ( !stricmp( find.filename, ".." )) {
char *p = &search_path[search_path_len-1];
int l = strlen(search_path);
char *p = &search_path[l-1];
while( (p > search_path) && (*p != DIR_SEPARATOR_CHAR) ) {
p--;
}
*p = 0;
} else {
if ( search_path_len && (search_path[search_path_len-1] != DIR_SEPARATOR_CHAR) ) {
strcat_s( search_path, DIR_SEPARATOR_STR );
if ( strlen(search_path) && (search_path[strlen(search_path)-1] != DIR_SEPARATOR_CHAR) ) {
strcat_s( search_path, DIR_SEPARATOR_STR );
}
strcat_s( search_path, find.filename );
}
@@ -829,7 +821,7 @@ void cf_free_secondary_filelist()
// 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 )
{
uint i;
int i;
int cfs_slow_search = 0;
char longname[MAX_PATH_LEN];
@@ -838,7 +830,7 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
_finddata_t findstruct;
#endif
Assert( (filespec != NULL) && (strlen(filespec) > 0) ); //-V805
Assert( (filespec != NULL) && (strlen(filespec) > 0) );
Assert( (pack_filename == NULL) || (max_out > 1) );
// see if we have something other than just a filename
@@ -868,13 +860,13 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
}
// Search the hard drive for files first.
uint num_search_dirs = 0;
int num_search_dirs = 0;
int search_order[CF_MAX_PATH_TYPES];
if ( CF_TYPE_SPECIFIED(pathtype) ) {
search_order[num_search_dirs++] = pathtype;
} else {
for (int i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
if (i != pathtype)
search_order[num_search_dirs++] = i;
}
@@ -906,21 +898,23 @@ int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[i], filespec, localize );
#if defined _WIN32
findhandle = _findfirst(longname, &findstruct);
if (findhandle != -1) {
if (size)
*size = findstruct.size;
if (!Cmdline_safeloading) {
findhandle = _findfirst(longname, &findstruct);
if (findhandle != -1) {
if (size)
*size = findstruct.size;
_findclose(findhandle);
_findclose(findhandle);
if (offset)
*offset = 0;
if (offset)
*offset = 0;
if (pack_filename)
strncpy( pack_filename, longname, max_out );
if (pack_filename)
strncpy( pack_filename, longname, max_out );
return 1;
}
return 1;
}
} else
#endif
{
FILE *fp = fopen(longname, "rb" );
@@ -1034,8 +1028,7 @@ extern char *stristr(const char *str, const char *substr);
// (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, char *pack_filename, int *size, int *offset, bool localize )
{
uint i;
int cur_ext;
int i, cur_ext;
int cfs_slow_search = 0;
char longname[MAX_PATH_LEN];
char filespec[MAX_FILENAME_LEN];
@@ -1063,13 +1056,13 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
}
// Search the hard drive for files first.
uint num_search_dirs = 0;
int num_search_dirs = 0;
int search_order[CF_MAX_PATH_TYPES];
if ( CF_TYPE_SPECIFIED(pathtype) ) {
search_order[num_search_dirs++] = pathtype;
} else {
for (int i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++)
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++)
search_order[num_search_dirs++] = i;
}
@@ -1116,21 +1109,23 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[i], filespec, localize );
#if defined _WIN32
findhandle = _findfirst(longname, &findstruct);
if (findhandle != -1) {
if (size)
*size = findstruct.size;
if (!Cmdline_safeloading) {
findhandle = _findfirst(longname, &findstruct);
if (findhandle != -1) {
if (size)
*size = findstruct.size;
_findclose(findhandle);
_findclose(findhandle);
if (offset)
*offset = 0;
if (offset)
*offset = 0;
if (pack_filename)
strncpy( pack_filename, longname, max_out );
if (pack_filename)
strncpy( pack_filename, longname, max_out );
return cur_ext;
}
return cur_ext;
}
} else
#endif
{
FILE *fp = fopen(longname, "rb" );
@@ -1173,7 +1168,7 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
int last_root_index = -1;
int last_path_index = -1;
file_list_index.reserve( MIN(ext_num * 4, (int)Num_files) );
file_list_index.reserve( MIN(ext_num * 4, Num_files) );
// next, run though and pick out base matches
for (i = 0; i < Num_files; i++) {
@@ -1219,10 +1214,17 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
file_list_index.push_back( f );
}
int file_list_size = (int)file_list_index.size();
// quick exit test
if (file_list_size < 1)
goto Bail;
// now try and find our preferred match
for (cur_ext = 0; cur_ext < ext_num; cur_ext++) {
for (SCP_vector<cf_file*>::iterator fli = file_list_index.begin(); fli != file_list_index.end(); ++fli) {
cf_file *f = *fli;
for (i = 0; i < file_list_size; i++) {
cf_file *f = file_list_index[i];
strcat_s( filespec, ext_list[cur_ext] );
@@ -1301,6 +1303,10 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
}
}
Bail:
// didn't find anything, bail...
file_list_index.clear();
return -1;
}
@@ -1342,245 +1348,8 @@ int cf_matches_spec(char *filespec, char *filename)
}
int (*Get_file_list_filter)(char *filename) = NULL;
const char *Get_file_list_child = NULL;
int Skip_packfile_search = 0;
static bool verify_file_list_child()
{
if (Get_file_list_child == NULL) {
return false;
}
// empty or too long
size_t len = strlen(Get_file_list_child);
if ( !len || (len > MAX_FILENAME_LEN) ) {
return false;
}
// can not being with directory separator
if (Get_file_list_child[0] == DIR_SEPARATOR_CHAR) {
return false;
}
// no ':' or spaces
if ( strchr(Get_file_list_child, ':') || strchr(Get_file_list_child, ' ') ) {
return false;
}
return true;
}
static int cf_file_already_in_list( SCP_vector<SCP_string> &list, char *filename )
{
char name_no_extension[MAX_PATH_LEN];
size_t i, size = list.size();
if (size == 0) {
return 0;
}
strcpy_s(name_no_extension, filename );
char *p = strrchr( name_no_extension, '.' );
if ( p ) *p = 0;
for (i = 0; i < size; i++) {
if ( !stricmp(list[i].c_str(), name_no_extension ) ) {
// Match found!
return 1;
}
}
// Not found
return 0;
}
// An alternative cf_get_file_list*(), true dynamic list version.
// This one has a 'type', which is a CF_TYPE_* value. Because this specifies the directory
// location, 'filter' only needs to be the filter itself, with no path information.
// See above descriptions of cf_get_file_list() for more information about how it all works.
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, char *filter, int sort, SCP_vector<file_list_info> *info )
{
char *ptr;
uint i;
int l, own_flag = 0;
SCP_vector<file_list_info> my_info;
file_list_info tinfo;
if ( !info && (sort == CF_SORT_TIME) ) {
info = &my_info;
own_flag = 1;
}
char filespec[MAX_PATH_LEN];
bool check_duplicates = !list.empty();
if ( check_duplicates && (sort != CF_SORT_NONE) ) {
Int3();
sort = CF_SORT_NONE;
}
if (Get_file_list_child && !verify_file_list_child() ) {
Get_file_list_child = NULL;
}
#if defined _WIN32
cf_create_default_path_string( filespec, sizeof(filespec)-1, pathtype, (char*)Get_file_list_child );
strcat_s(filespec, DIR_SEPARATOR_STR);
strcat_s(filespec, filter);
_finddata_t find;
int find_handle;
find_handle = _findfirst( filespec, &find );
if (find_handle != -1) {
do {
if (strcmp(strstr(filter, "."), strstr(find.name,".")) != 0)
continue;
if ( strlen(find.name) >= MAX_FILENAME_LEN )
continue;
if (!(find.attrib & _A_SUBDIR)) {
if ( !Get_file_list_filter || (*Get_file_list_filter)(find.name) ) {
if ( check_duplicates && cf_file_already_in_list(list, find.name) ) {
continue;
}
ptr = strrchr(find.name, '.');
if (ptr)
l = ptr - find.name;
else
l = strlen(find.name);
list.push_back( SCP_string(find.name, l) );
if (info) {
tinfo.write_time = find.time_write;
info->push_back( tinfo );
}
}
}
} while (!_findnext(find_handle, &find));
_findclose( find_handle );
}
#elif defined SCP_UNIX
cf_create_default_path_string( filespec, sizeof(filespec)-1, pathtype, (char*)Get_file_list_child );
DIR *dirp;
struct dirent *dir;
dirp = opendir (filespec);
if ( dirp ) {
while ((dir = readdir (dirp)) != NULL) {
if ( strlen(dir->d_name) >= MAX_FILENAME_LEN ) {
continue;
}
if (fnmatch(filter, dir->d_name, 0) != 0)
continue;
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 (!S_ISREG(buf.st_mode)) {
continue;
}
if ( !Get_file_list_filter || (*Get_file_list_filter)(dir->d_name) ) {
if ( check_duplicates && cf_file_already_in_list(list, dir->d_name) ) {
continue;
}
ptr = strrchr(dir->d_name, '.');
if (ptr)
l = ptr - dir->d_name;
else
l = strlen(dir->d_name);
list.push_back( SCP_string(dir->d_name, l) );
if (info) {
tinfo.write_time = buf.st_mtime;
info->push_back( tinfo );
}
}
}
closedir(dirp);
}
#endif
bool skip_packfiles = (Skip_packfile_search != 0);
if ( (pathtype == CF_TYPE_PLAYERS) || (pathtype == CF_TYPE_SINGLE_PLAYERS) || (pathtype == CF_TYPE_MULTI_PLAYERS) ) {
skip_packfiles = true;
} else if (Get_file_list_child != NULL) {
skip_packfiles = true;
}
// Search all the packfiles and CD.
if ( !skip_packfiles ) {
for (i=0; i<Num_files; i++ ) {
cf_file * f = cf_get_file(i);
// only search paths we're supposed to...
if ( (pathtype != CF_TYPE_ANY) && (pathtype != f->pathtype_index) ) {
continue;
}
if ( !cf_matches_spec( filter,f->name_ext)) {
continue;
}
if ( cf_file_already_in_list(list, f->name_ext)) {
continue;
}
if ( !Get_file_list_filter || (*Get_file_list_filter)(f->name_ext) ) {
//mprintf(( "Found '%s' in root %d path %d\n", f->name_ext, f->root_index, f->pathtype_index ));
ptr = strrchr(f->name_ext, '.');
if (ptr)
l = ptr - f->name_ext;
else
l = strlen(f->name_ext);
list.push_back( SCP_string(f->name_ext, l) );
if (info) {
tinfo.write_time = f->write_time;
info->push_back( tinfo );
}
}
}
}
if (sort != CF_SORT_NONE) {
cf_sort_filenames( list, sort, info );
}
if (own_flag) {
my_info.clear();
}
Get_file_list_filter = NULL;
Get_file_list_child = NULL;
return (int)list.size();
}
int cf_file_already_in_list( int num_files, char **list, char *filename )
{
int i;
@@ -1608,8 +1377,7 @@ int cf_file_already_in_list( int num_files, char **list, char *filename )
int cf_get_file_list( int max, char **list, int pathtype, char *filter, int sort, file_list_info *info )
{
char *ptr;
uint i;
int l, num_files = 0, own_flag = 0;
int i, l, num_files = 0, own_flag = 0;
if (max < 1) {
Get_file_list_filter = NULL;
@@ -1806,7 +1574,7 @@ int cf_file_already_in_list_preallocated( int num_files, char arr[][MAX_FILENAME
// See above descriptions of cf_get_file_list() for more information about how it all works.
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int pathtype, char *filter, int sort, file_list_info *info )
{
int num_files = 0, own_flag = 0;
int i, num_files = 0, own_flag = 0;
if (max < 1) {
Get_file_list_filter = NULL;
@@ -1815,7 +1583,7 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
}
if (list) {
for (int i=0; i<max; i++) {
for (i=0; i<max; i++) {
list[i] = arr[i];
}
} else {
@@ -1927,7 +1695,7 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
// Search all the packfiles and CD.
if ( !Skip_packfile_search ) {
for (uint i=0; i<Num_files; i++ ) {
for (i=0; i<Num_files; i++ ) {
cf_file * f = cf_get_file(i);
// only search paths we're supposed to...
@@ -2062,67 +1830,6 @@ int cf_create_default_path_string( char *path, uint path_max, int pathtype, char
return 1;
}
// 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_??
// filename - optional, if set, tacks the filename onto end of path.
// Output: path - Fully qualified pathname.
//Returns 0 if the result would be too long (invalid result)
int cf_create_default_path_string( SCP_string &path, int pathtype, char *filename, bool localize )
{
#ifdef SCP_UNIX
if ( filename && strpbrk(filename,"/") ) {
#else
if ( filename && strpbrk(filename,"/\\:") ) {
#endif
// Already has full path
path.assign(filename);
} else {
cf_root *root = cf_get_root(0);
if (!root) {
Assert( filename != NULL );
path.assign(filename);
return 1;
}
Assert(CF_TYPE_SPECIFIED(pathtype));
std::ostringstream s_path;
// force a specific directory to search for player files
if ( (pathtype == CF_TYPE_PLAYERS) || (pathtype == CF_TYPE_SINGLE_PLAYERS) || (pathtype == CF_TYPE_MULTI_PLAYERS) ) {
s_path << Pilot_file_path;
} else {
s_path << root->path;
}
s_path << Pathtypes[pathtype].path;
// Don't add slash for root directory
if (Pathtypes[pathtype].path[0] != '\0') {
if ( *(s_path.str().rbegin()) != DIR_SEPARATOR_CHAR ) {
s_path << DIR_SEPARATOR_STR;
}
// if ( path[strlen(path)-1] != DIR_SEPARATOR_CHAR ) {
// strcat_s(path, path_max, DIR_SEPARATOR_STR);
// }
}
// add filename
if (filename) {
s_path << filename;
}
path = s_path.str().c_str();
}
return 1;
}
void cfile_spew_pack_file_crcs()
{
int i;
+1 -1
View File
@@ -40,6 +40,6 @@ extern cf_pathtype Pathtypes[CF_MAX_PATH_TYPES];
// 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);
int cf_create_default_path_string( SCP_string &path, int pathtype, char *filename=NULL, bool localize = false );
#endif //_CFILESYSTEM_H
+10 -10
View File
@@ -140,7 +140,7 @@ void pack_file( char *filespec, char *filename, int filesize, _fs_time_t time_wr
}
memset( path, 0, sizeof(path) );
strcpy_s( path, filename );
strcpy( path, filename );
fswrite_int( (int*)&Total_size, fp_out_hdr );
fswrite_int( &filesize, fp_out_hdr );
@@ -186,7 +186,7 @@ void add_directory( char * dirname)
char *tmpptr;
int i = 0;
strcpy_s(path, dirname);
strcpy(path, dirname);
fswrite_int( (int*)&Total_size, fp_out_hdr);
fswrite_int( &i, fp_out_hdr);
@@ -217,7 +217,7 @@ void pack_directory( char * filespec)
while ( (*ts == DIR_SEPARATOR_CHAR) && (ts > filespec) )
*ts = '\0';
strcpy_s( tmp1, filespec );
strcpy( tmp1, filespec );
add_directory(filespec);
strcat( tmp1, DIR_SEPARATOR_STR"*.*" );
@@ -229,7 +229,7 @@ void pack_directory( char * filespec)
if( find_handle != -1 ) {
if ( find.attrib & _A_SUBDIR ) {
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
strcpy_s( tmp, filespec );
strcpy( tmp, filespec );
strcat( tmp, "\\" );
strcat( tmp, find.name );
pack_directory(tmp);
@@ -241,7 +241,7 @@ void pack_directory( char * filespec)
while( !_findnext( find_handle, &find ) ) {
if ( find.attrib & _A_SUBDIR ) {
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
strcpy_s( tmp, filespec );
strcpy( tmp, filespec );
strcat( tmp, "\\" );
strcat( tmp, find.name );
pack_directory(tmp);
@@ -278,7 +278,7 @@ void pack_directory( char * filespec)
}
if (S_ISDIR(buf.st_mode)) {
strcpy_s( tmp, filespec );
strcpy( tmp, filespec );
strcat( tmp, "/" );
strcat( tmp, dir->d_name );
pack_directory(tmp);
@@ -340,7 +340,7 @@ void print_instructions()
exit(0);
}
// we end up #include'ing SDL.h which on Windows and Mac will redefine main() which is something
// 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
@@ -364,14 +364,14 @@ int main(int argc, char *argv[] )
#endif
}
strcpy_s( archive, argv[1] );
strcpy( archive, argv[1] );
p = strchr( archive, '.' );
if (p) *p = 0; // remove extension
strcpy_s( archive_dat, archive );
strcpy( archive_dat, archive );
strcat( archive_dat, ".vp" );
strcpy_s( archive_hdr, archive );
strcpy( archive_hdr, archive );
strcat( archive_hdr, ".hdr" );
fp_out = fopen( archive_dat, "wb" );
+6 -6
View File
@@ -97,7 +97,7 @@ typedef struct vp_fileinfo {
~vp_fileinfo() {}
} vp_fileinfo;
SCP_vector<vp_fileinfo> VP_FileInfo;
std::vector<vp_fileinfo> VP_FileInfo;
// just like strlwr() but without actually including it here
void lowercase(char *s)
@@ -224,7 +224,7 @@ void read_index(int lc = 0)
if (lc == 1)
lowercase( vpinfo.file_name );
strcpy_s( vpinfo.file_path, path );
strcpy( vpinfo.file_path, path );
VP_FileInfo.push_back(vpinfo);
}
}
@@ -261,7 +261,7 @@ void extract_all_files(char *file)
printf("Extracting: %s...\n", file);
for (size_t i = 0; i < VP_FileInfo.size(); i++) {
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 )
@@ -311,7 +311,7 @@ void extract_all_files(char *file)
sprintf(path2, "%s%s%s", out_dir, DIR_SEPARATOR_STR, path);
} else {
strcpy_s(path2, path);
strcpy(path2, path);
}
fp_out = fopen(path2, "wb");
@@ -365,7 +365,7 @@ void list_all_files(char *file)
printf(" Name Size Offset Date/Time Path\n");
printf("-------------------------------------------------------------------------------\n");
for (size_t i = 0; i < VP_FileInfo.size(); i++) {
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)
@@ -422,7 +422,7 @@ void help()
printf("\n");
}
// we end up #include'ing SDL.h which on Windows and Mac will redefine main() which is something
// 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
+96 -148
View File
@@ -79,8 +79,6 @@ enum
#define BUILD_CAP_NO_D3D (1<<1)
#define BUILD_CAP_NEW_SND (1<<2)
#define PARSE_COMMAND_LINE_STRING "-parse_cmdline_only"
typedef struct
{
// DO NOT CHANGE THE SIZE OF THIS STRING!
@@ -114,92 +112,84 @@ typedef struct
Flag exe_params[] =
{
{ "-spec", "Enable specular", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
{ "-glow", "Enable glow maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
{ "-glow", "Enable glowmaps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
{ "-env", "Enable environment maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
{ "-nomotiondebris", "Disable motion debris", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomotiondebris",},
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
{ "-missile_lighting", "Apply lighting to missiles" , true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missile_lighting", },
{ "-missile_lighting", "Apply Lighting to Missiles" , true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missile_lighting", },
{ "-normal", "Enable normal maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
{ "-post_process", "Enable post processing", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
{ "-soft_particles", "Enable soft particles", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
{ "-fxaa", "Enable FXAA anti-aliasing", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-flightshaftsoff", "Force Lightshafts off", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
{ "-img2dds", "Compress non-compressed images", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-img2dds", },
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
{ "-cache_bitmaps", "Cache bitmaps between missions", true, 0, EASY_DEFAULT_MEM, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-cache_bitmaps", },
{ "-dualscanlines", "Add another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
{ "-dualscanlines", "Another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
{ "-targetinfo", "Enable info next to target", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-targetinfo", },
{ "-orbradar", "Enable 3D radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
{ "-rearm_timer", "Enable rearm/repair completion timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
{ "-ballistic_gauge", "Enable analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
{ "-orbradar", "Enables 3d radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
{ "-rearm_timer", "Enable Rearm/Repair Completion Timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
{ "-ballistic_gauge", "Enable the analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
{ "-ship_choice_3d", "Use 3D models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
{ "-weapon_choice_3d", "Use 3D models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
{ "-3dwarp", "Enable 3D warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
{ "-ship_choice_3d", "Use models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
{ "-weapon_choice_3d", "Use models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
{ "-3dwarp", "Enable 3d warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
{ "-nosound", "Disable all sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
{ "-nosound", "Disable sound and music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
{ "-standalone", "Run as standalone server", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-standalone", },
{ "-standalone", "Run as Stand Alone Server", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-standalone", },
{ "-startgame", "Skip mainhall and start hosting", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-startgame", },
{ "-closed", "Start hosted server as closed", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-closed", },
{ "-restricted", "Host confirms join requests", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-restricted", },
{ "-multilog", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-multilog", },
{ "-clientdamage", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-clientdamage", },
{ "-mpnoreturn", "Disable flight deck option", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
{ "-mpnoreturn", "Disables flight deck option", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
{ "-oldfire", "", false, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-oldfire", },
{ "-nohtl", "Software mode (very slow)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nohtl", },
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
{ "-query_speech", "Check if this build has speech", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
{ "-novbo", "Disable OpenGL VBO", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-novbo", },
{ "-noibx", "Don't use cached index buffers (IBX)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noibx", },
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_fbo", },
{ "-no_glsl", "Disable GLSL (shader) support", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_glsl", },
{ "-ati_swap", "Fix colour issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_3d_sound", },
{ "-disable_glsl_model","Don't use shaders for model rendering", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_glsl_model", },
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
#ifndef SCP_UNIX
{ "-disable_di_mouse", "Don't use DirectInput for mouse control", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
#endif
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-safeloading", "", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-safeloading", },
{ "-query_speech", "Does this build have speech?", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
{ "-d3d_bad_tsys", "Enable inefficient textures", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-d3d_bad_tsys", },
{ "-novbo", "Disable OpenGL VBO", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-novbo", },
{ "-noibx", "Don't use cached index buffers (IBX)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noibx", },
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-no_glsl", "Disable GLSL (shader) support", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-ati_swap", "Fix Color issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-ingame_join", "Allow in-game joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
{ "-voicer", "Enable voice recognition", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-voicer", },
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, 0, EASY_DEFAULT, "Experimental", "", },
{ "-ingame_join", "Allows ingame joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
{ "-voicer", "Voice recognition", true, 0, EASY_DEFAULT, "Experimental", "", },
{ "-post_process", "Enable post processing", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
#ifndef SCP_UNIX
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fullscreen_window", },
#endif
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
{ "-pofspew", "", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
{ "-tablecrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
{ "-missioncrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
{ "-dis_collisions", "Disable collisions", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_collisions", },
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
{ "-output_sexps", "Output SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
{ "-output_scripting", "Output scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-save_render_target", },
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
#ifdef SCP_UNIX
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
{ "-output_sexps", "Outputs SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
{ "-output_scripting", "Outputs scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-verify_vps", "Spew VP crcs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "", },
#ifdef SCP_UNIX
{ "-nograb", "Don't grab mouse/keyboard in a window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", },
#endif
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", },
#endif
};
// here are the command line parameters that we will be using for FreeSpace
@@ -218,6 +208,7 @@ cmdline_parm gameclosed_arg("-closed", NULL); // Cmdline_closed_game
cmdline_parm gamerestricted_arg("-restricted", NULL); // Cmdline_restricted_game
cmdline_parm port_arg("-port", NULL);
cmdline_parm multilog_arg("-multilog", NULL); // Cmdline_multi_log
cmdline_parm server_firing_arg("-oldfire", NULL); // Cmdline_server_firing
cmdline_parm client_dodamage("-clientdamage", NULL); // Cmdline_client_dodamage
cmdline_parm pof_spew("-pofspew", NULL); // Cmdline_spew_pof_info
cmdline_parm mouse_coords("-coords", NULL); // Cmdline_mouse_coords
@@ -240,6 +231,7 @@ int Cmdline_multi_log = 0;
int Cmdline_multi_stream_chat_to_file = 0;
int Cmdline_network_port = -1;
int Cmdline_restricted_game = 0;
int Cmdline_server_firing = 0;
int Cmdline_spew_pof_info = 0;
int Cmdline_start_netgame = 0;
int Cmdline_timeout = -1;
@@ -257,7 +249,10 @@ cmdline_parm spec_static_arg("-spec_static", NULL);
cmdline_parm spec_point_arg("-spec_point", NULL);
cmdline_parm spec_tube_arg("-spec_tube", NULL);
cmdline_parm ambient_factor_arg("-ambient_factor", NULL); // Cmdline_ambient_factor
cmdline_parm cell_arg("-cell", NULL); // Cmdline_cell
cmdline_parm decals("-decals", NULL); // Cmdline_decals
cmdline_parm env("-env", NULL); // Cmdline_env
cmdline_parm mipmap_arg("-mipmap", NULL); // Cmdline_mipmap
cmdline_parm missile_lighting_arg("-missile_lighting", NULL); // Cmdline_missile_lighting
cmdline_parm glow_arg("-glow", NULL); // Cmdline_glow -- use Bobs glow code
cmdline_parm nomotiondebris_arg("-nomotiondebris", NULL); // Cmdline_nomotiondebris -- Removes those ugly floating rocks -C
@@ -267,18 +262,15 @@ cmdline_parm noemissive_arg("-no_emissive_light", NULL); // Cmdline_no_emissive
cmdline_parm normal_arg("-normal", NULL); // Cmdline_normal -- enable normal mapping
cmdline_parm height_arg("-height", NULL); // Cmdline_height -- enable support for parallax mapping
cmdline_parm enable_3d_shockwave_arg("-3dshockwave", NULL);
cmdline_parm softparticles_arg("-soft_particles", NULL);
cmdline_parm postprocess_arg("-post_process", NULL);
cmdline_parm bloom_intensity_arg("-bloom_intensity", NULL);
cmdline_parm fxaa_arg("-fxaa", NULL);
cmdline_parm fxaa_preset_arg("-fxaa_preset", NULL);
cmdline_parm fb_explosions_arg("-fb_explosions", NULL);
cmdline_parm flightshaftsoff_arg("-flightshaftsoff", NULL);
float Cmdline_clip_dist = Default_min_draw_distance;
float Cmdline_fov = 0.75f;
float Cmdline_ogl_spec = 80.0f;
int Cmdline_ambient_factor = 128;
int Cmdline_cell = 0;
int Cmdline_decals = 0;
int Cmdline_env = 0;
int Cmdline_mipmap = 0;
int Cmdline_missile_lighting = 0;
@@ -290,14 +282,8 @@ int Cmdline_no_emissive = 0;
int Cmdline_normal = 0;
int Cmdline_height = 0;
int Cmdline_enable_3d_shockwave = 0;
int Cmdline_softparticles = 0;
int Cmdline_postprocess = 0;
int Cmdline_bloom_intensity = 75;
bool Cmdline_fxaa = false;
int Cmdline_fxaa_preset = 6;
extern int Fxaa_preset_last_frame;
bool Cmdline_fb_explosions = 0;
extern bool ls_force_off;
// Game Speed related
cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL); // Cmdline_cache_bitmaps
@@ -366,36 +352,31 @@ char *Cmdline_spew_table_crcs = NULL;
int Cmdline_objupd = 3; // client object updates on LAN by default
// Troubleshooting
cmdline_parm d3d_lesstmem_arg("-d3d_bad_tsys", NULL); // Cmdline_d3d_lesstmem
cmdline_parm loadallweapons_arg("-loadallweps", NULL); // Cmdline_load_all_weapons
cmdline_parm htl_arg("-nohtl", NULL); // Cmdline_nohtl -- don't use HT&L
cmdline_parm noibx_arg("-noibx", NULL); // Cmdline_noibx
cmdline_parm nomovies_arg("-nomovies", NULL); // Cmdline_nomovies -- Allows video streaming
cmdline_parm no_set_gamma_arg("-no_set_gamma", NULL); // Cmdline_no_set_gamma
cmdline_parm no_vbo_arg("-novbo", NULL); // Cmdline_novbo
cmdline_parm safeloading_arg("-safeloading", NULL); // Cmdline_safeloading -- Uses old loading method -C
cmdline_parm no_fbo_arg("-disable_fbo", NULL); // Cmdline_no_fbo
cmdline_parm noglsl_arg("-no_glsl", NULL); // Cmdline_noglsl -- disable GLSL support in OpenGL
cmdline_parm mipmap_arg("-mipmap", NULL); // Cmdline_mipmap
cmdline_parm atiswap_arg("-ati_swap", NULL); // Cmdline_atiswap - Fix ATI color swap issue for screenshots.
cmdline_parm no3dsound_arg("-no_3d_sound", NULL); // Cmdline_no_3d_sound - Disable use of full 3D sounds
cmdline_parm no_glsl_models_arg("-disable_glsl_model", NULL); // Cmdline_no_glsl_model_rendering -- switches model rendering to fixed pipeline
cmdline_parm no_di_mouse_arg("-disable_di_mouse", NULL); // Cmdline_no_di_mouse -- Disables directinput use for mouse control
cmdline_parm no_drawrangeelements("-use_gldrawelements", NULL); // Cmdline_drawelements -- Uses glDrawElements instead of glDrawRangeElements
cmdline_parm keyboard_layout("-keyboard_layout", NULL);
int Cmdline_d3d_lesstmem = 0;
int Cmdline_load_all_weapons = 0;
int Cmdline_nohtl = 0;
int Cmdline_noibx = 0;
int Cmdline_nomovies = 0;
int Cmdline_no_set_gamma = 0;
int Cmdline_novbo = 0; // turn off OGL VBO support, troubleshooting
int Cmdline_safeloading = 0;
int Cmdline_no_fbo = 0;
int Cmdline_noglsl = 0;
int Cmdline_ati_color_swap = 0;
int Cmdline_no_3d_sound = 0;
int Cmdline_no_glsl_model_rendering = 0;
int Cmdline_no_di_mouse = 0;
int Cmdline_drawelements = 0;
char* Cmdline_keyboard_layout = NULL;
// Developer/Testing related
cmdline_parm start_mission_arg("-start_mission", NULL); // Cmdline_start_mission
@@ -408,17 +389,16 @@ cmdline_parm fps_arg("-fps", NULL); // Cmdline_show_fps
cmdline_parm show_mem_usage_arg("-show_mem_usage", NULL); // Cmdline_show_mem_usage
cmdline_parm pos_arg("-pos", NULL); // Cmdline_show_pos
cmdline_parm stats_arg("-stats", NULL); // Cmdline_show_stats
cmdline_parm timerbar_arg("-timerbar", NULL); // Cmdline_timerbar
cmdline_parm save_render_targets_arg("-save_render_target", NULL); // Cmdline_save_render_targets
cmdline_parm debug_window_arg("-debug_window", NULL); // Cmdline_debug_window
cmdline_parm window_arg("-window", NULL); // Cmdline_window
cmdline_parm fullscreen_window_arg("-fullscreen_window",NULL);
cmdline_parm res_arg("-res", NULL); // Cmdline_lores
cmdline_parm verify_vps_arg("-verify_vps", NULL); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, NULL);
#ifdef SCP_UNIX
cmdline_parm no_grab("-nograb", NULL); // Cmdline_no_grab
#endif
cmdline_parm reparse_mainhall_arg("-reparse_mainhall", NULL); //Cmdline_reparse_mainhall
char *Cmdline_start_mission = NULL;
int Cmdline_dis_collisions = 0;
@@ -429,6 +409,7 @@ int Cmdline_extra_warn = 0;
int Cmdline_show_mem_usage = 0;
int Cmdline_show_pos = 0;
int Cmdline_show_stats = 0;
int Cmdline_timerbar = 0;
int Cmdline_save_render_targets = 0;
int Cmdline_debug_window = 0;
int Cmdline_window = 0;
@@ -438,7 +419,6 @@ int Cmdline_verify_vps = 0;
#ifdef SCP_UNIX
int Cmdline_no_grab = 0;
#endif
int Cmdline_reparse_mainhall = 0;
// Other
cmdline_parm get_flags_arg("-get_flags", NULL);
@@ -592,12 +572,10 @@ void os_parse_parms(char *cmdline)
if ( !cmdline_offset )
break;
int parmp_len = strlen(parmp->name);
// the new offset should be our currently location + the length of the current option
get_new_offset = (strlen(cmdline) - strlen(cmdline_offset) + parmp_len);
get_new_offset = (strlen(cmdline) - strlen(cmdline_offset) + strlen(parmp->name));
if ( (*(cmdline_offset + parmp_len)) && !is_extra_space(*(cmdline_offset + parmp_len)) ) {
if ( (*(cmdline_offset + strlen(parmp->name))) && !is_extra_space(*(cmdline_offset + strlen(parmp->name))) ) {
// we found a similar, but not exact, match for this option, continue checking for the correct one
} else {
// we found what we were looking for so break out and process it
@@ -626,8 +604,8 @@ void os_validate_parms(char *cmdline)
char *token;
int parm_found;
token = strtok(cmdline, seps);
while(token != NULL) {
token = strtok(cmdline, seps);
while(token != NULL) {
if (token[0] == '-') {
parm_found = 0;
@@ -653,17 +631,11 @@ void os_validate_parms(char *cmdline)
snprintf(buffer, 128, "Unrecognized command line parameter, \"%s\", continue?", token);
message = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingASCII);
if ( CFUserNotificationDisplayAlert(0, kCFUserNotificationPlainAlertLevel, NULL, NULL, NULL, CFSTR("Unknown Command"), message, NULL, CFSTR("Quit"), NULL, &result) ) {
CFRelease(message);
if ( CFUserNotificationDisplayAlert(0, kCFUserNotificationPlainAlertLevel, NULL, NULL, NULL, CFSTR("Unknown Command"), message, NULL, CFSTR("Quit"), NULL, &result) )
exit(0);
}
if (result != kCFUserNotificationDefaultResponse) {
CFRelease(message);
if (result != kCFUserNotificationDefaultResponse)
exit(0);
}
CFRelease(message);
#else
// if we got a -help, --help, -h, or -? then show the help text, otherwise show unknown option
if ( !stricmp(token, "-help") || !stricmp(token, "--help") || !stricmp(token, "-h") || !stricmp(token, "-?") ) {
@@ -706,12 +678,6 @@ void os_init_cmdline(char *cmdline)
{
FILE *fp;
bool parse_config = true;
if (strstr(cmdline, PARSE_COMMAND_LINE_STRING) != NULL) {
parse_config = false;
}
// read the cmdline.cfg file from the data folder, and pass the command line arguments to
// the the parse_parms and validate_parms line. Read these first so anything actually on
// the command line will take precedence
@@ -736,7 +702,7 @@ void os_init_cmdline(char *cmdline)
#endif
// if the file exists, get a single line, and deal with it
if ( fp && parse_config ) {
if ( fp ) {
char *buf, *p;
size_t len = filelength( fileno(fp) ) + 2;
@@ -938,12 +904,23 @@ bool SetCmdlineParams()
{
Cmdline_nowarn = 1;
}
/* karajorma - let's just use -nohtl instead
if (fred2_htl_arg.found())
{
Cmdline_FRED2_htl = 1;
}*/
if (extra_warn_arg.found())
{
Cmdline_extra_warn = 1;
}
if (timerbar_arg.found()) {
#ifdef WIN32
MessageBox(NULL, "the timerbar has been disabled in builds after August 31, 2010. Please remove the \"-timerbar\" command line from the launcher to prevent this message from appearing the the future.", "", MB_OK | MB_ICONINFORMATION);
#endif
}
if ( missioncrcspew_arg.found() ) {
Cmdline_spew_mission_crcs = missioncrcspew_arg.str();
@@ -962,11 +939,9 @@ bool SetCmdlineParams()
}
}
if (!Fred_running) { //There is no standalone FRED
// is this a standalone server??
if (standalone_arg.found()) {
Is_standalone = 1;
}
// is this a standalone server??
if (standalone_arg.found()) {
Is_standalone = 1;
}
// object update control
@@ -1058,6 +1033,10 @@ bool SetCmdlineParams()
Cmdline_multi_log = 1;
}
// maybe use old-school server-side firing
if (server_firing_arg.found() ){
Cmdline_server_firing = 1;
}
// maybe use old-school client damage
if(client_dodamage.found()){
@@ -1167,6 +1146,10 @@ bool SetCmdlineParams()
Cmdline_show_pos = 1;
}
if ( safeloading_arg.found() ) {
Cmdline_safeloading = 1;
}
if ( nomotiondebris_arg.found() ) {
Cmdline_nomotiondebris = 1;
}
@@ -1225,6 +1208,10 @@ bool SetCmdlineParams()
static_tube_factor = spec_tube_arg.get_float();
}
if ( cell_arg.found() ) {
Cmdline_cell = 1;
}
if ( spec_arg.found() )
{
Cmdline_spec = 1;
@@ -1265,24 +1252,6 @@ bool SetCmdlineParams()
Cmdline_noglsl = 1;
}
if (no_glsl_models_arg.found() ) {
Cmdline_no_glsl_model_rendering = 1;
}
if (fxaa_arg.found() ) {
Cmdline_fxaa = true;
if (fxaa_preset_arg.found()) {
Cmdline_fxaa_preset = fxaa_preset_arg.get_int();
}
Fxaa_preset_last_frame = Cmdline_fxaa_preset;
}
if (no_di_mouse_arg.found() ) {
Cmdline_no_di_mouse = 1;
}
if ( img2dds_arg.found() )
Cmdline_img2dds = 1;
@@ -1363,21 +1332,13 @@ bool SetCmdlineParams()
output_sexps("sexps.html");
}
Cmdline_d3d_lesstmem = !d3d_lesstmem_arg.found();
if ( no_vbo_arg.found() )
{
Cmdline_novbo = 1;
}
if ( no_drawrangeelements.found() )
{
Cmdline_drawelements = 1;
}
if( keyboard_layout.found())
{
Cmdline_keyboard_layout = keyboard_layout.str();
}
if ( snd_preload_arg.found() )
{
Cmdline_snd_preload = 1;
@@ -1387,6 +1348,13 @@ bool SetCmdlineParams()
Cmdline_env = 1;
}
if ( decals.found() ) {
#ifdef WIN32
MessageBox(NULL, "Decals have been disabled in builds after May 4, 2006. Please remove the \"-decals\" command line from the launcher to prevent this message from appearing the the future.", "", MB_OK | MB_ICONINFORMATION);
#endif
}
if ( ballistic_gauge.found() ) {
Cmdline_ballistic_gauge = 1;
}
@@ -1451,16 +1419,6 @@ bool SetCmdlineParams()
Cmdline_enable_3d_shockwave = 1;
}
if ( softparticles_arg.found() )
{
Cmdline_softparticles = 1;
}
if ( fb_explosions_arg.found() )
{
Cmdline_fb_explosions = 1;
}
if ( postprocess_arg.found() )
{
Cmdline_postprocess = 1;
@@ -1471,16 +1429,6 @@ bool SetCmdlineParams()
Cmdline_bloom_intensity = bloom_intensity_arg.get_int();
}
if ( flightshaftsoff_arg.found() )
{
ls_force_off = true;
}
if( reparse_mainhall_arg.found() )
{
Cmdline_reparse_mainhall = 1;
}
return true;
}
+10 -10
View File
@@ -41,6 +41,7 @@ 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;
@@ -61,7 +62,10 @@ 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_decals;
extern int Cmdline_env;
extern int Cmdline_mipmap;
extern int Cmdline_missile_lighting;
extern int Cmdline_glow;
extern int Cmdline_nomotiondebris;
@@ -70,12 +74,8 @@ extern int Cmdline_spec;
extern int Cmdline_normal;
extern int Cmdline_height;
extern int Cmdline_enable_3d_shockwave;
extern int Cmdline_softparticles;
extern int Cmdline_postprocess;
extern int Cmdline_bloom_intensity;
extern bool Cmdline_fxaa;
extern int Cmdline_fxaa_preset;
extern bool Cmdline_fb_explosions;
// Game Speed related
extern int Cmdline_cache_bitmaps;
@@ -113,21 +113,18 @@ 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_mipmap;
extern int Cmdline_ati_color_swap;
extern int Cmdline_no_3d_sound;
extern int Cmdline_no_glsl_model_rendering;
extern int Cmdline_no_di_mouse;
extern int Cmdline_drawelements;
extern char* Cmdline_keyboard_layout;
// Developer/Testing related
extern char *Cmdline_start_mission;
@@ -139,12 +136,15 @@ 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 int Cmdline_reparse_mainhall;
//extern char FreeSpace_Directory[]; // allievating a cfilesystem problem caused by fred -- Kazan
#endif
+195 -10
View File
@@ -10,6 +10,8 @@
#include "cmeasure/cmeasure.h"
//#include "freespace2/freespace.h"
//#include "model/model.h"
#include "ship/ship.h"
#include "math/staticrand.h"
#include "object/object.h"
@@ -19,9 +21,192 @@
#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)
@@ -44,6 +229,12 @@ void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
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;
@@ -68,18 +259,12 @@ void cmeasure_select_next(ship *shipp)
}
}
//snd_play( &Snds[SND_CMEASURE_CYCLE] );
mprintf(("Countermeasure type set to %i in frame %i\n", shipp->current_cmeasure, Framecount));
}
/**
* @brief If this is a player countermeasure, let the player know they evaded a missile.
* @param objp [description]
*
* During single player games, this function notifies the player that evasion has occurred.
* Multiplayer games ensure that #send_countermeasure_success_packet() is called to notify the other player.
*/
// 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
@@ -91,7 +276,7 @@ void cmeasure_maybe_alert_success(object *objp)
if ( objp->parent == OBJ_INDEX(Player_obj) ) {
hud_start_text_flash(XSTR("Evaded", 1430), 800);
snd_play(&Snds[ship_get_sound(Player_obj, SND_MISSILE_EVADED_POPUP)]);
snd_play(&Snds[SND_MISSILE_EVADED_POPUP]);
} else if ( Objects[objp->parent].flags & OF_PLAYER_SHIP ) {
send_countermeasure_success_packet( objp->parent );
}
+45
View File
@@ -16,18 +16,63 @@
#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
+143 -141
View File
@@ -48,169 +48,171 @@ typedef struct config_item {
int used; // has control been used yet in mission? If so, this is the timestamp
} config_item;
/**
* All available actions
* This is the value of the id field in config_item
*/
enum IoActionId {
// targeting a ship
TARGET_NEXT =0, //!< target next
TARGET_PREV =1, //!< target previous
TARGET_NEXT_CLOSEST_HOSTILE =2, //!< target the next hostile target
TARGET_PREV_CLOSEST_HOSTILE =3, //!< target the previous closest hostile
TOGGLE_AUTO_TARGETING =4, //!< toggle auto-targeting
TARGET_NEXT_CLOSEST_FRIENDLY =5, //!< target the next friendly ship
TARGET_PREV_CLOSEST_FRIENDLY =6, //!< target the closest friendly ship
TARGET_SHIP_IN_RETICLE =7, //!< target ship closest to center of reticle
TARGET_CLOSEST_SHIP_ATTACKING_TARGET =8, //!< target the closest ship attacking current target
TARGET_LAST_TRANMISSION_SENDER =9, //!< TARGET_LAST_TRANMISSION_SENDER
STOP_TARGETING_SHIP =10, //!< stop targeting ship
// --------------------------------------------------
// Keyboard #defines for the actions
// This is the value of the id field in config_item
// --------------------------------------------------
// targeting a ship's subsystem
TARGET_SUBOBJECT_IN_RETICLE =11, //!< target ships subsystem in reticle
TARGET_NEXT_SUBOBJECT =12, //!< target next subsystem on current target
TARGET_PREV_SUBOBJECT =13, //!< TARGET_PREV_SUBOBJECT
STOP_TARGETING_SUBSYSTEM =14, //!< stop targeting subsystems on ship
// targeting a ship
// speed matching
MATCH_TARGET_SPEED =15, //!< match target speed
TOGGLE_AUTO_MATCH_TARGET_SPEED =16, //!< toggle auto-match target speed
#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
// weapons
FIRE_PRIMARY =17, //!< FIRE_PRIMARY
FIRE_SECONDARY =18, //!< FIRE_SECONDARY
CYCLE_NEXT_PRIMARY =19, //!< cycle to next primary weapon
CYCLE_PREV_PRIMARY =20, //!< cycle to previous primary weapon
CYCLE_SECONDARY =21, //!< cycle to next secondary weapon
CYCLE_NUM_MISSLES =22, //!< cycle number of missiles fired from secondary bank
LAUNCH_COUNTERMEASURE =23, //!< LAUNCH_COUNTERMEASURE
// 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
// controls
FORWARD_THRUST =24, //!< FORWARD_THRUST
REVERSE_THRUST =25, //!< REVERSE_THRUST
BANK_LEFT =26, //!< BANK_LEFT
BANK_RIGHT =27, //!< BANK_RIGHT
PITCH_FORWARD =28, //!< PITCH_FORWARD
PITCH_BACK =29, //!< PITCH_BACK
YAW_LEFT =30, //!< YAW_LEFT
YAW_RIGHT =31, //!< YAW_RIGHT
// speed matching
#define MATCH_TARGET_SPEED 15
#define TOGGLE_AUTO_MATCH_TARGET_SPEED 16
// throttle control
ZERO_THROTTLE =32, //!< ZERO_THROTTLE
MAX_THROTTLE =33, //!< MAX_THROTTLE
ONE_THIRD_THROTTLE =34, //!< ONE_THIRD_THROTTLE
TWO_THIRDS_THROTTLE =35, //!< TWO_THIRDS_THROTTLE
PLUS_5_PERCENT_THROTTLE =36, //!< PLUS_5_PERCENT_THROTTLE
MINUS_5_PERCENT_THROTTLE =37, //!< MINUS_5_PERCENT_THROTTLE
// 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
// squadmate messaging keys
ATTACK_MESSAGE =38, //!< wingman message: attack current target
DISARM_MESSAGE =39, //!< wingman message: disarm current target
DISABLE_MESSAGE =40, //!< wingman message: disable current target
ATTACK_SUBSYSTEM_MESSAGE =41, //!< wingman message: disable current target
CAPTURE_MESSAGE =42, //!< wingman message: capture current target
ENGAGE_MESSAGE =43, //!< wingman message: engage enemy
FORM_MESSAGE =44, //!< wingman message: form on my wing
IGNORE_MESSAGE =45, //!< IGNORE_MESSAGE
PROTECT_MESSAGE =46, //!< wingman message: protect current target
COVER_MESSAGE =47, //!< wingman message: cover me
WARP_MESSAGE =48, //!< wingman message: warp out
REARM_MESSAGE =49, //!< REARM_MESSAGE
TARGET_CLOSEST_SHIP_ATTACKING_SELF =50, //!< target closest ship that is attacking player
// 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
// Views
VIEW_CHASE =51, //!< VIEW_CHASE
VIEW_EXTERNAL =52, //!< VIEW_EXTERNAL
VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK =53, //!< VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK
VIEW_SLEW =54, //!< VIEW_SLEW
VIEW_OTHER_SHIP =55, //!< VIEW_OTHER_SHIP
VIEW_DIST_INCREASE =56, //!< VIEW_DIST_INCREASE
VIEW_DIST_DECREASE =57, //!< VIEW_DIST_DECREASE
VIEW_CENTER =58, //!< VIEW_CENTER
PADLOCK_UP =59, //!< PADLOCK_UP
PADLOCK_DOWN =60, //!< PADLOCK_DOWN
PADLOCK_LEFT =61, //!< PADLOCK_LEFT
PADLOCK_RIGHT =62, //!< PADLOCK_RIGHT
// 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
RADAR_RANGE_CYCLE =63, //!< cycle to next radar range
SQUADMSG_MENU =64, //!< toggle the squadmate messaging menu
SHOW_GOALS =65, //!< show the mission goals screen
END_MISSION =66, //!< end the mission
TARGET_TARGETS_TARGET =67, //!< target your target's target
AFTERBURNER =68, //!< AFTERBURNER
// 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
INCREASE_WEAPON =69, //!< increase weapon recharge rate
DECREASE_WEAPON =70, //!< decrease weapon recharge rate
INCREASE_SHIELD =71, //!< increase shield recharge rate
DECREASE_SHIELD =72, //!< decrease shield recharge rate
INCREASE_ENGINE =73, //!< increase energy to engines
DECREASE_ENGINE =74, //!< decrease energy to engines
ETS_EQUALIZE =75, //!< equalize recharge rates
SHIELD_EQUALIZE =76, //!< equalize shield energy to all quadrants
SHIELD_XFER_TOP =77, //!< transfer shield energy to front
SHIELD_XFER_BOTTOM =78, //!< transfer shield energy to rear
SHIELD_XFER_LEFT =79, //!< transfer shield energy to left
SHIELD_XFER_RIGHT =80, //!< transfer shield energy to right
#define TARGET_CLOSEST_SHIP_ATTACKING_SELF 50
XFER_SHIELD =81, //!< transfer energy to shield from weapons
XFER_LASER =82, //!< transfer energy to weapons from shield
// 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
//Backslash -- this was a convenient place for Glide When Pressed, since Show Damage Popup isn't used
GLIDE_WHEN_PRESSED =83, //!< GLIDE_WHEN_PRESSED
BANK_WHEN_PRESSED =84, //!< BANK_WHEN_PRESSED
SHOW_NAVMAP =85, //!< SHOW_NAVMAP
ADD_REMOVE_ESCORT =86, //!< ADD_REMOVE_ESCORT
ESCORT_CLEAR =87, //!< ESCORT_CLEAR
TARGET_NEXT_ESCORT_SHIP =88, //!< TARGET_NEXT_ESCORT_SHIP
TARGET_CLOSEST_REPAIR_SHIP =89, //!< target the closest repair ship
TARGET_NEXT_UNINSPECTED_CARGO =90, //!< TARGET_NEXT_UNINSPECTED_CARGO
TARGET_PREV_UNINSPECTED_CARGO =91, //!< TARGET_PREV_UNINSPECTED_CARGO
TARGET_NEWEST_SHIP =92, //!< TARGET_NEWEST_SHIP
TARGET_NEXT_LIVE_TURRET =93, //!< TARGET_NEXT_LIVE_TURRET
TARGET_PREV_LIVE_TURRET =94, //!< TARGET_PREV_LIVE_TURRET
TARGET_NEXT_BOMB =95, //!< TARGET_NEXT_BOMB
TARGET_PREV_BOMB =96, //!< TARGET_PREV_BOMB
#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
// multiplayer messaging keys
MULTI_MESSAGE_ALL =97, //!< message all netplayers
MULTI_MESSAGE_FRIENDLY =98, //!< message all friendlies
MULTI_MESSAGE_HOSTILE =99, //!< message all hostiles
MULTI_MESSAGE_TARGET =100, //!< message targeted ship (if player)
#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
// multiplayer misc keys
MULTI_OBSERVER_ZOOM_TO =101, //!< if i'm an observer, zoom to my targeted object
#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
TIME_SPEED_UP =102, //!< TIME_SPEED_UP
TIME_SLOW_DOWN =103, //!< TIME_SLOW_DOWN
#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
TOGGLE_HUD_CONTRAST =104, //!< toggle between high and low HUD contrast
#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
MULTI_TOGGLE_NETINFO =105, //!< toggle network info
#define TARGET_NEXT_BOMB 95
#define TARGET_PREV_BOMB 96
MULTI_SELF_DESTRUCT =106, //!< self destruct (multiplayer only)
// multiplayer messaging keys
#define MULTI_MESSAGE_ALL 97
#define MULTI_MESSAGE_FRIENDLY 98
#define MULTI_MESSAGE_HOSTILE 99
#define MULTI_MESSAGE_TARGET 100
TOGGLE_HUD =107, //!< TOGGLE_HUD
RIGHT_SLIDE_THRUST =108, //!< RIGHT_SLIDE_THRUST
LEFT_SLIDE_THRUST =109, //!< LEFT_SLIDE_THRUST
UP_SLIDE_THRUST =110, //!< UP_SLIDE_THRUST
DOWN_SLIDE_THRUST =111, //!< DOWN_SLIDE_THRUST
HUD_TARGETBOX_TOGGLE_WIREFRAME =112, //!< HUD_TARGETBOX_TOGGLE_WIREFRAME
VIEW_TOPDOWN =113, //!< VIEW_TOPDOWN
VIEW_TRACK_TARGET =114, //!< VIEW_TRACK_TARGET
// multiplayer misc keys
#define MULTI_OBSERVER_ZOOM_TO 101
//AutoPilot - Kazan
AUTO_PILOT_TOGGLE =115, //!< Autopilot key control
NAV_CYCLE =116, //!< NAV_CYCLE
#define TIME_SPEED_UP 102
#define TIME_SLOW_DOWN 103
//Gliding
TOGGLE_GLIDING =117, //!< TOGGLE_GLIDING
#define TOGGLE_HUD_CONTRAST 104
/**
* This must always be below the last defined action
*/
CCFG_MAX //!< The total number of defined control actions (or last define + 1)
};
#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;
+11 -273
View File
@@ -7,17 +7,13 @@
*
*/
#include <stdio.h>
#include <stdarg.h>
#include "cfile/cfile.h"
#include "controlconfig/controlsconfig.h"
#include "io/key.h"
#include "io/joy.h"
#include "localization/localize.h"
#include "parse/parselo.h"
#include "globalincs/systemvars.h"
#include "globalincs/def_files.h"
#define TARGET_TAB 0
#define SHIP_TAB 1
@@ -289,7 +285,7 @@ char *Joy_button_text_french[] = {
"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 Arriere", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
"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
@@ -449,48 +445,21 @@ int translate_key_to_index(char *key)
// or there is no key current bound to the function, NULL is returned.
char *translate_key(char *key)
{
int index = -1, key_code = -1, joy_code = -1;
char *key_text = NULL;
char *joy_text = NULL;
static char text[40] = {"None"};
int index = -1, code = -1;
index = translate_key_to_index(key);
if (index < 0) {
if (index < 0)
return NULL;
}
key_code = Control_config[index].key_id;
joy_code = Control_config[index].joy_id;
code = Control_config[index].key_id;
Failed_key_index = index;
if (key_code >= 0) {
key_text = textify_scancode(key_code);
if (code < 0) {
code = Control_config[index].joy_id;
if (code >= 0)
return Joy_button_text[code];
}
if (joy_code >= 0) {
joy_text = Joy_button_text[joy_code];
}
// both key and joystick button are mapped to this control
if ((key_code >= 0 ) && (joy_code >= 0) ) {
strcpy_s(text, key_text);
strcat_s(text, " or ");
strcat_s(text, joy_text);
}
// if we only have one
else if (key_code >= 0 ) {
strcpy_s(text, key_text);
}
else if (joy_code >= 0) {
strcpy_s(text, joy_text);
}
else {
strcpy_s(text, "None");
}
return text;
return textify_scancode(code);
}
char *textify_scancode(int code)
@@ -528,12 +497,9 @@ char *textify_scancode(int code)
}
//XSTR:ON
void control_config_common_load_overrides();
// initialize common control config stuff - call at game startup after localization has been initialized
void control_config_common_init()
{
control_config_common_load_overrides();
if(Lcl_gr){
Scan_code_text = Scan_code_text_german;
Joy_button_text = Joy_button_text_german;
@@ -551,231 +517,3 @@ void control_config_common_init()
Joy_button_text = Joy_button_text_english;
}
}
#include <map>
#include <string>
SCP_map<SCP_string, int> mEnumNameToVal;
void LoadEnumsIntoMap();
void control_config_common_load_overrides()
{
LoadEnumsIntoMap();
if (cf_exists_full("controlconfigdefaults.tbl", CF_TYPE_TABLES))
read_file_text("controlconfigdefaults.tbl", CF_TYPE_TABLES);
else
read_file_text_from_array(defaults_get_file("controlconfigdefaults.tbl"));
reset_parse();
// start parsing
required_string("#ControlConfigOverride");
// read fonts
while (required_string_either("#End","$Bind Name:"))
{
const int iBufferLength = 64;
char szTempBuffer[iBufferLength];
required_string("$Bind Name:");
stuff_string(szTempBuffer, F_NAME, iBufferLength);
const size_t cCntrlAryLength = sizeof(Control_config) / sizeof(Control_config[0]);
for (size_t i = 0; i < cCntrlAryLength; ++i)
{
config_item& r_ccConfig = Control_config[i];
if (!strcmp(szTempBuffer, r_ccConfig.text))
{
/**
* short key_default;
* short joy_default;
* char tab;
* bool hasXSTR;
* char type;
*/
int iTemp;
if (optional_string("$Key Default:"))
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.key_default = (short)mEnumNameToVal[szTempBuffer];}
if (optional_string("$Joy Default:"))
{stuff_int(&iTemp); r_ccConfig.joy_default = (short)iTemp;}
if (optional_string("$Key Mod Shift:"))
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_SHIFTED : 0;}
if (optional_string("$Key Mod Alt:"))
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_ALTED : 0;}
if (optional_string("$Key Mod Ctrl:"))
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_CTRLED : 0;}
if (optional_string("$Category:"))
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.tab = (char)mEnumNameToVal[szTempBuffer];}
if (optional_string("$Has XStr:"))
{stuff_int(&iTemp); r_ccConfig.hasXSTR = (iTemp == 1);}
if (optional_string("$Type:"))
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.type = (char)mEnumNameToVal[szTempBuffer];}
// Nerf the buffer now.
szTempBuffer[0] = '\0';
}
else if ((i + 1) == cCntrlAryLength)
{
error_display(1, "Bind Name not found: %s\n", szTempBuffer);
advance_to_eoln(NULL);
ignore_white_space();
return;
}
}
}
required_string("#End");
}
#define ADD_ENUM_TO_ENUM_MAP(Enum) mEnumNameToVal[#Enum] = (Enum);
void LoadEnumsIntoMap()
{
mEnumNameToVal["KEY_SHIFTED"] = KEY_SHIFTED;
/*
ADD_ENUM_TO_ENUM_MAP(KEY_SHIFTED)
ADD_ENUM_TO_ENUM_MAP(KEY_ALTED)
ADD_ENUM_TO_ENUM_MAP(KEY_CTRLED)
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUGGED)
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUGGED1)
ADD_ENUM_TO_ENUM_MAP(KEY_MASK)
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUG_KEY)
*/
ADD_ENUM_TO_ENUM_MAP(KEY_0)
ADD_ENUM_TO_ENUM_MAP(KEY_1)
ADD_ENUM_TO_ENUM_MAP(KEY_2)
ADD_ENUM_TO_ENUM_MAP(KEY_3)
ADD_ENUM_TO_ENUM_MAP(KEY_4)
ADD_ENUM_TO_ENUM_MAP(KEY_5)
ADD_ENUM_TO_ENUM_MAP(KEY_6)
ADD_ENUM_TO_ENUM_MAP(KEY_7)
ADD_ENUM_TO_ENUM_MAP(KEY_8)
ADD_ENUM_TO_ENUM_MAP(KEY_9)
ADD_ENUM_TO_ENUM_MAP(KEY_A)
ADD_ENUM_TO_ENUM_MAP(KEY_B)
ADD_ENUM_TO_ENUM_MAP(KEY_C)
ADD_ENUM_TO_ENUM_MAP(KEY_D)
ADD_ENUM_TO_ENUM_MAP(KEY_E)
ADD_ENUM_TO_ENUM_MAP(KEY_F)
ADD_ENUM_TO_ENUM_MAP(KEY_G)
ADD_ENUM_TO_ENUM_MAP(KEY_H)
ADD_ENUM_TO_ENUM_MAP(KEY_I)
ADD_ENUM_TO_ENUM_MAP(KEY_J)
ADD_ENUM_TO_ENUM_MAP(KEY_K)
ADD_ENUM_TO_ENUM_MAP(KEY_L)
ADD_ENUM_TO_ENUM_MAP(KEY_M)
ADD_ENUM_TO_ENUM_MAP(KEY_N)
ADD_ENUM_TO_ENUM_MAP(KEY_O)
ADD_ENUM_TO_ENUM_MAP(KEY_P)
ADD_ENUM_TO_ENUM_MAP(KEY_Q)
ADD_ENUM_TO_ENUM_MAP(KEY_R)
ADD_ENUM_TO_ENUM_MAP(KEY_S)
ADD_ENUM_TO_ENUM_MAP(KEY_T)
ADD_ENUM_TO_ENUM_MAP(KEY_U)
ADD_ENUM_TO_ENUM_MAP(KEY_V)
ADD_ENUM_TO_ENUM_MAP(KEY_W)
ADD_ENUM_TO_ENUM_MAP(KEY_X)
ADD_ENUM_TO_ENUM_MAP(KEY_Y)
ADD_ENUM_TO_ENUM_MAP(KEY_Z)
ADD_ENUM_TO_ENUM_MAP(KEY_MINUS)
ADD_ENUM_TO_ENUM_MAP(KEY_EQUAL)
ADD_ENUM_TO_ENUM_MAP(KEY_DIVIDE)
ADD_ENUM_TO_ENUM_MAP(KEY_SLASH)
ADD_ENUM_TO_ENUM_MAP(KEY_SLASH_UK)
ADD_ENUM_TO_ENUM_MAP(KEY_COMMA)
ADD_ENUM_TO_ENUM_MAP(KEY_PERIOD)
ADD_ENUM_TO_ENUM_MAP(KEY_SEMICOL)
ADD_ENUM_TO_ENUM_MAP(KEY_LBRACKET)
ADD_ENUM_TO_ENUM_MAP(KEY_RBRACKET)
ADD_ENUM_TO_ENUM_MAP(KEY_RAPOSTRO)
ADD_ENUM_TO_ENUM_MAP(KEY_LAPOSTRO)
ADD_ENUM_TO_ENUM_MAP(KEY_ESC)
ADD_ENUM_TO_ENUM_MAP(KEY_ENTER)
ADD_ENUM_TO_ENUM_MAP(KEY_BACKSP)
ADD_ENUM_TO_ENUM_MAP(KEY_TAB)
ADD_ENUM_TO_ENUM_MAP(KEY_SPACEBAR)
ADD_ENUM_TO_ENUM_MAP(KEY_NUMLOCK)
ADD_ENUM_TO_ENUM_MAP(KEY_SCROLLOCK)
ADD_ENUM_TO_ENUM_MAP(KEY_CAPSLOCK)
ADD_ENUM_TO_ENUM_MAP(KEY_LSHIFT)
ADD_ENUM_TO_ENUM_MAP(KEY_RSHIFT)
ADD_ENUM_TO_ENUM_MAP(KEY_LALT)
ADD_ENUM_TO_ENUM_MAP(KEY_RALT)
ADD_ENUM_TO_ENUM_MAP(KEY_LCTRL)
ADD_ENUM_TO_ENUM_MAP(KEY_RCTRL)
ADD_ENUM_TO_ENUM_MAP(KEY_F1)
ADD_ENUM_TO_ENUM_MAP(KEY_F2)
ADD_ENUM_TO_ENUM_MAP(KEY_F3)
ADD_ENUM_TO_ENUM_MAP(KEY_F4)
ADD_ENUM_TO_ENUM_MAP(KEY_F5)
ADD_ENUM_TO_ENUM_MAP(KEY_F6)
ADD_ENUM_TO_ENUM_MAP(KEY_F7)
ADD_ENUM_TO_ENUM_MAP(KEY_F8)
ADD_ENUM_TO_ENUM_MAP(KEY_F9)
ADD_ENUM_TO_ENUM_MAP(KEY_F10)
ADD_ENUM_TO_ENUM_MAP(KEY_F11)
ADD_ENUM_TO_ENUM_MAP(KEY_F12)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD0)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD1)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD2)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD3)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD4)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD5)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD6)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD7)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD8)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD9)
ADD_ENUM_TO_ENUM_MAP(KEY_PADMINUS)
ADD_ENUM_TO_ENUM_MAP(KEY_PADPLUS)
ADD_ENUM_TO_ENUM_MAP(KEY_PADPERIOD)
ADD_ENUM_TO_ENUM_MAP(KEY_PADDIVIDE)
ADD_ENUM_TO_ENUM_MAP(KEY_PADMULTIPLY)
ADD_ENUM_TO_ENUM_MAP(KEY_PADENTER)
ADD_ENUM_TO_ENUM_MAP(KEY_INSERT)
ADD_ENUM_TO_ENUM_MAP(KEY_HOME)
ADD_ENUM_TO_ENUM_MAP(KEY_PAGEUP)
ADD_ENUM_TO_ENUM_MAP(KEY_DELETE)
ADD_ENUM_TO_ENUM_MAP(KEY_END)
ADD_ENUM_TO_ENUM_MAP(KEY_PAGEDOWN)
ADD_ENUM_TO_ENUM_MAP(KEY_UP)
ADD_ENUM_TO_ENUM_MAP(KEY_DOWN)
ADD_ENUM_TO_ENUM_MAP(KEY_LEFT)
ADD_ENUM_TO_ENUM_MAP(KEY_RIGHT)
ADD_ENUM_TO_ENUM_MAP(KEY_PRINT_SCRN)
ADD_ENUM_TO_ENUM_MAP(KEY_PAUSE)
ADD_ENUM_TO_ENUM_MAP(KEY_BREAK)
ADD_ENUM_TO_ENUM_MAP(TARGET_TAB)
ADD_ENUM_TO_ENUM_MAP(SHIP_TAB)
ADD_ENUM_TO_ENUM_MAP(WEAPON_TAB)
ADD_ENUM_TO_ENUM_MAP(COMPUTER_TAB)
}
+72
View File
@@ -0,0 +1,72 @@
/*
* 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);
}
+49 -22
View File
@@ -42,9 +42,13 @@ 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(SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut)
if(cut->description)
vm_free(cut->description);
for(size_t i = 0; i < Cutscenes.size(); i++)
{
if(Cutscenes[i].description)
{
vm_free(Cutscenes[i].description);
}
}
}
// initialization stuff for cutscenes
@@ -106,13 +110,18 @@ void cutscene_init()
// returns -1 on failure.
int cutscenes_get_cd_num( char *filename )
{
for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut) {
if ( !stricmp(cut->filename, filename) ) {
return (cut->cd - 1);
#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
@@ -132,10 +141,10 @@ void cutscene_mark_viewable(char *filename)
// change to lower case
strlwr(file);
int i = 0;
for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut) {
for (size_t i = 0; i < Cutscenes.size(); i++ ) {
// change the cutscene file name to lower case
strcpy_s(cut_file, cut->filename);
strcpy_s(cut_file, Cutscenes[i].filename);
strlwr(cut_file);
// see if the stripped filename matches the cutscene filename
@@ -143,7 +152,6 @@ void cutscene_mark_viewable(char *filename)
Cutscenes_viewable |= (1<<i);
return;
}
i++;
}
}
@@ -159,6 +167,7 @@ void cutscene_mark_viewable(char *filename)
#define PLAY_BUTTON 6
#define EXIT_BUTTON 7
static int Num_files;
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
@@ -253,7 +262,9 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
int cd_mve_is_on;
char volume_name[128];
#ifdef RELEASE_REAL
int num_attempts = 0;
#endif
while(1) {
int path_set_ok;
@@ -264,7 +275,12 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
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);
@@ -274,6 +290,7 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
break;
}
#ifdef RELEASE_REAL
if ( !prompt_for_cd ) {
cd_present = 0;
break;
@@ -283,7 +300,11 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
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 ) {
@@ -295,6 +316,11 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
cd_present = 0;
break;
}
#else
cd_present = 0;
break;
#endif
}
return cd_present;
@@ -305,7 +331,7 @@ void cutscenes_screen_play()
char name[MAX_FILENAME_LEN]; // *full_name
int which_cutscene;
Assert( (Selected_line >= 0) && (Selected_line < (int)Cutscene_list.size()) );
Assert( (Selected_line >= 0) && (Selected_line < Num_files) );
which_cutscene = Cutscene_list[Selected_line];
strcpy_s(name, Cutscenes[which_cutscene].filename );
@@ -346,7 +372,7 @@ void cutscenes_screen_scroll_line_down()
{
int h;
if (Selected_line < (int)Cutscene_list.size() - 1) {
if (Selected_line < Num_files - 1) {
Selected_line++;
gamesnd_play_iface(SND_SCROLL);
@@ -383,7 +409,7 @@ 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()) {
if (Scroll_offset + h < Num_files) {
Scroll_offset++;
if (Selected_line < Scroll_offset){
Selected_line = Scroll_offset;
@@ -481,12 +507,12 @@ void cutscenes_screen_init()
// if (All_movies_enabled)
// Cutscenes_viewable = 0xffffffff; // Cheat code enables all movies.
Num_files = 0;
Cutscene_list.clear();
size_t size = Cutscenes.size();
for (size_t j=0;j < size;j++) {
for (size_t j = 0; j < Cutscenes.size(); j++ ) {
if ( Cutscenes_viewable & (1<<j) ) {
Cutscene_list.push_back((int)j);
Num_files++;
}
}
}
@@ -544,10 +570,11 @@ void cutscenes_screen_do_frame()
// the "show-all" hotkey
case KEY_CTRLED | KEY_SHIFTED | KEY_S:
{
Num_files = 0;
Cutscene_list.clear();
size_t size = Cutscenes.size();
for (size_t t = 0; t < size; t++) {
for (size_t t = 0; t < Cutscenes.size(); t++) {
Cutscene_list.push_back((int)t);
Num_files++;
}
break;
@@ -565,14 +592,14 @@ void cutscenes_screen_do_frame()
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()))
if ((z >= 0) && (z < Num_files))
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()))
if ((z >= 0) && (z < Num_files))
Selected_line = z;
}
@@ -597,7 +624,7 @@ void cutscenes_screen_do_frame()
y = 0;
z = Scroll_offset;
while (y + font_height <= Cutscene_list_coords[gr_screen.res][3]) {
if (z >= (int)Cutscene_list.size()){
if (z >= Num_files){
break;
}
@@ -639,7 +666,7 @@ void cutscenes_screen_do_frame()
y = 0;
z = Text_offset;
while (y + font_height <= Cutscene_desc_coords[gr_screen.res][3]) {
if (z >= Text_size || z >= MAX_TEXT_LINES-1)
if (z >= Text_size)
break;
len = Text_line_size[z];
+112 -28
View File
@@ -10,14 +10,18 @@ extern void *g_vBackBuf1, *g_vBackBuf2;
static ushort *backBuf1, *backBuf2;
static int lookup_initialized;
static void dispatchDecoder16(ushort **pFrame, ubyte codeType, ubyte **pData, ubyte **pOffData, int *pDataRemain, int *curXb, int *curYb);
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(ubyte *pFrame, ubyte *pMap, int mapRemain, unsigned char *pData, int dataRemain)
void decodeFrame16(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
{
ubyte *pOrig, *pOffData, *pEnd, op;
unsigned char *pOrig;
unsigned char *pOffData, *pEnd;
ushort offset;
int length = 0, i, j, xb, yb;
int length;
int op;
int i, j;
int xb, yb;
if (!lookup_initialized) {
genLoopkupTable();
@@ -152,7 +156,21 @@ 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;
@@ -190,9 +208,10 @@ static void patternQuadrant4Pixels(ushort *pFrame, unsigned char pat0, unsigned
for (i=0; i<16; i++) {
pFrame[i&3] = p[(pat & mask) >> shift];
if ((i&3) == 3) {
if ((i&3) == 3)
pFrame += g_width;
}
mask <<= 2;
shift += 2;
}
@@ -213,6 +232,19 @@ 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];
@@ -234,9 +266,10 @@ static void patternQuadrant2Pixels(ushort *pFrame, unsigned char pat0, unsigned
for (i=0; i<16; i++) {
pFrame[i&3] = p[(pat & mask) ? 1 : 0];
if ((i&3) == 3) {
if ((i&3) == 3)
pFrame += g_width;
}
mask <<= 1;
}
@@ -255,63 +288,76 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
switch(codeType) {
case 0x0:
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1));
break; // ADDED
break; // ADDED
case 0x1:
break;
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;
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;
(*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;
break;
case 0x5:
x = (char)*(*pData)++;
y = (char)*(*pData)++;
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
*pDataRemain -= 2;
break;
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)) {
if (++*curYb == (g_height >> 3))
return;
}
}
}
break;
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 {
@@ -320,21 +366,26 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
*pFrame += 2*g_width;
patternRow2Pixels2(*pFrame, *(*pData) >> 4, p);
(*pData)++;
*pFrame += 2*g_width;
}
}
break;
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 {
@@ -343,6 +394,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
}
} else {
p[2] = GETPIXEL(pData, 8);
if (!(p[2]&0x8000)) {
for (i=0; i<4; i++) {
if ((i & 1) == 0) {
@@ -352,6 +404,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
pat[0] = *(*pData)++;
pat[1] = *(*pData)++;
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
if (i & 1) {
*pFrame -= (4*g_width - 4);
} else {
@@ -366,18 +419,21 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
}
patternRow2Pixels(*pFrame, *(*pData), p);
(*pData)++;
*pFrame += g_width;
}
}
}
break;
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++) {
@@ -396,6 +452,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
patternRow4Pixels2(*pFrame, (*pData)[2], p);
*pFrame += 2*g_width;
patternRow4Pixels2(*pFrame, (*pData)[3], p);
(*pData) += 4;
*pDataRemain -= 4;
}
@@ -412,7 +469,9 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
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);
@@ -421,10 +480,11 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
*pDataRemain -= 8;
}
}
break;
break;
case 0xa:
p[0] = GETPIXEL(pData, 0);
if (!(p[0] & 0x8000)) {
for (i=0; i<4; i++) {
p[0] = GETPIXELI(pData, 0);
@@ -435,8 +495,11 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
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 {
@@ -445,6 +508,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
}
} else {
p[0] = GETPIXEL(pData, 16);
if (!(p[0] & 0x8000)) {
for (i=0; i<4; i++) {
if ((i&1) == 0) {
@@ -453,12 +517,16 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
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 {
@@ -473,21 +541,24 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
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;
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);
@@ -501,7 +572,7 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
*pData += 16;
*pDataRemain -= 16;
}
break;
break;
case 0xc:
for (i=0; i<4; i++) {
@@ -509,61 +580,74 @@ static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned
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;
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;
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;
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;
break;
default:
break;
break;
}
*pFrame = pDstBak+8;
+20 -19
View File
@@ -22,35 +22,36 @@ static int audio_exp_table[256] =
static int getWord(unsigned char **fin)
{
int value = ((*fin)[1] << 8) | (*fin)[0];
*fin += 2;
return value;
int value = ((*fin)[1] << 8) | (*fin)[0];
*fin += 2;
return value;
}
static void sendWord(short **fout, int nOffset)
{
*(*fout)++ = (short)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]);
}
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)
void mveaudio_uncompress(short *buffer, unsigned char *data, int length)
{
int nCurOffsets[2];
int swath;
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);
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);
}
+63 -71
View File
@@ -59,7 +59,7 @@ typedef struct MVE_AUDIO_T {
mve_audio_t *mas; // mve_audio_stream
// audio decompressor
extern void mveaudio_uncompress(short *buffer, unsigned char *data);
extern void mveaudio_uncompress(short *buffer, unsigned char *data, int length);
// video variables
int g_width, g_height;
@@ -137,9 +137,8 @@ static void mve_timer_start(void)
static int mve_do_timer_wait(void)
{
if (!timer_started) {
if (!timer_started)
return 0;
}
#ifdef SCP_UNIX
int nsec = 0;
@@ -148,13 +147,11 @@ static int mve_do_timer_wait(void)
gettimeofday(&tv, NULL);
if (tv.tv_sec > timer_expire.tv_sec) {
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) ) {
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);
@@ -173,24 +170,25 @@ static int mve_do_timer_wait(void)
}
end:
timer_expire.tv_usec += micro_frame_delay;
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;
}
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) {
if (tv > timer_expire)
goto end;
}
ts = timer_expire - tv;
ts2 = ts/1000;
Sleep(ts2);
end:
@@ -218,9 +216,8 @@ static void mve_timer_stop()
// setup the audio information from the data stream
void mve_audio_createbuf(ubyte minor, ubyte *data)
{
if (audiobuf_created) {
if (audiobuf_created)
return;
}
// if game sound disabled don't try and play movie audio
if (!Sound_enabled) {
@@ -228,29 +225,29 @@ void mve_audio_createbuf(ubyte minor, ubyte *data)
return;
}
int flags, desired_buffer, sample_rate;
int flags, desired_buffer, sample_rate;
mas = (mve_audio_t *) vm_malloc ( sizeof(mve_audio_t) );
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);
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->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 {
if (minor > 0) {
mve_audio_compressed = flags & 0x0004 ? 1 : 0;
} else {
mve_audio_compressed = 0;
}
}
if (mas->bitsize == 16) {
if (mas->bitsize == 16) {
if (mas->channels == 2) {
mas->format = AL_FORMAT_STEREO16;
} else if (mas->channels == 1) {
@@ -279,7 +276,7 @@ void mve_audio_createbuf(ubyte minor, ubyte *data)
memset(mas->audio_buffer, 0, MVE_AUDIO_BUFFERS * sizeof(ALuint));
mve_audio_buffer_tail = 0;
mve_audio_buffer_tail = 0;
audiobuf_created = 1;
}
@@ -291,9 +288,9 @@ void mve_audio_play()
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) {
@@ -305,9 +302,8 @@ void mve_audio_play()
// call this in shutdown to stop and close audio
static void mve_audio_stop()
{
if (!audiobuf_created) {
if (!audiobuf_created)
return;
}
ALint p = 0;
@@ -347,15 +343,13 @@ int mve_audio_data(ubyte major, ubyte *data)
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &bprocessed), return 0 );
while (bprocessed-- > 2) {
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) {
if (bqueued == 0)
mprintf(("MVE: Buffer underun (First is normal)\n"));
}
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return 0 );
@@ -368,34 +362,37 @@ int mve_audio_data(ubyte major, ubyte *data)
/* HACK: +4 mveaudio_uncompress adds 4 more bytes */
if (major == 8) {
if (mve_audio_compressed) {
if (mve_audio_compressed) {
nsamp += 4;
buf = (short *)vm_malloc(nsamp);
mveaudio_uncompress(buf, data); /* XXX */
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) {
if (++mve_audio_buffer_tail == MVE_AUDIO_BUFFERS)
mve_audio_buffer_tail = 0;
}
bqueued++;
vm_free(buf);
@@ -414,9 +411,8 @@ int mve_audio_data(ubyte major, ubyte *data)
int mve_video_createbuf(ubyte minor, ubyte *data)
{
if (videobuf_created) {
if (videobuf_created)
return 1;
}
short w, h;
short count, truecolor;
@@ -446,11 +442,11 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
return 0;
}
if (truecolor) {
if (truecolor)
g_vBackBuf2 = (ushort *)g_vBackBuf1 + (g_width * g_height);
} else {
else
g_vBackBuf2 = (ubyte *)g_vBackBuf1 + (g_width * g_height);
}
memset(g_vBackBuf1, 0, g_width * g_height * 4);
g_truecolor = truecolor;
@@ -462,11 +458,10 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
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) {
if (screen_ratio > movie_ratio)
scale_by = (float)gr_screen.max_h / (float)g_height;
} else {
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)) {
@@ -512,26 +507,26 @@ static void mve_convert_and_draw()
ubyte r, g, b;
ushort bit_16;
if (g_truecolor) {
if (g_truecolor)
pSrcs = pixels;
} else {
else
pSrcs8 = pixels8;
}
pDests = pixelbuf;
if (gr_screen.mode != GR_OPENGL) {
if (g_screenWidth > g_width) {
if (g_screenWidth > g_width)
pDests += ((g_screenWidth - g_width) / 2) / 2;
}
if (g_screenHeight > g_height) {
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 {
@@ -626,9 +621,8 @@ void mve_video_display()
int mve_video_init(ubyte *data)
{
if (video_inited) {
if (video_inited)
return 1;
}
short width, height;
@@ -674,10 +668,8 @@ int mve_video_init(ubyte *data)
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);
GL_state.Texture.SetWrapS(GL_CLAMP_TO_EDGE);
GL_state.Texture.SetWrapT(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);
@@ -687,8 +679,9 @@ int mve_video_init(ubyte *data)
}
memset(g_palette, 0, 768);
video_inited = 1;
return 1;
}
@@ -728,11 +721,10 @@ void mve_video_data(ubyte *data, int len)
g_vBackBuf2 = temp;
}
if (g_truecolor) {
if (g_truecolor)
decodeFrame16((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
} else {
else
decodeFrame8((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
}
}
void mve_end_chunk()
@@ -761,9 +753,8 @@ void mve_play(MVESTREAM *mve)
int init_timer = 0, timer_error = 0;
int cont = 1;
if (!timer_started) {
if (!timer_started)
mve_timer_start();
}
while (cont && mve_playing && !timer_error) {
cont = mve_play_next_chunk(mve);
@@ -802,5 +793,6 @@ void mve_shutdown()
}
mve_audio_stop();
mve_timer_stop();
}
+34 -176
View File
@@ -10,7 +10,6 @@
#endif
#include "globalincs/pstypes.h"
#include "globalincs/def_files.h"
#include "cfile/cfile.h"
#include "graphics/gropengl.h"
#include "graphics/gropengltexture.h"
@@ -43,9 +42,6 @@ static int g_screenX = 0;
static int g_screenY = 0;
static GLuint GLtex = 0;
static GLuint ytex = 0;
static GLuint utex = 0;
static GLuint vtex = 0;
static GLint gl_screenYH = 0;
static GLint gl_screenXW = 0;
static GLfloat gl_screenU = 0;
@@ -78,7 +74,7 @@ static int audiofd_fragsize = 0;
static longlong videobuf_granulepos = -1;
static double videobuf_time = 0;
static bool use_shaders = true;
// -----------------------------------------------------------------------------
// Utility items
//
@@ -86,8 +82,8 @@ static bool use_shaders = true;
// 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, 8192); // Doubled read size to fix choppy audio with high bitrate movies - Valathil
int bytes = cfread(buffer, 1, 8192, movie->cfp);
char *buffer = ogg_sync_buffer(&movie->osyncstate, 4096);
int bytes = cfread(buffer, 1, 4096, movie->cfp);
ogg_sync_wrote(&movie->osyncstate, bytes);
@@ -330,8 +326,6 @@ static void OGG_video_init(theora_info *tinfo)
{
float scale_by = 0.0f;
GLhandleARB shader_id = 0;
if (video_inited)
return;
@@ -345,137 +339,33 @@ static void OGG_video_init(theora_info *tinfo)
opengl_set_texture_target(GL_TEXTURE_2D);
opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
if(!Use_GLSL)
use_shaders = false;
glGenTextures(1, &GLtex);
if(use_shaders) {
glGenTextures(1, &ytex);
glGenTextures(1, &utex);
glGenTextures(1, &vtex);
Assert( GLtex != 0 );
Assert( ytex != 0 );
Assert( utex != 0 );
Assert( vtex != 0 );
if ( ytex + utex + vtex == 0 ) {
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
video_inited = 1;
return;
}
char *vert = NULL, *frag = NULL;
opengl_shader_t new_shader;
// choose appropriate files
char *vert_name = "video-v.sdr";
char *frag_name = "video-f.sdr";
mprintf(("Compiling video-processing shader ... \n"));
// read vertex shader
CFILE *cf_shader = cfopen(vert_name, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
if (cf_shader != NULL) {
int len = cfilelength(cf_shader);
vert = (char*) vm_malloc(len + 1);
cfread(vert, len + 1, 1, cf_shader);
cfclose(cf_shader);
} else {
mprintf((" Loading built-in default shader for: %s\n", vert_name));
vert = defaults_get_file(vert_name);
}
if(!vert)
use_shaders = false;
// read fragment shader
cf_shader = cfopen(frag_name, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
if (cf_shader != NULL) {
int len = cfilelength(cf_shader);
frag = (char*) vm_malloc(len + 1);
cfread(frag, len + 1, 1, cf_shader);
cfclose(cf_shader);
} else {
mprintf((" Loading built-in default shader for: %s\n", frag_name));
frag = defaults_get_file(frag_name);
}
if(!vert)
use_shaders = false;
Verify( vert != NULL );
Verify( frag != NULL );
shader_id = opengl_shader_create(vert, frag);
vglUseProgramObjectARB(shader_id);
if (!shader_id)
use_shaders = false;
}
if(!use_shaders) {
glGenTextures(1, &GLtex);
Assert( GLtex != 0 );
if ( GLtex == 0 ) {
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
video_inited = 1;
return;
}
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();
if(!use_shaders) {
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_texture_target);
GL_state.Texture.Enable(GLtex);
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);
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB8, wp2, hp2, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
}
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);
if(use_shaders) {
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_texture_target);
GL_state.Texture.Enable(ytex);
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_LUMINANCE8, 2048, 2048, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
GL_state.Texture.SetWrapS(GL_CLAMP_TO_EDGE);
GL_state.Texture.SetWrapT(GL_CLAMP_TO_EDGE);
GL_state.Texture.SetActiveUnit(1);
GL_state.Texture.SetTarget(GL_texture_target);
GL_state.Texture.Enable(utex);
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);
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 1024, 1024, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
GL_state.Texture.SetActiveUnit(2);
GL_state.Texture.SetTarget(GL_texture_target);
GL_state.Texture.Enable(vtex);
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_LUMINANCE8, 1024, 1024, 0, GL_LUMINANCE, 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;
@@ -498,17 +388,15 @@ static void OGG_video_init(theora_info *tinfo)
glColor3f(1.0f, 1.0f, 1.0f);
}
if(!use_shaders) {
pixelbuf = (ubyte *) vm_malloc_q(g_screenWidth * g_screenHeight * 3);
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 (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);
@@ -526,19 +414,8 @@ static void OGG_video_init(theora_info *tinfo)
gl_screenU = i2fl(g_screenWidth) / i2fl(wp2);
gl_screenV = i2fl(g_screenHeight) / i2fl(hp2);
}
if(use_shaders) {
gl_screenU = i2fl(tinfo->frame_width-1) / i2fl(2048) ;
gl_screenV = i2fl(tinfo->frame_height-1) / i2fl(2048);
GL_state.Texture.SetShaderMode(GL_TRUE);
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "ytex"), 0 );
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "utex"), 1 );
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "vtex"), 2 );
}
}
if(!use_shaders && tinfo->frame_height > 450) {
mprintf(("VIDEO: No shader support and hd video is beeing played this can get choppy."));
}
video_inited = 1;
}
@@ -555,23 +432,12 @@ static void OGG_video_close()
}
GL_state.Texture.Disable();
if(use_shaders) {
GL_state.Texture.Delete(ytex);
GL_state.Texture.Delete(utex);
GL_state.Texture.Delete(vtex);
glDeleteTextures(1, &ytex);
glDeleteTextures(1, &utex);
glDeleteTextures(1, &vtex);
} else {
GL_state.Texture.Delete(GLtex);
glDeleteTextures(1, &GLtex);
}
GL_state.Texture.Delete(GLtex);
glDeleteTextures(1, &GLtex);
opengl_set_texture_target();
ytex = utex = vtex = 0;
GLtex = 0;
GL_state.Texture.SetShaderMode(GL_FALSE);
opengl_shader_set_current( 0 );
}
if (pixelbuf != NULL) {
@@ -587,6 +453,7 @@ static void OGG_video_close()
g_screenX = 0;
g_screenY = 0;
GLtex = 0;
gl_screenYH = 0;
gl_screenXW = 0;
gl_screenU = 0;
@@ -661,25 +528,16 @@ static void convert_YUV_to_RGB(yuv_buffer *yuv)
}
}
extern int Mouse_hidden;
static void OGG_video_draw(theora_state *tstate)
{
yuv_buffer yuv;
theora_decode_YUVout(tstate, &yuv);
if(!use_shaders)
convert_YUV_to_RGB(&yuv);
convert_YUV_to_RGB(&yuv);
if (gr_screen.mode == GR_OPENGL) {
if(use_shaders) {
GL_state.Texture.SetActiveUnit(0);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.y_stride, yuv.y_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.y);
GL_state.Texture.SetActiveUnit(1);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.u);
GL_state.Texture.SetActiveUnit(2);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.v);
} else {
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGR, GL_UNSIGNED_BYTE, pixelbuf);
}
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);
@@ -694,7 +552,7 @@ static void OGG_video_draw(theora_state *tstate)
glVertex2i(gl_screenXW, g_screenY);
glEnd();
}
Mouse_hidden = 1;
gr_flip();
os_poll();
+3
View File
@@ -495,4 +495,7 @@ const char *dds_error_string(int code)
default:
return "Abort, retry, fail?";
}
//get a warning otherwise
return "Abort, retry, fail?";
}
+134 -96
View File
@@ -9,6 +9,7 @@
#include "debris/debris.h"
#include "render/3d.h"
#include "fireball/fireballs.h"
@@ -27,14 +28,17 @@
#include "network/multi.h"
#include "network/multimsgs.h"
#include "network/multiutil.h"
#include "weapon/weapon.h"
#define MAX_LIFE 10.0f
#define MIN_RADIUS_FOR_PERSISTANT_DEBRIS 50 // ship radius at which debris from it becomes persistant
#define DEBRIS_SOUND_DELAY 2000 // time to start debris sound after created
#define MAX_HULL_PIECES MAX_DEBRIS_PIECES // limit the number of hull debris chunks that can exist.
// limit the number of hull debris chunks that can exist.
//#define MAX_HULL_PIECES 10
#define MAX_HULL_PIECES MAX_DEBRIS_PIECES //-WMCD
int Num_hull_pieces; // number of hull pieces in existance
debris Hull_debris_list; // head of linked list for hull debris chunks, for quick search
@@ -54,10 +58,13 @@ int Debris_num_submodels = 0;
#define MAX_SPEED_SMALL_DEBRIS 200 // maximum velocity of small debris piece
#define MAX_SPEED_BIG_DEBRIS 150 // maximum velocity of big debris piece
#define MAX_SPEED_CAPITAL_DEBRIS 100 // maximum velocity of capital debris piece
//#define DEBRIS_SPEED_DEBUG
/**
* Start the sequence of a piece of debris writhing in unholy agony!!!
*/
// ---------------------------------------------------------------------------------------
// debris_start_death_roll()
//
// Start the sequence of a piece of debris writhing in unholy agony!!!
//
static void debris_start_death_roll(object *debris_obj, debris *debris_p)
{
if (debris_p->is_hull) {
@@ -79,11 +86,14 @@ static void debris_start_death_roll(object *debris_obj, debris *debris_p)
}
debris_obj->flags |= OF_SHOULD_BE_DEAD;
// demo_do_flag_dead(OBJ_INDEX(debris_obj));
}
/**
* This will get called at the start of each level.
*/
// ---------------------------------------------------------------------------------------
// debris_init()
//
// This will get called at the start of each level.
//
void debris_init()
{
int i;
@@ -107,9 +117,7 @@ void debris_init()
list_init(&Hull_debris_list);
}
/**
* Page in debris bitmaps at level load
*/
// Page in debris bitmaps at level load
void debris_page_in()
{
uint i;
@@ -143,9 +151,10 @@ void debris_page_in()
MONITOR(NumSmallDebrisRend)
MONITOR(NumHullDebrisRend)
/**
* Render debris
*/
// ---------------------------------------------------------------------------------------
// debris_render()
//
//
void debris_render(object * obj)
{
int i, num, swapped;
@@ -201,9 +210,7 @@ void debris_render(object * obj)
}
}
/**
* Removed the ::DEBRIS_EXPIRE flag, and remove item from ::Hull_debris_list
*/
// Removed the DEBRIS_EXPIRE flag, and remove item from Hull_debris_list
void debris_clear_expired_flag(debris *db)
{
if ( db->flags & DEBRIS_EXPIRE ) {
@@ -216,11 +223,12 @@ void debris_clear_expired_flag(debris *db)
}
}
/**
* Delete the debris object.
* This is only ever called via obj_delete(). Do not call directly.
* Use debris_start_death_roll() if you want to force a debris piece to die.
*/
// ---------------------------------------------------------------------------------------
// debris_delete()
//
// Delete the debris object. This is only ever called via obj_delete(). Do not call directly.
// Use debris_start_death_roll() if you want to force a debris piece to die.
//
void debris_delete( object * obj )
{
int num;
@@ -240,11 +248,9 @@ void debris_delete( object * obj )
Num_debris_pieces--;
}
/**
* If debris piece *db is far away from all players, make it go away very soon.
* In single player game, delete if MAX_DEBRIS_DIST from player.
* In multiplayer game, delete if MAX_DEBRIS_DIST from all players.
*/
// If debris piece *db is far away from all players, make it go away very soon.
// In single player game, delete if MAX_DEBRIS_DIST from player.
// In multiplayer game, delete if MAX_DEBRIS_DIST from all players.
void maybe_delete_debris(debris *db)
{
object *objp;
@@ -269,16 +275,24 @@ void maybe_delete_debris(debris *db)
}
}
// broke debris_move into debris_process_pre and debris_process_post as was done with all
// *_move functions on 8/13 by MK and MA.
void debris_process_pre( object *objp, float frame_time)
{
}
MONITOR(NumSmallDebris)
MONITOR(NumHullDebris)
/**
* Do various updates to debris: check if time to die, start fireballs
* Maybe delete debris if it's very far away from player.
*
* @param obj pointer to debris object
* @param frame_time time elapsed since last debris_move() called
*/
// ---------------------------------------------------------------------------------------
// debris_process_post()
//
// Do various updates to debris: check if time to die, start fireballs
//
// parameters: obj => pointer to debris object
// frame_time => time elapsed since last debris_move() called
//
// Maybe delete debris if it's very far away from player.
void debris_process_post(object * obj, float frame_time)
{
int i, num;
@@ -314,7 +328,10 @@ void debris_process_post(object * obj, float frame_time)
return; // If arc_frequency <= 0, this piece has no arcs on it
}
if ( !timestamp_elapsed(db->fire_timeout) && timestamp_elapsed(db->next_fireball)) {
if ( !timestamp_elapsed(db->fire_timeout) && timestamp_elapsed(db->next_fireball)) {
// start the next fireball up in the next 50 - 100 ms
//db->next_fireball = timestamp_rand(60,80);
db->next_fireball = timestamp_rand(db->arc_frequency,db->arc_frequency*2 );
db->arc_frequency += 100;
@@ -335,7 +352,7 @@ void debris_process_post(object * obj, float frame_time)
// Create the spark effects
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
if ( !timestamp_valid( db->arc_timestamp[i] ) ) {
//db->arc_timestamp[i] = timestamp_rand(400,1000); // live up to a second
db->arc_timestamp[i] = timestamp(lifetime); // live up to a second
switch( n ) {
@@ -387,7 +404,11 @@ void debris_process_post(object * obj, float frame_time)
// 0.10 second effect
snd_play_3d( &Snds[SND_DEBRIS_ARC_01], &snd_pos, &View_position, obj->radius );
}
}
}
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
@@ -406,12 +427,15 @@ void debris_process_post(object * obj, float frame_time)
}
}
}
}
/**
* Locate the oldest hull debris chunk. Search through the ::Hull_debris_list, which is a list
* of all the hull debris chunks.
*/
// ---------------------------------------------------------------------------------------
// debris_find_oldest()
//
// Locate the oldest hull debris chunk. Search through the Hull_debris_list, which is a list
// of all the hull debris chunks.
//
int debris_find_oldest()
{
int oldest_index;
@@ -433,18 +457,13 @@ int debris_find_oldest()
#define DEBRIS_ROTVEL_SCALE 5.0f
void calc_debris_physics_properties( physics_info *pi, vec3d *min, vec3d *max );
/**
* Create debris from an object
*
* @param source_obj Source object
* @param model_num Model number
* @param submodel_num Sub-model number
* @param pos Position in vector space
* @param exp_center Explosion center in vector space
* @param hull_flag Hull flag settings
* @param exp_force Explosion force, used to assign velocity to pieces. 1.0f assigns velocity like before. 2.0f assigns twice as much to non-inherited part of velocity
*/
// ---------------------------------------------------------------------------------------
// debris_create()
//
// Create debris from an object
//
// exp_force: Explosion force, used to assign velocity to pieces.
// 1.0f assigns velocity like before. 2.0f assigns twice as much to non-inherited part of velocity
object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force)
{
int i, n, objnum, parent_objnum;
@@ -471,6 +490,7 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
dist /= 2.0f;
}
if ( dist > 200.0f ) {
//mprintf(( "Not creating debris that is %.1f m away\n", dist ));
return NULL;
}
}
@@ -560,6 +580,7 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
db->arc_timestamp[i] = timestamp(-1);
// vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
}
if ( db->is_hull ) {
@@ -613,6 +634,8 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
obj->net_signature = multi_get_next_network_signature( MULTI_SIG_DEBRIS );
}
// -- No long need shield: bset_shield_strength(obj, 100.0f); // Hey! Set to some meaningful value!
if (source_obj->type == OBJ_SHIP) {
obj->hull_strength = Ships[source_obj->instance].ship_max_hull_strength/8.0f;
} else
@@ -685,8 +708,14 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
vm_vec_copy_scale(&radial_vel, &to_center, scale );
}
// MK: This next line causes debris pieces to get between 50% and 100% of the parent ship's
// velocity. What would be very cool is if the rotational velocity of the parent would become
// translational velocity of the debris piece. This would be based on the location of the debris
// piece in the parent object.
// DA: here we need to vel_from_rot = w x to_center, where w is world is unrotated to world coords and offset is the
// displacement fromt the center of the parent object to the center of the debris piece
vec3d world_rotvel, vel_from_rotvel;
vm_vec_unrotate ( &world_rotvel, &source_obj->phys_info.rotvel, &source_obj->orient );
vm_vec_crossprod ( &vel_from_rotvel, &world_rotvel, &to_center );
@@ -695,7 +724,10 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
vm_vec_add (&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel);
vm_vec_add2(&obj->phys_info.vel, &vel_from_rotvel);
// make sure rotational velocity does not get too high
// vm_vec_scale_add(&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel, frand()/2.0f + 0.5f);
// nprintf(("Andsager","object vel from rotvel: %0.2f, %0.2f, %0.2f\n",vel_from_rotvel.x, vel_from_rotvel.y, vel_from_rotvel.z));
// make sure rotational velocity does not get too high
if (radius < 1.0) {
radius = 1.0f;
}
@@ -723,20 +755,29 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
vm_vec_zero(&pi->max_vel); // make so he can't turn on his own VOLITION anymore.
vm_vec_zero(&pi->max_rotvel); // make so he can't change speed on his own VOLITION anymore.
// ensure vel is valid
Assert( !vm_is_vec_nan(&obj->phys_info.vel) );
// if ( hull_flag ) {
// vm_vec_zero(&pi->vel);
// vm_vec_zero(&pi->rotvel);
// }
return obj;
}
/**
* Alas, poor debris_obj got whacked. Fortunately, we know who did it, where and how hard, so we
* can do something about it.
*/
// ---------------------------------------------------------------------------------------
// debris_hit()
//
// Alas, poor debris_obj got whacked. Fortunately, we know who did it, where and how hard, so we
// can do something about it.
//
void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float damage)
{
debris *debris_p = &Debris[debris_obj->instance];
// Do a little particle spark shower to show we hit
{
particle_emitter pe;
@@ -785,11 +826,13 @@ void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float dama
}
}
/**
* See if poor debris object *obj got whacked by evil *other_obj at point *hitpos.
* NOTE: debris_hit_info pointer NULL for debris:weapon collision, otherwise debris:ship collision.
* @return true if hit, else return false.
*/
// ---------------------------------------------------------------------------------------
// debris_check_collision()
//
// See if poor debris object *obj got whacked by evil *other_obj at point *hitpos.
// NOTE: debris_hit_info pointer NULL for debris:weapon collision, otherwise debris:ship collision.
// Return true if hit, else return false.
//
int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, collision_info_struct *debris_hit_info)
{
mc_info mc;
@@ -806,7 +849,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
if ( debris_hit_info == NULL ) {
// debris weapon collision
Assert( other_obj->type == OBJ_WEAPON );
mc.model_instance_num = -1;
mc.model_num = Debris[num].model_num; // Fill in the model to check
mc.submodel_num = Debris[num].submodel_num;
model_clear_instance( mc.model_num );
@@ -820,10 +862,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
*hitpos = mc.hit_point_world;
}
weapon *wp = &Weapons[other_obj->instance];
wp->collisionOccured = true;
wp->collisionInfo = mc_info(mc);
return mc.num_hits;
}
@@ -866,7 +904,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
int mc_ret_val = 0;
if ( debris_hit_info->heavy == ship_obj ) { // ship is heavier, so debris is sphere. Check sphere collision against ship poly model
mc.model_instance_num = Ships[ship_obj->instance].model_instance_num;
mc.model_num = Ship_info[Ships[ship_obj->instance].ship_info_index].model_num; // Fill in the model to check
mc.orient = &ship_obj->orient; // The object's orient
mc.radius = pdebris->radius;
@@ -881,9 +918,9 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
// first test against the sphere - if this fails then don't do any submodel tests
mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE;
SCP_vector<int> submodel_vector;
int submodel_list[MAX_ROTATING_SUBMODELS];
int num_rotating_submodels = 0;
polymodel *pm;
polymodel_instance *pmi;
ship_model_start(ship_obj);
@@ -894,43 +931,42 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
// Do collision the cool new way
if ( debris_hit_info->collide_rotate ) {
SCP_vector<int>::iterator smv;
// We collide with the sphere, find the list of rotating submodels and test one at a time
model_get_rotating_submodel_list(&submodel_vector, heavy_obj);
model_get_rotating_submodel_list(submodel_list, &num_rotating_submodels, heavy_obj);
// Get polymodel and turn off all rotating submodels, collide against only 1 at a time.
pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num);
pmi = model_get_instance(Ships[heavy_obj->instance].model_instance_num);
// turn off all rotating submodels and test for collision
for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
pmi->submodel[*smv].collision_checked = true;
int i;
for (i=0; i<num_rotating_submodels; i++) {
pm->submodel[submodel_list[i]].blown_off = 1;
}
// reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE
mc.flags = copy_flags | MC_SUBMODEL_INSTANCE;
// check each submodel in turn
for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
for (i=0; i<num_rotating_submodels; i++) {
// turn on submodel for collision test
pmi->submodel[*smv].collision_checked = false;
pm->submodel[submodel_list[i]].blown_off = 0;
// set angles for last frame (need to set to prev to get p0)
angles copy_angles = pmi->submodel[*smv].angs;
angles copy_angles = pm->submodel[submodel_list[i]].angs;
// find the start and end positions of the sphere in submodel RF
pmi->submodel[*smv].angs = pmi->submodel[*smv].prev_angs;
world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, *smv, &heavy_obj->last_orient, &heavy_obj->last_pos);
pm->submodel[submodel_list[i]].angs = pm->submodel[submodel_list[i]].sii->prev_angs;
world_find_model_point(&p0, &light_obj->last_pos, pm, submodel_list[i], &heavy_obj->last_orient, &heavy_obj->last_pos);
pmi->submodel[*smv].angs = copy_angles;
world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, *smv, &heavy_obj->orient, &heavy_obj->pos);
pm->submodel[submodel_list[i]].angs = copy_angles;
world_find_model_point(&p1, &light_obj->pos, pm, submodel_list[i], &heavy_obj->orient, &heavy_obj->pos);
mc.p0 = &p0;
mc.p1 = &p1;
// mc.pos = zero // in submodel RF
mc.orient = &vmd_identity_matrix;
mc.submodel_num = *smv;
mc.submodel_num = submodel_list[i];
if ( model_collide(&mc) ) {
if ( mc.hit_dist < debris_hit_info->hit_time ) {
@@ -938,23 +974,24 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
// set up debris_hit_info common
set_hit_struct_info(debris_hit_info, &mc, SUBMODEL_ROT_HIT);
model_instance_find_world_point(&debris_hit_info->hit_pos, &mc.hit_point, mc.model_num, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
model_find_world_point(&debris_hit_info->hit_pos, &mc.hit_point, mc.model_num, mc.hit_submodel, &heavy_obj->orient, &zero);
// set up debris_hit_info for rotating submodel
if (debris_hit_info->edge_hit == 0) {
model_instance_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
model_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
}
// find position in submodel RF of light object at collison
vec3d int_light_pos, diff;
vm_vec_sub(&diff, mc.p1, mc.p0);
vm_vec_scale_add(&int_light_pos, mc.p0, &diff, mc.hit_dist);
model_instance_find_world_point(&debris_hit_info->light_collision_cm_pos, &int_light_pos, mc.model_num, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
model_find_world_point(&debris_hit_info->light_collision_cm_pos, &int_light_pos, mc.model_num, mc.hit_submodel, &heavy_obj->orient, &zero);
}
}
// Don't look at this submodel again
pmi->submodel[*smv].collision_checked = true;
pm->submodel[submodel_list[i]].blown_off = 1;
}
}
// Recover and do usual ship_ship collision, but without rotating submodels
@@ -973,7 +1010,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
// get collision normal if not edge hit
if (debris_hit_info->edge_hit == 0) {
model_instance_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
model_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
}
// find position in submodel RF of light object at collison
@@ -983,11 +1020,12 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
}
}
ship_model_stop( ship_obj );
}
} else {
// Debris is heavier obj
mc.model_instance_num = -1;
mc.model_num = Debris[num].model_num; // Fill in the model to check
mc.submodel_num = Debris[num].submodel_num;
model_clear_instance( mc.model_num );
@@ -1043,9 +1081,11 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
}
}
/**
* Return the team field for a debris object
*/
// ---------------------------------------------------------------------------------------
// debris_get_team()
//
// Return the team field for a debris object
//
int debris_get_team(object *objp)
{
Assert( objp->type == OBJ_DEBRIS );
@@ -1053,9 +1093,7 @@ int debris_get_team(object *objp)
return Debris[objp->instance].team;
}
/**
* Fills in debris physics properties when created, specifically mass and moment of inertia
*/
// fills in debris physics properties when created, specifically mass and moment of inertia
void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs )
{
float dx, dy, dz, mass;
+3 -1
View File
@@ -42,7 +42,7 @@ typedef struct 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;
char parent_alt_name;
float damage_mult;
} debris;
@@ -52,6 +52,7 @@ typedef struct debris {
#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];
@@ -63,6 +64,7 @@ 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 );
+166 -195
View File
@@ -21,6 +21,7 @@
#include "io/key.h"
#include "globalincs/alphacolors.h"
#include "osapi/osapi.h"
#include "debugconsole/dbugfile.h"
#define MAX_COMMANDS 300
@@ -33,35 +34,35 @@ debug_command::debug_command(char *_name, char *_help, void (*_func)() )
{
int i;
if ( Num_debug_commands >= MAX_COMMANDS ) {
if ( Num_debug_commands >= MAX_COMMANDS ) {
Int3(); // Too many debug console commands!! Increase MAX_COMMANDS!!
return;
}
for (i=0; i<Num_debug_commands; i++ ) {
for (i=0; i<Num_debug_commands; i++ ) {
int ret = stricmp( Debug_command[i]->name, _name );
if ( ret == 0) {
if ( ret == 0) {
Int3(); // This debug console command already exists!!!!
return;
} else if ( ret > 0 ) {
} else if ( ret > 0 ) {
break; // Insert it here
} else if ( ret < 0 ) {
} else if ( ret < 0 ) {
// do nothing
}
}
if ( i < Num_debug_commands ) {
if ( i < Num_debug_commands ) {
// Insert it at element i
int j;
for (j=Num_debug_commands; j>i; j-- ) {
for (j=Num_debug_commands; j>i; j-- ) {
Debug_command[j] = Debug_command[j-1];
}
Debug_command[i] = this;
Debug_command[i] = this;
Num_debug_commands++;
} else {
Debug_command[Num_debug_commands] = this;
Debug_command[Num_debug_commands] = this;
Num_debug_commands++;
}
@@ -71,18 +72,17 @@ debug_command::debug_command(char *_name, char *_help, void (*_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
ubyte Dc_arg_ubyte; // If Dc_arg_type & ARG_UBYTE 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 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 scroll_times = 0; // incremented each time display scrolls
int debug_inited = 0;
@@ -112,7 +112,7 @@ typedef enum {
#define MAX_TOKEN_STRING_LENGTH 128
char scanner_ch;
char scanner_ch;
TOKEN_CODE scanner_token;
char scanner_token_string[MAX_TOKEN_STRING_LENGTH];
@@ -126,7 +126,7 @@ CHAR_CODE scanner_char_table[256];
void scanner_get_char()
{
if ( *scanner_bufferp == '\0' ) {
if ( *scanner_bufferp == '\0' ) {
scanner_ch = 0;
return;
}
@@ -144,23 +144,26 @@ void scanner_init()
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') )
while( (scanner_ch ==' ') || (scanner_ch =='\t') )
scanner_get_char();
}
void scanner_downshift_word()
{
int offset = 'a' - 'A';
@@ -175,9 +178,10 @@ void scanner_downshift_word()
} while (*tp != '\0' );
}
void scanner_get_word()
{
while( (scanner_char_code(scanner_ch)==LETTER) || (scanner_char_code(scanner_ch)==DIGIT) ) {
while( (scanner_char_code(scanner_ch)==LETTER) || (scanner_char_code(scanner_ch)==DIGIT) ) {
*scanner_tokenp++ = scanner_ch;
scanner_get_char();
}
@@ -186,12 +190,13 @@ void scanner_get_word()
scanner_token = IDENTIFIER;
}
void scanner_get_string()
{
*scanner_tokenp++ = 34;
scanner_get_char();
while(scanner_ch != 34 ) {
while(scanner_ch != 34 ) {
*scanner_tokenp++ = scanner_ch;
scanner_get_char();
}
@@ -201,18 +206,21 @@ void scanner_get_string()
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;
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:
case LETTER: scanner_get_word(); break;
default:
*scanner_tokenp++ = scanner_ch;
*scanner_tokenp = '\0';
scanner_get_char();
@@ -229,6 +237,7 @@ void scanner_start_command( char * s )
scanner_get_char();
}
int Dc_debug_on = 0;
jmp_buf dc_bad_arg;
@@ -236,126 +245,98 @@ void dc_get_arg(uint type)
{
scanner_get_token();
Dc_command_line = scanner_bufferp;
Dc_command_line = scanner_bufferp;
Dc_arg_org = scanner_token_string;
Dc_arg = scanner_word_string;
if (Dc_debug_on) {
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 ) {
if ( scanner_token == NO_TOKEN ) {
Dc_arg_type = ARG_NONE;
} else if ( scanner_token == IDENTIFIER ) {
} else if ( scanner_token == IDENTIFIER ) {
Dc_arg_type = ARG_STRING;
} else if ( scanner_token == STRING ) {
} else if ( scanner_token == STRING ) {
Dc_arg_type = ARG_QUOTE;
} else {
Dc_arg_type = ARG_STRING;
}
if ( 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++;
}
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);
Dc_arg_type |= ARG_UBYTE;
Dc_arg_ubyte = (ubyte)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 ( 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 ) {
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 ) {
if ( Dc_arg_type & ARG_INT )
dc_printf( "Found int number! %d\n", Dc_arg_int );
}
if ( Dc_arg_type & ARG_UBYTE ) {
dc_printf( "Found ubyte number! %d\n", Dc_arg_ubyte );
}
if ( Dc_arg_type & ARG_HEX ) {
if ( Dc_arg_type & ARG_HEX )
dc_printf( "Found hex number! 0x%x\n", Dc_arg_int );
}
}
if ( !stricmp( Dc_arg, "on" ) ) {
if ( !stricmp( Dc_arg, "on" ))
Dc_arg_type |= ARG_TRUE;
}
if ( !stricmp( Dc_arg, "true" ) ) {
if ( !stricmp( Dc_arg, "true" ))
Dc_arg_type |= ARG_TRUE;
}
if ( !stricmp( Dc_arg, "off" ) ) {
if ( !stricmp( Dc_arg, "off" ))
Dc_arg_type |= ARG_FALSE;
}
if ( !stricmp( Dc_arg, "false" ) ) {
if ( !stricmp( Dc_arg, "false" ))
Dc_arg_type |= ARG_FALSE;
}
if ( !stricmp( Dc_arg, "+" ) ) {
if ( !stricmp( Dc_arg, "+" ))
Dc_arg_type |= ARG_PLUS;
}
if ( !stricmp( Dc_arg, "-" ) ) {
if ( !stricmp( Dc_arg, "-" ))
Dc_arg_type |= ARG_MINUS;
}
if ( !stricmp( Dc_arg, "," ) ) {
if ( !stricmp( Dc_arg, "," ))
Dc_arg_type |= ARG_COMMA;
}
}
if ( Dc_arg_type & ARG_INT) {
if ( Dc_arg_int ) {
if ( Dc_arg_type & ARG_INT) {
if ( Dc_arg_int )
Dc_arg_type |= ARG_TRUE;
} else {
else
Dc_arg_type |= ARG_FALSE;
}
}
if ( Dc_arg_type & ARG_UBYTE) {
if ( Dc_arg_ubyte ) {
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) ) {
if ( !(Dc_arg_type&type) ) {
if ( (Dc_arg_type & ARG_NONE) && !(type & ARG_NONE))
dc_printf( "Error: Not enough parameters.\n" );
} else {
else
dc_printf( "Error: '%s' invalid type\n", Dc_arg );
longjmp(dc_bad_arg,1);
}
longjmp(dc_bad_arg,1);
}
}
void debug_help();
@@ -366,85 +347,80 @@ void debug_do_command(char * command)
int i;
int mode = 0;
if ( strlen(command) < 1 ) {
return;
}
if ( strlen(command) < 1 ) return;
Dc_debug_on = 0;
Dc_command_line = command;
scanner_start_command(command);
if (setjmp(dc_bad_arg) ) {
if (setjmp(dc_bad_arg) ) {
return;
}
dc_get_arg( ARG_ANY );
if ( !strcmp( Dc_arg, "debug" ) ) {
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" ) ) {
if ( !stricmp( Dc_arg, "xyzzy" ) ) {
dc_printf("Nothing happens.\n");
return;
}
if ( !strcmp( Dc_arg, "?" ) ) {
if ( !strcmp( Dc_arg, "?" ) ) {
mode = 1;
dc_get_arg( ARG_ANY );
if ( Dc_arg_type&ARG_NONE ) {
debug_help();
if ( Dc_arg_type&ARG_NONE ) {
debug_help();
return;
}
}
if ( !strcmp( Dc_arg, "help" ) || !strcmp( Dc_arg, "man" ) ) {
if ( !strcmp( Dc_arg, "help" ) || !strcmp( Dc_arg, "man" ) ) {
mode = 2;
dc_get_arg( ARG_ANY );
if ( Dc_arg_type&ARG_NONE ) {
debug_help();
if ( Dc_arg_type&ARG_NONE ) {
debug_help();
return;
}
}
if ( strstr( Dc_command_line, "?" ) ) {
if ( strstr( Dc_command_line, "?" ) ) {
mode = 2;
}
if ( !(Dc_arg_type&ARG_STRING) ) {
if ( !(Dc_arg_type&ARG_STRING) ) {
dc_printf( "Invalid keyword '%s'\n", Dc_arg );
return;
}
if (Dc_debug_on) {
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 ) ) {
for (i=0; i<Num_debug_commands; i++ ) {
if ( !stricmp( Debug_command[i]->name, Dc_arg )) {
if (mode==0) {
if (Dc_debug_on) {
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) {
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) {
if (Dc_debug_on)
dc_printf( "Doing help for '%s'\n", Dc_arg );
}
Dc_command = 0;
Dc_help = 1;
Dc_status = 0;
@@ -452,9 +428,9 @@ void debug_do_command(char * command)
(*Debug_command[i]->func)();
if (mode==0) {
if (mode==0) {
dc_get_arg(ARG_ANY);
if (!(Dc_arg_type&ARG_NONE)) {
if (!(Dc_arg_type&ARG_NONE)) {
dc_printf( "Ignoring the unused command line tail '%s %s'\n", Dc_arg_org, Dc_command_line );
}
}
@@ -469,7 +445,7 @@ void debug_do_command(char * command)
void debug_draw()
{
int i;
gr_clear();
gr_set_font(FONT1);
gr_set_color_fast( &Color_bright );
@@ -477,12 +453,12 @@ void debug_draw()
gr_set_color_fast( &Color_normal );
for (i=0; i<DROWS; i++ ) {
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 ) {
if ( t & 1 ) {
int w,h;
char c;
@@ -490,10 +466,10 @@ void debug_draw()
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;
}
@@ -503,18 +479,17 @@ void debug_draw()
void debug_output( char c )
{
if ( c == '\t' ) {
if ( c == '\t' ) {
int next_tab = ((debug_x/28)+1)*28;
if ( next_tab >= DCOLS-1 ) {
if ( next_tab >= DCOLS-1 ) {
debug_x=0;
debug_y++;
scroll_times++;
if ( debug_y >= DROWS ) {
if ( debug_y >= DROWS ) {
int i;
for (i=1; i<DROWS; 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;
@@ -523,30 +498,26 @@ void debug_output( char c )
return;
}
for ( ; debug_x < next_tab; ) {
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) ) {
if ( (c == '\n') || (debug_x >= DCOLS-1) ) {
debug_x=0;
debug_y++;
scroll_times++;
if ( debug_y >= DROWS ) {
if ( debug_y >= DROWS ) {
int i;
for (i=1; i<DROWS; 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;
}
if ( c == '\n' ) return;
}
debug_text[debug_y][debug_x++] = c;
@@ -557,72 +528,72 @@ 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' ) {
while( *p != '\0' ) {
debug_output(*p);
p++;
}
}
}
void debug_init()
{
int i;
if ( debug_inited ) {
return;
}
if ( debug_inited ) return;
debug_inited = 1;
debug_x=0;
debug_y=0;
for (i=0; i<DROWS; i++ ) {
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() ) {
while( key_inkey() ){
os_poll();
}
if ( !debug_inited ) {
debug_init();
}
if ( !debug_inited ) debug_init();
debug_draw();
while (!done) {
while (!done) {
// poll the os
os_poll();
int k = key_inkey();
switch( k ) {
switch( k ) {
case KEY_SHIFTED+KEY_ENTER:
case KEY_ESC:
done=1; break;
case KEY_ESC:
done=1; break;
case KEY_BACKSP:
if ( command_line_pos > 0 ) {
if ( command_line_pos > 0 ) {
command_line[--command_line_pos] = 0;
}
break;
case KEY_F3:
if ( last_oldcommand > -1 ) {
if ( last_oldcommand > -1 ) {
strcpy_s( command_line, oldcommand_line[last_oldcommand] );
command_line_pos = strlen(command_line);
command_line[command_line_pos] = 0;
@@ -631,11 +602,10 @@ void debug_console( void (*_func)() )
case KEY_UP:
command_scroll--;
if (command_scroll<0) {
if (command_scroll<0)
command_scroll = last_oldcommand;
}
if ( 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;
@@ -644,44 +614,46 @@ void debug_console( void (*_func)() )
case KEY_DOWN:
command_scroll++;
if (command_scroll>last_oldcommand) {
if (command_scroll>last_oldcommand)
command_scroll = 0;
}
if (command_scroll>last_oldcommand) {
if (command_scroll>last_oldcommand)
command_scroll = -1;
}
if ( 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: {
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 )) {
for (i=0; i<=last_oldcommand; i++ ) {
if (!stricmp( oldcommand_line[i], command_line )) {
found = 1;
}
}
if ( !found ) {
if ( last_oldcommand < DEBUG_HISTORY-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++ ) {
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;
@@ -690,7 +662,7 @@ void debug_console( void (*_func)() )
}
break;
default: {
default: {
ubyte c = (ubyte)key_to_ascii(k);
if ( c != 255 ) {
command_line[command_line_pos++] = c;
@@ -703,12 +675,12 @@ void debug_console( void (*_func)() )
strcat_s( debug_text[debug_y], command_line );
debug_draw();
if ( _func ) {
if ( _func ){
_func();
}
}
while( key_inkey() ) {
while( key_inkey() ){
os_poll();
}
}
@@ -717,25 +689,24 @@ void debug_help()
{
int s, i;
dc_printf( "Available functions:\n\n" );
dc_printf( "Available functions:\n\n" );
s = scroll_times;
for (i=0; i<Num_debug_commands; i++ ) {
for (i=0; i<Num_debug_commands; i++ ) {
dc_printf( " %s - %s\n", Debug_command[i]->name, Debug_command[i]->help );
if ( scroll_times - s > DROWS - 3 ) {
//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 ) {
if ( k == KEY_B ) {
i -= ((DROWS-3)*2);
if ( i <= 0 ) {
if ( i <= 0 )
i = -1;
}
}
}
}
debug_draw();
}
dc_printf( "\n" );
+406
View File
@@ -0,0 +1,406 @@
#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]);
}
+66
View File
@@ -0,0 +1,66 @@
#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
+5 -5
View File
@@ -109,10 +109,10 @@ const float WIDTHF = ((float) WIDTH) * 1.01f;
/**
* Internal conversion function to convert draw data into bars for the screen
*
* @param colour Colour index (>=0)
* @param xpos X position to start bar on
* @param xwidth Width of bar
* @param yrow Index of row bar belongs to
* @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)
{
@@ -212,7 +212,7 @@ void timerbar_switch_type(int num)
}
/**
* @param (*new_draw_func_ptr)(int colour, float x, float y, float w, float h) Pointer to draw function
* @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.
+8
View File
@@ -26,5 +26,13 @@ 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
File diff suppressed because it is too large. Load diff
+129
View File
@@ -0,0 +1,129 @@
//header file for making decals-Bobboau
#ifndef _DECAL_H
#define _DECAL_H
#include "object/object.h"
#include "globalincs/pstypes.h"
//#include "ship/ship.h"
#ifdef ENABLE_DECALS
#define MAX_DECAL_POLY 40
#define MAX_DECAL_POLY_POINT 10
#define MAX_DECAL_DEFPOINTS 10000
#define MAX_DECAL_POINT 10
#define MAX_SHIP_DECALS 25
#define MAX_GLOBAL_DECAL_POLYS 11000
#define QUICKFIND_SUBDIVISION 100
#define QUICKFIND_SEGMENT_LENGTH (MAX_GLOBAL_DECAL_POLYS/QUICKFIND_SUBDIVISION)
#define MAX_GLOBAL_DECALS 5000
#define DP_EOF 0
#define DP_DEFPOINTS 1
#define DP_FLATPOLY 2
#define DP_TMAPPOLY 3
#define DP_SORTNORM 4
#define DP_BOUNDBOX 5
#endif // ENABLE_DECALS
struct decal;
struct decal_list;
struct decal_list_controle;
struct decal_poly{
vec3d norm[3];
vertex point[3];
decal_poly *next;
decal* parent;
int idx;
};
struct decal{
int n_poly;
int timestamp; //when this decal was created
int burn_time; //how long it takes for the glow texture to fade
int vertex_buffer_start; //were is the start of this decal's polys in the vertex buffer
decal_poly* poly;
decal_poly* add_poly();
decal_poly* get_last_poly();
void remove_last_poly();
decal_list_controle *parent;
};
struct decal_list{
decal dec;
decal_list *next;
};
struct decal_item{
decal_list dec;
bool used;
};
struct decal_list_controle{
int n_decals;
int buffer;
int texture;
int n_poly;
int burn_texture;
int glow_texture;
bool modifyed;
decal_list *d_list;
decal_list *end;
decal_list *add_new();
void trim();
void clear();
~decal_list_controle();
decal_list_controle();
};
struct decal_system{
decal_list_controle *decals;
int n_decal_textures;
bool decals_modified;
int max_decals;
decal_system():decals(NULL),n_decal_textures(0),decals_modified(false){};
};
//this is used to give all the data to the generation data to the functions that make them
struct decal_point{
vec3d pnt;
matrix orient;
float radius;
};
#ifdef ENABLE_DECALS
int decal_create(object * obj, decal_point *point, int subobject, int texture, int backfaced_texture = -1, int glow_texture = -1, int burn_texture = -1, int burn_time = 1000);//makes the decal
int decal_create_simple(object * obj, decal_point *point, int texture);//makes a simple non-clipped decal
void decal_render_all(object * obj); //renders all decals
int decal_create_sub(void *model_ptr);
void clear_decals(decal_system *system);
void init_decals();
#else // ENABLE_DECALS
inline int decal_create(object * obj, decal_point *point, int subobject, int texture, int backfaced_texture = -1, int glow_texture = -1, int burn_texture = -1, int burn_time = 1000)
{
return 0;
}
#define decal_create_simple(a, b, c) (0)
#define decal_render_all(a)
#define decal_create_sub(a) (0);
#define clear_decals(a)
#define init_decals()
#endif // ENABLE_DECALS
#endif // _DECAL_H
+974
View File
@@ -0,0 +1,974 @@
/*
* 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;
}
+91
View File
@@ -0,0 +1,91 @@
/*
* 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
+109 -115
View File
@@ -20,7 +20,6 @@
#include "cmdline/cmdline.h"
#include "parse/parselo.h"
#include "globalincs/pstypes.h"
#include "asteroid/asteroid.h"
#include <stdlib.h>
@@ -48,6 +47,7 @@ fireball_info Fireball_info[MAX_FIREBALL_TYPES];
int fireball_used[MAX_FIREBALL_TYPES];
int Num_fireballs = 0;
int Num_fireball_types = 0;
int fireballs_inited = 0;
@@ -57,9 +57,7 @@ int Warp_ball_bitmap = -1;
#define FB_INDEX(fb) (fb-Fireballs)
/**
* Play warp in sound for warp effect
*/
// play warp in sound for warp effect
void fireball_play_warphole_open_sound(int ship_class, fireball *fb)
{
int sound_index;
@@ -89,9 +87,7 @@ void fireball_play_warphole_open_sound(int ship_class, fireball *fb)
snd_play_3d(&Snds[sound_index], &fireball_objp->pos, &Eye_position, fireball_objp->radius, NULL, 0, 1.0f, SND_PRIORITY_DOUBLE_INSTANCE, NULL, range_multiplier); // play warp sound effect
}
/**
* Play warp out sound for warp effect
*/
// play warp out sound for warp effect
void fireball_play_warphole_close_sound(fireball *fb)
{
int sound_index;
@@ -107,15 +103,14 @@ void fireball_play_warphole_close_sound(fireball *fb)
} else if ( fb->flags & FBF_WARP_CAPITAL_SIZE ) {
sound_index = SND_CAPITAL_WARP_OUT;
} else {
// AL 27-3-98: Decided that warphole closing is only required for capital ship sized warp effects.
return;
}
snd_play_3d(&Snds[sound_index], &fireball_objp->pos, &Eye_position, fireball_objp->radius); // play warp sound effect
}
/**
* Set default colors for each explosion type (original values from object.cpp)
*/
// set default colors for each explosion type (original values from object.cpp)
static void fireball_set_default_color(int idx)
{
Assert( (idx >= 0) && (idx < MAX_FIREBALL_TYPES) );
@@ -152,11 +147,7 @@ static void fireball_set_default_color(int idx)
}
}
/**
* Parse fireball tbl
*
* NOTE: we can't be too trusting here so a tbm will only modify the LOD count, not add an entry
*/
// NOTE: we can't be too trusting here so a tbm will only modify the LOD count, not add an entry
void parse_fireball_tbl(char *filename)
{
int rval;
@@ -248,8 +239,7 @@ void parse_fireball_tbl(char *filename)
void fireball_parse_tbl()
{
int i = 0, j;
SCP_vector<lod_checker>::iterator lod;
int i, j;
memset( &Fireball_info, 0, sizeof(fireball_info) * MAX_FIREBALL_TYPES );
@@ -261,10 +251,10 @@ void fireball_parse_tbl()
// we've got our list so pass it off for final checking and loading.
// we assume that entries in fireball.tbl are in the correct order
for (lod = LOD_checker.begin(); lod != LOD_checker.end(); ++lod) {
if ( (i < MAX_FIREBALL_TYPES) && (lod->override < 0) ) {
strcpy_s( Fireball_info[i].lod[0].filename, lod->filename );
Fireball_info[i].lod_count = lod->num_lods;
for (i = 0; i < (int)LOD_checker.size(); i++) {
if ( (i < MAX_FIREBALL_TYPES) && (LOD_checker[i].override < 0) ) {
strcpy_s( Fireball_info[i].lod[0].filename, LOD_checker[i].filename );
Fireball_info[i].lod_count = LOD_checker[i].num_lods;
Num_fireball_types++;
if (LOD_color[i].alpha == 255) {
@@ -275,24 +265,22 @@ void fireball_parse_tbl()
fireball_set_default_color(i);
}
}
i++;
}
// having to do this twice is less than optimal, but less error prone too.
// this handles (and should only have to handle) TBM related entries
i = 0;
for (lod = LOD_checker.begin(); lod != LOD_checker.end(); ++lod) {
for (i = 0; i < (int)LOD_checker.size(); i++) {
// try entry replacement
if ( (lod->override >= 0) && (lod->override < Num_fireball_types) ) {
strcpy_s( Fireball_info[lod->override].lod[0].filename, lod->filename );
Fireball_info[lod->override].lod_count = lod->num_lods;
if ( (LOD_checker[i].override >= 0) && (LOD_checker[i].override < Num_fireball_types) ) {
strcpy_s( Fireball_info[LOD_checker[i].override].lod[0].filename, LOD_checker[i].filename );
Fireball_info[LOD_checker[i].override].lod_count = LOD_checker[i].num_lods;
if (LOD_color[i].alpha == 255) {
Fireball_info[lod->override].exp_color[0] = (LOD_color[i].red / 255.0f);
Fireball_info[lod->override].exp_color[1] = (LOD_color[i].green / 255.0f);
Fireball_info[lod->override].exp_color[2] = (LOD_color[i].blue / 255.0f);
Fireball_info[LOD_checker[i].override].exp_color[0] = (LOD_color[i].red / 255.0f);
Fireball_info[LOD_checker[i].override].exp_color[1] = (LOD_color[i].green / 255.0f);
Fireball_info[LOD_checker[i].override].exp_color[2] = (LOD_color[i].blue / 255.0f);
} else {
fireball_set_default_color(lod->override);
fireball_set_default_color(LOD_checker[i].override);
}
}
}
@@ -335,6 +323,15 @@ void fireball_load_data()
if ( Warp_ball_bitmap == -1 ) {
Warp_ball_bitmap = bm_load( NOX("warpball01") );
}
// polymodel Warp_pm;
}
void fireball_preload()
{
// Do nothing. Called before level init, this used to page in warp effect.
// Not needed with new BmpMan system.
}
// This will get called at the start of each level.
@@ -375,6 +372,8 @@ MONITOR( NumFireballsRend )
void fireball_render(object * obj)
{
// if(!Cmdline_nohtl)gr_set_lighting(false,false);
int num;
vertex p;
fireball *fb;
@@ -389,6 +388,10 @@ void fireball_render(object * obj)
if ( Fireballs[num].current_bitmap < 0 )
return;
// gr_set_color( 0, 100, 0 );
// g3_draw_sphere_ez( &obj->pos, obj->radius );
// return;
// turn off fogging
if(The_mission.flags & MISSION_FLAG_FULLNEB){
gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
@@ -403,24 +406,14 @@ void fireball_render(object * obj)
switch( fb->fireball_render_type ) {
case FIREBALL_MEDIUM_EXPLOSION:
batch_add_bitmap (
Fireballs[num].current_bitmap,
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD,
&p,
fb->orient,
obj->radius
);
gr_set_bitmap(Fireballs[num].current_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.3f );
g3_draw_bitmap(&p, fb->orient, obj->radius, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
break;
case FIREBALL_LARGE_EXPLOSION:
// Make the big explosions rotate with the viewer.
batch_add_bitmap_rotated (
Fireballs[num].current_bitmap,
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD,
&p,
(i2fl(fb->orient)*PI)/180.0f,
obj->radius
);
gr_set_bitmap(Fireballs[num].current_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.3f );
g3_draw_rotated_bitmap(&p, (i2fl(fb->orient)*PI)/180.0f, obj->radius, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
break;
case FIREBALL_WARP_EFFECT: {
@@ -434,11 +427,17 @@ void fireball_render(object * obj)
if ( t < WARPHOLE_GROW_TIME ) {
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
//rad = t*obj->radius/WARPHOLE_GROW_TIME;
//mprintf(( "T=%.2f, Rad = %.2f\n", t, rad ));
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
rad = obj->radius;
} else {
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
//rad = (fb->total_time - t )*obj->radius/WARPHOLE_GROW_TIME;
}
//rad = obj->radius;
// obj->alt_rad = rad;
warpin_render(obj, &obj->orient, &obj->pos, Fireballs[num].current_bitmap, rad, percent_life, obj->radius, (Fireballs[num].flags & FBF_WARP_3D) );
}
@@ -450,10 +449,12 @@ void fireball_render(object * obj)
}
}
/**
* Delete a fireball.
* Called by object_delete() code... do not call directly.
*/
// -----------------------------------------------------------------
// fireball_delete()
//
// Delete a fireball. Called by object_delete() code... do not call
// directly.
//
void fireball_delete( object * obj )
{
int num;
@@ -469,9 +470,11 @@ void fireball_delete( object * obj )
Assert( Num_fireballs >= 0 );
}
/**
* Delete all active fireballs, by calling obj_delete directly.
*/
// -----------------------------------------------------------------
// fireball_delete_all()
//
// Delete all active fireballs, by calling obj_delete directly.
//
void fireball_delete_all()
{
fireball *fb;
@@ -561,12 +564,12 @@ int fireball_is_perishable(object * obj)
}
/**
* There are too many fireballs, so delete the oldest small one
* to free up a slot.
*
* @return The fireball slot freed.
*/
// -----------------------------------------------------------------
// fireball_free_one()
//
// There are too many fireballs, so delete the oldest small one
// to free up a slot. Returns the fireball slot freed.
//
int fireball_free_one()
{
fireball *fb;
@@ -597,6 +600,12 @@ int fireball_free_one()
return oldest_slotnum;
}
// broke fireball_move into fireball_process_pre and fireball_process_post as was done
// with all *_move functions on 8/13 by Mike K. and Mark A.
void fireball_process_pre( object *objp, float frame_time)
{
}
int fireball_is_warp(object * obj)
{
int num, objnum;
@@ -662,9 +671,7 @@ void fireball_process_post(object * obj, float frame_time)
fireball_set_framenum(num);
}
/**
* Returns life left of a fireball in seconds
*/
// Returns life left of a fireball in seconds
float fireball_lifeleft( object *obj )
{
int num, objnum;
@@ -679,9 +686,7 @@ float fireball_lifeleft( object *obj )
return fb->total_time - fb->time_elapsed;
}
/**
* Returns life left of a fireball in percent
*/
// Returns life left of a fireball in percent
float fireball_lifeleft_percent( object *obj )
{
int num, objnum;
@@ -693,14 +698,14 @@ float fireball_lifeleft_percent( object *obj )
fb = &Fireballs[num];
// Assert((fb->total_time - fb->time_elapsed) / fb->total_time >=0);
float p = (fb->total_time - fb->time_elapsed) / fb->total_time;
if (p < 0)p=0.0f;
return p;
}
/**
* Determine LOD to use
*/
// determine LOD to use
int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
{
vertex v;
@@ -781,9 +786,7 @@ int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
return MIN(ret_lod, fd->lod_count - 1);
}
/**
* Create a fireball, return object index.
*/
// Create a fireball, return object index.
int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent_obj, float size, int reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, int warp_open_sound, int warp_close_sound)
{
int n, objnum, fb_lod;
@@ -808,11 +811,22 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
}
if ( (Num_fireballs >= MAX_FIREBALLS) || (Num_objects >= MAX_OBJECTS) ) {
// who cares if we don't create a spark.
// JAS - Should this code be in? Is it better to remove an old spark
// and start a new one, or just not start the new one?
//if ( fd->type == FIREBALL_TYPE_SMALL ) {
// return -1;
//}
//mprintf(( "Out of fireball slots, trying to free one up!\n" ));
// out of slots, so free one up.
n = fireball_free_one();
if ( n < 0 ) {
if ( n < 0 ) {
// If there's still no free slots, then exit
//mprintf(( "ERROR: Couldn't free one up!!\n" ));
return -1;
} else {
//mprintf(( "Freed one up just fine!!\n" ));
}
} else {
for ( n = 0; n < MAX_FIREBALLS; n++ ) {
@@ -836,6 +850,11 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
// if this is a warpout fireball, never go higher than LOD 1
if(fireball_type == FIREBALL_WARP){
/*
if(fb_lod > 1){
fb_lod = 1;
}
*/
fb_lod = MAX_WARP_LOD;
}
fl = &fd->lod[fb_lod];
@@ -930,9 +949,11 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
return objnum;
}
/**
* Called at game shutdown to clean up the fireball system
*/
// -----------------------------------------------------------------
// fireball_close()
//
// Called at game shutdown to clean up the fireball system
//
void fireball_close()
{
if ( !fireballs_inited )
@@ -941,6 +962,20 @@ void fireball_close()
fireball_delete_all();
}
// -----------------------------------------------------------------
// fireball_level_close()
//
// Called when a mission ends... frees up any animations that might
// be partially played
//
void fireball_level_close()
{
if ( !fireballs_inited )
return;
fireball_delete_all();
}
void fireballs_page_in()
{
int i, idx;
@@ -1009,44 +1044,3 @@ int fireball_ship_explosion_type(ship_info *sip)
return index;
}
int fireball_asteroid_explosion_type(asteroid_info *aip)
{
Assert( aip != NULL );
if (aip->explosion_bitmap_anims.empty())
return -1;
int index = -1;
int roid_fireballs = (int)aip->explosion_bitmap_anims.size();
if (roid_fireballs > 0) {
index = aip->explosion_bitmap_anims[rand()%roid_fireballs];
}
return index;
}
float fireball_wormhole_intensity( object *obj )
{
int num, objnum;
fireball *fb;
num = obj->instance;
objnum = OBJ_INDEX(obj);
Assertion( Fireballs[num].objnum == objnum, "Basic sanity check. Fireballs[num].objnum (%d) should == objnum (%d)", Fireballs[num].objnum, objnum );
fb = &Fireballs[num];
float t = fb->time_elapsed;
float rad;
if ( t < WARPHOLE_GROW_TIME ) {
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f);
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
rad = 1;
} else {
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f);
}
return rad;
}
+21 -25
View File
@@ -16,7 +16,6 @@
struct object;
struct ship_info;
struct asteroid_info;
// values correspond to the fireball render types
#define FIREBALL_MEDIUM_EXPLOSION 0
@@ -24,15 +23,15 @@ struct asteroid_info;
#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 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 MAX_FIREBALL_TYPES 32 // The maximum number of fireballs that can be defined
#define NUM_DEFAULT_FIREBALLS 6
#define FIREBALL_NUM_LARGE_EXPLOSIONS 2
@@ -42,12 +41,12 @@ 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;
int bitmap_id;
int num_frames;
int fps;
} fireball_lod;
typedef struct fireball_info {
typedef struct fireball_info {
int lod_count;
float exp_color[3];
fireball_lod lod[4];
@@ -60,24 +59,25 @@ typedef struct fireball_info {
#define FBF_WARP_3D (1<<3) // Goober5000
#define FBF_WARP_VIA_SEXP (1<<4) // Goober5000
typedef struct fireball {
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
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
@@ -86,6 +86,8 @@ void fireball_process_post(object * obj, float frame_time);
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);
@@ -105,12 +107,6 @@ 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);
// returns the index of the fireball bitmap for this asteroid. -1 if there is none.
int fireball_asteroid_explosion_type(asteroid_info *aip);
// returns the intensity of a wormhole
float fireball_wormhole_intensity( object *obj );
// 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 );
+8 -17
View File
@@ -32,8 +32,8 @@ void draw_face( vertex *v1, vertex *v2, vertex *v3 )
vec3d norm;
vertex *vertlist[3];
vm_vec_perp(&norm,&v1->world, &v2->world, &v3->world);
if ( vm_vec_dot(&norm, &v1->world ) >= 0.0 ) {
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;
@@ -92,7 +92,7 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
}
vecs[4] = center;
verts[4].texture_position.u = 0.5f; verts[4].texture_position.v = 0.5f;
verts[4].u = 0.5f; verts[4].v = 0.5f;
if (Cmdline_nohtl) {
g3_rotate_vertex( &verts[4], &vecs[4] );
@@ -141,20 +141,11 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
vecs[4] = center;
verts[0].texture_position.u = 0.01f;
verts[0].texture_position.v = 0.01f;
verts[1].texture_position.u = 0.99f;
verts[1].texture_position.v = 0.01f;
verts[2].texture_position.u = 0.99f;
verts[2].texture_position.v = 0.99f;
verts[3].texture_position.u = 0.01f;
verts[3].texture_position.v = 0.99f;
verts[4].texture_position.u = 0.5f;
verts[4].texture_position.v = 0.5f;
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] );
+406 -406
View File
@@ -1,406 +1,406 @@
/*
* 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();
int inext = index + 1;
// 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[inext]);
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;
}
/*
* 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
#define new DEBUG_NEW
#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;
}
+86 -86
View File
@@ -1,86 +1,86 @@
/*
* 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_)
/*
* 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_)
+116 -115
View File
@@ -1,115 +1,116 @@
// 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);
}
// FictionViewerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "fred.h"
#include "FictionViewerDlg.h"
#include "missionui/fictionviewer.h"
#include "gamesnd/eventmusic.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#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);
}
+52 -52
View File
@@ -1,52 +1,52 @@
#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_)
#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_)
+4 -3
View File
@@ -16,6 +16,7 @@
#include "parse/sexp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -153,7 +154,7 @@ void CAddVariableDlg::validate_variable_name(int set_focus)
// Check if any change and not already in list
if ( stricmp(temp_name, "<Variable Name>") ) {
if ( (strlen(temp_name) > 0) && (get_index_sexp_variable_name(LPCTSTR(temp_name)) == -1) ) { //not already in list and length > 0 { //-V805
if ( (strlen(temp_name) > 0) && (get_index_sexp_variable_name(LPCTSTR(temp_name)) == -1) ) { //not already in list and length > 0 {
// Goober5000 - replace spaces with hyphens
if (strchr(temp_name, ' ') != NULL)
{
@@ -174,7 +175,7 @@ void CAddVariableDlg::validate_variable_name(int set_focus)
m_name_validated = true;
} else {
// conflicting variable name
if (strlen(temp_name) == 0) { //-V805
if (strlen(temp_name) == 0) {
edit->SetWindowText("<Variable Name>");
}
m_name_validated = false;
@@ -204,7 +205,7 @@ void CAddVariableDlg::validate_data(int set_focus)
edit->GetWindowText(temp_data);
// check for 0 string length
if (strlen(temp_data) == 0) { //-V805
if (strlen(temp_data) == 0) {
m_data_validated = false;
} else {
if (m_type_number) {
+1
View File
@@ -15,6 +15,7 @@
#include "mission/missiongrid.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+1
View File
@@ -19,6 +19,7 @@
#include "species_defs/species_defs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+1
View File
@@ -7,6 +7,7 @@
#include "ship/ship.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+12 -18
View File
@@ -26,6 +26,7 @@
#include "mission/missionparse.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -129,8 +130,6 @@ void bg_bitmap_dlg::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_SKY_FLAG_NO_CULL, m_sky_flag_4);
DDX_Check(pDX, IDC_SKY_FLAG_NO_GLOW, m_sky_flag_5);
DDX_Check(pDX, IDC_SKY_FLAG_CLAMP, m_sky_flag_6);
DDX_Text(pDX, IDC_NEB_FAR_MULTIPLIER, m_neb_far_multi);
DDX_Text(pDX, IDC_NEB_NEAR_MULTIPLIER, m_neb_near_multi);
//}}AFX_DATA_MAP
}
@@ -212,12 +211,12 @@ void bg_bitmap_dlg::create()
m_envmap = _T(The_mission.envmap_name);
for(i=0; i<MAX_NEB2_BITMAPS; i++){
if(strlen(Neb2_bitmap_filenames[i]) > 0){ //-V805
if(strlen(Neb2_bitmap_filenames[i]) > 0){
((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->AddString(Neb2_bitmap_filenames[i]);
}
}
// if we have a texture selected already
if(strlen(Neb2_texture_name) > 0){ //-V805
if(strlen(Neb2_texture_name) > 0){
m_neb2_texture = ((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->SelectString(-1, Neb2_texture_name);
if(m_neb2_texture == CB_ERR){
((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->SetCurSel(0);
@@ -230,8 +229,8 @@ void bg_bitmap_dlg::create()
// setup lightning storm names
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->ResetContent();
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->AddString(CString("none"));
for(size_t j=0; j<Storm_types.size(); j++){
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->AddString(CString(Storm_types[j].name));
for(i=0; i<Num_storm_types; i++){
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->AddString(CString(Storm_types[i].name));
}
((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->SelectString(-1, Mission_parse_storm_name);
@@ -300,9 +299,7 @@ void bg_bitmap_dlg::create()
GetDlgItem(IDC_AMBIENT_G_TEXT)->SetWindowText(buf);
sprintf(buf, "Blue: %d", m_amb_blue.GetPos());
GetDlgItem(IDC_AMBIENT_B_TEXT)->SetWindowText(buf);
m_neb_near_multi = Neb2_fog_near_mult;
m_neb_far_multi = Neb2_fog_far_mult;
UpdateData(FALSE);
OnFullNeb();
@@ -424,9 +421,6 @@ void bg_bitmap_dlg::OnClose()
The_mission.skybox_flags |= MR_FORCE_CLAMP;
}
Neb2_fog_near_mult = m_neb_near_multi;
Neb2_fog_far_mult = m_neb_far_multi;
// close sun data
sun_data_close();
@@ -668,9 +662,9 @@ void bg_bitmap_dlg::sun_data_save_current()
// store the data
strcpy_s(sle->filename, s_name);
sle->ang.p = (float) fl_radians(s_pitch);
sle->ang.b = (float) fl_radians(s_bank);
sle->ang.h = (float) fl_radians(s_heading);
sle->ang.p = (float) fl_radian(s_pitch);
sle->ang.b = (float) fl_radian(s_bank);
sle->ang.h = (float) fl_radian(s_heading);
sle->scale_x = (float) s_scale;
sle->scale_y = 1.0f;
sle->div_x = 1;
@@ -832,9 +826,9 @@ void bg_bitmap_dlg::bitmap_data_save_current()
// store the data
strcpy_s(sle->filename, b_name);
sle->ang.p = (float) fl_radians(b_pitch);
sle->ang.b = (float) fl_radians(b_bank);
sle->ang.h = (float) fl_radians(b_heading);
sle->ang.p = (float) fl_radian(b_pitch);
sle->ang.b = (float) fl_radian(b_bank);
sle->ang.h = (float) fl_radian(b_heading);
sle->scale_x = (float) b_scale_x;
sle->scale_y = (float) b_scale_y;
sle->div_x = b_div_x;
-2
View File
@@ -85,8 +85,6 @@ public:
int m_sky_flag_6;
CString m_skybox_model;
CString m_envmap;
float m_neb_near_multi;
float m_neb_far_multi;
//}}AFX_DATA
// Overrides
+7 -13
View File
@@ -30,6 +30,7 @@
#include "localization/localize.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -186,7 +187,7 @@ void briefing_editor_dlg::create()
box->AddString(Icon_names[i]);
box = (CComboBox *) GetDlgItem(IDC_TEAM);
for (i=0; i<Num_iffs; i++)
for (i=0; i<Num_team_names; i++)
box->AddString(Iff_info[i].iff_name);
box = (CComboBox *) GetDlgItem(IDC_SHIP_TYPE);
@@ -916,7 +917,7 @@ void briefing_editor_dlg::OnMakeIcon()
iconp = &Briefing->stages[m_cur_stage].icons[m_cur_icon];
ship = waypoint = -1;
team = 0;
SCP_list<jump_node>::iterator jnp;
jump_node *jnp = NULL;
vm_vec_make(&min, 9e19f, 9e19f, 9e19f);
vm_vec_make(&max, -9e19f, -9e19f, -9e19f);
@@ -947,10 +948,7 @@ void briefing_editor_dlg::OnMakeIcon()
break;
case OBJ_JUMP_NODE:
for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
if(jnp->get_obj() == ptr)
break;
}
jnp = ptr->jnp;
break;
default:
@@ -991,12 +989,8 @@ void briefing_editor_dlg::OnMakeIcon()
if (ship >= 0)
name = Ships[ship].ship_name;
else if (waypoint >= 0)
{
waypoint_list *wp_list = find_waypoint_list_with_instance(waypoint);
Assert(wp_list != NULL);
name = wp_list->get_name();
}
else if (jnp != Jump_nodes.end())
name = Waypoint_lists[waypoint / 65536].name;
else if (jnp != NULL)
name = jnp->get_name_ptr();
else
return;
@@ -1091,7 +1085,7 @@ void briefing_editor_dlg::OnMakeIcon()
}
}
// jumpnodes
else if(jnp != Jump_nodes.end()){
else if(jnp != NULL){
// find the first navbuoy
iconp->ship_class = -1;
for (int i = 0; i < Num_ship_classes; i++)
+72 -72
View File
@@ -23,6 +23,7 @@
#include "mission/missiongoals.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -45,9 +46,9 @@ campaign_editor::campaign_editor()
m_type = -1;
m_num_players = _T("");
m_desc = _T("");
m_branch_desc = _T("");
m_branch_brief_anim = _T("");
m_branch_brief_sound = _T("");
m_loop_desc = _T("");
m_loop_brief_anim = _T("");
m_loop_brief_sound = _T("");
m_custom_tech_db = FALSE;
//}}AFX_DATA_INIT
@@ -71,14 +72,14 @@ void campaign_editor::DoDataExchange(CDataExchange* pDX)
DDX_CBIndex(pDX, IDC_CAMPAIGN_TYPE, m_type);
DDX_Text(pDX, IDC_NUM_PLAYERS, m_num_players);
DDX_Text(pDX, IDC_DESC2, m_desc);
DDX_Text(pDX, IDC_MISSISON_LOOP_DESC, m_branch_desc);
DDX_Text(pDX, IDC_LOOP_BRIEF_ANIM, m_branch_brief_anim);
DDX_Text(pDX, IDC_LOOP_BRIEF_SOUND, m_branch_brief_sound);
DDX_Text(pDX, IDC_MISSISON_LOOP_DESC, m_loop_desc);
DDX_Text(pDX, IDC_LOOP_BRIEF_ANIM, m_loop_brief_anim);
DDX_Text(pDX, IDC_LOOP_BRIEF_SOUND, m_loop_brief_sound);
DDX_Check(pDX, IDC_CUSTOM_TECH_DB, m_custom_tech_db);
//}}AFX_DATA_MAP
DDV_MaxChars(pDX, m_desc, MISSION_DESC_LENGTH - 1);
DDV_MaxChars(pDX, m_branch_desc, MISSION_DESC_LENGTH - 1);
DDV_MaxChars(pDX, m_loop_desc, MISSION_DESC_LENGTH - 1);
}
BEGIN_MESSAGE_MAP(campaign_editor, CFormView)
@@ -223,10 +224,10 @@ void campaign_editor::initialize( int init_files )
m_desc = _T("");
}
m_branch_desc = _T("");
m_loop_desc = _T("");
m_branch_brief_anim = _T("");
m_branch_brief_sound = _T("");
m_loop_brief_anim = _T("");
m_loop_brief_sound = _T("");
// single player should hide the two dialog items about number of players allowed
if ( m_type == CAMPAIGN_TYPE_SINGLE ) {
@@ -361,7 +362,7 @@ void campaign_editor::load_tree(int save_first)
// insert item into tree
int image, sel_image;
if (Links[i].is_mission_loop || Links[i].is_mission_fork) {
if (Links[i].mission_loop) {
image = BITMAP_BLUE_DOT;
sel_image = BITMAP_GREEN_DOT;
} else {
@@ -654,76 +655,76 @@ void campaign_editor::save_loop_desc_window()
{
char buffer[MISSION_DESC_LENGTH];
// update only if active link and there is a mission has mission loop or fork
if ( (Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) ) {
deconvert_multiline_string(buffer, m_branch_desc, MISSION_DESC_LENGTH);
if (Links[Cur_campaign_link].mission_branch_txt) {
free(Links[Cur_campaign_link].mission_branch_txt);
// update only if active link and there is a mission has mission loop
if ( (Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop ) {
deconvert_multiline_string(buffer, m_loop_desc, MISSION_DESC_LENGTH);
if (Links[Cur_campaign_link].mission_loop_txt) {
free(Links[Cur_campaign_link].mission_loop_txt);
}
if (Links[Cur_campaign_link].mission_branch_brief_anim) {
free(Links[Cur_campaign_link].mission_branch_brief_anim);
if (Links[Cur_campaign_link].mission_loop_brief_anim) {
free(Links[Cur_campaign_link].mission_loop_brief_anim);
}
if (Links[Cur_campaign_link].mission_branch_brief_sound) {
free(Links[Cur_campaign_link].mission_branch_brief_sound);
if (Links[Cur_campaign_link].mission_loop_brief_sound) {
free(Links[Cur_campaign_link].mission_loop_brief_sound);
}
if (strlen(buffer)) {
Links[Cur_campaign_link].mission_branch_txt = strdup(buffer);
Links[Cur_campaign_link].mission_loop_txt = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_txt = NULL;
Links[Cur_campaign_link].mission_loop_txt = NULL;
}
deconvert_multiline_string(buffer, m_branch_brief_anim, MAX_FILENAME_LEN);
deconvert_multiline_string(buffer, m_loop_brief_anim, MAX_FILENAME_LEN);
if(strlen(buffer)){
Links[Cur_campaign_link].mission_branch_brief_anim = strdup(buffer);
Links[Cur_campaign_link].mission_loop_brief_anim = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_brief_anim = NULL;
Links[Cur_campaign_link].mission_loop_brief_anim = NULL;
}
deconvert_multiline_string(buffer, m_branch_brief_sound, MAX_FILENAME_LEN);
deconvert_multiline_string(buffer, m_loop_brief_sound, MAX_FILENAME_LEN);
if(strlen(buffer)){
Links[Cur_campaign_link].mission_branch_brief_sound = strdup(buffer);
Links[Cur_campaign_link].mission_loop_brief_sound = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_brief_sound = NULL;
Links[Cur_campaign_link].mission_loop_brief_sound = NULL;
}
}
}
void campaign_editor::update_loop_desc_window()
{
bool enable_branch_desc_window;
bool enable_loop_desc_window;
enable_branch_desc_window = false;
if ((Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork)) {
enable_branch_desc_window = true;
enable_loop_desc_window = false;
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop) {
enable_loop_desc_window = true;
}
// maybe enable description window
GetDlgItem(IDC_MISSISON_LOOP_DESC)->EnableWindow(enable_branch_desc_window);
GetDlgItem(IDC_LOOP_BRIEF_ANIM)->EnableWindow(enable_branch_desc_window);
GetDlgItem(IDC_LOOP_BRIEF_SOUND)->EnableWindow(enable_branch_desc_window);
GetDlgItem(IDC_LOOP_BRIEF_BROWSE)->EnableWindow(enable_branch_desc_window);
GetDlgItem(IDC_LOOP_BRIEF_SOUND_BROWSE)->EnableWindow(enable_branch_desc_window);
GetDlgItem(IDC_MISSISON_LOOP_DESC)->EnableWindow(enable_loop_desc_window);
GetDlgItem(IDC_LOOP_BRIEF_ANIM)->EnableWindow(enable_loop_desc_window);
GetDlgItem(IDC_LOOP_BRIEF_SOUND)->EnableWindow(enable_loop_desc_window);
GetDlgItem(IDC_LOOP_BRIEF_BROWSE)->EnableWindow(enable_loop_desc_window);
GetDlgItem(IDC_LOOP_BRIEF_SOUND_BROWSE)->EnableWindow(enable_loop_desc_window);
// set new text
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_txt && enable_branch_desc_window) {
m_branch_desc = convert_multiline_string(Links[Cur_campaign_link].mission_branch_txt);
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_txt && enable_loop_desc_window) {
m_loop_desc = convert_multiline_string(Links[Cur_campaign_link].mission_loop_txt);
} else {
m_branch_desc = _T("");
m_loop_desc = _T("");
}
// set new text
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_brief_anim && enable_branch_desc_window) {
m_branch_brief_anim = convert_multiline_string(Links[Cur_campaign_link].mission_branch_brief_anim);
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_brief_anim && enable_loop_desc_window) {
m_loop_brief_anim = convert_multiline_string(Links[Cur_campaign_link].mission_loop_brief_anim);
} else {
m_branch_brief_anim = _T("");
m_loop_brief_anim = _T("");
}
// set new text
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_brief_sound && enable_branch_desc_window) {
m_branch_brief_sound = convert_multiline_string(Links[Cur_campaign_link].mission_branch_brief_sound);
if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_brief_sound && enable_loop_desc_window) {
m_loop_brief_sound = convert_multiline_string(Links[Cur_campaign_link].mission_loop_brief_sound);
} else {
m_branch_brief_sound = _T("");
m_loop_brief_sound = _T("");
}
// reset text
@@ -737,56 +738,55 @@ void campaign_editor::OnToggleLoop()
return;
}
// store mission loop text
// store mission looop text
UpdateData(TRUE);
if ( (Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) ) {
if (Links[Cur_campaign_link].mission_branch_txt) {
free(Links[Cur_campaign_link].mission_branch_txt);
if ( (Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop ) {
if (Links[Cur_campaign_link].mission_loop_txt) {
free(Links[Cur_campaign_link].mission_loop_txt);
}
if (Links[Cur_campaign_link].mission_branch_brief_anim) {
free(Links[Cur_campaign_link].mission_branch_brief_anim);
if (Links[Cur_campaign_link].mission_loop_brief_anim) {
free(Links[Cur_campaign_link].mission_loop_brief_anim);
}
if (Links[Cur_campaign_link].mission_branch_brief_sound) {
free(Links[Cur_campaign_link].mission_branch_brief_sound);
if (Links[Cur_campaign_link].mission_loop_brief_sound) {
free(Links[Cur_campaign_link].mission_loop_brief_sound);
}
char buffer[MISSION_DESC_LENGTH];
deconvert_multiline_string(buffer, m_branch_desc, MISSION_DESC_LENGTH);
if (m_branch_desc && strlen(buffer)) {
Links[Cur_campaign_link].mission_branch_txt = strdup(buffer);
deconvert_multiline_string(buffer, m_loop_desc, MISSION_DESC_LENGTH);
if (m_loop_desc && strlen(buffer)) {
Links[Cur_campaign_link].mission_loop_txt = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_txt = NULL;
Links[Cur_campaign_link].mission_loop_txt = NULL;
}
deconvert_multiline_string(buffer, m_branch_brief_anim, MISSION_DESC_LENGTH);
if (m_branch_brief_anim && strlen(buffer)) {
Links[Cur_campaign_link].mission_branch_brief_anim = strdup(buffer);
deconvert_multiline_string(buffer, m_loop_brief_anim, MISSION_DESC_LENGTH);
if (m_loop_brief_anim && strlen(buffer)) {
Links[Cur_campaign_link].mission_loop_brief_anim = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_brief_anim = NULL;
Links[Cur_campaign_link].mission_loop_brief_anim = NULL;
}
deconvert_multiline_string(buffer, m_branch_brief_sound, MISSION_DESC_LENGTH);
if (m_branch_brief_sound && strlen(buffer)) {
Links[Cur_campaign_link].mission_branch_brief_sound = strdup(buffer);
deconvert_multiline_string(buffer, m_loop_brief_sound, MISSION_DESC_LENGTH);
if (m_loop_brief_sound && strlen(buffer)) {
Links[Cur_campaign_link].mission_loop_brief_sound = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_brief_sound = NULL;
Links[Cur_campaign_link].mission_loop_brief_sound = NULL;
}
}
// toggle to mission_loop setting
Links[Cur_campaign_link].is_mission_loop = !Links[Cur_campaign_link].is_mission_loop;
Links[Cur_campaign_link].is_mission_fork = false;
Links[Cur_campaign_link].mission_loop = !Links[Cur_campaign_link].mission_loop;
// reset loop desc window (gray if inactive)
update_loop_desc_window();
// set root icon
int bitmap1, bitmap2;
if (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) {
if (Links[Cur_campaign_link].mission_loop) {
bitmap2 = BITMAP_GREEN_DOT;
bitmap1 = BITMAP_BLUE_DOT;
} else {
@@ -820,7 +820,7 @@ void campaign_editor::OnBrowseLoopAni()
CFileDialog dlg(TRUE, "ani", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Ani Files (*.ani)|*.ani");
if (dlg.DoModal() == IDOK) {
m_branch_brief_anim = dlg.GetFileName();
m_loop_brief_anim = dlg.GetFileName();
UpdateData(FALSE);
}
@@ -842,7 +842,7 @@ void campaign_editor::OnBrowseLoopSound()
"Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
if (dlg.DoModal() == IDOK) {
m_branch_brief_sound = dlg.GetFileName();
m_loop_brief_sound = dlg.GetFileName();
UpdateData(FALSE);
}
@@ -886,7 +886,7 @@ void campaign_editor::OnChangeDebriefingPersona()
if (persona < 0 || persona > 0xff)
persona = 0;
Campaign.missions[Cur_campaign_mission].debrief_persona_index = (ubyte) persona;
Campaign.missions[Cur_campaign_mission].debrief_persona_index = persona;
}
}
+3 -3
View File
@@ -56,9 +56,9 @@ public:
int m_type;
CString m_num_players;
CString m_desc;
CString m_branch_desc;
CString m_branch_brief_anim;
CString m_branch_brief_sound;
CString m_loop_desc;
CString m_loop_brief_anim;
CString m_loop_brief_sound;
BOOL m_custom_tech_db;
//}}AFX_DATA
+1
View File
@@ -19,6 +19,7 @@
#include "mission/missionparse.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+37 -44
View File
@@ -18,6 +18,7 @@
#include "mission/missionparse.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -183,14 +184,14 @@ void campaign_tree_view::OnDraw(CDC* pDC)
Links[i].p2.x = Elements[t].box.left + Links[i].to_pos * Bx / (Elements[t].to_links + 1);
Links[i].p2.y = Elements[t].box.top;
// if special mission link, select blue pen
if (Links[i].is_mission_loop || Links[i].is_mission_fork) {
// if mission_loop link, select blue pen
if (Links[i].mission_loop) {
pDC->SelectObject(&blue_pen);
}
// if active link, select highlight pen (red - normal, green - special)
// if active link, select highlight pen (red - normal, green - mission loop)
if (i == Cur_campaign_link) {
if (Links[i].is_mission_loop || Links[i].is_mission_fork) {
if (Links[i].mission_loop) {
pDC->SelectObject(&green_pen);
} else {
pDC->SelectObject(&red_pen);
@@ -248,9 +249,9 @@ void stuff_link_with_formula(int *link_idx, int formula, int mission_num)
node2 = CAR(node);
Links[*link_idx].from = mission_num;
Links[*link_idx].sexp = CAR(node2);
Links[*link_idx].mission_branch_txt = NULL;
Links[*link_idx].mission_branch_brief_anim = NULL;
Links[*link_idx].mission_branch_brief_sound = NULL;
Links[*link_idx].mission_loop_txt = NULL;
Links[*link_idx].mission_loop_brief_anim = NULL;
Links[*link_idx].mission_loop_brief_sound = NULL;
sexp_mark_persistent(CAR(node2));
free_one_sexp(node2);
node3 = CADR(node2);
@@ -300,20 +301,13 @@ void campaign_tree_view::construct_tree()
// do main campaign path
stuff_link_with_formula(&link_idx, Campaign.missions[i].formula, i);
// do special mission path
if ( Campaign.missions[i].flags & CMISSION_FLAG_HAS_LOOP ) {
// do mission loop path
if ( Campaign.missions[i].has_mission_loop ) {
stuff_link_with_formula(&link_idx, Campaign.missions[i].mission_loop_formula, i);
Links[link_idx-1].mission_branch_txt = Campaign.missions[i].mission_branch_desc;
Links[link_idx-1].mission_branch_brief_anim = Campaign.missions[i].mission_branch_brief_anim;
Links[link_idx-1].mission_branch_brief_sound = Campaign.missions[i].mission_branch_brief_sound;
Links[link_idx-1].is_mission_loop = true;
}
else if ( Campaign.missions[i].flags & CMISSION_FLAG_HAS_FORK ) {
Campaign.missions[i].mission_loop_formula = -1;
Links[link_idx-1].mission_branch_txt = Campaign.missions[i].mission_branch_desc;
Links[link_idx-1].mission_branch_brief_anim = Campaign.missions[i].mission_branch_brief_anim;
Links[link_idx-1].mission_branch_brief_sound = Campaign.missions[i].mission_branch_brief_sound;
Links[link_idx-1].is_mission_fork = true;
Links[link_idx-1].mission_loop_txt = Campaign.missions[i].mission_loop_desc;
Links[link_idx-1].mission_loop_brief_anim = Campaign.missions[i].mission_loop_brief_anim;
Links[link_idx-1].mission_loop_brief_sound = Campaign.missions[i].mission_loop_brief_sound;
Links[link_idx-1].mission_loop = 1;
}
}
@@ -517,45 +511,45 @@ void campaign_tree_view::OnLButtonDown(UINT nFlags, CPoint point)
dc.DrawDragRect(Dragging_rect, Last_draw_size, NULL, CSize(0, 0));
} else {
if ( (Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork)) {
// HACK!! UPDATE mission loop/fork desc before changing selections
// save mission loop/fork desc
if ( (Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop) {
// HACK!! UPDATE mission loop desc before changing selections
// save mission loop desc
char buffer[MISSION_DESC_LENGTH];
box = (CEdit *) Campaign_tree_formp->GetDlgItem(IDC_MISSISON_LOOP_DESC);
box->GetWindowText(buffer, MISSION_DESC_LENGTH);
if (strlen(buffer)) {
if (Links[Cur_campaign_link].mission_branch_txt) {
free(Links[Cur_campaign_link].mission_branch_txt);
if (Links[Cur_campaign_link].mission_loop_txt) {
free(Links[Cur_campaign_link].mission_loop_txt);
}
Links[Cur_campaign_link].mission_branch_txt = strdup(buffer);
Links[Cur_campaign_link].mission_loop_txt = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_txt = NULL;
Links[Cur_campaign_link].mission_loop_txt = NULL;
}
// HACK!! UPDATE mission loop/fork desc before changing selections
// save mission loop/fork desc
// HACK!! UPDATE mission loop desc before changing selections
// save mission loop desc
box = (CEdit *) Campaign_tree_formp->GetDlgItem(IDC_LOOP_BRIEF_ANIM);
box->GetWindowText(buffer, MISSION_DESC_LENGTH);
if (strlen(buffer)) {
if (Links[Cur_campaign_link].mission_branch_brief_anim) {
free(Links[Cur_campaign_link].mission_branch_brief_anim);
if (Links[Cur_campaign_link].mission_loop_brief_anim) {
free(Links[Cur_campaign_link].mission_loop_brief_anim);
}
Links[Cur_campaign_link].mission_branch_brief_anim = strdup(buffer);
Links[Cur_campaign_link].mission_loop_brief_anim = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_brief_anim = NULL;
Links[Cur_campaign_link].mission_loop_brief_anim = NULL;
}
// HACK!! UPDATE mission loop/fork desc before changing selections
// save mission loop/fork desc
// HACK!! UPDATE mission loop desc before changing selections
// save mission loop desc
box = (CEdit *) Campaign_tree_formp->GetDlgItem(IDC_LOOP_BRIEF_SOUND);
box->GetWindowText(buffer, MISSION_DESC_LENGTH);
if (strlen(buffer)) {
if (Links[Cur_campaign_link].mission_branch_brief_sound) {
free(Links[Cur_campaign_link].mission_branch_brief_sound);
if (Links[Cur_campaign_link].mission_loop_brief_sound) {
free(Links[Cur_campaign_link].mission_loop_brief_sound);
}
Links[Cur_campaign_link].mission_branch_brief_sound = strdup(buffer);
Links[Cur_campaign_link].mission_loop_brief_sound = strdup(buffer);
} else {
Links[Cur_campaign_link].mission_branch_brief_sound = NULL;
Links[Cur_campaign_link].mission_loop_brief_sound = NULL;
}
}
Mission_dragging = Cur_campaign_mission = Cur_campaign_link = -1;
@@ -751,11 +745,10 @@ int campaign_tree_view::add_link(int from, int to)
Links[Total_links].from = from;
Links[Total_links].to = to;
Links[Total_links].sexp = Locked_sexp_true;
Links[Total_links].is_mission_loop = false;
Links[Total_links].is_mission_fork = false;
Links[Total_links].mission_branch_txt = NULL;
Links[Total_links].mission_branch_brief_anim = NULL;
Links[Total_links].mission_branch_brief_sound = NULL;
Links[Total_links].mission_loop = false;
Links[Total_links].mission_loop_txt = NULL;
Links[Total_links].mission_loop_brief_anim = NULL;
Links[Total_links].mission_loop_brief_sound = NULL;
Total_links++;
if (from != to) {
Elements[from].from_links++;
+4 -5
View File
@@ -28,11 +28,10 @@ typedef struct campaign_tree_link {
int node; // node tracker when link is in sexp tree window
int from_pos; // from link drawing offset
int to_pos; // to link drawing offset
bool is_mission_loop; // whether link leads to mission loop
bool is_mission_fork; // whether link leads to mission fork
char *mission_branch_txt; // text describing mission loop
char *mission_branch_brief_anim; // filename of anim to play in the brief
char *mission_branch_brief_sound; // filename of anim to play in the brief
bool mission_loop; // whether link leads to mission loop
char *mission_loop_txt; // text describing mission loop
char *mission_loop_brief_anim; // filename of anim to play in the brief
char *mission_loop_brief_sound; // filename of anim to play in the brief
CPoint p1; // coordinates of line last draw for link, from p1 to p2
CPoint p2;
} campaign_tree_link;
+3 -2
View File
@@ -22,6 +22,7 @@
#include "mission/missionparse.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -410,7 +411,7 @@ int campaign_tree_wnd::internal_error(char *msg, ...)
int campaign_tree_wnd::fred_check_sexp(int sexp, int type, char *msg, ...)
{
char buf[512], buf2[2048], buf3[MAX_EVENT_SIZE];
char buf[512], buf2[2048], buf3[4096];
int err = 0, z, faulty_node;
va_list args;
@@ -425,7 +426,7 @@ int campaign_tree_wnd::fred_check_sexp(int sexp, int type, char *msg, ...)
if (!z)
return 0;
convert_sexp_to_string(sexp, buf2, SEXP_ERROR_CHECK_MODE, MAX_EVENT_SIZE);
convert_sexp_to_string(sexp, buf2, SEXP_ERROR_CHECK_MODE, 2048);
sprintf(buf3, "Error in %s: %s\n\nIn sexpression: %s\n\n(Error appears to be: %s)",
buf, sexp_error_message(z), buf2, Sexp_nodes[faulty_node].text);
+1
View File
@@ -17,6 +17,7 @@
#include "localization/localize.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+6 -4
View File
@@ -20,6 +20,7 @@
#include "iff_defs/iff_defs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -119,10 +120,11 @@ void create_wing_dlg::OnOK()
}
}
if (find_matching_waypoint_list(const_cast<char *>((const char *) m_name)) != NULL)
{
MessageBox("This wing name is already being used by a waypoint path");
return;
for (i=0; i<MAX_WAYPOINT_LISTS; i++) {
if (Waypoint_lists[i].count && !stricmp(Waypoint_lists[i].name, m_name)) {
MessageBox("This wing name is already being used by a waypoint path");
return;
}
}
if (!stricmp(m_name.Left(1), "<")) {
+1
View File
@@ -7,6 +7,7 @@
#include "ship/ship.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+1 -38
View File
@@ -14,17 +14,13 @@
#include "DebriefingEditorDlg.h"
#include "FREDDoc.h"
#include "mission/missionbriefcommon.h"
#include "mission/missionparse.h"
#include "globalincs/linklist.h"
#include "parse/sexp.h"
#include "gamesnd/eventmusic.h"
#include "cfile/cfile.h"
#include "sound/audiostr.h"
#include "localization/localize.h"
#include "jumpnode/jumpnode.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -40,9 +36,6 @@ debriefing_editor_dlg::debriefing_editor_dlg(CWnd* pParent /*=NULL*/)
m_voice = _T("");
m_stage_title = _T("");
m_rec_text = _T("");
m_debriefPass_music = 0;
m_debriefAvg_music = 0;
m_debriefFail_music = 0;
m_current_debriefing = -1;
//}}AFX_DATA_INIT
@@ -62,9 +55,6 @@ void debriefing_editor_dlg::DoDataExchange(CDataExchange* pDX)
DDX_Text(pDX, IDC_VOICE, m_voice);
DDX_Text(pDX, IDC_STAGE_TITLE, m_stage_title);
DDX_Text(pDX, IDC_REC_TEXT, m_rec_text);
DDX_CBIndex(pDX, IDC_SUCCESSFUL_MISSION_TRACK, m_debriefPass_music);
DDX_CBIndex(pDX, IDC_DEBRIEFING_TRACK, m_debriefAvg_music);
DDX_CBIndex(pDX, IDC_FAILED_MISSION_TRACK, m_debriefFail_music);
//}}AFX_DATA_MAP
DDV_MaxChars(pDX, m_text, MAX_BRIEF_LEN - 1);
@@ -126,33 +116,12 @@ BOOL debriefing_editor_dlg::OnInitDialog()
CDialog::OnInitDialog();
m_play_bm.LoadBitmap(IDB_PLAY);
((CButton *) GetDlgItem(IDC_PLAY)) -> SetBitmap(m_play_bm);
CComboBox *box;
box = (CComboBox *) GetDlgItem(IDC_ICON_IMAGE);
m_current_debriefing = 0;
UpdateData(FALSE);
Debriefing = &Debriefings[m_current_debriefing];
box = (CComboBox *) GetDlgItem(IDC_SUCCESSFUL_MISSION_TRACK);
box->AddString("None");
for (i=0; i<Num_music_files; i++)
box->AddString(Spooled_music[i].name);
box = (CComboBox *) GetDlgItem(IDC_DEBRIEFING_TRACK);
box->AddString("None");
for (i=0; i<Num_music_files; i++)
box->AddString(Spooled_music[i].name);
box = (CComboBox *) GetDlgItem(IDC_FAILED_MISSION_TRACK);
box->AddString("None");
for (i=0; i<Num_music_files; i++)
box->AddString(Spooled_music[i].name);
m_debriefPass_music = Mission_music[SCORE_DEBRIEF_SUCCESS] + 1;
m_debriefAvg_music = Mission_music[SCORE_DEBRIEF_AVERAGE] + 1;
m_debriefFail_music = Mission_music[SCORE_DEBRIEF_FAIL] + 1;
m_tree.link_modified(&modified); // provide way to indicate trees are modified in dialog
n = m_tree.select_sexp_node = select_sexp_node;
select_sexp_node = -1;
@@ -171,7 +140,6 @@ BOOL debriefing_editor_dlg::OnInitDialog()
}
}
CDialog::OnInitDialog();
update_data();
set_modified();
@@ -435,11 +403,6 @@ void debriefing_editor_dlg::OnClose()
m_voice_id = -1;
m_cur_stage = -1;
update_data(1);
Mission_music[SCORE_DEBRIEF_SUCCESS] = m_debriefPass_music - 1;
Mission_music[SCORE_DEBRIEF_AVERAGE] = m_debriefAvg_music - 1;
Mission_music[SCORE_DEBRIEF_FAIL] = m_debriefFail_music - 1;
CDialog::OnClose();
}
-4
View File
@@ -8,7 +8,6 @@
*/
#include "mission/missionbriefcommon.h"
/////////////////////////////////////////////////////////////////////////////
// debriefing_editor_dlg dialog
@@ -30,9 +29,6 @@ public:
CString m_voice;
CString m_stage_title;
CString m_rec_text;
int m_debriefPass_music;
int m_debriefAvg_music;
int m_debriefFail_music;
int m_current_debriefing;
//}}AFX_DATA
+1
View File
@@ -14,6 +14,7 @@
#include "dialog1.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+15 -16
View File
@@ -27,6 +27,7 @@
#include "weapon/weapon.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -281,7 +282,7 @@ void DumpStats::get_background_stats(CString &buffer)
}
// nebula texture
if (strlen(Neb2_texture_name) > 0) { //-V805
if (strlen(Neb2_texture_name) > 0) {
temp.Format("\tNebula texture: %s\r\n", Neb2_texture_name);
buffer += temp;
}
@@ -385,12 +386,11 @@ void DumpStats::get_object_stats(CString &buffer)
// Waypoints
int total_waypoints = 0;
buffer += "\r\nWAYPOINTS\r\n";
SCP_list<waypoint_list>::iterator ii;
for (ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++ii) {
temp.Format("\tWaypoint: %s, count: %d\r\n", ii->get_name(), ii->get_waypoints().size());
for (i=0; i<Num_waypoint_lists; i++) {
temp.Format("\tWaypoint: %s, count: %d\r\n", Waypoint_lists[i].name, Waypoint_lists[i].count);
buffer += temp;
total_waypoints += ii->get_waypoints().size();
total_waypoints += Waypoint_lists[i].count;
}
if (total_waypoints > 0) {
@@ -400,15 +400,13 @@ void DumpStats::get_object_stats(CString &buffer)
// Jumpnodes
buffer += "\r\nJUMPNODES\r\n";
SCP_list<jump_node>::iterator jnp;
for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
for ( jump_node *jnp = (jump_node *)Jump_nodes.get_first(); !Jump_nodes.is_end(jnp); jnp = (jump_node *)jnp->get_next() ) {
temp.Format("\tJumpnode: %s\r\n", jnp->get_name_ptr());
buffer += temp;
}
if (Jump_nodes.size() > 0) {
temp.Format("\ttotal_jumpnodes: %d\r\n", Jump_nodes.size());
if (Jump_nodes.get_num_elements() > 0) {
temp.Format("\ttotal_jumpnodes: %d\r\n", Jump_nodes.get_num_elements());
buffer += temp;
}
@@ -485,7 +483,7 @@ void DumpStats::get_objectives_and_goals(CString &buffer)
// goals
for (i=0; i<Num_goals; i++) {
temp.Format("\tGoal: %s, text: %s", Mission_goals[i].name, Mission_goals[i].message);
temp.Format("\tGoal: %s, text: ", Mission_goals[i].name, Mission_goals[i].message);
buffer += temp;
switch(Mission_goals[i].type & GOAL_TYPE_MASK) {
@@ -572,14 +570,15 @@ void DumpStats::get_species_ship_breakdown(CString &buffer)
{
CString temp;
int i;
int species;
uint species;
object *objp;
ship *shipp;
buffer += "\r\nSHIP SPECIES BREAKDOWN\r\n";
for (species=0; (uint) species < Species_info.size(); species++) {
for (species=0; species < Species_info.size(); species++) {
buffer += Species_info[species].species_name;
buffer += "\r\n";
@@ -752,7 +751,7 @@ void dump_loadout(ship *shipp, CString &loadout)
void DumpStats::get_default_ship_loadouts(CString &buffer)
{
int i;
int species;
uint species;
object *objp;
ship *shipp;
CString temp, loadout;
@@ -760,7 +759,7 @@ void DumpStats::get_default_ship_loadouts(CString &buffer)
buffer += "\r\nSHIP SPECIES BREAKDOWN\r\n";
for (species=0; (uint) species < Species_info.size(); species++) {
for (species=0; species < Species_info.size(); species++) {
buffer += Species_info[species].species_name;
buffer += "\r\n";
+9 -12
View File
@@ -22,6 +22,7 @@
#include "localization/localize.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -81,17 +82,15 @@ void event_editor::DoDataExchange(CDataExchange* pDX)
DDX_CBString(pDX, IDC_WAVE_FILENAME, m_wave_filename);
DDX_LBIndex(pDX, IDC_MESSAGE_LIST, m_cur_msg);
// m_team == -1 maps to 2
if(m_team == -1){
m_team = MAX_TVT_TEAMS;
m_team = 2;
}
DDX_CBIndex(pDX, IDC_EVENT_TEAM, m_team);
// m_message_team == -1 maps to 2
if(m_message_team == -1){
m_message_team = MAX_TVT_TEAMS;
m_message_team = 2;
}
DDX_CBIndex(pDX, IDC_MESSAGE_TEAM, m_message_team);
//}}AFX_DATA_MAP
@@ -571,7 +570,7 @@ void event_editor::update_cur_message()
m_persona = 0;
}
if(m_messages[m_cur_msg].multi_team >= MAX_TVT_TEAMS){
if(m_messages[m_cur_msg].multi_team >= 2){
m_message_team = -1;
m_messages[m_cur_msg].multi_team = -1;
} else {
@@ -716,7 +715,6 @@ void event_editor::reset_event(int num, HTREEITEM after)
m_events[num].chain_delay = -1;
m_events[num].objective_text = NULL;
m_events[num].objective_key_text = NULL;
m_events[num].team = -1;
m_sig[num] = -1;
m_event_tree.item_index = -1;
@@ -1176,7 +1174,7 @@ int event_editor::save_message(int num)
// box list.
m_messages[num].persona_index = m_persona - 1;
if(m_message_team >= MAX_TVT_TEAMS){
if(m_message_team >= 2){
m_messages[num].multi_team = -1;
m_message_team = -1;
} else {
@@ -1229,7 +1227,6 @@ void event_editor::OnDeleteMsg()
((CListBox *) GetDlgItem(IDC_MESSAGE_LIST))->DeleteString(m_cur_msg);
sprintf(buf, "<%s>", m_messages[m_cur_msg].name);
update_sexp_references(m_messages[m_cur_msg].name, buf, OPF_MESSAGE);
update_sexp_references(m_messages[m_cur_msg].name, buf, OPF_MESSAGE_OR_STRING);
m_messages.erase(m_messages.begin() + m_cur_msg);
@@ -1412,8 +1409,8 @@ void event_editor::OnSelchangeTeam()
UpdateData(TRUE);
// If the team isn't valid mark it as such.
if((m_team >= MAX_TVT_TEAMS) || (m_team < -1) ){
// team == 2, means no team
if(m_team == 2){
m_team = -1;
}
@@ -1429,8 +1426,8 @@ void event_editor::OnSelchangeMessageTeam()
UpdateData(TRUE);
// If the team isn't valid mark it as such.
if((m_message_team>= MAX_TVT_TEAMS) || (m_message_team < -1) ) {
// team == 2, means no team
if(m_message_team == 2){
m_message_team = -1;
}
+1 -1
View File
@@ -185,7 +185,7 @@ BOOL CFolderDialog::SetSelectedFolder( IN LPCTSTR pszPath )
VOID CFolderDialog::OnInitialized( VOID )
{
if( ::lstrlen( m_szSelPath ) > 0 ) //-V805
if( ::lstrlen( m_szSelPath ) > 0 )
SetSelection( m_szSelPath );
}
+5 -4
View File
@@ -25,6 +25,7 @@
#include "CampaignTreeWnd.h"
#include "CampaignTreeView.h"
#include "CampaignEditorDlg.h"
#include "debugconsole/dbugfile.h"
#include "globalincs/mspdb_callstack.h"
#include "AFXADV.H"
@@ -36,6 +37,7 @@
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -97,6 +99,7 @@ CFREDApp::CFREDApp()
{
app_init = 0;
DBUGFILE_INIT();
SCP_mspdbcs_Initialise( );
#ifndef NDEBUG
@@ -107,6 +110,7 @@ CFREDApp::CFREDApp()
CFREDApp::~CFREDApp()
{
SCP_mspdbcs_Cleanup( );
DBUGFILE_DEINIT();
}
/////////////////////////////////////////////////////////////////////////////
@@ -123,7 +127,7 @@ BOOL CFREDApp::InitInstance()
// disable the debug memory stuff
// _CrtSetDbgFlag(~(_CRTDBG_ALLOC_MEM_DF) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
_CrtSetDbgFlag(~(_CRTDBG_ALLOC_MEM_DF) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
// Standard initialization
// If you are not using these features and wish to reduce the size
@@ -703,6 +707,3 @@ int CFREDApp::ExitInstance()
// Empty functions to make fred link with the sexp_mission_set_subspace
void game_start_subspace_ambient_sound() {}
void game_stop_subspace_ambient_sound() {}
// Variables to make fred.ccp more like freespace2.cpp so fred will link
float Sun_spot = 0.0f;
+1229 -701
View File
File diff suppressed because it is too large. Load diff
+4 -3
View File
@@ -50,6 +50,7 @@
extern int Num_objects;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -426,7 +427,7 @@ int CFREDDoc::load_mission(char *pathname, int flags)
generate_weaponry_usage_list(i, used_pool);
for (j=0; j<Team_data[i].num_weapon_choices; j++) {
// The amount used in wings is always set by a static loadout entry so skip any that were set by Sexp variables
if ( (!strlen(Team_data[i].weaponry_pool_variable[j])) && (!strlen(Team_data[i].weaponry_amount_variable[j])) ) {
if ((Team_data[i].weaponry_pool_variable[j] == -1) && (Team_data[i].weaponry_amount_variable[j] == -1) ) {
// convert weaponry_pool to be extras available beyond the current ships weapons
Team_data[i].weaponry_count[j] -= used_pool[Team_data[i].weaponry_pool[j]];
if (Team_data[i].weaponry_count[j] < 0) {
@@ -445,8 +446,8 @@ int CFREDDoc::load_mission(char *pathname, int flags)
// add the weapon as a new entry
Team_data[i].weaponry_pool[Team_data[i].num_weapon_choices] = j;
Team_data[i].weaponry_count[Team_data[i].num_weapon_choices] = used_pool[j];
strcpy_s(Team_data[i].weaponry_amount_variable[Team_data[i].num_weapon_choices], "");
strcpy_s(Team_data[i].weaponry_pool_variable[Team_data[i].num_weapon_choices++], "");
Team_data[i].weaponry_amount_variable[Team_data[i].num_weapon_choices] = -1;
Team_data[i].weaponry_pool_variable[Team_data[i].num_weapon_choices++] = -1;
}
}
}
+31 -37
View File
@@ -58,6 +58,7 @@ extern float flFrametime;
extern subsys_to_render Render_subsys;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -403,47 +404,44 @@ void process_system_keys(int key)
void render_waypoints(void)
{
int i, j;
vertex v;
waypoint_list *ptr;
SCP_list<waypoint_list>::iterator ii;
SCP_list<waypoint>::iterator jj;
for (ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++ii)
for (i=0; i<Num_waypoint_lists; i++)
{
vec3d *prev_vec = NULL;
for (jj = ii->get_waypoints().begin(); jj != ii->get_waypoints().end(); ++jj)
ptr = &Waypoint_lists[i];
for (j=0; j<ptr->count; j++)
{
g3_rotate_vertex(&v, jj->get_pos());
g3_rotate_vertex(&v, &ptr->waypoints[j]);
if (!(v.codes & CC_BEHIND))
{
if (!(g3_project_vertex(&v) & PF_OVERFLOW))
{
if (cur_waypoint_list == &(*ii) && cur_waypoint == &(*jj))
if (cur_waypoint_list == i && cur_waypoint == j)
gr_set_color(255, 255, 255);
else if (Objects[jj->get_objnum()].flags & OF_MARKED)
else if (Waypoint_lists[i].flags[j] & WL_MARKED)
gr_set_color(160, 255, 0);
else
gr_set_color(160, 96, 0);
g3_draw_sphere(&v, LOLLIPOP_SIZE);
if (prev_vec == NULL)
gr_set_color(160, 96, 0);
else
if (j)
gr_set_color(0, 0, 0);
else
gr_set_color(160, 96, 0);
g3_draw_sphere(&v, LOLLIPOP_SIZE * 0.66667f);
gr_set_color(160, 96, 0);
g3_draw_sphere(&v, LOLLIPOP_SIZE * 0.33333f);
}
}
render_model_x(jj->get_pos(), The_grid, 1);
gr_set_color(160, 96, 0);
if (prev_vec != NULL)
rpd_line(prev_vec, jj->get_pos());
prev_vec = jj->get_pos();
}
for (j=0; j<ptr->count; j++)
render_model_x(&ptr->waypoints[j], The_grid, 1);
gr_set_color(160, 96, 0);
for (j=1; j<ptr->count; j++)
rpd_line(&ptr->waypoints[j-1], &ptr->waypoints[j]);
}
}
@@ -586,7 +584,7 @@ void fredhtl_render_subsystem_bounding_box(subsys_to_render * s2r)
g3_rotate_vertex(&text_center, &center_pt);
g3_project_vertex(&text_center);
gr_set_color_fast(&colour_white);
gr_string_win( (int)text_center.screen.xyw.x, (int)text_center.screen.xyw.y, buf);
gr_string_win( (int)text_center.sx, (int)text_center.sy, buf);
}
void display_active_ship_subsystem()
@@ -1004,7 +1002,7 @@ void display_distances()
if (!(g3_project_vertex(&v) & PF_OVERFLOW)) {
sprintf(buf, "%.1f", vm_vec_dist(&objp->pos, &o2->pos));
gr_set_color_fast(&colour_white);
gr_string_win((int) v.screen.xyw.x, (int) v.screen.xyw.y, buf);
gr_string_win((int) v.sx, (int) v.sy, buf);
}
}
@@ -1068,10 +1066,9 @@ void display_ship_info()
sprintf(buf, "%s\n%s", shipp->ship_name, Ship_info[ship_type].short_name);
} else if (objp->type == OBJ_WAYPOINT) {
int idx;
waypoint_list *wp_list = find_waypoint_list_with_instance(objp->instance, &idx);
Assert(wp_list != NULL);
sprintf(buf, "%s\nWaypoint %d", wp_list->get_name(), idx + 1);
sprintf(buf, "%s\nWaypoint %d",
Waypoint_lists[objp->instance / 65536].name,
(objp->instance & 0xffff) + 1);
} else if (objp->type == OBJ_POINT) {
if (objp->instance == BRIEFING_LOOKAT_POINT_ID)
@@ -1103,7 +1100,7 @@ void display_ship_info()
else
gr_set_color_fast(&colour_white);
gr_string_win((int) v.screen.xyw.x, (int) v.screen.xyw.y, buf);
gr_string_win((int) v.sx, (int) v.sy, buf);
}
}
@@ -1535,10 +1532,8 @@ void render_frame()
pos.xyz.x, pos.xyz.y, pos.xyz.z, a.h, a.p, a.b);
} else if (Objects[Cursor_over].type == OBJ_WAYPOINT) {
int idx;
waypoint_list *wp_list = find_waypoint_list_with_instance(inst, &idx);
Assert(wp_list != NULL);
sprintf(buf, "%s\nWaypoint %d\n( %.1f , %.1f , %.1f ) ", wp_list->get_name(), idx + 1, pos.xyz.x, pos.xyz.y, pos.xyz.z);
sprintf(buf, "%s\nWaypoint %d\n( %.1f , %.1f , %.1f ) ",
Waypoint_lists[inst / 65536].name, (inst & 0xffff) + 1, pos.xyz.x, pos.xyz.y, pos.xyz.z);
} else if (Objects[Cursor_over].type == OBJ_POINT) {
sprintf(buf, "Briefing icon\n( %.1f , %.1f , %.1f ) ", pos.xyz.x, pos.xyz.y, pos.xyz.z);
@@ -1552,8 +1547,8 @@ void render_frame()
gr_get_string_size(&w, &h, buf);
x = (int) v.screen.xyw.x;
y = (int) v.screen.xyw.y + 20;
x = (int) v.sx;
y = (int) v.sy + 20;
gr_set_color_fast(&colour_white);
gr_rect(x-7, y-6, w+8, h+7);
@@ -1881,7 +1876,6 @@ int object_check_collision(object *objp, vec3d *p0, vec3d *p1, vec3d *hitpos)
} else
return fvi_ray_sphere(hitpos, p0, p1, &objp->pos, (objp->radius > 0.1f) ? objp->radius : LOLLIPOP_SIZE);
mc.model_instance_num = -1;
mc.orient = &objp->orient; // The object's orient
mc.pos = &objp->pos; // The object's position
mc.p0 = p0; // Point 1 of ray to check
@@ -1959,8 +1953,8 @@ int select_object(int cx, int cy)
g3_rotate_vertex(&vt, &ptr->pos);
if (!(vt.codes & CC_BEHIND))
if (!(g3_project_vertex(&vt) & PF_OVERFLOW)) {
hitpos.xyz.x = vt.screen.xyw.x - cx;
hitpos.xyz.y = vt.screen.xyw.y - cy;
hitpos.xyz.x = vt.sx - cx;
hitpos.xyz.y = vt.sy - cy;
dist = hitpos.xyz.x * hitpos.xyz.x + hitpos.xyz.y * hitpos.xyz.y;
if ((dist < 8) && (dist < best_dist)) {
best = OBJ_INDEX(ptr);
+3 -1
View File
@@ -15,7 +15,7 @@
#include "ship/ship.h"
#include "graphics/2d.h"
#include "mission/missionparse.h"
#include "network/psnet2.h"
#include "network/psnet.h"
#include "stats/scoring.h"
#include "cfile/cfile.h"
@@ -211,9 +211,11 @@ int last_single_step;
void get_version_string_short(char *){}
void game_tst_mark(struct object *, struct ship *){}
int tst;
int game_do_cd_mission_check(char *){return 1;}
//int Player_multi_died_check;
int Show_framerate = 0;
void game_feature_not_in_demo_popup() {}
void alt_tab_pause(){}
void game_feature_disabled_popup() {}
+44 -44
View File
@@ -54,6 +54,7 @@
#include "VoiceActingManager.h"
#include "FictionViewerDlg.h"
#include "cmdline/cmdline.h"
#include "debugconsole/dbugfile.h"
#include "object/objectdock.h"
#include "species_defs/species_defs.h"
#include "sound/audiostr.h"
@@ -64,6 +65,7 @@
#include "gl/glu.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -675,9 +677,8 @@ int drag_objects()
if (objp->flags & OF_MARKED) {
vm_vec_add(&objp->pos, &objp->pos, &movement_vector);
if (objp->type == OBJ_WAYPOINT) {
waypoint *wpt = find_waypoint_with_instance(objp->instance);
Assert(wpt != NULL);
wpt->set_pos(&objp->pos);
Waypoint_lists[objp->instance / 65536].waypoints[objp->instance & 0xffff] =
objp->pos;
}
}
@@ -902,18 +903,15 @@ void CFREDView::OnLButtonDown(UINT nFlags, CPoint point)
{
// RT point
int waypoint_instance = -1;
int list = -1;
if (!Fred_active) {
CView::OnLButtonDown(nFlags, point);
return;
}
if (cur_waypoint != NULL)
{
Assert(cur_waypoint_list != NULL);
waypoint_instance = Objects[cur_waypoint->get_objnum()].instance;
}
if (cur_waypoint != -1)
list = cur_waypoint_list * 65536 + cur_waypoint;
marking_box.x1 = point.x;
marking_box.y1 = point.y;
@@ -928,7 +926,7 @@ void CFREDView::OnLButtonDown(UINT nFlags, CPoint point)
if (!Bg_bitmap_dialog) {
if (on_object == -1) {
Selection_lock = 0; // force off selection lock
on_object = create_object_on_grid(waypoint_instance);
on_object = create_object_on_grid(list);
} else
Dup_drag = 1;
@@ -1312,8 +1310,8 @@ void select_objects()
g3_rotate_vertex(&v, &ptr->pos);
if (!(v.codes & CC_BEHIND) && valid)
if (!(g3_project_vertex(&v) & PF_OVERFLOW)) {
x = (int) v.screen.xyw.x;
y = (int) v.screen.xyw.y;
x = (int) v.sx;
y = (int) v.sy;
if (x >= marking_box.x1 && x <= marking_box.x2 && y >= marking_box.y1 && y <= marking_box.y2) {
if (ptr->flags & OF_MARKED)
@@ -1394,7 +1392,6 @@ void CFREDView::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
CMenu menu;
int objnum;
CPoint local = point;
SCP_list<jump_node>::iterator jnp;
if (button_down) {
cancel_drag();
@@ -1421,19 +1418,12 @@ void CFREDView::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
else if (Objects[objnum].type == OBJ_JUMP_NODE) {
id = ID_EDITORS_WAYPOINT;
for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
if(jnp->get_obj() == &Objects[objnum])
break;
}
str.Format("Edit %s", jnp->get_name_ptr());
str.Format("Edit %s", Objects[objnum].jnp->get_name_ptr());
} else if (Objects[objnum].type == OBJ_WAYPOINT) {
int idx;
waypoint_list *wp_list = find_waypoint_list_with_instance(Objects[objnum].instance, &idx);
Assert(wp_list != NULL);
id = ID_EDITORS_WAYPOINT;
str.Format("Edit %s:%d", wp_list->get_name(), idx + 1);
str.Format("Edit %s:%d", Waypoint_lists[Objects[objnum].instance / 65536].name,
(Objects[objnum].instance & 0xffff) + 1);
} else if (Objects[objnum].type == OBJ_POINT) {
return;
@@ -2457,6 +2447,12 @@ int CFREDView::global_error_check()
count++;
}
}
if (!count && Ships[i].weapons.num_secondary_banks > 0){
if (error("Player \"%s\" has no secondary weapons. Should have at least 1", Ships[i].ship_name)){
return 1;
}
}
}
if (Ships[i].objnum != OBJ_INDEX(ptr)){
@@ -2490,7 +2486,7 @@ int CFREDView::global_error_check()
}
// wing squad logo check - Goober5000
if (strlen(Wings[wing].wing_squad_filename) > 0) //-V805
if (strlen(Wings[wing].wing_squad_filename) > 0)
{
if (The_mission.game_type & MISSION_TYPE_MULTI)
{
@@ -2524,18 +2520,17 @@ int CFREDView::global_error_check()
}
}
} else if (ptr->type == OBJ_WAYPOINT) {
int waypoint_num;
waypoint_list *wp_list = find_waypoint_list_with_instance(i, &waypoint_num);
if (wp_list == NULL) {
j = i / 65536; // waypoint path number
z = i & 0xffff; // waypoint number in path
if (j < 0 || j >= Num_waypoint_lists){
return internal_error("Object references an illegal waypoint path number");
}
if (waypoint_num < 0 || (uint) waypoint_num >= wp_list->get_waypoints().size()) {
if (z >= Waypoint_lists[j].count){
return internal_error("Object references an illegal waypoint number in path");
}
sprintf(buf, "%s:%d", wp_list->get_name(), waypoint_num + 1);
sprintf(buf, "%s:%d", Waypoint_lists[j].name, z + 1);
names[obj_count] = new char[strlen(buf) + 1];
strcpy(names[obj_count], buf);
flags[obj_count] = 1;
@@ -2788,18 +2783,18 @@ int CFREDView::global_error_check()
return internal_error("Num_wings is incorrect");
}
SCP_list<waypoint_list>::iterator ii;
for (ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++ii) {
for (i=0; i<Num_waypoint_lists; i++) {
for (z=0; z<obj_count; z++){
if (names[z]){
if (!stricmp(names[z], ii->get_name())){
if (!stricmp(names[z], Waypoint_lists[i].name)){
return internal_error("Waypoint path name is also used by an object (%s)", names[z]);
}
}
}
for (j = 0; (uint) j < ii->get_waypoints().size(); j++) {
sprintf(buf, "%s:%d", ii->get_name(), j + 1);
j = Waypoint_lists[i].count;
while (j--) {
sprintf(buf, "%s:%d", Waypoint_lists[i].name, j + 1);
for (z=0; z<obj_count; z++){
if (names[z]){
if (!stricmp(names[z], buf)){
@@ -3277,7 +3272,7 @@ int CFREDView::internal_error(char *msg, ...)
int CFREDView::fred_check_sexp(int sexp, int type, char *msg, ...)
{
char buf[512], buf2[2048], buf3[MAX_EVENT_SIZE];
char buf[512], buf2[2048], buf3[4096];
int err = 0, z, faulty_node;
va_list args;
@@ -3292,7 +3287,7 @@ int CFREDView::fred_check_sexp(int sexp, int type, char *msg, ...)
if (!z)
return 0;
convert_sexp_to_string(sexp, buf2, SEXP_ERROR_CHECK_MODE, MAX_EVENT_SIZE);
convert_sexp_to_string(sexp, buf2, SEXP_ERROR_CHECK_MODE, 2048);
sprintf(buf3, "Error in %s: %s\n\nIn sexpression: %s\n(Error appears to be: %s)",
buf, sexp_error_message(z), buf2, Sexp_nodes[faulty_node].text);
@@ -3401,10 +3396,10 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
found = 0;
if (flag > 0) {
if (*goals[i].target_name == '<')
if (*goals[i].ship_name == '<')
return "Invalid target";
if (!stricmp(goals[i].target_name, source))
if (!stricmp(goals[i].ship_name, source))
if (ship >= 0)
return "Target of ship's goal is itself";
else
@@ -3413,7 +3408,11 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
inst = team2 = -1;
if (flag == 1) { // target waypoint required
if (find_matching_waypoint_list(goals[i].target_name) == NULL)
for (j=0; j<Num_waypoint_lists; j++)
if (!stricmp(goals[i].ship_name, Waypoint_lists[j].name))
found = 1;
if (!found)
return "*Invalid target waypoint path name";
} else if (flag == 2) { // target ship required
@@ -3421,7 +3420,7 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
while (ptr != END_OF_LIST(&obj_used_list)) {
if (ptr->type == OBJ_SHIP || ptr->type == OBJ_START) {
inst = ptr->instance;
if (!stricmp(goals[i].target_name, Ships[inst].ship_name)) {
if (!stricmp(goals[i].ship_name, Ships[inst].ship_name)) {
found = 1;
break;
}
@@ -3442,7 +3441,7 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
} else if (flag == 3) { // target wing required
for (j=0; j<MAX_WINGS; j++)
if (Wings[j].wave_count && !stricmp(Wings[j].name, goals[i].target_name))
if (Wings[j].wave_count && !stricmp(Wings[j].name, goals[i].ship_name))
break;
if (j >= MAX_WINGS)
@@ -3460,13 +3459,13 @@ char *error_check_initial_orders(ai_goal *goals, int ship, int wing)
while (ptr != END_OF_LIST(&obj_used_list)) {
if (ptr->type == OBJ_SHIP || ptr->type == OBJ_START) {
inst = ptr->instance;
if (!stricmp(goals[i].target_name, Ships[inst].ship_name)) {
if (!stricmp(goals[i].ship_name, Ships[inst].ship_name)) {
found = 2;
break;
}
} else if (ptr->type == OBJ_WAYPOINT) {
if (!stricmp(goals[i].target_name, object_name(OBJ_INDEX(ptr)))) {
if (!stricmp(goals[i].ship_name, object_name(OBJ_INDEX(ptr)))) {
found = 1;
break;
}
@@ -4591,6 +4590,7 @@ void CFREDView::OnDestroy()
{
audiostream_close();
snd_close();
DBUGFILE_OUTPUT_0("About to gr_close");
gr_close();
os_set_window(NULL);
+1
View File
@@ -18,6 +18,7 @@
#include "editor.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+1
View File
@@ -16,6 +16,7 @@
#include "globalincs/linklist.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
+3 -2
View File
@@ -18,6 +18,7 @@
#include "weapon/weapon.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -68,7 +69,7 @@ BOOL InitialShips::OnInitDialog()
m_initial_list.AddString( Ship_info[i].name );
if ( Campaign.ships_allowed[i] ) {
m_initial_list.SetCheck(m_list_count, 1);
} else if ( (strlen(Campaign.filename) == 0) && strstr(Ship_info[i].name, "Myrmidon") ) { //-V805
} else if ( (strlen(Campaign.filename) == 0) && strstr(Ship_info[i].name, "Myrmidon") ) {
m_initial_list.SetCheck(m_list_count, 1);
} else {
m_initial_list.SetCheck(m_list_count, 0);
@@ -102,7 +103,7 @@ BOOL InitialShips::OnInitDialog()
int add_weapon = 0;
if ( Campaign.weapons_allowed[i] ) {
add_weapon = 1;
} else if ( strlen(Campaign.filename) == 0 ) { //-V805
} else if ( strlen(Campaign.filename) == 0 ) {
if ( strstr(Weapon_info[i].name, "Subach")) {
add_weapon = 1;
} else if ( strstr(Weapon_info[i].name, "Akheton")) {
+28 -65
View File
@@ -19,6 +19,7 @@
#include "object/objectdock.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
@@ -43,8 +44,7 @@ initial_status::initial_status(CWnd* pParent /*=NULL*/)
m_hull = 0;
m_has_shields = FALSE;
m_force_shields = FALSE;
m_ship_locked = FALSE;
m_weapons_locked = FALSE;
m_locked = FALSE;
m_primaries_locked = FALSE;
m_secondaries_locked = FALSE;
m_turrets_locked = FALSE;
@@ -84,8 +84,7 @@ void initial_status::DoDataExchange(CDataExchange* pDX)
DDV_MinMaxInt(pDX, m_damage, 0, 100);
DDX_Check(pDX, IDC_HAS_SHIELDS, m_has_shields);
DDX_Check(pDX, IDC_FORCE_SHIELDS, m_force_shields);
DDX_Check(pDX, IDC_SHIP_LOCKED, m_ship_locked);
DDX_Check(pDX, IDC_WEAPONS_LOCKED, m_weapons_locked);
DDX_Check(pDX, IDC_LOCKED, m_locked);
DDX_Check(pDX, IDC_PRIMARIES_LOCKED, m_primaries_locked);
DDX_Check(pDX, IDC_SECONDARIES_LOCKED, m_secondaries_locked);
DDX_Check(pDX, IDC_TURRETS_LOCKED, m_turrets_locked);
@@ -126,8 +125,7 @@ BEGIN_MESSAGE_MAP(initial_status, CDialog)
ON_CBN_SELCHANGE(IDC_DOCKEE_POINT, OnSelchangeDockeePoint)
ON_BN_CLICKED(IDC_HAS_SHIELDS, OnHasShields)
ON_BN_CLICKED(IDC_FORCE_SHIELDS, OnForceShields)
ON_BN_CLICKED(IDC_SHIP_LOCKED, OnShipLocked)
ON_BN_CLICKED(IDC_WEAPONS_LOCKED, OnWeaponsLocked)
ON_BN_CLICKED(IDC_LOCKED, OnLocked)
ON_BN_CLICKED(IDC_PRIMARIES_LOCKED, OnPrimariesLocked)
ON_BN_CLICKED(IDC_SECONDARIES_LOCKED, OnSecondariesLocked)
ON_BN_CLICKED(IDC_TURRETS_LOCKED, OnTurretsLocked)
@@ -188,15 +186,10 @@ BOOL initial_status::OnInitDialog()
else
m_force_shields = 0;
if (Ships[m_ship].flags2 & SF2_SHIP_LOCKED)
m_ship_locked = 1;
if (Ships[m_ship].flags & SF_LOCKED)
m_locked = 1;
else
m_ship_locked = 0;
if (Ships[m_ship].flags2 & SF2_WEAPONS_LOCKED)
m_weapons_locked = 1;
else
m_weapons_locked = 0;
m_locked = 0;
// Lock primaries
if (Ships[m_ship].flags2 & SF2_PRIMARIES_LOCKED) {
@@ -260,23 +253,13 @@ BOOL initial_status::OnInitDialog()
if (m_force_shields)
m_force_shields = 2;
}
if (Ships[get_ship_from_obj(objp)].flags2 & SF2_SHIP_LOCKED) {
if (!m_ship_locked)
m_ship_locked = 2;
if (Ships[get_ship_from_obj(objp)].flags & SF_LOCKED) {
if (!m_locked)
m_locked = 2;
} else {
if (m_ship_locked)
m_ship_locked = 2;
}
if (Ships[get_ship_from_obj(objp)].flags2 & SF2_WEAPONS_LOCKED) {
if (!m_weapons_locked)
m_weapons_locked = 2;
} else {
if (m_weapons_locked)
m_weapons_locked = 2;
if (m_locked)
m_locked = 2;
}
if (Ships[get_ship_from_obj(objp)].flags2 & SF2_PRIMARIES_LOCKED){
@@ -421,15 +404,10 @@ void initial_status::OnOK()
Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_FORCE_SHIELDS_ON;
}
if (m_ship_locked == 1)
Ships[get_ship_from_obj(objp)].flags2 |= SF2_SHIP_LOCKED;
else if (!m_ship_locked)
Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_SHIP_LOCKED;
if (m_weapons_locked == 1)
Ships[get_ship_from_obj(objp)].flags2 |= SF2_WEAPONS_LOCKED;
else if (!m_weapons_locked)
Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_WEAPONS_LOCKED;
if (m_locked == 1)
Ships[get_ship_from_obj(objp)].flags |= SF_LOCKED;
else if (!m_locked)
Ships[get_ship_from_obj(objp)].flags &= ~SF_LOCKED;
if (m_primaries_locked == 1) {
Ships[get_ship_from_obj(objp)].flags2 |= SF2_PRIMARIES_LOCKED;
@@ -477,15 +455,10 @@ void initial_status::OnOK()
else if (!m_force_shields)
Ships[m_ship].flags2 &= ~SF2_FORCE_SHIELDS_ON;
if (m_ship_locked == 1)
Ships[m_ship].flags2 |= SF2_SHIP_LOCKED;
else if (!m_ship_locked)
Ships[m_ship].flags2 &= ~SF2_SHIP_LOCKED;
if (m_weapons_locked == 1)
Ships[m_ship].flags2 |= SF2_WEAPONS_LOCKED;
else if (!m_weapons_locked)
Ships[m_ship].flags2 &= ~SF2_WEAPONS_LOCKED;
if (m_locked == 1)
Ships[m_ship].flags |= SF_LOCKED;
else if (!m_locked)
Ships[m_ship].flags &= ~SF_LOCKED;
if (m_primaries_locked == 1)
Ships[m_ship].flags2 |= SF2_PRIMARIES_LOCKED;
@@ -562,24 +535,14 @@ void initial_status::OnForceShields()
((CButton *) GetDlgItem(IDC_FORCE_SHIELDS))->SetCheck(m_force_shields);
}
void initial_status::OnShipLocked()
void initial_status::OnLocked()
{
if (m_ship_locked == 1)
m_ship_locked = 0;
if (m_locked == 1)
m_locked = 0;
else
m_ship_locked = 1;
m_locked = 1;
((CButton *) GetDlgItem(IDC_SHIP_LOCKED))->SetCheck(m_ship_locked);
}
void initial_status::OnWeaponsLocked()
{
if (m_weapons_locked == 1)
m_weapons_locked = 0;
else
m_weapons_locked = 1;
((CButton *) GetDlgItem(IDC_WEAPONS_LOCKED))->SetCheck(m_weapons_locked);
((CButton *) GetDlgItem(IDC_LOCKED))->SetCheck(m_locked);
}
void initial_status::OnSelchangeSubsys()
@@ -610,7 +573,7 @@ void initial_status::change_subsys()
MODIFY(ptr -> current_hits, 100.0f - (float) m_damage);
// update cargo name
if (strlen(m_cargo_name) > 0) { //-V805
if (strlen(m_cargo_name) > 0) {
cargo_index = string_lookup(m_cargo_name, Cargo_names, Num_cargo);
if (cargo_index == -1) {
if (Num_cargo < MAX_CARGO);
@@ -621,7 +584,7 @@ void initial_status::change_subsys()
ptr->subsys_cargo_name = cargo_index;
}
} else {
ptr->subsys_cargo_name = 0;
ptr->subsys_cargo_name = -1;
}
set_modified();
}
@@ -640,7 +603,7 @@ void initial_status::change_subsys()
m_damage = 100 - (int) ptr -> current_hits;
if ( ship_has_scannable_subsystems && valid_cap_subsys_cargo_list(ptr->system_info->subobj_name) ) {
enable_cargo_name = TRUE;
if (ptr->subsys_cargo_name > 0) {
if (ptr->subsys_cargo_name != -1) {
m_cargo_name = Cargo_names[ptr->subsys_cargo_name];
} else {
m_cargo_name = _T("");
+2 -4
View File
@@ -51,8 +51,7 @@ public:
int m_velocity;
int m_hull;
BOOL m_has_shields;
int m_ship_locked;
int m_weapons_locked;
int m_locked;
CString m_cargo_name;
int m_primaries_locked;
int m_secondaries_locked;
@@ -81,8 +80,7 @@ protected:
afx_msg void OnSelchangeDockeePoint();
afx_msg void OnHasShields();
afx_msg void OnForceShields();
afx_msg void OnShipLocked();
afx_msg void OnWeaponsLocked();
afx_msg void OnLocked();
afx_msg void OnPrimariesLocked();
afx_msg void OnSecondariesLocked();
afx_msg void OnTurretsLocked();
Loaded 100 of 647 files, more files were not shown because too many files have changed in this diff. Show more