Compare commits

..
Author SHA1 Message Date
chief1983 eb46c94d08 Automated 3.7.2 Final versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11329 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-24 12:07:13 +10:00
chief1983 3afde9b623 Automated 3.7.2 RC6 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11313 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-19 00:07:51 +10:00
chief1983 65aceccc13 Project file version catchup to RC5.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11312 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-19 00:07:50 +10:00
chief1983 e37bc109c8 Trunk sync r11307.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11308 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-18 18:09:47 +10:00
chief1983 dafca28717 Trunk sync r11305.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11306 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-17 18:08:19 +10:00
chief1983 2a9e6719a7 Automated 3.7.2 RC5 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11227 387891d4-d844-0410-90c0-e4c51a9137d3
2015-01-24 09:22:21 +10:00
chief1983 aed59d2125 I goofed, let's revert that and try again.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11226 387891d4-d844-0410-90c0-e4c51a9137d3
2015-01-24 09:22:20 +10:00
chief1983 c599955813 Automated 3.7.2 RC5 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11225 387891d4-d844-0410-90c0-e4c51a9137d3
2015-01-24 09:22:20 +10:00
chief1983 3bcab10109 Trunk sync r11222.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11223 387891d4-d844-0410-90c0-e4c51a9137d3
2015-01-24 09:22:20 +10:00
chief1983 78cf382996 Trunk sync r11173.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11174 387891d4-d844-0410-90c0-e4c51a9137d3
2014-11-21 18:45:26 +10:00
chief1983 54b2994204 Automated 3.7.2 RC4 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10997 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:09 +10:00
chief1983 3960161427 Trunk sync r10995.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10996 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 0b68d9c09c Automated 3.7.2 RC3 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10783 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 66285e2cab Trunk sync r10774.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10782 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 ff8607d74e Automated 3.7.2 RC2 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10724 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 acf72ef431 Trunk sync r10722.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10723 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 9f61dd5286 Automated 3.7.2 RC1 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10634 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 6e6b4b1620 Trunk sync r10632.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10633 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 3b9869a00a Trunk sync r10572.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10573 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
chief1983 c761256461 Trunk sync r10570.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10571 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
The_E 5f7b9159b8 Fix for Mantis 3023 by Yarn: Make sure the vasudan mainhall fun cheat works again
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10519 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
The_E 89291af840 Fix for Mantis 3015: Makes sure rotation values are always in the 0-359 degree range
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10518 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
niffiwan 6401a8266d Remove gcc warnings (unused & shadow)
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10517 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
niffiwan 8706f824fa Fix mantis 2921: start mainhall music when leaving the credits state
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10507 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
Goober5000 77a0d6a841 add briefing icons for ship-with-cargo and wing-with-cargo
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10506 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
zookeeper 4e590a6761 Changed the label of the "Broadcast Locally" multiplayer option from "/multidata" to "Broadcast Locally".
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10498 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
niffiwan 953f47560e From Axem: fix newly added hud gauge sexps
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10497 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
karajorma f3d747db32 Yarn's fix for Mantis 3017 (Certain HUD elements don't work after the changes to strings.tbl). Not very happy with the way it fixes thing (it only solves problems for French, German and Polish, which kinda makes the changes to strings.tbl in r9761 somewhat pointless) but it makes sense to wait for SDL and truetype support and then fix everything properly then.
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10496 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
niffiwan 117dd15bda From Axem & niffiwan: stop briefing/credits/mainhall music with scripting
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10495 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:06 +10:00
m_m 5431beb81d Fix for Mantis 3018: Setting a weapon's Target/HomingObject/HomingPosition etc doesn't work
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10494 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:06 +10:00
545 changed files with 58785 additions and 40686 deletions

No files matched your search

-4
View File
@@ -1,4 +0,0 @@
root = true
[*.{h,cpp}]
indent_style = tab
+4 -9
View File
@@ -24,6 +24,7 @@ install-sh
missing
.svn
*.layout
projects/Xcode4/Frameworks/
projects/Xcode/Frameworks/
#========
@@ -136,7 +137,7 @@ packages/
*.swp
# *.lock - this is used and abused by many editors for many different things.
# For the main ones I use (e.g. Eclipse), it should be excluded
# For the main ones I use (e.g. Eclipse), it should be excluded
# from source-control, but YMMV
*.lock
@@ -148,7 +149,7 @@ packages/
####
# Xcode temporary files that should never be committed
#
#
# NB: NIB/XIB files still exist even on Storyboard projects, so we want this...
*~.nib
@@ -262,12 +263,6 @@ xcuserdata
# .xccheckout
#
# Per http://stackoverflow.com/questions/18340453/should-xccheckout-files-in-xcode5-be-ignored-under-vcs
#
#
*.xccheckout
####
# Documentation
#
documentation/doxygen/*
!documentation/doxygen/.gitkeep
-75
View File
@@ -1,75 +0,0 @@
language: cpp
sudo: false
addons:
apt:
packages:
- libopenal-dev
- libogg-dev
- libvorbis-dev
- build-essential
- automake
- autoconf
- libsdl1.2-dev
- libtheora-dev
- libreadline6-dev
- libpng12-dev
- libjpeg62-dev
- liblua5.1-0-dev
- libjansson-dev
- libtool
coverity_scan:
project:
name: "scp-fs2open/fs2open.github.com"
description: "Coverity via Travis CI"
notification_email: [email protected]
build_command_prepend: "./autogen.sh --enable-debug"
build_command: "make -j2"
# must match TRAVIS_BRANCH check below
branch_pattern: coverity_scan
env:
global:
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
matrix:
include:
# note that gcc Debug MUST be 1st for Coverity
- os: linux
compiler: gcc
env: CONFIGURATION="Debug"
- os: linux
compiler: clang
env: CONFIGURATION="Debug"
- os: osx
compiler: clang
env: CONFIGURATION="Debug" MACOSX_ARCH=i386
- os: osx
compiler: clang
env: CONFIGURATION="Debug" MACOSX_ARCH=x86_64
- os: linux
compiler: gcc
env: CONFIGURATION="Release"
- os: linux
compiler: clang
env: CONFIGURATION="Release"
- os: osx
compiler: clang
env: CONFIGURATION="Release" MACOSX_ARCH=i386
- os: osx
compiler: clang
env: CONFIGURATION="Release" MACOSX_ARCH=x86_64
before_install:
# ugly hack; if running a coverity scan abort all except the 1st build
# see note re gcc compiler above needing to be 1st
# also note that branch_pattern & the TRAVIS_BRANCH check must match
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
# build process
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
- ./ci/travis/before_install.sh
install:
- ./ci/travis/install.sh
before_script:
- ./ci/travis/before_script.sh
script:
- ./ci/travis/script.sh
+10 -7
View File
@@ -9,6 +9,16 @@ SUBDIRS = mongoose code
EXTRA_DIST = \
FS2OpenSCPReadMe.doc \
projects/MSVC_2005/Freespace2.sln \
projects/MSVC_2005/Freespace2.vcproj \
projects/MSVC_2005/code.vcproj \
projects/MSVC_6/Fred2.dsp \
projects/MSVC_6/Freespace2.dsp \
projects/MSVC_6/Freespace2.dsw \
projects/MSVC_6/code.dsp \
projects/MSVC_6/libjpeg.dsp \
projects/MSVC_6/liblua.dsp \
projects/MSVC_6/wxFRED2.dsp \
projects/Xcode/English.lproj/InfoPlist.strings \
projects/Xcode/FS2_Open.icns \
projects/Xcode/FS2_Open.xcodeproj/project.pbxproj \
@@ -31,8 +41,6 @@ EXTRA_PROGRAMS = cfilearchiver cfileextractor
## Begin utilitites
##
CPPSOURCES=$(wildcard code/*/*.cpp code/*/*.h)
# cfilearchiver -- to create VPs
cfilearchiver_SOURCES = \
code/cfilearchiver/cfilearchiver.cpp
@@ -48,11 +56,6 @@ tools: cfilearchiver cfileextractor
clean-tools:
-test -z "$(EXTRA_PROGRAMS)" || rm -f $(EXTRA_PROGRAMS)
## cppcheck : check for many code issues
cppcheck: ${CPPSOURCES}
cppcheck ${CPPSOURCES} --enable=all --platform=unix64 \
--std=c99 --inline-suppr --quiet
##
## End utilitites
##
-19
View File
@@ -1,19 +0,0 @@
[![Coverity](https://scan.coverity.com/projects/870/badge.svg)](https://scan.coverity.com/projects/870)
[![Build Status](https://travis-ci.org/scp-fs2open/fs2open.github.com.svg?branch=master)](https://travis-ci.org/scp-fs2open/fs2open.github.com)
Welcome to Freespace Open!
In 2002 Volition released the source code for Freespace2. In the years since dedicated individuals have added countless new features to create a flexible and powerful space combat simulation engine. More info can be found on our [wiki](http://www.hard-light.net/wiki/index.php/Source_Code_Project)
People interested in contributing are encouraged to read [this thread](http://www.hard-light.net/forums/index.php?topic=82688.0)
The "projects" directory contains ready projects for:
* Microsoft Visual C++ 6, 2005, 2008, 2010, 2011, 2013, 2015
* Apple Xcode
* Code::Blocks
* Eclipse
Review the commit logs to see what's new.
See the INSTALL file for instructions on how to build fs2_open, or open the relevant MSVC project
-16
View File
@@ -1,16 +0,0 @@
version: 3.7.3.{build}
shallow_clone: true
environment:
matrix:
- VisualStudioVersion: 10.0
PlatformToolset: v100
ProjectPath: projects/MSVC_2010/Freespace2.vcxproj
- VisualStudioVersion: 12.0
PlatformToolset: v120
ProjectPath: projects/MSVC_2013/Freespace2.vcxproj
- VisualStudioVersion: 14.0
PlatformToolset: v140
ProjectPath: projects/MSVC_2015/Freespace2.vcxproj
build_script:
- msbuild "%ProjectPath%" /p:Configuration="Debug SSE2" /m /p:PlatformToolset="%PlatformToolset%" /verbosity:minimal
test: off
-11
View File
@@ -1,11 +0,0 @@
#!/usr/bin/env sh
set -e
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
# Nothing to do here
:
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
# Nothing to do here
:
fi
-18
View File
@@ -1,18 +0,0 @@
#!/usr/bin/env sh
set -e
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
# Due to a bug in gcc the array bounds check isn't working correctly
# This can be removed when gcc is updated
AUTOGEN_CONFIG="CXXFLAGS=-Wno-array-bounds --enable-fatal-warnings --enable-generic-architecture"
if [ "$CONFIGURATION" = "Debug" ]; then
AUTOGEN_CONFIG="$AUTOGEN_CONFIG --enable-debug"
fi
./autogen.sh $AUTOGEN_CONFIG
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
cd projects/Xcode
tar -xvzf Frameworks.tgz
fi
-10
View File
@@ -1,10 +0,0 @@
#!/usr/bin/env sh
set -e
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
# Nothing to do here
:
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
gem install xcpretty
fi
-10
View File
@@ -1,10 +0,0 @@
#!/usr/bin/env sh
set -e
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
make -j 4
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
cd projects/Xcode
xcodebuild ARCHS=$MACOSX_ARCH ONLY_ACTIVE_ARCH=NO -configuration "$CONFIGURATION" | xcpretty -c && exit ${PIPESTATUS[0]}
fi
+8 -3
View File
@@ -199,7 +199,7 @@ bin_PROGRAMS = @FS2_BINARY@
EXTRA_PROGRAMS = fs2_open_@PACKAGE_VERSION@ \
fs2_open_@PACKAGE_VERSION@_DEBUG \
wxFRED2_@PACKAGE_VERSION@ \
wxFRED2_@PACKAGE_VERSION@_DEBUG
wxFRED2_@PACKAGE_VERSION@_DEBUG
###############################################################################
##
@@ -215,6 +215,7 @@ FS2_SOURCES = \
ai/aigoals.cpp \
ai/aigoals.h \
ai/aiinternal.h \
ai/ailocal.h \
ai/aiturret.cpp \
ai/ai_profiles.cpp \
ai/ai_profiles.h \
@@ -266,6 +267,8 @@ FS2_SOURCES = \
debugconsole/consolecmds.cpp \
debugconsole/consoleparse.cpp \
debugconsole/consoleparse.h \
debugconsole/timerbar.cpp \
debugconsole/timerbar.h \
exceptionhandler/exceptionhandler.cpp \
exceptionhandler/exceptionhandler.h \
external_dll/externalcode.h \
@@ -340,7 +343,6 @@ FS2_SOURCES = \
graphics/grstub.cpp \
graphics/grstub.h \
graphics/line.h \
graphics/shadows.cpp \
graphics/tmapper.h \
hud/hud.cpp \
hud/hud.h \
@@ -477,10 +479,14 @@ FS2_SOURCES = \
missionui/missionloopbrief.h \
missionui/missionpause.cpp \
missionui/missionpause.h \
missionui/missionrecommend.cpp \
missionui/missionrecommend.h \
missionui/missionscreencommon.cpp \
missionui/missionscreencommon.h \
missionui/missionshipchoice.cpp \
missionui/missionshipchoice.h \
missionui/missionstats.cpp \
missionui/missionstats.h \
missionui/missionweaponchoice.cpp \
missionui/missionweaponchoice.h \
missionui/redalert.cpp \
@@ -495,7 +501,6 @@ FS2_SOURCES = \
model/modelsinc.h \
model/modeloctant.cpp \
model/modelread.cpp \
model/modelrender.cpp \
nebula/neb.cpp \
nebula/neb.h \
nebula/neblightning.cpp \
+6 -5
View File
@@ -12,12 +12,12 @@
#ifndef _AI_H
#define _AI_H
#include "ai/ai_profiles.h"
#include "globalincs/globals.h"
#include "globalincs/pstypes.h"
#include "globalincs/globals.h"
#include "globalincs/systemvars.h"
#include "object/waypoint.h"
#include "ai/ai_profiles.h"
#include "physics/physics.h"
#include "object/waypoint.h"
struct ship_weapon;
class ship_subsys;
@@ -622,7 +622,7 @@ extern void init_ai_system(void);
extern void ai_attack_object(object *attacker, object *attacked, ship_subsys *ssp);
extern void ai_evade_object(object *evader, object *evaded);
extern void ai_ignore_object(object *ignorer, object *ignored, int ignore_new);
extern void ai_ignore_wing(object *ignorer, int wingnum);
extern void ai_ignore_wing(object *ignorer, int wingnum, int priority);
extern void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type);
extern void ai_stay_still(object *still_objp, vec3d *view_pos);
extern void ai_do_default_behavior(object *obj);
@@ -726,7 +726,8 @@ void process_subobjects(int objnum);
//SUSHI: Setting ai_info stuff from both ai class and ai profile
void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t *profile);
void ai_update_aim(ai_info *aip);
//SUSHI: Updating AI aim
void ai_update_aim(ai_info *aip, object* En_Objp);
//SUSHI: Random evasive sidethrust
void do_random_sidethrust(ai_info *aip, ship_info *sip);
+426 -442
View File
@@ -7,13 +7,13 @@
#include "ai/ai_profiles.h"
#include "globalincs/def_files.h"
#include "globalincs/pstypes.h"
#include "localization/localize.h"
#include "globalincs/def_files.h"
#include "ai/ai_profiles.h"
#include "parse/parselo.h"
#include "ship/ship.h"
#include "localization/localize.h"
#include "weapon/weapon.h"
#include "ship/ship.h"
// global stuff
@@ -69,461 +69,445 @@ int ai_path_type_match(char *p)
void parse_ai_profiles_tbl(const char *filename)
{
int i;
int i, rval;
char profile_name[NAME_LENGTH];
ai_profile_t dummy_profile;
char *saved_Mp = NULL;
char buf[NAME_LENGTH];
try
if ((rval = setjmp(parse_abort)) != 0)
{
if (filename == NULL)
read_file_text_from_array(defaults_get_file("ai_profiles.tbl"));
else
read_file_text(filename, CF_TYPE_TABLES);
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default ai_profiles.tbl>", rval));
return;
}
reset_parse();
if (filename == NULL)
read_file_text_from_array(defaults_get_file("ai_profiles.tbl"));
else
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
// start parsing
required_string("#AI Profiles");
// start parsing
required_string("#AI Profiles");
// new default?
if (optional_string("$Default Profile:"))
stuff_string(Default_profile_name, F_NAME, NAME_LENGTH);
// new default?
if (optional_string("$Default Profile:"))
stuff_string(Default_profile_name, F_NAME, NAME_LENGTH);
// begin reading data
while (required_string_either("#End", "$Profile Name:"))
// begin reading data
while (required_string_either("#End","$Profile Name:"))
{
ai_profile_t *profile = &dummy_profile;
ai_profile_t *previous_profile = NULL;
bool no_create = false;
// get the name
required_string("$Profile Name:");
stuff_string(profile_name, F_NAME, NAME_LENGTH);
// see if it exists
for (i = 0; i < Num_ai_profiles; i++)
{
ai_profile_t *profile = &dummy_profile;
ai_profile_t *previous_profile = NULL;
bool no_create = false;
// get the name
required_string("$Profile Name:");
stuff_string(profile_name, F_NAME, NAME_LENGTH);
// see if it exists
for (i = 0; i < Num_ai_profiles; i++)
if (!stricmp(Ai_profiles[i].profile_name, profile_name))
{
if (!stricmp(Ai_profiles[i].profile_name, profile_name))
{
previous_profile = &Ai_profiles[i];
break;
}
}
// modular table stuff
if (optional_string("+nocreate"))
{
no_create = true;
// use the previous one if possible,
// otherwise continue to use the dummy one
if (previous_profile != NULL)
profile = previous_profile;
}
else
{
// don't create multiple profiles with the same name
if (previous_profile != NULL)
{
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
}
else
{
// make sure we're under the limit
if (Num_ai_profiles >= MAX_AI_PROFILES)
{
Warning(LOCATION, "Too many profiles in ai_profiles.tbl! Max is %d.\n", MAX_AI_PROFILES - 1); // -1 because one is built-in
skip_to_string("#End", NULL);
break;
}
profile = &Ai_profiles[Num_ai_profiles];
Num_ai_profiles++;
}
}
// initialize profile if we're not building from a previously parsed one
if (!no_create)
{
// base profile, so zero it out
if (profile == &Ai_profiles[0])
{
memset(profile, 0, sizeof(ai_profile_t));
}
// brand new profile, so set it to the base defaults
else
{
memcpy(profile, &Ai_profiles[0], sizeof(ai_profile_t));
}
}
// set the name
strcpy_s(profile->profile_name, profile_name);
// fill in any and all settings; they're all optional and can be in any order
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
{
if (optional_string("$Player Afterburner Recharge Scale:"))
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
if (optional_string("$Max Beam Friendly Fire Damage:"))
parse_float_list(profile->beam_friendly_damage_cap, NUM_SKILL_LEVELS);
if (optional_string("$Player Countermeasure Life Scale:"))
parse_float_list(profile->cmeasure_life_scale, NUM_SKILL_LEVELS);
if (optional_string("$AI Countermeasure Firing Chance:"))
parse_float_list(profile->cmeasure_fire_chance, NUM_SKILL_LEVELS);
if (optional_string("$AI In Range Time:"))
parse_float_list(profile->in_range_time, NUM_SKILL_LEVELS);
if (optional_string("$AI Always Links Ammo Weapons:"))
parse_float_list(profile->link_ammo_levels_always, NUM_SKILL_LEVELS);
if (optional_string("$AI Maybe Links Ammo Weapons:"))
parse_float_list(profile->link_ammo_levels_maybe, NUM_SKILL_LEVELS);
if (optional_string("$Primary Ammo Burst Multiplier:"))
parse_float_list(profile->primary_ammo_burst_mult, NUM_SKILL_LEVELS);
if (optional_string("$AI Always Links Energy Weapons:"))
parse_float_list(profile->link_energy_levels_always, NUM_SKILL_LEVELS);
if (optional_string("$AI Maybe Links Energy Weapons:"))
parse_float_list(profile->link_energy_levels_maybe, NUM_SKILL_LEVELS);
if (optional_string("$Max Missles Locked on Player:") || optional_string("$Max Missiles Locked on Player:"))
parse_int_list(profile->max_allowed_player_homers, NUM_SKILL_LEVELS);
if (optional_string("$Max Player Attackers:"))
parse_int_list(profile->max_attackers, NUM_SKILL_LEVELS);
if (optional_string("$Max Incoming Asteroids:"))
parse_int_list(profile->max_incoming_asteroids, NUM_SKILL_LEVELS);
if (optional_string("$Player Damage Factor:") || optional_string("$AI Damage Reduction to Player Hull:"))
parse_float_list(profile->player_damage_scale, NUM_SKILL_LEVELS);
if (optional_string("$Player Subsys Damage Factor:") || optional_string("$AI Damage Reduction to Player Subsys:"))
parse_float_list(profile->subsys_damage_scale, NUM_SKILL_LEVELS);
// represented in fractions of F1_0
if (optional_string("$Predict Position Delay:"))
{
int iLoop;
float temp_list[NUM_SKILL_LEVELS];
parse_float_list(temp_list, NUM_SKILL_LEVELS);
for (iLoop = 0; iLoop < NUM_SKILL_LEVELS; iLoop++)
profile->predict_position_delay[iLoop] = fl2f(temp_list[iLoop]);
}
if (optional_string("$AI Shield Manage Delay:") || optional_string("$AI Shield Manage Delays:"))
parse_float_list(profile->shield_manage_delay, NUM_SKILL_LEVELS);
if (optional_string("$Friendly AI Fire Delay Scale:"))
parse_float_list(profile->ship_fire_delay_scale_friendly, NUM_SKILL_LEVELS);
if (optional_string("$Hostile AI Fire Delay Scale:"))
parse_float_list(profile->ship_fire_delay_scale_hostile, NUM_SKILL_LEVELS);
if (optional_string("$Friendly AI Secondary Fire Delay Scale:"))
parse_float_list(profile->ship_fire_secondary_delay_scale_friendly, NUM_SKILL_LEVELS);
if (optional_string("$Hostile AI Secondary Fire Delay Scale:"))
parse_float_list(profile->ship_fire_secondary_delay_scale_hostile, NUM_SKILL_LEVELS);
if (optional_string("$AI Turn Time Scale:"))
parse_float_list(profile->turn_time_scale, NUM_SKILL_LEVELS);
if (optional_string("$Glide Attack Percent:")) {
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (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;
}
profile->glide_attack_percent[i] /= 100.0;
}
}
if (optional_string("$Circle Strafe Percent:")) {
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (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;
}
profile->circle_strafe_percent[i] /= 100.0;
}
}
if (optional_string("$Glide Strafe Percent:")) {
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (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;
}
profile->glide_strafe_percent[i] /= 100.0;
}
}
if (optional_string("$Random Sidethrust Percent:")) {
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (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;
}
profile->random_sidethrust_percent[i] /= 100.0;
}
}
if (optional_string("$Stalemate Time Threshold:"))
parse_float_list(profile->stalemate_time_thresh, NUM_SKILL_LEVELS);
if (optional_string("$Stalemate Distance Threshold:"))
parse_float_list(profile->stalemate_dist_thresh, NUM_SKILL_LEVELS);
if (optional_string("$Player Shield Recharge Scale:"))
parse_float_list(profile->shield_energy_scale, NUM_SKILL_LEVELS);
if (optional_string("$Player Weapon Recharge Scale:"))
parse_float_list(profile->weapon_energy_scale, NUM_SKILL_LEVELS);
if (optional_string("$Max Turret Target Ownage:"))
parse_int_list(profile->max_turret_ownage_target, NUM_SKILL_LEVELS);
if (optional_string("$Max Turret Player Ownage:"))
parse_int_list(profile->max_turret_ownage_player, NUM_SKILL_LEVELS);
if (optional_string("$Percentage Required For Kill Scale:"))
parse_float_list(profile->kill_percentage_scale, NUM_SKILL_LEVELS);
if (optional_string("$Percentage Required For Assist Scale:"))
parse_float_list(profile->assist_percentage_scale, NUM_SKILL_LEVELS);
if (optional_string("$Percentage Awarded For Capship Assist:"))
parse_float_list(profile->assist_award_percentage_scale, NUM_SKILL_LEVELS);
if (optional_string("$Repair Penalty:"))
parse_int_list(profile->repair_penalty, NUM_SKILL_LEVELS);
if (optional_string("$Delay Before Allowing Bombs to Be Shot Down:"))
parse_float_list(profile->delay_bomb_arm_timer, NUM_SKILL_LEVELS);
if (optional_string("$Chance AI Has to Fire Missiles at Player:"))
parse_int_list(profile->chance_to_use_missiles_on_plr, NUM_SKILL_LEVELS);
if (optional_string("$Max Aim Update Delay:"))
parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS);
if (optional_string("$Turret Max Aim Update Delay:"))
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
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);
set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION, AIP_FLAG);
set_flag(profile, "$smart shield management:", AIPF_SMART_SHIELD_MANAGEMENT, AIP_FLAG);
set_flag(profile, "$smart afterburner management:", AIPF_SMART_AFTERBURNER_MANAGEMENT, AIP_FLAG);
set_flag(profile, "$allow rapid secondary dumbfire:", AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE, AIP_FLAG);
set_flag(profile, "$huge turret weapons ignore bombs:", AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS, AIP_FLAG);
set_flag(profile, "$don't insert random turret fire delay:", AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY, AIP_FLAG);
set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY, AIP_FLAG);
set_flag(profile, "$shockwaves damage small ship subsystems:", AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS, AIP_FLAG);
set_flag(profile, "$navigation subsystem governs warpout capability:", AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP, AIP_FLAG);
set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP, AIP_FLAG);
set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY, AIP_FLAG);
set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING, AIP_FLAG);
set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY, AIP_FLAG);
set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING, AIP_FLAG);
set_flag(profile, "$include beams for kills and assists:", AIPF_INCLUDE_BEAMS_IN_STAT_CALCS, AIP_FLAG);
set_flag(profile, "$score kills based on damage caused:", AIPF_KILL_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
set_flag(profile, "$score assists based on damage caused:", AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING, AIP_FLAG);
set_flag(profile, "$fix linked primary weapon decision bug:", AIPF_FIX_LINKED_PRIMARY_BUG, AIP_FLAG);
set_flag(profile, "$prevent turrets targeting too distant bombs:", AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE, AIP_FLAG);
set_flag(profile, "$smart subsystem targeting for turrets:", AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS, AIP_FLAG);
set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AIPF_FIX_HEAT_SEEKER_STEALTH_BUG, AIP_FLAG);
set_flag(profile, "$multi allow empty primaries:", AIPF_MULTI_ALLOW_EMPTY_PRIMARIES, AIP_FLAG);
set_flag(profile, "$multi allow empty secondaries:", AIPF_MULTI_ALLOW_EMPTY_SECONDARIES, AIP_FLAG);
set_flag(profile, "$allow turrets target weapons freely:", AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY, AIP_FLAG);
set_flag(profile, "$use only single fov for turrets:", AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS, AIP_FLAG);
set_flag(profile, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG);
set_flag(profile, "$force beam turrets to use normal fov:", AIPF_FORCE_BEAM_TURRET_FOV, AIP_FLAG);
set_flag(profile, "$fix ai class bug:", AIPF_FIX_AI_CLASS_BUG, AIP_FLAG);
set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2);
set_flag(profile, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
set_flag(profile, "$perform fewer checks for death screams:", AIPF2_PERFORM_FEWER_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 at mission start:", AIPF2_ALLOW_PRIMARY_LINK_AT_START, 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);
set_flag(profile, "$countermeasures affect aspect seekers:", AIPF2_ASPECT_LOCK_COUNTERMEASURE, AIP_FLAG2);
set_flag(profile, "$ai guards specific ship in wing:", AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING, 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);
}
}
set_flag(profile, "$no warp camera:", AIPF2_NO_WARP_CAMERA, AIP_FLAG2);
set_flag(profile, "$fix ai path order bug:", AIPF2_FIX_AI_PATH_ORDER_BUG, AIP_FLAG2);
set_flag(profile, "$strict turret-tagged-only targeting:", AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING, AIP_FLAG2);
set_flag(profile, "$aspect bomb invulnerability fix:", AIPF2_ASPECT_INVULNERABILITY_FIX, AIP_FLAG2);
set_flag(profile, "$glide decay requires thrust:", AIPF2_GLIDE_DECAY_REQUIRES_THRUST, AIP_FLAG2);
profile->bay_arrive_speed_mult = 1.0f;
profile->bay_depart_speed_mult = 1.0f;
if (optional_string("$bay arrive speed multiplier:")) {
stuff_float(&profile->bay_arrive_speed_mult);
}
if (optional_string("$bay depart speed multiplier:")) {
stuff_float(&profile->bay_depart_speed_mult);
}
// ----------
// compatibility
if (optional_string("$perform less checks for death screams:"))
{
mprintf(("Warning: \"$perform less checks for death screams\" flag is deprecated in favor of \"$perform fewer checks for death screams\"\n"));
bool temp;
stuff_boolean(&temp);
if (temp)
profile->flags2 |= AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
else
profile->flags2 &= ~AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
}
if (optional_string("$allow primary link delay:"))
{
mprintf(("Warning: \"$allow primary link delay\" flag is deprecated in favor of \"$allow primary link at mission start\"\n"));
bool temp;
stuff_boolean(&temp);
if (temp)
profile->flags2 &= ~AIPF2_ALLOW_PRIMARY_LINK_AT_START;
else
profile->flags2 |= AIPF2_ALLOW_PRIMARY_LINK_AT_START;
}
// if we've been through once already and are at the same place, force a move
if (saved_Mp && (saved_Mp == Mp))
{
char tmp[60];
memset(tmp, 0, 60);
strncpy(tmp, Mp, 59);
mprintf(("WARNING: Unrecognized parameter in ai_profiles: %s\n", tmp));
Mp++;
}
// find next valid option
skip_to_start_of_string_either("$", "#");
saved_Mp = Mp;
previous_profile = &Ai_profiles[i];
break;
}
}
required_string("#End");
}
catch (const parse::ParseException& e)
{
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : "<default ai_profiles.tbl>", e.what()));
return;
// modular table stuff
if (optional_string("+nocreate"))
{
no_create = true;
// use the previous one if possible,
// otherwise continue to use the dummy one
if (previous_profile != NULL)
profile = previous_profile;
}
else
{
// don't create multiple profiles with the same name
if (previous_profile != NULL)
{
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
}
else
{
// make sure we're under the limit
if (Num_ai_profiles >= MAX_AI_PROFILES)
{
Warning(LOCATION, "Too many profiles in ai_profiles.tbl! Max is %d.\n", MAX_AI_PROFILES-1); // -1 because one is built-in
skip_to_string("#End", NULL);
break;
}
profile = &Ai_profiles[Num_ai_profiles];
Num_ai_profiles++;
}
}
// initialize profile if we're not building from a previously parsed one
if (!no_create)
{
// base profile, so zero it out
if (profile == &Ai_profiles[0])
{
memset(profile, 0, sizeof(ai_profile_t));
}
// brand new profile, so set it to the base defaults
else
{
memcpy(profile, &Ai_profiles[0], sizeof(ai_profile_t));
}
}
// set the name
strcpy_s(profile->profile_name, profile_name);
// fill in any and all settings; they're all optional and can be in any order
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
{
if (optional_string("$Player Afterburner Recharge Scale:"))
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
if (optional_string("$Max Beam Friendly Fire Damage:"))
parse_float_list(profile->beam_friendly_damage_cap, NUM_SKILL_LEVELS);
if (optional_string("$Player Countermeasure Life Scale:"))
parse_float_list(profile->cmeasure_life_scale, NUM_SKILL_LEVELS);
if (optional_string("$AI Countermeasure Firing Chance:"))
parse_float_list(profile->cmeasure_fire_chance, NUM_SKILL_LEVELS);
if (optional_string("$AI In Range Time:"))
parse_float_list(profile->in_range_time, NUM_SKILL_LEVELS);
if (optional_string("$AI Always Links Ammo Weapons:"))
parse_float_list(profile->link_ammo_levels_always, NUM_SKILL_LEVELS);
if (optional_string("$AI Maybe Links Ammo Weapons:"))
parse_float_list(profile->link_ammo_levels_maybe, NUM_SKILL_LEVELS);
if (optional_string("$Primary Ammo Burst Multiplier:"))
parse_float_list(profile->primary_ammo_burst_mult, NUM_SKILL_LEVELS);
if (optional_string("$AI Always Links Energy Weapons:"))
parse_float_list(profile->link_energy_levels_always, NUM_SKILL_LEVELS);
if (optional_string("$AI Maybe Links Energy Weapons:"))
parse_float_list(profile->link_energy_levels_maybe, NUM_SKILL_LEVELS);
if (optional_string("$Max Missles Locked on Player:") || optional_string("$Max Missiles Locked on Player:"))
parse_int_list(profile->max_allowed_player_homers, NUM_SKILL_LEVELS);
if (optional_string("$Max Player Attackers:"))
parse_int_list(profile->max_attackers, NUM_SKILL_LEVELS);
if (optional_string("$Max Incoming Asteroids:"))
parse_int_list(profile->max_incoming_asteroids, NUM_SKILL_LEVELS);
if (optional_string("$Player Damage Factor:") || optional_string("$AI Damage Reduction to Player Hull:"))
parse_float_list(profile->player_damage_scale, NUM_SKILL_LEVELS);
if (optional_string("$Player Subsys Damage Factor:") || optional_string("$AI Damage Reduction to Player Subsys:"))
parse_float_list(profile->subsys_damage_scale, NUM_SKILL_LEVELS);
// represented in fractions of F1_0
if (optional_string("$Predict Position Delay:"))
{
int iLoop;
float temp_list[NUM_SKILL_LEVELS];
parse_float_list(temp_list, NUM_SKILL_LEVELS);
for (iLoop = 0; iLoop < NUM_SKILL_LEVELS; iLoop++)
profile->predict_position_delay[iLoop] = fl2f(temp_list[iLoop]);
}
if (optional_string("$AI Shield Manage Delay:") || optional_string("$AI Shield Manage Delays:"))
parse_float_list(profile->shield_manage_delay, NUM_SKILL_LEVELS);
if (optional_string("$Friendly AI Fire Delay Scale:"))
parse_float_list(profile->ship_fire_delay_scale_friendly, NUM_SKILL_LEVELS);
if (optional_string("$Hostile AI Fire Delay Scale:"))
parse_float_list(profile->ship_fire_delay_scale_hostile, NUM_SKILL_LEVELS);
if (optional_string("$Friendly AI Secondary Fire Delay Scale:"))
parse_float_list(profile->ship_fire_secondary_delay_scale_friendly, NUM_SKILL_LEVELS);
if (optional_string("$Hostile AI Secondary Fire Delay Scale:"))
parse_float_list(profile->ship_fire_secondary_delay_scale_hostile, NUM_SKILL_LEVELS);
if (optional_string("$AI Turn Time Scale:"))
parse_float_list(profile->turn_time_scale, NUM_SKILL_LEVELS);
if (optional_string("$Glide Attack Percent:")) {
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (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;
}
profile->glide_attack_percent[i] /= 100.0;
}
}
if (optional_string("$Circle Strafe Percent:")) {
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (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;
}
profile->circle_strafe_percent[i] /= 100.0;
}
}
if (optional_string("$Glide Strafe Percent:")) {
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (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;
}
profile->glide_strafe_percent[i] /= 100.0;
}
}
if (optional_string("$Random Sidethrust Percent:")) {
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (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;
}
profile->random_sidethrust_percent[i] /= 100.0;
}
}
if (optional_string("$Stalemate Time Threshold:"))
parse_float_list(profile->stalemate_time_thresh, NUM_SKILL_LEVELS);
if (optional_string("$Stalemate Distance Threshold:"))
parse_float_list(profile->stalemate_dist_thresh, NUM_SKILL_LEVELS);
if (optional_string("$Player Shield Recharge Scale:"))
parse_float_list(profile->shield_energy_scale, NUM_SKILL_LEVELS);
if (optional_string("$Player Weapon Recharge Scale:"))
parse_float_list(profile->weapon_energy_scale, NUM_SKILL_LEVELS);
if (optional_string("$Max Turret Target Ownage:"))
parse_int_list(profile->max_turret_ownage_target, NUM_SKILL_LEVELS);
if (optional_string("$Max Turret Player Ownage:"))
parse_int_list(profile->max_turret_ownage_player, NUM_SKILL_LEVELS);
if (optional_string("$Percentage Required For Kill Scale:"))
parse_float_list(profile->kill_percentage_scale, NUM_SKILL_LEVELS);
if (optional_string("$Percentage Required For Assist Scale:"))
parse_float_list(profile->assist_percentage_scale, NUM_SKILL_LEVELS);
if (optional_string("$Percentage Awarded For Capship Assist:"))
parse_float_list(profile->assist_award_percentage_scale, NUM_SKILL_LEVELS);
if (optional_string("$Repair Penalty:"))
parse_int_list(profile->repair_penalty, NUM_SKILL_LEVELS);
if (optional_string("$Delay Before Allowing Bombs to Be Shot Down:"))
parse_float_list(profile->delay_bomb_arm_timer, NUM_SKILL_LEVELS);
if (optional_string("$Chance AI Has to Fire Missiles at Player:"))
parse_int_list(profile->chance_to_use_missiles_on_plr, NUM_SKILL_LEVELS);
if (optional_string("$Max Aim Update Delay:"))
parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS);
if (optional_string("$Turret Max Aim Update Delay:"))
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
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);
set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION, AIP_FLAG);
set_flag(profile, "$smart shield management:", AIPF_SMART_SHIELD_MANAGEMENT, AIP_FLAG);
set_flag(profile, "$smart afterburner management:", AIPF_SMART_AFTERBURNER_MANAGEMENT, AIP_FLAG);
set_flag(profile, "$allow rapid secondary dumbfire:", AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE, AIP_FLAG);
set_flag(profile, "$huge turret weapons ignore bombs:", AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS, AIP_FLAG);
set_flag(profile, "$don't insert random turret fire delay:", AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY, AIP_FLAG);
set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY, AIP_FLAG);
set_flag(profile, "$shockwaves damage small ship subsystems:", AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS, AIP_FLAG);
set_flag(profile, "$navigation subsystem governs warpout capability:", AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP, AIP_FLAG);
set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP, AIP_FLAG);
set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY, AIP_FLAG);
set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING, AIP_FLAG);
set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY, AIP_FLAG);
set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING, AIP_FLAG);
set_flag(profile, "$include beams for kills and assists:", AIPF_INCLUDE_BEAMS_IN_STAT_CALCS, AIP_FLAG);
set_flag(profile, "$score kills based on damage caused:", AIPF_KILL_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
set_flag(profile, "$score assists based on damage caused:", AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING, AIP_FLAG);
set_flag(profile, "$fix linked primary weapon decision bug:", AIPF_FIX_LINKED_PRIMARY_BUG, AIP_FLAG);
set_flag(profile, "$prevent turrets targeting too distant bombs:", AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE, AIP_FLAG);
set_flag(profile, "$smart subsystem targeting for turrets:", AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS, AIP_FLAG);
set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AIPF_FIX_HEAT_SEEKER_STEALTH_BUG, AIP_FLAG);
set_flag(profile, "$multi allow empty primaries:", AIPF_MULTI_ALLOW_EMPTY_PRIMARIES, AIP_FLAG);
set_flag(profile, "$multi allow empty secondaries:", AIPF_MULTI_ALLOW_EMPTY_SECONDARIES, AIP_FLAG);
set_flag(profile, "$allow turrets target weapons freely:", AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY, AIP_FLAG);
set_flag(profile, "$use only single fov for turrets:", AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS, AIP_FLAG);
set_flag(profile, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG);
set_flag(profile, "$force beam turrets to use normal fov:", AIPF_FORCE_BEAM_TURRET_FOV, AIP_FLAG);
set_flag(profile, "$fix ai class bug:", AIPF_FIX_AI_CLASS_BUG, AIP_FLAG);
set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2);
set_flag(profile, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
set_flag(profile, "$perform fewer checks for death screams:", AIPF2_PERFORM_FEWER_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 at mission start:", AIPF2_ALLOW_PRIMARY_LINK_AT_START, 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);
set_flag(profile, "$countermeasures affect aspect seekers:", AIPF2_ASPECT_LOCK_COUNTERMEASURE, AIP_FLAG2);
set_flag(profile, "$ai guards specific ship in wing:", AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING, 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);
}
}
set_flag(profile, "$no warp camera:", AIPF2_NO_WARP_CAMERA, AIP_FLAG2);
set_flag(profile, "$fix ai path order bug:", AIPF2_FIX_AI_PATH_ORDER_BUG, AIP_FLAG2);
set_flag(profile, "$strict turret-tagged-only targeting:", AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING, AIP_FLAG2);
// ----------
// compatibility
if (optional_string("$perform less checks for death screams:"))
{
mprintf(("Warning: \"$perform less checks for death screams\" flag is deprecated in favor of \"$perform fewer checks for death screams\"\n"));
bool temp;
stuff_boolean(&temp);
if (temp)
profile->flags2 |= AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
else
profile->flags2 &= ~AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
}
if (optional_string("$allow primary link delay:"))
{
mprintf(("Warning: \"$allow primary link delay\" flag is deprecated in favor of \"$allow primary link at mission start\"\n"));
bool temp;
stuff_boolean(&temp);
if (temp)
profile->flags2 &= ~AIPF2_ALLOW_PRIMARY_LINK_AT_START;
else
profile->flags2 |= AIPF2_ALLOW_PRIMARY_LINK_AT_START;
}
// if we've been through once already and are at the same place, force a move
if ( saved_Mp && (saved_Mp == Mp) )
{
char tmp[60];
memset(tmp, 0, 60);
strncpy(tmp, Mp, 59);
mprintf(("WARNING: Unrecognized parameter in ai_profiles: %s\n", tmp));
Mp++;
}
// find next valid option
skip_to_start_of_string_either("$", "#");
saved_Mp = Mp;
}
}
required_string("#End");
// add tbl/tbm to multiplayer validation list
extern void fs2netd_add_table_validation(const char *tblname);
+1 -8
View File
@@ -9,8 +9,8 @@
#ifndef _AI_PROFILES_H_
#define _AI_PROFILES_H_
#include "globalincs/globals.h"
#include "globalincs/pstypes.h"
#include "globalincs/globals.h"
#include "globalincs/systemvars.h"
// flag int defines
@@ -66,8 +66,6 @@
#define AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING (1 << 12)
#define AIPF2_FIX_AI_PATH_ORDER_BUG (1 << 13)
#define AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING (1 << 14)
#define AIPF2_ASPECT_INVULNERABILITY_FIX (1 << 15)
#define AIPF2_GLIDE_DECAY_REQUIRES_THRUST (1 << 16)
// AI Path types
#define AI_PATH_MODE_NORMAL 0
@@ -153,11 +151,6 @@ typedef struct ai_profile_t {
int ai_path_mode;
// Ships flying bay paths will gradually accelerate/decelerate instead of
// flying the whole path at max speed
float bay_arrive_speed_mult;
float bay_depart_speed_mult;
} ai_profile_t;
+11 -11
View File
@@ -10,23 +10,22 @@
#include "ai/aibig.h"
#include "ai/aigoals.h"
#include "freespace2/freespace.h"
#include "globalincs/linklist.h"
#include "iff_defs/iff_defs.h"
#include "io/timer.h"
#include "math/staticrand.h"
#include "mission/missionparse.h"
#include "object/object.h"
#include "ship/afterburner.h"
#include "ship/ship.h"
#include "ship/afterburner.h"
#include "freespace2/freespace.h"
#include "weapon/weapon.h"
#include "io/timer.h"
#include "mission/missionparse.h"
#include "iff_defs/iff_defs.h"
#include "math/staticrand.h"
#include "ai/aigoals.h"
#ifdef _MSC_VER
#pragma optimize("", off)
#pragma auto_inline(off)
#endif
#define SCAN_FIGHTERS_INTERVAL 2000 // how often an AI fighter/bomber should scan for enemy fighter/bombers
// if sitting still and pounding on a big ship. If enemy fighters are
@@ -1239,7 +1238,7 @@ int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
float dist_to_target, dist_normal_to_target, time_to_target;
dist_to_target = vm_vec_mag_quick(&vec_to_target);
if (vm_vec_mag_quick(&aip->big_attack_surface_normal) > 0.9) {
dist_normal_to_target = -vm_vec_dot(&vec_to_target, &aip->big_attack_surface_normal);
dist_normal_to_target = -vm_vec_dotprod(&vec_to_target, &aip->big_attack_surface_normal);
} else {
dist_normal_to_target = 0.2f * vm_vec_mag_quick(&vec_to_target);
}
@@ -1264,9 +1263,10 @@ int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
aip->submode = AIS_STRAFE_RETREAT1;
aip->submode_start_time = Missiontime;
float box_dist;
int is_inside;
vec3d goal_point;
get_world_closest_box_point_with_delta(&goal_point, En_objp, &Pl_objp->pos, &is_inside, STRAFE_RETREAT_BOX_DIST);
box_dist = get_world_closest_box_point_with_delta(&goal_point, En_objp, &Pl_objp->pos, &is_inside, STRAFE_RETREAT_BOX_DIST);
// set goal point
aip->goal_point = goal_point;
+181 -196
View File
@@ -18,63 +18,61 @@
#include "ai/ai.h"
#include "ai/ai_profiles.h"
#include "ai/aibig.h"
#include "ai/aigoals.h"
#include "ai/aiinternal.h"
#include "asteroid/asteroid.h"
#include "autopilot/autopilot.h"
#include "cmeasure/cmeasure.h"
#include "debugconsole/console.h"
#include "freespace2/freespace.h"
#include "gamesequence/gamesequence.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/linklist.h"
#include "hud/hud.h"
#include "hud/hudets.h"
#include "hud/hudlock.h"
#include "iff_defs/iff_defs.h"
#include "io/joy_ff.h"
#include "io/timer.h"
#include "localization/localize.h"
#include "math/fvi.h"
#include "math/staticrand.h"
#include "object/object.h"
#include "physics/physics.h"
#include "ship/ship.h"
#include "model/model.h"
#include "render/3d.h"
#include "playerman/player.h"
#include "freespace2/freespace.h"
#include "mission/missiongoals.h"
#include "mission/missionlog.h"
#include "io/timer.h"
#include "ai/aigoals.h"
#include "gamesnd/gamesnd.h"
#include "mission/missionmessage.h"
#include "mission/missionparse.h"
#include "mission/missiontraining.h"
#include "model/model.h"
#include "network/multi.h"
#include "network/multimsgs.h"
#include "network/multiutil.h"
#include "object/deadobjectdock.h"
#include "object/objcollide.h"
#include "object/object.h"
#include "object/objectdock.h"
#include "object/objectshield.h"
#include "object/waypoint.h"
#include "parse/parselo.h"
#include "physics/physics.h"
#include "playerman/player.h"
#include "render/3d.h"
#include "cmeasure/cmeasure.h"
#include "math/staticrand.h"
#include "ship/afterburner.h"
#include "ship/awacs.h"
#include "ship/ship.h"
#include "ship/shipfx.h"
#include "ship/shiphit.h"
#include "weapon/beam.h"
#include "weapon/flak.h"
#include "weapon/swarm.h"
#include "ai/aibig.h"
#include "hud/hud.h"
#include "hud/hudets.h"
#include "object/objcollide.h"
#include "object/objectshield.h"
#include "asteroid/asteroid.h"
#include "hud/hudlock.h"
#include "mission/missiontraining.h"
#include "gamesequence/gamesequence.h"
#include "io/joy_ff.h"
#include "localization/localize.h"
#include "weapon/weapon.h"
#include "weapon/flak.h"
#include "weapon/beam.h"
#include "weapon/swarm.h"
#include "ship/awacs.h"
#include "math/fvi.h"
#include "parse/parselo.h"
#include "object/objectdock.h"
#include "object/deadobjectdock.h"
#include "object/waypoint.h"
#include "ai/aiinternal.h"
#include "iff_defs/iff_defs.h"
#include "network/multimsgs.h"
#include "network/multiutil.h"
#include "network/multi.h"
#include "ai/ai_profiles.h"
#include "autopilot/autopilot.h"
#include <map>
#include <limits.h>
#ifdef _MSC_VER
#pragma optimize("", off)
#pragma auto_inline(off)
#endif
#define UNINITIALIZED_VALUE -99999.9f
@@ -828,14 +826,13 @@ LOCAL int ai_inited = 0;
void ai_init()
{
if ( !ai_inited ) {
// Do the first time initialization stuff here
try
{
parse_aitbl();
}
catch (const parse::ParseException& e)
{
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "ai.tbl", e.what()));
// Do the first time initialization stuff here
int rval;
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "ai.tbl", rval));
} else {
parse_aitbl();
}
ai_inited = 1;
@@ -980,7 +977,7 @@ int ai_is_stealth_visible(object *viewer_objp, object *stealth_objp)
if ( !ship_is_visible_by_team(stealth_objp, &Ships[viewer_objp->instance]) ) {
vm_vec_sub(&vec_to_stealth, &stealth_objp->pos, &viewer_objp->pos);
dist_to_stealth = vm_vec_mag_quick(&vec_to_stealth);
dot_to_stealth = vm_vec_dot(&viewer_objp->orient.vec.fvec, &vec_to_stealth) / dist_to_stealth;
dot_to_stealth = vm_vec_dotprod(&viewer_objp->orient.vec.fvec, &vec_to_stealth) / dist_to_stealth;
// get max dist at which stealth is visible
max_stealth_dist = get_skill_stealth_dist_scaler() * STEALTH_MAX_VIEW_DIST;
@@ -1539,8 +1536,8 @@ float turn_towards_tangent(object *objp, vec3d *point, float radius)
vec3d v2g;
vm_vec_normalized_dir(&vec_to_point, point, &objp->pos);
vm_vec_cross(&up_vec, &vec_to_point, &objp->orient.vec.fvec);
vm_vec_cross(&perp_vec, &vec_to_point, &up_vec);
vm_vec_crossprod(&up_vec, &vec_to_point, &objp->orient.vec.fvec);
vm_vec_crossprod(&perp_vec, &vec_to_point, &up_vec);
vm_vec_scale_add(&perp_point, point, &vec_to_point, -radius);
if (vm_vec_dot(&objp->orient.vec.fvec, &perp_vec) > 0.0f) {
@@ -1563,7 +1560,7 @@ float turn_toward_tangent_with_axis(object *objp, object *center_objp, float rad
// find closest z of center objp
vm_vec_sub(&sph_r_vec, &objp->pos, &center_objp->pos);
center_obj_z = vm_vec_dot(&sph_r_vec, &center_objp->orient.vec.fvec);
center_obj_z = vm_vec_dotprod(&sph_r_vec, &center_objp->orient.vec.fvec);
// find pt on axis with closest z
vm_vec_scale_add(&center_vec, &center_objp->pos, &center_objp->orient.vec.fvec, center_obj_z);
@@ -1571,10 +1568,10 @@ float turn_toward_tangent_with_axis(object *objp, object *center_objp, float rad
// get r_vec
vm_vec_sub(&r_vec, &objp->pos, &center_vec);
Assert( (vm_vec_dot(&r_vec, &center_objp->orient.vec.fvec) < 0.0001));
Assert( (vm_vec_dotprod(&r_vec, &center_objp->orient.vec.fvec) < 0.0001));
// get theta vec - perp to r_vec and z_vec
vm_vec_cross(&theta_vec, &center_objp->orient.vec.fvec, &r_vec);
vm_vec_crossprod(&theta_vec, &center_objp->orient.vec.fvec, &r_vec);
#ifndef NDEBUG
float mag;
@@ -1583,11 +1580,11 @@ float turn_toward_tangent_with_axis(object *objp, object *center_objp, float rad
#endif
vec3d temp;
vm_vec_cross(&temp, &r_vec, &theta_vec);
vm_vec_crossprod(&temp, &r_vec, &theta_vec);
#ifndef NDEBUG
float dot;
dot = vm_vec_dot(&temp, &center_objp->orient.vec.fvec);
dot = vm_vec_dotprod(&temp, &center_objp->orient.vec.fvec);
Assert( dot >0.9999 && dot < 1.0001);
#endif
@@ -1613,17 +1610,17 @@ void get_tangent_point(vec3d *goal_point, object *objp, vec3d *point, float radi
vec3d up_vec, perp_vec;
vm_vec_normalized_dir(&vec_to_point, point, &objp->pos);
vm_vec_cross(&up_vec, &vec_to_point, &objp->orient.vec.fvec);
vm_vec_crossprod(&up_vec, &vec_to_point, &objp->orient.vec.fvec);
while (IS_VEC_NULL(&up_vec)) {
vec3d rnd_vec;
vm_vec_rand_vec_quick(&rnd_vec);
vm_vec_add2(&rnd_vec, &objp->orient.vec.fvec);
vm_vec_cross(&up_vec, &vec_to_point, &rnd_vec);
vm_vec_crossprod(&up_vec, &vec_to_point, &rnd_vec);
}
vm_vec_cross(&perp_vec, &vec_to_point, &up_vec);
vm_vec_crossprod(&perp_vec, &vec_to_point, &up_vec);
vm_vec_normalize(&perp_vec);
vm_vec_scale_add(&perp_point, point, &vec_to_point, -radius);
@@ -2001,6 +1998,11 @@ void evaluate_object_as_nearest_objnum(eval_nearest_objnum *eno)
}
if (eno->trial_objp->flags & OF_PLAYER_SHIP){
// Goober5000: oh dear, it looks like this was originally meant to scale
// the distance according to skill, but as it is, the effect appears negligible.
// I could fix it with parentheses, but we all know how quickly AI pilots
// die usually, so the overall effect would probably be worse. So I left
// this unchanged.
dist *= 1.0f + (NUM_SKILL_LEVELS - Game_skill_level - 1)/NUM_SKILL_LEVELS; // Favor attacking non-players based on skill level.
}
@@ -2482,7 +2484,7 @@ void ai_ignore_object(object *ignorer, object *ignored, int ignore_new)
/**
* Ignore some object without changing mode.
*/
void ai_ignore_wing(object *ignorer, int wingnum)
void ai_ignore_wing(object *ignorer, int wingnum, int priority)
{
ai_info *aip;
@@ -2621,7 +2623,7 @@ void create_path_to_point(vec3d *curpos, vec3d *goalpos, object *curobjp, object
void copy_xlate_model_path_points(object *objp, model_path *mp, int dir, int count, int path_num, pnode *pnp, int randomize_pnt)
{
polymodel *pm;
int i, modelnum, model_instance_num;
int i, modelnum;
vec3d v1;
int pp_index; // index in Path_points at which to store point, if this is a modify-in-place (pnp ! NULL)
int start_index, finish_index;
@@ -2646,12 +2648,14 @@ void copy_xlate_model_path_points(object *objp, model_path *mp, int dir, int cou
// Goober5000 - check for rotating submodels
modelnum = Ship_info[Ships[objp->instance].ship_info_index].model_num;
model_instance_num = Ships[objp->instance].model_instance_num;
pm = model_get(modelnum);
if ((mp->parent_submodel >= 0) && (pm->submodel[mp->parent_submodel].movement_type >= 0))
{
rotating_submodel = true;
// start submodel calculation
ship_model_start(objp);
model_find_submodel_offset(&submodel_offset, modelnum, mp->parent_submodel);
}
else
@@ -2668,7 +2672,7 @@ void copy_xlate_model_path_points(object *objp, model_path *mp, int dir, int cou
{
// movement... find location of point like with docking code and spark generation
vm_vec_sub(&local_vert, &mp->verts[i].pos, &submodel_offset);
model_instance_find_world_point(&v1, &local_vert, model_instance_num, mp->parent_submodel, &objp->orient, &objp->pos);
model_find_world_point(&v1, &local_vert, modelnum, mp->parent_submodel, &objp->orient, &objp->pos);
}
else
{
@@ -2690,6 +2694,12 @@ void copy_xlate_model_path_points(object *objp, model_path *mp, int dir, int cou
add_path_point(&v1, path_num, i, pp_index);
offset++;
}
// stop submodel calculation
if (!rotating_submodel)
{
ship_model_stop(objp);
}
}
@@ -2958,8 +2968,8 @@ int maybe_avoid_player(object *objp, vec3d *goal_pos)
} else {
vec3d tvec1;
vm_vec_normalize(&avoid_vec);
vm_vec_cross(&tvec1, &n_vec_to_goal, &avoid_vec);
vm_vec_cross(&avoid_vec, &tvec1, &n_vec_to_player);
vm_vec_crossprod(&tvec1, &n_vec_to_goal, &avoid_vec);
vm_vec_crossprod(&avoid_vec, &tvec1, &n_vec_to_player);
}
// Now, avoid_vec is a vector perpendicular to the vector to the player and the direction *objp
@@ -3400,7 +3410,7 @@ float compute_collision_time(vec3d *targpos, vec3d *targvel, vec3d *attackpos, f
// This function doesn't account for the fact that by the time the player
// (or his laser) gets to the current enemy position, the enemy will have moved.
// This is dealt with in polish_predicted_enemy_pos.
float compute_time_to_enemy(float dist_to_enemy, object *pobjp)
float compute_time_to_enemy(float dist_to_enemy, object *pobjp, object *eobjp)
{
float time_to_enemy;
float pl_speed = pobjp->phys_info.speed;
@@ -3482,12 +3492,8 @@ void ai_set_positions(object *pl_objp, object *en_objp, ai_info *aip, vec3d *pla
}
/**
* Updates AI aim automatically based on targetted enemy.
*
* @param aip Pointer to AI info
*/
void ai_update_aim(ai_info *aip)
// --------------------------------------------------------------------------
void ai_update_aim(ai_info *aip, object* En_Objp)
{
if (Missiontime >= aip->next_aim_pos_time)
{
@@ -3640,7 +3646,7 @@ float maybe_recreate_path(object *objp, ai_info *aip, int force_recreate_flag, i
/**
* Set acceleration for ai_dock().
*/
void set_accel_for_docking(object *objp, ai_info *aip, float dot, float dot_to_next, float dist_to_next, float dist_to_goal, ship_info *sip, float max_allowed_speed, object *gobjp)
void set_accel_for_docking(object *objp, ai_info *aip, float dot, float dot_to_next, float dist_to_next, float dist_to_goal, ship_info *sip, float max_allowed_speed)
{
float prev_dot_to_goal = aip->prev_dot_to_goal;
@@ -3655,55 +3661,9 @@ void set_accel_for_docking(object *objp, ai_info *aip, float dot, float dot_to_n
change_acceleration(aip, -1.0f); // -1.0f means subtract off flFrametime from acceleration value in 0.0..1.0
}
} else {
float max_bay_speed = sip->max_speed;
// Maybe gradually ramp up/down the speed of a ship flying a fighterbay path
if (aip->mode == AIM_BAY_EMERGE || (aip->mode == AIM_BAY_DEPART && aip->path_cur != aip->path_start)) {
ship_info *gsip = &Ship_info[Ships[gobjp->instance].ship_info_index];
polymodel *pm = model_get(gsip->model_num);
SCP_string pathName(pm->paths[Path_points[aip->path_start].path_num].name);
float speed_mult = FLT_MIN;
if (aip->mode == AIM_BAY_EMERGE) { // Arriving
if (gsip->pathMetadata.find(pathName) != gsip->pathMetadata.end()) {
speed_mult = gsip->pathMetadata[pathName].arrive_speed_mult;
}
if (speed_mult == FLT_MIN) {
speed_mult = The_mission.ai_profile->bay_arrive_speed_mult;
}
} else { // Departing
if (gsip->pathMetadata.find(pathName) != gsip->pathMetadata.end()) {
speed_mult = gsip->pathMetadata[pathName].depart_speed_mult;
}
if (speed_mult == FLT_MIN) {
speed_mult = The_mission.ai_profile->bay_depart_speed_mult;
}
}
if (speed_mult != FLT_MIN && speed_mult != 1.0f) {
// We use the distance between the first and last point on the path here; it's not accurate
// if the path is not straight, but should be good enough usually; can be changed if necessary.
float total_path_length = vm_vec_dist_quick(&Path_points[aip->path_start].pos, &Path_points[aip->path_start + aip->path_length - 1].pos);
float dist_to_end;
if (aip->mode == AIM_BAY_EMERGE) { // Arriving
dist_to_end = vm_vec_dist_quick(&Pl_objp->pos, &Path_points[aip->path_start].pos);
} else { // Departing
dist_to_end = vm_vec_dist_quick(&Pl_objp->pos, &Path_points[aip->path_start + aip->path_length - 1].pos);
}
// Calculate max speed, but respect the waypoint speed cap if it's lower
max_bay_speed = sip->max_speed * (speed_mult + (1.0f - speed_mult) * (dist_to_end / total_path_length));
}
}
// Cap speed to max_allowed_speed, if it's set
// If max_allowed_speed isn't set, use the ship max speed
if (max_allowed_speed <= 0)
max_allowed_speed = max_bay_speed;
else
max_allowed_speed = MIN(max_allowed_speed, max_bay_speed);
max_allowed_speed = sip->max_speed;
if ((aip->mode == AIM_DOCK) && (dist_to_next < 150.0f) && (aip->path_start + aip->path_length - 2 == aip->path_cur)) {
set_accel_for_target_speed(objp, max_allowed_speed * MAX(dist_to_next/500.0f, 1.0f));
@@ -3779,7 +3739,8 @@ void set_accel_for_docking(object *objp, ai_info *aip, float dot, float dot_to_n
// Returns distance to goal point.
float ai_path_0()
{
int num_points;
polymodel *pm;
int num_paths, num_points;
float dot, dist_to_goal, dist_to_next, dot_to_next;
ship *shipp = &Ships[Pl_objp->instance];
ship_info *sip = &Ship_info[shipp->ship_info_index];
@@ -3788,6 +3749,7 @@ float ai_path_0()
float mag;
vec3d temp_vec, *slop_vec;
object *gobjp;
ship *gshipp;
vec3d *cvp, *nvp, next_vec, gcvp, gnvp; // current and next vertices in global coordinates.
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -3796,6 +3758,11 @@ float ai_path_0()
Assert(Objects[aip->goal_objnum].type == OBJ_SHIP);
gobjp = &Objects[aip->goal_objnum];
gshipp = &Ships[gobjp->instance];
pm = model_get(Ship_info[gshipp->ship_info_index].model_num);
num_paths = pm->n_paths;
Assert(num_paths > 0);
if (aip->path_start == -1) {
Assert(aip->goal_objnum >= 0 && aip->goal_objnum < MAX_OBJECTS);
@@ -3887,7 +3854,7 @@ float ai_path_0()
dot = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, &gcvp);
dot_to_next = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, &gnvp);
set_accel_for_docking(Pl_objp, aip, dot, dot_to_next, dist_to_next, dist_to_goal, sip, 0, gobjp);
set_accel_for_docking(Pl_objp, aip, dot, dot_to_next, dist_to_next, dist_to_goal, sip, 0);
aip->prev_dot_to_goal = dot;
// If moving at a non-tiny velocity, detect attaining path point by its being close to
@@ -3923,7 +3890,8 @@ float ai_path_0()
// 1.
float ai_path_1()
{
int num_points;
polymodel *pm;
int num_paths, num_points;
float dot, dist_to_goal, dist_to_next, dot_to_next;
ship *shipp = &Ships[Pl_objp->instance];
ship_info *sip = &Ship_info[shipp->ship_info_index];
@@ -3931,6 +3899,7 @@ float ai_path_1()
vec3d nvel_vec;
float mag;
object *gobjp;
ship *gshipp;
vec3d *pvp, *cvp, *nvp, next_vec, gpvp, gcvp, gnvp; // previous, current and next vertices in global coordinates.
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -3939,6 +3908,12 @@ float ai_path_1()
Assert(Objects[aip->goal_objnum].type == OBJ_SHIP);
gobjp = &Objects[aip->goal_objnum];
gshipp = &Ships[gobjp->instance];
// Get path data
pm = model_get(Ship_info[gshipp->ship_info_index].model_num);
num_paths = pm->n_paths;
Assert(num_paths > 0);
if (aip->path_start == -1) {
Assert(aip->goal_objnum >= 0 && aip->goal_objnum < MAX_OBJECTS);
@@ -4035,12 +4010,12 @@ float ai_path_1()
dot_to_next = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, &gnvp);
// This path mode respects the "cap-waypoint-speed" SEXP
float max_allowed_speed = 0.0f;
float max_allowed_speed = 0;
if ( aip->waypoint_speed_cap > 0) {
max_allowed_speed = (float) aip->waypoint_speed_cap;
}
set_accel_for_docking(Pl_objp, aip, dot, dot_to_next, dist_to_next, dist_to_goal, sip, max_allowed_speed, gobjp);
set_accel_for_docking(Pl_objp, aip, dot, dot_to_next, dist_to_next, dist_to_goal, sip, max_allowed_speed);
aip->prev_dot_to_goal = dot;
// If moving at a non-tiny velocity, detect attaining path point by its being close to
@@ -5225,7 +5200,7 @@ int ai_select_primary_weapon_OLD(object *objp, object *other_objp, int flags)
ship *shipp = &Ships[objp->instance];
ship_weapon *swp = &shipp->weapons;
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < Num_ship_classes);
if (flags & WIF_PUNCTURE) {
if (swp->current_primary_bank >= 0) {
@@ -5314,7 +5289,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
return ai_select_primary_weapon_OLD(objp, other_objp, flags);
}
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < Num_ship_classes);
//made it so it only selects puncture weapons if the active goal is to disable something -Bobboau
if ((flags & WIF_PUNCTURE) && (Ai_info[shipp->ai_index].goals[0].ai_mode & (AI_GOAL_DISARM_SHIP | AI_GOAL_DISABLE_SHIP)))
@@ -5631,7 +5606,7 @@ int ai_fire_primary_weapon(object *objp)
ai_info *aip;
object *enemy_objp;
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < Num_ship_classes);
aip = &Ai_info[shipp->ai_index];
@@ -6064,7 +6039,7 @@ int ai_fire_secondary_weapon(object *objp, int priority1, int priority2)
shipp = &Ships[objp->instance];
swp = &shipp->weapons;
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < Num_ship_classes);
// Select secondary weapon.
current_bank = swp->current_secondary_bank; //ai_select_secondary_weapon(objp, swp, priority1, priority2);
@@ -6144,7 +6119,7 @@ int might_hit_teammate(object *firing_objp)
void render_all_ship_bay_paths(object *objp)
{
int i,j,clr;
int i,j,color;
polymodel *pm;
model_path *mp;
@@ -6157,17 +6132,17 @@ void render_all_ship_bay_paths(object *objp)
memset(&v, 0, sizeof(v));
for ( i = 0; i < pm->ship_bay->num_paths; i++ ) {
for ( i = 0; i < pm->ship_bay->num_paths; i++ ) {
mp = &pm->paths[pm->ship_bay->path_indexes[i]];
for ( j = 0; j < mp->nverts; j++ ) {
vm_vec_unrotate(&global_path_point, &mp->verts[j].pos, &objp->orient);
vm_vec_add2(&global_path_point, &objp->pos);
g3_rotate_vertex(&v, &global_path_point);
clr = 255 - j*50;
if ( clr < 50 )
clr = 100;
gr_set_color(0, clr, 0);
color = 255 - j*50;
if ( color < 50 )
color = 100;
gr_set_color(0, color, 0);
if ( j == mp->nverts-1 ) {
gr_set_color(255, 0, 0);
@@ -6189,7 +6164,7 @@ void render_all_ship_bay_paths(object *objp)
*/
void render_all_subsys_paths(object *objp)
{
int i,j,clr;
int i,j,color;
polymodel *pm;
model_path *mp;
@@ -6200,7 +6175,7 @@ void render_all_subsys_paths(object *objp)
if ( pm->ship_bay == NULL )
return;
memset(&v, 0, sizeof(v));
memset(&v, 0, sizeof(v));
for ( i = 0; i < pm->n_paths; i++ ) {
mp = &pm->paths[i];
@@ -6208,10 +6183,10 @@ void render_all_subsys_paths(object *objp)
vm_vec_unrotate(&global_path_point, &mp->verts[j].pos, &objp->orient);
vm_vec_add2(&global_path_point, &objp->pos);
g3_rotate_vertex(&v, &global_path_point);
clr = 255 - j*50;
if ( clr < 50 )
clr = 100;
gr_set_color(0, clr, 0);
color = 255 - j*50;
if ( color < 50 )
color = 100;
gr_set_color(0, color, 0);
if ( j == mp->nverts-1 ) {
gr_set_color(255, 0, 0);
@@ -6245,9 +6220,10 @@ void render_path_points(object *objp)
vec3d dock_point, global_dock_point;
vertex v;
ship_model_start(&Objects[aip->goal_objnum]);
if (pm->n_docks) {
dock_point = pm->docking_bays[0].pnt[0];
model_instance_find_world_point(&global_dock_point, &dock_point, shipp->model_instance_num, 0, &dobjp->orient, &dobjp->pos );
model_find_world_point(&global_dock_point, &dock_point, pm->id, 0, &dobjp->orient, &dobjp->pos );
g3_rotate_vertex(&v, &global_dock_point);
gr_set_color(255, 255, 255);
g3_draw_sphere( &v, 1.5f);
@@ -6280,6 +6256,8 @@ void render_path_points(object *objp)
pp++;
}
}
ship_model_stop(&Objects[aip->goal_objnum]);
}
/**
@@ -6485,7 +6463,7 @@ void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *e
vec3d temp;
vm_vec_sub(&temp, enemy_pos, &pobjp->pos);
vm_vec_normalize_quick(&temp);
float dot = vm_vec_dot(&temp, &pobjp->orient.vec.fvec);
float dot = vm_vec_dotprod(&temp, &pobjp->orient.vec.fvec);
float st_err = 3.0f * (1.4f - dot) * (1.0f + dist / (get_skill_stealth_dist_scaler() * STEALTH_MAX_VIEW_DIST)) * (1 - aip->ai_accuracy);
scale += st_err;
}
@@ -6752,10 +6730,11 @@ void attack_set_accel(ai_info *aip, ship_info *sip, float dist_to_enemy, float d
void get_behind_ship(ai_info *aip, ship_info *sip, float dist_to_enemy)
{
vec3d new_pos;
float dot;
float dot;
vec3d vec_from_enemy;
float dist;
vm_vec_normalized_dir(&vec_from_enemy, &Pl_objp->pos, &En_objp->pos);
dist = vm_vec_normalized_dir(&vec_from_enemy, &Pl_objp->pos, &En_objp->pos);
vm_vec_scale_add(&new_pos, &En_objp->pos, &En_objp->orient.vec.fvec, -100.0f); // Pick point 100 units behind.
ai_turn_towards_vector(&new_pos, Pl_objp, flFrametime, sip->srotation_time, NULL, NULL, 0.0f, 0);
@@ -7045,7 +7024,7 @@ void ai_stealth_find()
// if dist is near max and dot is close to 1, accel, afterburn
vm_vec_sub(&vec_to_enemy, &new_pos, &Pl_objp->pos);
dist_to_enemy = vm_vec_normalize_quick(&vec_to_enemy);
dot_to_enemy = vm_vec_dot(&vec_to_enemy, &Pl_objp->orient.vec.fvec);
dot_to_enemy = vm_vec_dotprod(&vec_to_enemy, &Pl_objp->orient.vec.fvec);
// if i think i should see him ahead and i don't, set goal pos and turn around, but only if I haven't seen him for a while
if ( (delta_time > 800) && (aip->submode_parm0 == SM_SF_AHEAD) && (dot_to_enemy > .94) && (dist_to_enemy < get_skill_stealth_dist_scaler()*STEALTH_MAX_VIEW_DIST + 50) ) {
@@ -7054,7 +7033,7 @@ void ai_stealth_find()
aip->submode_parm0 = SM_SF_BEHIND;
vm_vec_sub(&vec_to_enemy, &new_pos, &Pl_objp->pos);
dist_to_enemy = vm_vec_normalize_quick(&vec_to_enemy);
dot_to_enemy = vm_vec_dot(&vec_to_enemy, &Pl_objp->orient.vec.fvec);
dot_to_enemy = vm_vec_dotprod(&vec_to_enemy, &Pl_objp->orient.vec.fvec);
}
if ( (dist_to_enemy > get_skill_stealth_dist_scaler()*STEALTH_MAX_VIEW_DIST) && (dot_to_enemy > 0.94f) ) { // 20 degree half angle
@@ -7084,7 +7063,7 @@ void ai_stealth_find()
ai_turn_towards_vector(&new_pos, Pl_objp, flFrametime, sip->srotation_time, NULL, NULL, 0.0f, 0);
}
dot_from_enemy = -vm_vec_dot(&vec_to_enemy, &En_objp->orient.vec.fvec);
dot_from_enemy = -vm_vec_dotprod(&vec_to_enemy, &En_objp->orient.vec.fvec);
attack_set_accel(aip, sip, dist_to_enemy, dot_to_enemy, dot_from_enemy);
}
@@ -7133,10 +7112,10 @@ void ai_stealth_sweep()
}
// get "right" vector for box
vm_vec_cross(&right, &aip->stealth_velocity, &vmd_y_vector);
vm_vec_crossprod(&right, &aip->stealth_velocity, &vmd_y_vector);
if ( vm_vec_mag_quick(&right) < 0.01 ) {
vm_vec_cross(&right, &aip->stealth_velocity, &vmd_z_vector);
vm_vec_crossprod(&right, &aip->stealth_velocity, &vmd_z_vector);
}
vm_vec_normalize_quick(&right);
@@ -7145,7 +7124,7 @@ void ai_stealth_sweep()
vm_vec_copy_normalize_quick(&forward, &aip->stealth_velocity);
// get "up" for box
vm_vec_cross(&up, &forward, &right);
vm_vec_crossprod(&up, &forward, &right);
// lost far away ahead (do box)
switch(aip->submode_parm0) {
@@ -7215,7 +7194,7 @@ void ai_stealth_sweep()
if (dist_to_goal < 100) {
vec3d vec_to_goal;
vm_vec_normalized_dir(&vec_to_goal, &goal_pt, &Pl_objp->pos);
dot = vm_vec_dot(&vec_to_goal, &Pl_objp->orient.vec.fvec);
dot = vm_vec_dotprod(&vec_to_goal, &Pl_objp->orient.vec.fvec);
}
accelerate_ship(aip, 0.8f*dot);
@@ -7603,7 +7582,7 @@ void update_aspect_lock_information(ai_info *aip, vec3d *vec_to_enemy, float dis
wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]];
if (num_weapon_types && (wip->wi_flags & WIF_LOCKED_HOMING) && !(shipp->flags2 & SF2_NO_SECONDARY_LOCKON)) {
if (num_weapon_types && (wip->wi_flags & WIF_LOCKED_HOMING)) {
if (dist_to_enemy > 300.0f - MIN(enemy_radius, 100.0f))
aip->ai_flags |= AIF_SEEK_LOCK;
else
@@ -7861,7 +7840,7 @@ void ai_chase_big_get_separations(object *attack_objp, object *target_objp, vec3
vm_vec_sub(&vec_to_target, &attack_objp->pos, &target_objp->pos);
// find the distance between centers along forward direction of ships
perp_dist = vm_vec_dot(&vec_to_target, &target_objp->orient.vec.fvec);
perp_dist = vm_vec_dotprod(&vec_to_target, &target_objp->orient.vec.fvec);
// subtract off perp component to get "horizontal" separation vector between cylinders [ASSUMING parallel]
vm_vec_scale_add(horz_vec_to_target, &vec_to_target, &target_objp->orient.vec.fvec, -perp_dist);
@@ -7892,7 +7871,7 @@ void ai_chase_big_parallel_set_goal(vec3d *goal_pos, object *attack_objp, object
r_target = MAX(temp, r_target);
// are we opposing (only when other ship is not moving)
opposing = ( vm_vec_dot(&attack_objp->orient.vec.fvec, &target_objp->orient.vec.fvec) < 0 );
opposing = ( vm_vec_dotprod(&attack_objp->orient.vec.fvec, &target_objp->orient.vec.fvec) < 0 );
ai_chase_big_get_separations(attack_objp, target_objp, &horz_vec_to_target, &optimal_separation, &separation);
@@ -7910,7 +7889,7 @@ void ai_chase_big_parallel_set_goal(vec3d *goal_pos, object *attack_objp, object
// find the distance between centers along forward direction of ships
vec3d vec_to_target;
vm_vec_sub(&vec_to_target, &target_objp->pos, &attack_objp->pos);
float perp_dist = vm_vec_dot(&vec_to_target, &target_objp->orient.vec.fvec);
float perp_dist = vm_vec_dotprod(&vec_to_target, &target_objp->orient.vec.fvec);
float match_accel = 0.0f;
float length_scale = attack_objp->radius;
@@ -7999,6 +7978,10 @@ void ai_cruiser_chase()
return;
}
ship *eshipp;
eshipp = &Ships[En_objp->instance];
vec3d goal_pos;
float turn_time = Ship_info[Ships[Pl_objp->instance].ship_info_index].srotation_time;
@@ -8060,7 +8043,7 @@ void ai_cruiser_chase()
// moving
if (moving) {
// if within 90 degrees of en forward, go into parallel, otherwise circle
if ( vm_vec_dot(&En_objp->orient.vec.fvec, &Pl_objp->orient.vec.fvec) > 0 ) {
if ( vm_vec_dotprod(&En_objp->orient.vec.fvec, &Pl_objp->orient.vec.fvec) > 0 ) {
aip->submode = SM_BIG_PARALLEL;
aip->submode_start_time = Missiontime;
}
@@ -8080,9 +8063,9 @@ void ai_cruiser_chase()
vec3d temp;
float desired_sep, cur_sep;
// we're behind the enemy ship
if (vm_vec_dot(&vec_to_enemy, &En_objp->orient.vec.fvec) > 0) {
if (vm_vec_dotprod(&vec_to_enemy, &En_objp->orient.vec.fvec) > 0) {
// and we're turning toward the enemy
if (vm_vec_dot(&En_objp->orient.vec.fvec, &Pl_objp->orient.vec.fvec) > 0) {
if (vm_vec_dotprod(&En_objp->orient.vec.fvec, &Pl_objp->orient.vec.fvec) > 0) {
// get separation
ai_chase_big_get_separations(Pl_objp, En_objp, &temp, &desired_sep, &cur_sep);
// and the separation is > 0.9 desired
@@ -8097,9 +8080,9 @@ void ai_cruiser_chase()
vec3d temp;
float desired_sep, cur_sep;
// we're behind the enemy ship
if (vm_vec_dot(&vec_to_enemy, &En_objp->orient.vec.fvec) > 0) {
if (vm_vec_dotprod(&vec_to_enemy, &En_objp->orient.vec.fvec) > 0) {
// and we're turning toward the enemy
if (vm_vec_dot(&En_objp->orient.vec.fvec, &Pl_objp->orient.vec.fvec) > 0) {
if (vm_vec_dotprod(&En_objp->orient.vec.fvec, &Pl_objp->orient.vec.fvec) > 0) {
// get separation
ai_chase_big_get_separations(Pl_objp, En_objp, &temp, &desired_sep, &cur_sep);
// and the separation is > 0.9 desired
@@ -8112,7 +8095,7 @@ void ai_cruiser_chase()
// in front of ship
else {
// and we're turning toward the enemy
if (vm_vec_dot(&En_objp->orient.vec.fvec, &Pl_objp->orient.vec.fvec) < 0) {
if (vm_vec_dotprod(&En_objp->orient.vec.fvec, &Pl_objp->orient.vec.fvec) < 0) {
// get separation
ai_chase_big_get_separations(Pl_objp, En_objp, &temp, &desired_sep, &cur_sep);
// and the separation is > 0.9 desired
@@ -8127,7 +8110,7 @@ void ai_cruiser_chase()
case SM_BIG_PARALLEL:
// we're opposing
if ( vm_vec_dot(&Pl_objp->orient.vec.fvec, &En_objp->orient.vec.fvec) < 0 ) {
if ( vm_vec_dotprod(&Pl_objp->orient.vec.fvec, &En_objp->orient.vec.fvec) < 0 ) {
// and the other ship is moving
if (moving) {
// and we no longer overlap
@@ -8147,7 +8130,7 @@ void ai_cruiser_chase()
*/
void ai_chase()
{
float dist_to_enemy;
float dist_to_enemy, time_to_enemy;
float dot_to_enemy, dot_from_enemy, real_dot_to_enemy;
vec3d player_pos, enemy_pos, predicted_enemy_pos, real_vec_to_enemy, predicted_vec_to_enemy;
ship *shipp = &Ships[Pl_objp->instance];
@@ -8228,10 +8211,11 @@ void ai_chase()
ai_set_positions(Pl_objp, En_objp, aip, &player_pos, &enemy_pos);
dist_to_enemy = vm_vec_dist_quick(&player_pos, &enemy_pos);
time_to_enemy = compute_time_to_enemy(dist_to_enemy, Pl_objp, En_objp);
vm_vec_sub(&real_vec_to_enemy, &enemy_pos, &player_pos);
//Enemy position for the purpose of aiming is already calculated differently, do it explicitly here
ai_update_aim(aip);
ai_update_aim(aip, En_objp);
vm_vec_normalize(&real_vec_to_enemy);
@@ -8985,7 +8969,7 @@ void set_goal_dock_orient(matrix *dom, vec3d *docker_p0, vec3d *docker_p1, vec3d
// Pre-multiply the orientation of the source object (docker_orient) by the transpose
// of the docking bay's orientation, ie unrotate the source object's matrix.
vm_transpose(&m2);
vm_transpose_matrix(&m2);
vm_matrix_x_matrix(dom, &m3, &m2);
}
@@ -9029,9 +9013,8 @@ void find_adjusted_dockpoint_info(vec3d *global_p0, vec3d *global_p1, vec3d *glo
{
vec3d submodel_offset;
vec3d local_p0, local_p1;
ship *shipp;
shipp = &Ships[objp->instance];
ship_model_start(objp);
// calculate the dockpoint locations relative to the unrotated submodel
model_find_submodel_offset(&submodel_offset, modelnum, submodel);
@@ -9039,11 +9022,13 @@ void find_adjusted_dockpoint_info(vec3d *global_p0, vec3d *global_p1, vec3d *glo
vm_vec_sub(&local_p1, &pm->docking_bays[dock_index].pnt[1], &submodel_offset);
// find the dynamic positions of the dockpoints
model_instance_find_world_point(global_p0, &local_p0, shipp->model_instance_num, submodel, &objp->orient, &objp->pos);
model_instance_find_world_point(global_p1, &local_p1, shipp->model_instance_num, submodel, &objp->orient, &objp->pos);
model_find_world_point(global_p0, &local_p0, modelnum, submodel, &objp->orient, &objp->pos);
model_find_world_point(global_p1, &local_p1, modelnum, submodel, &objp->orient, &objp->pos);
// find the normal of the first dockpoint
model_instance_find_world_dir(global_p0_norm, &pm->docking_bays[dock_index].norm[0], shipp->model_instance_num, submodel, &objp->orient);
model_find_world_dir(global_p0_norm, &pm->docking_bays[dock_index].norm[0], modelnum, submodel, &objp->orient, &objp->pos);
ship_model_stop(objp);
}
// use the static dockpoints
else
@@ -9125,21 +9110,23 @@ float dock_orient_and_approach(object *docker_objp, int docker_index, object *do
vec3d submodel_offset;
vec3d dockpoint_temp;
ship_model_start(dockee_objp);
// get submodel center
model_find_submodel_offset(&submodel_offset, sip1->model_num, dockee_rotating_submodel);
vm_vec_add(&submodel_pos, &dockee_objp->pos, &submodel_offset);
polymodel_instance *pmi1 = model_get_instance(Ships[dockee_objp->instance].model_instance_num);
// get angular velocity of dockpoint
//WMC - hack(?) to fix bug where sii might not exist
if ( pmi1->submodel[dockee_rotating_submodel].sii != NULL ) {
submodel_omega = pmi1->submodel[dockee_rotating_submodel].sii->cur_turn_rate;
if(pm1->submodel[dockee_rotating_submodel].sii != NULL) {
submodel_omega = pm1->submodel[dockee_rotating_submodel].sii->cur_turn_rate;
}
// get radius to dockpoint
vm_vec_avg(&dockpoint_temp, &dockee_p0, &dockee_p1);
submodel_radius = vm_vec_dist(&submodel_pos, &dockpoint_temp);
ship_model_stop(dockee_objp);
}
// Goober5000
@@ -9247,7 +9234,7 @@ float dock_orient_and_approach(object *docker_objp, int docker_index, object *do
vec3d origin_docker_point, adjusted_docker_point, v_offset;
// find out the rotation matrix that will get us from the old to the new rotation
vm_copy_transpose(&temp, &docker_objp->orient);
vm_copy_transpose_matrix(&temp, &docker_objp->orient);
vm_matrix_x_matrix(&m_offset, &temp, &dom);
// now find out the new docker point after being adjusted for the new orientation
@@ -9787,7 +9774,7 @@ float get_cylinder_points(object *other_objp, object *cyl_objp, vec3d *axis_pt,
// get point on axis and on cylinder
// extended_cylinder_z is along extended cylinder
// cylinder_z is capped within cylinder
float extended_cylinder_z = vm_vec_dot(&r_sph, &cyl_objp->orient.vec.fvec);
float extended_cylinder_z = vm_vec_dotprod(&r_sph, &cyl_objp->orient.vec.fvec);
// get pt on axis of extended cylinder
vm_vec_scale_add(axis_pt, &cyl_objp->pos, &cyl_objp->orient.vec.fvec, extended_cylinder_z);
@@ -9823,7 +9810,7 @@ void ai_big_guard()
// get position relative to cylinder of guard_objp
extended_z = get_cylinder_points(Pl_objp, guard_objp, &axis_pt, &r_vec, &radius);
vm_vec_cross(&theta_vec, &guard_objp->orient.vec.fvec, &r_vec);
vm_vec_crossprod(&theta_vec, &guard_objp->orient.vec.fvec, &r_vec);
// half ships circle each way
if (objval > 0.5f) {
@@ -10694,6 +10681,7 @@ void ai_dock()
// This mode means to follow the path until just before the end.
case AIS_DOCK_1:
{
float dist;
int r;
if ((r = maybe_dock_obstructed(Pl_objp, goal_objp, 1)) != -1) {
@@ -10704,7 +10692,7 @@ void ai_dock()
}
} //else {
{
ai_path();
dist = ai_path();
if (aip->path_cur-aip->path_start >= aip->path_length-1) { // If got this far, advance no matter what.
aip->submode = AIS_DOCK_2;
@@ -11835,8 +11823,9 @@ int ai_formation()
} else {
vec3d v2f2;
float dot_to_f2;
float dist_to_f2;
vm_vec_normalized_dir(&v2f2, &future_goal_point_2, &Pl_objp->pos);
dist_to_f2 = vm_vec_normalized_dir(&v2f2, &future_goal_point_2, &Pl_objp->pos);
dot_to_f2 = vm_vec_dot(&v2f2, &Pl_objp->orient.vec.fvec);
// Leader flying like a maniac. Don't try hard to form on wing.
@@ -13648,7 +13637,7 @@ int aas_1(object *objp, ai_info *aip, vec3d *safe_pos)
vec3d vec_from_exp;
float dir = 1.0f;
vm_vec_sub(&vec_from_exp, &objp->pos, &expected_pos);
float dot = vm_vec_dot(&vec_from_exp, &weapon_objp->orient.vec.fvec);
float dot = vm_vec_dotprod(&vec_from_exp, &weapon_objp->orient.vec.fvec);
if (dot > -30) {
// if we're already on the other side of the explosion, don't try to fly behind it
dir = -1.0f;
@@ -13812,22 +13801,18 @@ int ai_await_repair_frame(object *objp, ai_info *aip)
// Maybe should only do this if they are preventing their wing from re-entering.
void ai_maybe_self_destruct(object *objp, ai_info *aip)
{
Assertion(objp->type == OBJ_SHIP, "ai_maybe_self_destruct() can only be called with objects that are ships!");
ship *shipp = &Ships[objp->instance];
// Some IFFs can be repaired, so no self-destruct.
// In multiplayer, just don't self-destruct. I figured there would be a problem. -- MK, 3/19/98.
if ((Iff_info[shipp->team].flags & IFFF_SUPPORT_ALLOWED) || (Game_mode & GM_MULTIPLAYER))
if ((Iff_info[Ships[objp->instance].team].flags & IFFF_SUPPORT_ALLOWED) || (Game_mode & GM_MULTIPLAYER))
return;
// Small ships in a wing blow themselves up after awhile if engine or weapons system has been destroyed.
// Reason: Don't want them to prevent a re-emergence of the wing.
// Note: Don't blow up if not in a wing for two reasons: One, won't affect re-emergence of waves and (1) disable the Dragon
// mission would be broken.
// Also, don't blow up the ship if it has a ship flag preventing this - Goober5000
if ((Ship_info[shipp->ship_info_index].flags & SIF_SMALL_SHIP) && (shipp->wingnum >= 0) && !(shipp->flags2 & SF2_NO_DISABLED_SELF_DESTRUCT)) {
if ((ship_get_subsystem_strength(shipp, SUBSYSTEM_ENGINE) <= 0.0f) ||
(ship_get_subsystem_strength(shipp, SUBSYSTEM_WEAPONS) <= 0.0f)) {
if ((Ship_info[Ships[objp->instance].ship_info_index].flags & SIF_SMALL_SHIP) && (Ships[objp->instance].wingnum != -1)) {
if ((ship_get_subsystem_strength(&Ships[objp->instance], SUBSYSTEM_ENGINE) <= 0.0f) ||
(ship_get_subsystem_strength(&Ships[objp->instance], SUBSYSTEM_WEAPONS) <= 0.0f)) {
if (aip->self_destruct_timestamp < 0)
aip->self_destruct_timestamp = timestamp(90 * 1000); // seconds until self-destruct
} else {
@@ -14099,7 +14084,7 @@ void ai_frame(int objnum)
}
if ((En_objp != NULL) && (En_objp->pos.xyz.x == Pl_objp->pos.xyz.x) && (En_objp->pos.xyz.y == Pl_objp->pos.xyz.y) && (En_objp->pos.xyz.z == Pl_objp->pos.xyz.z)) {
mprintf(("Warning: Object and its enemy have same position. Object #" PTRDIFF_T_ARG "\n", OBJ_INDEX(Pl_objp)));
mprintf(("Warning: Object and its enemy have same position. Object #%i\n", OBJ_INDEX(Pl_objp)));
En_objp = NULL;
}
@@ -14878,7 +14863,7 @@ void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *colli
float max_lethality = 0.0f;
void ai_update_lethality(object *pship_obj, object *other_obj, float damage)
void ai_update_lethality(object *ship_obj, object *other_obj, float damage)
{
// Goober5000 - stop any trickle-down errors from ship_do_damage
Assert(other_obj);
@@ -14887,8 +14872,8 @@ void ai_update_lethality(object *pship_obj, object *other_obj, float damage)
return;
}
Assert(pship_obj); // Goober5000
Assert(pship_obj->type == OBJ_SHIP);
Assert(ship_obj); // Goober5000
Assert(ship_obj->type == OBJ_SHIP);
Assert(other_obj->type == OBJ_WEAPON || other_obj->type == OBJ_SHOCKWAVE);
int dont_count = FALSE;
@@ -14897,7 +14882,7 @@ void ai_update_lethality(object *pship_obj, object *other_obj, float damage)
if (Objects[parent].signature == other_obj->parent_sig) {
// check damage done to enemy team
if (iff_x_attacks_y(Ships[pship_obj->instance].team, Ships[Objects[parent].instance].team)) {
if (iff_x_attacks_y(Ships[ship_obj->instance].team, Ships[Objects[parent].instance].team)) {
// other is weapon
if (other_obj->type == OBJ_WEAPON) {
+15 -20
View File
@@ -11,18 +11,18 @@
#include "ai/aigoals.h"
#include "globalincs/linklist.h"
#include "parse/sexp.h"
#include "mission/missionlog.h"
#include "mission/missionparse.h"
#include "network/multi.h"
#include "network/multimsgs.h"
#include "object/object.h"
#include "object/objectdock.h"
#include "object/waypoint.h"
#include "parse/sexp.h"
#include "globalincs/linklist.h"
#include "playerman/player.h"
#include "network/multimsgs.h"
#include "network/multi.h"
#include "ship/ship.h"
#include "weapon/weapon.h"
#include "object/objectdock.h"
#include "object/waypoint.h"
// all ai goals dealt with in this code are goals that are specified through
@@ -171,7 +171,7 @@ void ai_post_process_mission()
// Goober5000 - MK originally iterated on only the first wing; now we iterate on only the player wing
// because the player wing may not be first
for ( i = 0; i < MAX_STARTING_WINGS; i++ ) {
if (Starting_wings[i] >= 0 && Starting_wings[i] == Player_ship->wingnum) {
if ( Starting_wings[i] == Player_ship->wingnum ) {
wing *wingp;
wingp = &Wings[Starting_wings[i]];
@@ -199,17 +199,12 @@ void ai_post_process_mission()
return;
}
/**
* Determines if a goal is valid for a particular type of ship
*
* @param ship Ship type to test
* @param ai_goal_type Goal type to test
*/
int ai_query_goal_valid( int ship, int ai_goal_type )
// function which determines is a goal is valid for a particular type of ship
int ai_query_goal_valid( int ship, int ai_goal )
{
int accepted;
if (ai_goal_type == AI_GOAL_NONE)
if (ai_goal == AI_GOAL_NONE)
return 1; // anything can have no orders.
accepted = 0;
@@ -219,7 +214,7 @@ int ai_query_goal_valid( int ship, int ai_goal_type )
int ship_type = Ship_info[Ships[ship].ship_info_index].class_type;
if(ship_type > -1)
{
if(ai_goal_type & Ship_types[ship_type].ai_valid_goals) {
if(ai_goal & Ship_types[ship_type].ai_valid_goals) {
accepted = 1;
}
}
@@ -533,7 +528,7 @@ int ai_goal_find_dockpoint(int shipnum, int dock_type)
}
// function to fix up dock point references for objects.
// passed are the pointer to goal we are working with. aip is the ai_info pointer
// passed are the pointer to goal we are working with. aip if the ai_info pointer
// of the ship with the order. aigp is a pointer to the goal (of aip) of which we are
// fixing up the docking points
void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
@@ -542,7 +537,6 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
Assert ( aip->shipnum != -1 );
shipnum = ship_name_lookup( aigp->target_name );
Assertion ( shipnum != -1, "Couldn't find ai goal's target_name (%s); get a coder!\n", aigp->target_name );
docker_index = -1;
dockee_index = -1;
@@ -1888,8 +1882,9 @@ int ai_goal_priority_compare(const void *a, const void *b)
// Prioritize goal list.
// First sort on priority.
// Then sort on time for goals of equivalent priority.
// objnum The object number to act upon. Redundant with *aip.
// *aip The AI info to act upon. Goals are stored at aip->goals
void prioritize_goals(ai_info *aip)
void prioritize_goals(int objnum, ai_info *aip)
{
// First sort based on priority field.
insertion_sort(aip->goals, MAX_AI_GOALS, sizeof(ai_goal), ai_goal_priority_compare);
@@ -2005,7 +2000,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
validate_mission_goals(objnum, aip);
// Sort the goal array by priority and other factors.
prioritize_goals(aip);
prioritize_goals(objnum, aip);
// Make sure there's a goal to pursue, else return.
if (aip->goals[0].signature == -1) {
+1 -1
View File
@@ -121,7 +121,7 @@ extern void ai_update_goal_references(ai_goal *goals, int type, const char *old_
extern int query_referenced_in_ai_goals(ai_goal *goals, int type, const char *name);
extern char *ai_add_dock_name(const char *str);
extern int ai_query_goal_valid( int ship, int ai_goal_type );
extern int ai_query_goal_valid( int ship, int ai_goal );
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
extern void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate = 1 );
-3
View File
@@ -10,9 +10,6 @@
#ifndef _AIINTERNAL_H
#define _AIINTERNAL_H
#include "ship/ship.h"
#include "weapon/weapon.h"
//Returns true if the specified object is a stealth ship, false if not
bool is_object_stealth_ship(object* objp);
+16
View File
@@ -0,0 +1,16 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#ifndef _AILOCAL_H
#define _AILOCAL_H
// -- Don't put anything in here --
// Put it in ai.h!
#endif
+28 -194
View File
@@ -1,28 +1,28 @@
#include "ai/aibig.h"
#include "ai/aiinternal.h"
#include "asteroid/asteroid.h"
#include "debugconsole/console.h"
#include "freespace2/freespace.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/linklist.h"
#include "globalincs/systemvars.h"
#include "iff_defs/iff_defs.h"
#include "ship/ship.h"
#include "weapon/weapon.h"
#include "freespace2/freespace.h"
#include "asteroid/asteroid.h"
#include "globalincs/linklist.h"
#include "weapon/beam.h"
#include "weapon/swarm.h"
#include "io/timer.h"
#include "render/3d.h"
#include "gamesnd/gamesnd.h"
#include "ship/shipfx.h"
#include "network/multimsgs.h"
#include "weapon/flak.h"
#include "math/staticrand.h"
#include "network/multi.h"
#include "network/multimsgs.h"
#include "ai/aibig.h"
#include "object/objectdock.h"
#include "parse/scripting.h"
#include "render/3d.h"
#include "ship/ship.h"
#include "ship/shipfx.h"
#include "weapon/beam.h"
#include "weapon/flak.h"
#include "ai/aiinternal.h" //Included last, so less includes are needed
#include "iff_defs/iff_defs.h"
#include "weapon/muzzleflash.h"
#include "weapon/swarm.h"
#include "weapon/weapon.h"
#include "parse/scripting.h"
#include "debugconsole/console.h"
#include <limits.h>
@@ -1308,8 +1308,6 @@ void ship_get_global_turret_info(object *objp, model_subsystem *tp, vec3d *gpos,
vm_vec_unrotate(gvec, &tp->turret_norm, &objp->orient);
}
void turret_ai_update_aim(ai_info *aip, object *En_Objp, ship_subsys *ss);
/**
* Given an object and a turret on that object, return the actual firing point of the gun and its normal.
*
@@ -1334,59 +1332,11 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
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, Ships[objp->instance].model_instance_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);
if (use_angles) {
model_instance_find_world_dir(gvec, &tp->turret_norm, Ships[objp->instance].model_instance_num, tp->turret_gun_sobj, &objp->orient);
} else if (tp->flags2 & MSS_FLAG2_SHARE_FIRE_DIRECTION) {
vec3d avg, tmp_pos, tmp_target, enemy_point, turret_norm;
vm_vec_avg_n(&avg, tp->turret_num_firing_points, tp->turret_firing_point);
model_instance_find_world_point(&tmp_pos, &avg, Ships[objp->instance].model_instance_num, tp->turret_gun_sobj, &objp->orient, &objp->pos);
if (targetp == nullptr) {
Assertion(ssp->turret_enemy_objnum >= 0, "The turret enemy object number %d for %s on ship number %d is invalid.", ssp->turret_enemy_objnum, ssp->sub_name, ssp->parent_objnum);
object *lep = &Objects[ssp->turret_enemy_objnum];
int best_weapon_tidx = turret_select_best_weapon(ssp, lep);
//This turret doesn't have any good weapons
if (best_weapon_tidx < 0)
return;
weapon_info *wip = get_turret_weapon_wip(&ssp->weapons, best_weapon_tidx);
float weapon_system_strength = ship_get_subsystem_strength(&Ships[ssp->parent_objnum], SUBSYSTEM_WEAPONS);
turret_ai_update_aim(&Ai_info[Ships[ssp->parent_objnum].ai_index], &Objects[ssp->turret_enemy_objnum], ssp);
if ((ssp->targeted_subsys != nullptr) && !(ssp->flags & SSF_NO_SS_TARGETING)) {
vm_vec_unrotate(&enemy_point, &ssp->targeted_subsys->system_info->pnt, &Objects[ssp->turret_enemy_objnum].orient);
vm_vec_add2(&enemy_point, &ssp->last_aim_enemy_pos);
} else {
if ((lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
vm_vec_unrotate(&turret_norm, &tp->turret_norm, &objp->orient);
ai_big_pick_attack_point_turret(lep, ssp, &tmp_pos, &turret_norm, &enemy_point, MIN(wip->max_speed * wip->lifetime, wip->weapon_range), tp->turret_fov);
}
else {
enemy_point = ssp->last_aim_enemy_pos;
}
}
vec3d target_moving_direction = ssp->last_aim_enemy_vel;
//Try to guess where the enemy will be, and store that spot in predicted_enemy_pos
if (The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY) {
vm_vec_scale_sub2(&target_moving_direction, &objp->phys_info.vel, wip->vel_inherit_amount);
}
set_predicted_enemy_pos_turret(&tmp_target, &tmp_pos, objp, &enemy_point, &target_moving_direction, wip->max_speed, ssp->turret_time_enemy_in_range * (weapon_system_strength + 1.0f) / 2.0f);
} else {
tmp_target = *targetp;
}
vm_vec_normalized_dir(gvec, &tmp_target, &tmp_pos);
} else {
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 );
else {
//vector gun_pos2;
//vm_vec_add(&gun_pos2, gpos, gun_pos);
vm_vec_normalized_dir(gvec, targetp, gpos);
@@ -1427,7 +1377,7 @@ void turret_ai_update_aim(ai_info *aip, object *En_Objp, ship_subsys *ss)
*/
int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object *objp, object *lep, vec3d *predicted_enemy_pos, vec3d *gvec)
{
int ret_val __UNUSED = 0; // to be used in future, see comment @ end of function
int ret_val __attribute__((__unused__)) = 0; // to be used in future, see comment @ end of function
if (ss->turret_enemy_objnum != -1) {
model_subsystem *tp = ss->system_info;
@@ -1920,129 +1870,21 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
fire_info.turret = turret;
// fire a beam weapon
weapon_objnum = beam_fire(&fire_info);
if (weapon_objnum != -1) {
objp = &Objects[weapon_objnum];
parent_ship->last_fired_turret = turret;
turret->last_fired_weapon_info_index = turret_weapon_class;
Script_system.SetHookObjects(4, "Ship", &Objects[parent_objnum], "Weapon", nullptr, "Beam", objp, "Target", &Objects[turret->turret_enemy_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[parent_objnum]);
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
}
beam_fire(&fire_info);
turret->flags |= SSF_HAS_FIRED; //set fired flag for scripting -nike
return true;
}
// don't fire swam, but set up swarm info instead
else if ((wip->wi_flags & WIF_SWARM) || (wip->wi_flags & WIF_CORKSCREW)) {
ship_weapon *swp = &turret->weapons;
if (swp->current_secondary_bank < 0) {
swp->current_secondary_bank = 0;
}
int bank_to_fire = swp->current_secondary_bank;
if ((turret->system_info->flags2 & MSS_FLAG2_TURRET_USE_AMMO) && (swp->secondary_bank_ammo[bank_to_fire] < 0)) {
if (!(turret->system_info->flags & MSS_FLAG_USE_MULTIPLE_GUNS)) {
swp->current_secondary_bank++;
if (swp->current_secondary_bank >= swp->num_secondary_banks) {
swp->current_secondary_bank = 0;
}
return false;
} else {
return false;
}
} else {
turret_swarm_set_up_info(parent_objnum, turret, wip, turret->turret_next_fire_pos);
turret_swarm_set_up_info(parent_objnum, turret, wip, turret->turret_next_fire_pos);
turret->flags |= SSF_HAS_FIRED; //set fired flag for scripting -nike
return true;
}
turret->flags |= SSF_HAS_FIRED; //set fired flag for scripting -nike
return true;
}
// now do anything else
else {
for (int i = 0; i < wip->shots; i++) {
if (turret->system_info->flags2 & MSS_FLAG2_TURRET_USE_AMMO) {
ship_weapon *swp;
swp = &turret->weapons;
int bank_to_fire, num_slots = turret->system_info->turret_num_firing_points;
if (wip->subtype == WP_LASER) {
int points;
if (swp->num_primary_banks <= 0) {
return false;
}
if (swp->current_primary_bank < 0){
swp->current_primary_bank = 0;
return false;
}
int num_primary_banks = swp->num_primary_banks;
Assert(num_primary_banks > 0);
if (num_primary_banks < 1){
return false;
}
bank_to_fire = swp->current_primary_bank;
if (turret->system_info->flags & MSS_FLAG_TURRET_SALVO) {
points = num_slots;
} else {
points = 1;
}
if (swp->primary_bank_ammo[bank_to_fire] >= 0) {
swp->primary_bank_ammo[bank_to_fire] -= points;
} else if (!(turret->system_info->flags & MSS_FLAG_USE_MULTIPLE_GUNS) && (swp->primary_bank_ammo[bank_to_fire] < 0)) {
swp->current_primary_bank++;
if (swp->current_primary_bank >= swp->num_primary_banks) {
swp->current_primary_bank = 0;
}
return false;
} else {
return false;
}
}
else if (wip->subtype == WP_MISSILE) {
if (swp->num_secondary_banks <= 0) {
return false;
}
if (swp->current_secondary_bank < 0){
swp->current_secondary_bank = 0;
return false;
}
bank_to_fire = swp->current_secondary_bank;
int start_slot, end_slot;
start_slot = swp->secondary_next_slot[bank_to_fire];
end_slot = start_slot;
for (int j = start_slot; j <= end_slot; j++) {
swp->secondary_next_slot[bank_to_fire]++;
if (swp->secondary_next_slot[bank_to_fire] > (num_slots - 1)){
swp->secondary_next_slot[bank_to_fire] = 0;
}
if (swp->secondary_bank_ammo[bank_to_fire] >= 0) {
swp->secondary_bank_ammo[bank_to_fire]--;
} else if (!(turret->system_info->flags & MSS_FLAG_USE_MULTIPLE_GUNS) && (swp->secondary_bank_ammo[bank_to_fire] < 0)) {
swp->current_secondary_bank++;
if (swp->current_secondary_bank >= swp->num_secondary_banks) {
swp->current_secondary_bank = 0;
}
return false;
} else {
return false;
}
}
}
}
// 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);
@@ -2063,9 +1905,8 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
// AL 1-6-97: Store pointer to turret subsystem
wp->turret_subsys = turret;
Script_system.SetHookObjects(4, "Ship", &Objects[parent_objnum], "Weapon", objp, "Beam", nullptr, "Target", &Objects[turret->turret_enemy_objnum]);
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]);
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
// if the gun is a flak gun
if (wip->wi_flags & WIF_FLAK) {
@@ -2177,13 +2018,6 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
Weapons[Objects[weapon_objnum].instance].turret_subsys = tsi->turret;
Weapons[Objects[weapon_objnum].instance].target_num = tsi->turret->turret_enemy_objnum;
Ships[Objects[tsi->parent_objnum].instance].last_fired_turret = tsi->turret;
tsi->turret->last_fired_weapon_info_index = tsi->weapon_class;
Script_system.SetHookObjects(4, "Ship", &Objects[tsi->parent_objnum], "Weapon", &Objects[weapon_objnum], "Beam", nullptr, "Target", &Objects[tsi->turret->turret_enemy_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[tsi->parent_objnum]);
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
// muzzle flash?
if (Weapon_info[tsi->weapon_class].muzzle_flash >= 0) {
mflash_create(&turret_pos, &turret_fvec, &Objects[tsi->parent_objnum].phys_info, Weapon_info[tsi->weapon_class].muzzle_flash);
@@ -2629,7 +2463,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
ss->turret_next_fire_pos = ffp_pos;
}
ship_get_global_turret_gun_info(&Objects[parent_objnum], ss, &gpos, &gvec, use_angles, &predicted_enemy_pos);
ship_get_global_turret_gun_info(&Objects[parent_objnum], ss, &gpos, &gvec, use_angles, &predicted_enemy_pos);
// Fire in the direction the turret is facing, not right at the target regardless of turret dir.
vm_vec_sub(&v2e, &predicted_enemy_pos, &gpos);
+10 -7
View File
@@ -10,15 +10,15 @@
#include "anim/animplay.h"
#include "anim/packunpack.h"
#include "globalincs/linklist.h"
#include "io/timer.h"
#include "bmpman/bmpman.h"
#include "graphics/2d.h"
#include "render/3d.h"
#include "pcxutils/pcxutils.h"
#include "anim/packunpack.h"
#include "cfile/cfile.h"
#include "cmdline/cmdline.h"
#include "globalincs/linklist.h"
#include "graphics/2d.h"
#include "io/timer.h"
#include "pcxutils/pcxutils.h"
#include "render/3d.h"
@@ -254,7 +254,7 @@ anim_instance *anim_play(anim_play_struct *aps)
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, time;
float percent_through, decompress_time, render_time, time;
vertex image_vertex;
int aabitmap = 0;
int bpp = 16;
@@ -461,6 +461,8 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
instance->file_offset = instance->parent->file_offset;
instance->loop_count++;
}
decompress_time = f2fl(t2-t1);
t1 = timer_get_fixed_seconds();
if ( frame_diff == 0 && instance->last_bitmap != -1 ) {
@@ -512,6 +514,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
}
t2 = timer_get_fixed_seconds();
render_time = f2fl(t2-t1);
return 0;
}
+1 -1
View File
@@ -12,8 +12,8 @@
#ifndef __ANIMPLAY_H__
#define __ANIMPLAY_H__
#include "cfile/cfile.h"
#include "globalincs/pstypes.h"
#include "cfile/cfile.h"
struct anim;
struct anim_info;
+1 -1
View File
@@ -9,10 +9,10 @@
#include "anim/animplay.h"
#include "anim/packunpack.h"
#include "bmpman/bmpman.h"
#include "graphics/2d.h"
#include "anim/animplay.h"
const int packer_code = PACKER_CODE;
+224 -262
View File
@@ -10,39 +10,39 @@
#include "asteroid/asteroid.h"
#include "debugconsole/console.h"
#include "fireball/fireballs.h"
#include "object/object.h"
#include "object/objcollide.h"
#include "freespace2/freespace.h"
#include "io/timer.h"
#include "render/3d.h"
#include "fireball/fireballs.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/compatibility.h"
#include "particle/particle.h"
#include "globalincs/linklist.h"
#include "globalincs/systemvars.h"
#include "hud/hud.h"
#include "hud/hudescort.h"
#include "hud/hudgauges.h"
#include "hud/hudtarget.h"
#include "iff_defs/iff_defs.h"
#include "io/timer.h"
#include "localization/localize.h"
#include "ship/shiphit.h"
#include "math/staticrand.h"
#include "globalincs/systemvars.h"
#include "localization/localize.h"
#include "stats/scoring.h"
#include "hud/hudtarget.h"
#include "weapon/weapon.h"
#include "ship/ship.h"
#include "parse/parselo.h"
#include "math/vecmat.h"
#include "model/model.h"
#include "network/multi.h"
#include "network/multimsgs.h"
#include "network/multiutil.h"
#include "object/objcollide.h"
#include "object/object.h"
#include "parse/parselo.h"
#include "parse/scripting.h"
#include "particle/particle.h"
#include "render/3d.h"
#include "ship/ship.h"
#include "ship/shiphit.h"
#include "species_defs/species_defs.h"
#include "stats/scoring.h"
#include "weapon/weapon.h"
#include "iff_defs/iff_defs.h"
#include "network/multiutil.h"
#include "network/multimsgs.h"
#include "network/multi.h"
#include "parse/scripting.h"
#include "debugconsole/console.h"
#include <algorithm>
#include "globalincs/compatibility.h"
#define ASTEROID_OBJ_USED (1<<0) // flag used in asteroid_obj struct
#define MAX_ASTEROID_OBJS MAX_ASTEROIDS // max number of asteroids tracked in asteroid list
@@ -329,11 +329,6 @@ object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int asteroi
}
asp->objnum = objnum;
asp->model_instance_num = -1;
if (model_get(asip->model_num[asteroid_subtype])->flags & PM_FLAG_HAS_INTRINSIC_ROTATE) {
asp->model_instance_num = model_create_instance(false, asip->model_num[asteroid_subtype]);
}
// Add to Asteroid_used_list
asteroid_obj_list_add(objnum);
@@ -833,12 +828,10 @@ void asteroid_delete( object * obj )
asp = &Asteroids[num];
if (asp->model_instance_num >= 0)
model_delete_instance(asp->model_instance_num);
Assert( Num_asteroids >= 0 );
asp->flags = 0;
Num_asteroids--;
Assert(Num_asteroids >= 0);
asteroid_obj_list_remove( obj );
}
@@ -905,7 +898,7 @@ void lerp(float *goal, float f1, float f2, float scale)
*goal = (f2 - f1) * scale + f1;
}
void asteroid_process_pre( object *objp )
void asteroid_process_pre( object *objp, float frame_time)
{
if (Asteroids_enabled) {
// Make vel chase desired_vel
@@ -937,7 +930,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
if ( asteroid_hit_info == NULL ) {
// asteroid weapon collision
Assert( other_obj->type == OBJ_WEAPON );
mc.model_instance_num = Asteroids[num].model_instance_num;
mc.model_instance_num = -1;
mc.model_num = Asteroid_info[Asteroids[num].asteroid_type].model_num[asteroid_subtype]; // Fill in the model to check
model_clear_instance( mc.model_num );
mc.orient = &pasteroid->orient; // The object's orient
@@ -953,18 +946,18 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
}
// asteroid ship collision -- use asteroid_hit_info to calculate physics
object *pship_obj = other_obj;
Assert( pship_obj->type == OBJ_SHIP );
object *ship_obj = other_obj;
Assert( ship_obj->type == OBJ_SHIP );
object* heavy = asteroid_hit_info->heavy;
object* lighter = asteroid_hit_info->light;
object* light = asteroid_hit_info->light;
object *heavy_obj = heavy;
object *light_obj = lighter;
object *light_obj = light;
vec3d zero, p0, p1;
vm_vec_zero( &zero );
vm_vec_sub( &p0, &lighter->last_pos, &heavy->last_pos );
vm_vec_sub( &p1, &lighter->pos, &heavy->pos );
vm_vec_sub( &p0, &light->last_pos, &heavy->last_pos );
vm_vec_sub( &p1, &light->pos, &heavy->pos );
mc.pos = &zero; // The object's position
mc.p0 = &p0; // Point 1 of ray to check
@@ -986,19 +979,19 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
// HACK - this applies to big ships warping in/out of asteroid fields - not sure what it does
if (vm_vec_mag(&asteroid_hit_info->light_rel_vel) > 300) {
asteroid_hit_info->collide_rotate = 0;
vm_vec_sub( &asteroid_hit_info->light_rel_vel, &lighter->phys_info.vel, &heavy->phys_info.vel );
vm_vec_sub( &asteroid_hit_info->light_rel_vel, &light->phys_info.vel, &heavy->phys_info.vel );
}
} else {
asteroid_hit_info->collide_rotate = 0;
vm_vec_sub( &asteroid_hit_info->light_rel_vel, &lighter->phys_info.vel, &heavy->phys_info.vel );
vm_vec_sub( &asteroid_hit_info->light_rel_vel, &light->phys_info.vel, &heavy->phys_info.vel );
}
int mc_ret_val = 0;
if ( asteroid_hit_info->heavy == pship_obj ) { // ship is heavier, so asteroid is sphere. Check sphere collision against ship poly model
mc.model_instance_num = Ships[pship_obj->instance].model_instance_num;
mc.model_num = Ship_info[Ships[pship_obj->instance].ship_info_index].model_num; // Fill in the model to check
mc.orient = &pship_obj->orient; // The object's orient
if ( asteroid_hit_info->heavy == ship_obj ) { // ship is heavier, so asteroid 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 = pasteroid->radius;
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
@@ -1012,6 +1005,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE;
SCP_vector<int> submodel_vector;
polymodel *pm;
polymodel_instance *pmi;
if (model_collide(&mc)) {
@@ -1025,7 +1019,8 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
model_get_rotating_submodel_list(&submodel_vector, heavy_obj);
// Get polymodel and turn off all rotating submodels, collide against only 1 at a time.
pmi = model_get_instance(Ships[heavy_obj->instance].model_instance_num);
pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num);
pmi = model_get_instance(Ships[ship_obj->instance].model_instance_num);
// turn off all rotating submodels and test for collision
for (size_t j=0; j<submodel_vector.size(); j++) {
@@ -1046,10 +1041,10 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
// find the start and end positions of the sphere in submodel RF
pmi->submodel[submodel_vector[i]].angs = pmi->submodel[submodel_vector[i]].prev_angs;
world_find_model_instance_point(&p0, &light_obj->last_pos, pmi, submodel_vector[i], &heavy_obj->last_orient, &heavy_obj->last_pos);
world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_vector[i], &heavy_obj->last_orient, &heavy_obj->last_pos);
pmi->submodel[submodel_vector[i]].angs = copy_angles;
world_find_model_instance_point(&p1, &light_obj->pos, pmi, submodel_vector[i], &heavy_obj->orient, &heavy_obj->pos);
world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_vector[i], &heavy_obj->orient, &heavy_obj->pos);
mc.p0 = &p0;
mc.p1 = &p1;
@@ -1066,14 +1061,14 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
// set up asteroid_hit_info for rotating submodel
if (asteroid_hit_info->edge_hit == 0) {
model_instance_find_obj_dir(&asteroid_hit_info->collision_normal, &mc.hit_normal, Ships[heavy_obj->instance].model_instance_num, mc.hit_submodel, &heavy_obj->orient);
model_instance_find_obj_dir(&asteroid_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(&asteroid_hit_info->light_collision_cm_pos, &int_light_pos, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
model_instance_find_world_point(&asteroid_hit_info->light_collision_cm_pos, &int_light_pos, mc.model_num, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
}
}
// Don't look at this submodel again
@@ -1098,7 +1093,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
// get collision normal if not edge hit
if (asteroid_hit_info->edge_hit == 0) {
model_instance_find_obj_dir(&asteroid_hit_info->collision_normal, &mc.hit_normal, Ships[heavy_obj->instance].model_instance_num, mc.hit_submodel, &heavy_obj->orient);
model_instance_find_obj_dir(&asteroid_hit_info->collision_normal, &mc.hit_normal, heavy_obj, mc.hit_submodel);
}
// find position in submodel RF of light object at collison
@@ -1112,11 +1107,11 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
} else {
// Asteroid is heavier obj
mc.model_instance_num = Asteroids[num].model_instance_num;
mc.model_instance_num = -1;
mc.model_num = Asteroid_info[Asteroids[num].asteroid_type].model_num[asteroid_subtype]; // Fill in the model to check
model_clear_instance( mc.model_num );
mc.orient = &pasteroid->orient; // The object's orient
mc.radius = model_get_core_radius(Ship_info[Ships[pship_obj->instance].ship_info_index].model_num);
mc.radius = model_get_core_radius(Ship_info[Ships[ship_obj->instance].ship_info_index].model_num);
// check for collision between asteroid model and ship sphere
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
@@ -1167,7 +1162,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
}
}
void asteroid_render_DEPRECATED(object * obj)
void asteroid_render(object * obj)
{
if (Asteroids_enabled) {
int num;
@@ -1181,32 +1176,7 @@ void asteroid_render_DEPRECATED(object * obj)
Assert( asp->flags & AF_USED );
model_clear_instance( Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype]);
model_render_DEPRECATED(Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype], &obj->orient, &obj->pos, MR_DEPRECATED_NORMAL|MR_DEPRECATED_IS_ASTEROID, OBJ_INDEX(obj) ); // Replace MR_NORMAL with 0x07 for big yellow blobs
}
}
void asteroid_render(object * obj, draw_list *scene)
{
if (Asteroids_enabled) {
int num;
asteroid *asp;
num = obj->instance;
Assert((num >= 0) && (num < MAX_ASTEROIDS));
asp = &Asteroids[num];
Assert( asp->flags & AF_USED );
model_clear_instance( Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype]);
model_render_params render_info;
render_info.set_object_number( OBJ_INDEX(obj) );
render_info.set_flags(MR_IS_ASTEROID);
model_render_queue(&render_info, scene, Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype], &obj->orient, &obj->pos); // Replace MR_NORMAL with 0x07 for big yellow blobs
model_render(Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype], &obj->orient, &obj->pos, MR_NORMAL|MR_IS_ASTEROID, OBJ_INDEX(obj) ); // Replace MR_NORMAL with 0x07 for big yellow blobs
}
}
@@ -1360,42 +1330,42 @@ void asteroid_do_area_effect(object *asteroid_objp)
/**
* Upon asteroid asteroid_obj being hit. Apply damage and maybe make it break into smaller asteroids.
*
* @param pasteroid_obj pointer to asteroid object getting hit
* @param asteroid_obj pointer to asteroid object getting hit
* @param other_obj object that hit asteroid, can be NULL if asteroid hit by area effect
* @param hitpos world position asteroid was hit, can be NULL if hit by area effect
* @param damage amount of damage to apply to asteroid
*/
void asteroid_hit( object * pasteroid_obj, object * other_obj, vec3d * hitpos, float damage )
void asteroid_hit( object * asteroid_obj, object * other_obj, vec3d * hitpos, float damage )
{
float explosion_life;
asteroid *asp;
asp = &Asteroids[pasteroid_obj->instance];
asp = &Asteroids[asteroid_obj->instance];
if (pasteroid_obj->flags & OF_SHOULD_BE_DEAD){
if (asteroid_obj->flags & OF_SHOULD_BE_DEAD){
return;
}
if ( MULTIPLAYER_MASTER ){
send_asteroid_hit( pasteroid_obj, other_obj, hitpos, damage );
send_asteroid_hit( asteroid_obj, other_obj, hitpos, damage );
}
pasteroid_obj->hull_strength -= damage;
asteroid_obj->hull_strength -= damage;
if (pasteroid_obj->hull_strength < 0.0f) {
if (asteroid_obj->hull_strength < 0.0f) {
if ( asp->final_death_time <= 0 ) {
int play_loud_collision = 0;
explosion_life = asteroid_create_explosion(pasteroid_obj);
explosion_life = asteroid_create_explosion(asteroid_obj);
asteriod_explode_sound(pasteroid_obj, asp->asteroid_type, play_loud_collision);
asteroid_do_area_effect(pasteroid_obj);
asteriod_explode_sound(asteroid_obj, asp->asteroid_type, play_loud_collision);
asteroid_do_area_effect(asteroid_obj);
asp->final_death_time = timestamp( fl2i(explosion_life*1000.0f)/5 ); // Wait till 30% of vclip time before breaking the asteroid up.
if ( hitpos ) {
asp->death_hit_pos = *hitpos;
} else {
asp->death_hit_pos = pasteroid_obj->pos;
asp->death_hit_pos = asteroid_obj->pos;
// randomize hit pos a bit, otherwise we will get a NULL vector when trying to find direction to toss child asteroids
vec3d rand_vec;
vm_vec_rand_vec_quick(&rand_vec);
@@ -1414,7 +1384,7 @@ void asteroid_hit( object * pasteroid_obj, object * other_obj, vec3d * hitpos, f
}
// evaluate any relevant player scoring implications
scoring_eval_hit(pasteroid_obj,other_obj);
scoring_eval_hit(asteroid_obj,other_obj);
}
/**
@@ -1479,21 +1449,21 @@ int asteroid_count()
* See if asteroid should split up.
* We delay splitting up to allow the explosion animation to play for a bit.
*/
void asteroid_maybe_break_up(object *pasteroid_obj)
void asteroid_maybe_break_up(object *asteroid_obj)
{
asteroid *asp;
asteroid_info *asip;
asp = &Asteroids[pasteroid_obj->instance];
asp = &Asteroids[asteroid_obj->instance];
asip = &Asteroid_info[asp->asteroid_type];
if ( timestamp_elapsed(asp->final_death_time) ) {
vec3d relvec, vfh, tvec;
Script_system.SetHookObject("Self", pasteroid_obj);
if(!Script_system.IsConditionOverride(CHA_DEATH, pasteroid_obj))
Script_system.SetHookObject("Self", asteroid_obj);
if(!Script_system.IsConditionOverride(CHA_DEATH, asteroid_obj))
{
pasteroid_obj->flags |= OF_SHOULD_BE_DEAD;
asteroid_obj->flags |= OF_SHOULD_BE_DEAD;
// multiplayer clients won't go through the following code. asteroid_sub_create will send
// a create packet to the client in the above named function
@@ -1504,29 +1474,29 @@ void asteroid_maybe_break_up(object *pasteroid_obj)
case ASTEROID_TYPE_SMALL:
break;
case ASTEROID_TYPE_MEDIUM:
asc_get_relvec(&relvec, pasteroid_obj, &asp->death_hit_pos);
asteroid_sub_create(pasteroid_obj, ASTEROID_TYPE_SMALL, &relvec);
asc_get_relvec(&relvec, asteroid_obj, &asp->death_hit_pos);
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &relvec);
vm_vec_normalized_dir(&vfh, &pasteroid_obj->pos, &asp->death_hit_pos);
vm_vec_normalized_dir(&vfh, &asteroid_obj->pos, &asp->death_hit_pos);
vm_vec_copy_scale(&tvec, &vfh, 2.0f);
vm_vec_sub2(&tvec, &relvec);
asteroid_sub_create(pasteroid_obj, ASTEROID_TYPE_SMALL, &tvec);
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &tvec);
break;
case ASTEROID_TYPE_LARGE:
asc_get_relvec(&relvec, pasteroid_obj, &asp->death_hit_pos);
asteroid_sub_create(pasteroid_obj, ASTEROID_TYPE_MEDIUM, &relvec);
asc_get_relvec(&relvec, asteroid_obj, &asp->death_hit_pos);
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_MEDIUM, &relvec);
vm_vec_normalized_dir(&vfh, &pasteroid_obj->pos, &asp->death_hit_pos);
vm_vec_normalized_dir(&vfh, &asteroid_obj->pos, &asp->death_hit_pos);
vm_vec_copy_scale(&tvec, &vfh, 2.0f);
vm_vec_sub2(&tvec, &relvec);
asteroid_sub_create(pasteroid_obj, ASTEROID_TYPE_MEDIUM, &tvec);
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_MEDIUM, &tvec);
while (frand() > 0.6f) {
vec3d rvec, tvec2;
vm_vec_rand_vec_quick(&rvec);
vm_vec_scale_add(&tvec2, &vfh, &rvec, 0.75f);
asteroid_sub_create(pasteroid_obj, ASTEROID_TYPE_SMALL, &tvec2);
asteroid_sub_create(asteroid_obj, ASTEROID_TYPE_SMALL, &tvec2);
}
break;
@@ -1575,24 +1545,24 @@ void asteroid_maybe_break_up(object *pasteroid_obj)
vm_vec_random_cone(&dir_vec, &tempv, (360.0f / total_roids / 2));
// Make the roid inherit half of the parent's velocity
vm_vec_copy_normalize(&parent_vel, &pasteroid_obj->phys_info.vel);
vm_vec_copy_normalize(&parent_vel, &asteroid_obj->phys_info.vel);
vm_vec_scale(&parent_vel, 0.5f);
// Make the hit position affect the direction, but only a little
vm_vec_sub(&hit_rel_vec, &pasteroid_obj->pos, &asp->death_hit_pos);
vm_vec_sub(&hit_rel_vec, &asteroid_obj->pos, &asp->death_hit_pos);
vm_vec_normalize(&hit_rel_vec);
vm_vec_scale(&hit_rel_vec, 0.25f);
vm_vec_avg3(&final_vec, &parent_vel, &hit_rel_vec, &dir_vec);
vm_vec_normalize(&final_vec);
asteroid_sub_create(pasteroid_obj, roids_to_create[i], &final_vec);
asteroid_sub_create(asteroid_obj, roids_to_create[i], &final_vec);
}
}
}
asp->final_death_time = timestamp(-1);
}
Script_system.RunCondition(CHA_DEATH, '\0', NULL, pasteroid_obj);
Script_system.RunCondition(CHA_DEATH, '\0', NULL, asteroid_obj);
Script_system.RemHookVar("Self");
}
}
@@ -1616,36 +1586,36 @@ int asteroid_get_random_in_cone(vec3d *pos, vec3d *dir, float ang, int danger)
return -1;
}
void asteroid_test_collide(object *pasteroid_obj, object *pship_obj, mc_info *mc, bool lazy = false)
void asteroid_test_collide(object *asteroid_obj, object *ship_obj, mc_info *mc, bool lazy = false)
{
float asteroid_ray_dist;
vec3d asteroid_fvec, terminus;
// See if ray from asteroid intersects bounding box of escort ship
asteroid_ray_dist = vm_vec_mag_quick(&pasteroid_obj->phys_info.desired_vel) * ASTEROID_MIN_COLLIDE_TIME;
asteroid_fvec = pasteroid_obj->phys_info.desired_vel;
asteroid_ray_dist = vm_vec_mag_quick(&asteroid_obj->phys_info.desired_vel) * ASTEROID_MIN_COLLIDE_TIME;
asteroid_fvec = asteroid_obj->phys_info.desired_vel;
if(IS_VEC_NULL_SQ_SAFE(&asteroid_fvec)){
terminus = pasteroid_obj->pos;
terminus = asteroid_obj->pos;
} else {
vm_vec_normalize(&asteroid_fvec);
vm_vec_scale_add(&terminus, &pasteroid_obj->pos, &asteroid_fvec, asteroid_ray_dist);
vm_vec_scale_add(&terminus, &asteroid_obj->pos, &asteroid_fvec, asteroid_ray_dist);
}
Assert(pship_obj->type == OBJ_SHIP);
Assert(ship_obj->type == OBJ_SHIP);
mc->model_instance_num = Ships[pship_obj->instance].model_instance_num;
mc->model_num = Ship_info[Ships[pship_obj->instance].ship_info_index].model_num; // Fill in the model to check
mc->orient = &pship_obj->orient; // The object's orientation
mc->pos = &pship_obj->pos; // The object's position
mc->p0 = &pasteroid_obj->pos; // Point 1 of ray to check
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 orientation
mc->pos = &ship_obj->pos; // The object's position
mc->p0 = &asteroid_obj->pos; // Point 1 of ray to check
mc->p1 = &terminus; // Point 2 of ray to check
if (lazy) {
mc->flags = MC_CHECK_MODEL | MC_ONLY_BOUND_BOX;
} else {
mc->flags = MC_CHECK_MODEL | MC_CHECK_SPHERELINE;
}
mc->radius = pasteroid_obj->radius;
mc->radius = asteroid_obj->radius;
model_collide(mc);
@@ -1653,17 +1623,14 @@ void asteroid_test_collide(object *pasteroid_obj, object *pship_obj, mc_info *mc
mc->p1 = NULL;
}
/**
* Test if asteroid will collide with escort ship within ASTEROID_MIN_COLLIDE_TIME seconds
*
* @return !0 if the asteroid will collide with the escort
*/
int asteroid_will_collide(object *pasteroid_obj, object *escort_objp)
// Return !0 is the asteroid will collide with the escort ship within ASTEROID_MIN_COLLIDE_TIME
// seconds
int asteroid_will_collide(object *asteroid_obj, object *escort_objp)
{
mc_info mc;
mc_info_init(&mc);
asteroid_test_collide(pasteroid_obj, escort_objp, &mc);
asteroid_test_collide(asteroid_obj, escort_objp, &mc);
if ( !mc.num_hits ) {
return 0;
@@ -1747,7 +1714,7 @@ void asteroid_verify_collide_objnum(asteroid *asp)
}
}
void asteroid_process_post(object * obj)
void asteroid_process_post(object * obj, float frame_time)
{
if (Asteroids_enabled) {
int num;
@@ -1920,149 +1887,144 @@ that is being protected.
void asteroid_parse_tbl()
{
char impact_ani_file[MAX_FILENAME_LEN];
int rval;
// How did we get here without having any species defined?
Assertion(Species_info.size() > 0,
"Cannot parse asteroids/debris if there "
"are no species for them to belong to."
);
try
{
read_file_text("asteroid.tbl", CF_TYPE_TABLES);
reset_parse();
required_string("#Asteroid Types");
int tally = 0;
int max_asteroids =
NUM_DEBRIS_SIZES + Species_info.size() * NUM_DEBRIS_SIZES;
#ifndef NDEBUG
SCP_vector<SCP_string> parsed_asteroids;
#endif
// parse and tally each asteroid
while (required_string_either("#End", "$Name:"))
{
asteroid_info new_asteroid;
asteroid_parse_section(&new_asteroid);
int species = tally / NUM_DEBRIS_SIZES;
if (tally >= max_asteroids)
{
#ifdef NDEBUG
// Bump the warning count in release so they get something
// even if the message never gets displayed.
Warning(LOCATION, "Ignoring extra asteroid/debris");
#else
SCP_string msg("Ignoring extra asteroid/debris '");
msg.append(new_asteroid.name);
msg.append("'\n");
Warning(LOCATION, "%s", msg.c_str());
parsed_asteroids.push_back(msg);
#endif
}
else
{
#ifndef NDEBUG
SCP_string msg;
msg.append("Parsing asteroid: '");
msg.append(new_asteroid.name);
msg.append("' as a '");
msg.append((species == 0) ? "generic" : Species_info[species - 1].species_name);
msg.append("'");
switch (tally % NUM_DEBRIS_SIZES) {
case ASTEROID_TYPE_SMALL:
msg.append(" small\n");
break;
case ASTEROID_TYPE_MEDIUM:
msg.append(" medium\n");
break;
case ASTEROID_TYPE_LARGE:
msg.append(" large\n");
break;
default:
Error(LOCATION, "Get a coder! Math has broken!\n"
"Important numbers:\n"
"\ttally: %d\n"
"\tNUM_DEBRIS_SIZES: %d\n",
tally, NUM_DEBRIS_SIZES
);
msg.append(" unknown\n");
}
parsed_asteroids.push_back(msg);
#endif
Asteroid_info.push_back(new_asteroid);
}
tally++;
}
required_string("#End");
if (tally != max_asteroids)
{
#ifndef NDEBUG
for (SCP_vector<SCP_string>::iterator iter = parsed_asteroids.begin();
iter != parsed_asteroids.end(); ++iter)
{
mprintf(("Asteroid.tbl as parsed:\n"));
mprintf(("%s", iter->c_str()));
}
#endif
Error(LOCATION,
"Found %d asteroids/debris when %d expected\n\n"
"<Number expected> = <Number of species> * %d + %d generic asteroids\n"
"%d = " SIZE_T_ARG "*%d + %d\n\n"
#ifdef NDEBUG
"Run a debug build to see a list of all parsed asteroids\n",
#else
"See the debug.log for a listing of all parsed asteroids\n",
#endif
tally, max_asteroids,
NUM_DEBRIS_SIZES, NUM_DEBRIS_SIZES,
max_asteroids, Species_info.size(), NUM_DEBRIS_SIZES, NUM_DEBRIS_SIZES
);
}
Asteroid_impact_explosion_ani = -1;
required_string("$Impact Explosion:");
stuff_string(impact_ani_file, F_NAME, MAX_FILENAME_LEN);
if (VALID_FNAME(impact_ani_file)) {
int num_frames;
Asteroid_impact_explosion_ani = bm_load_animation(impact_ani_file, &num_frames, NULL, NULL, 1);
}
required_string("$Impact Explosion Radius:");
stuff_float(&Asteroid_impact_explosion_radius);
if (optional_string("$Briefing Icon Closeup Model:")) {
stuff_string(Asteroid_icon_closeup_model, F_NAME, NAME_LENGTH);
}
else {
strcpy_s(Asteroid_icon_closeup_model, Asteroid_info[ASTEROID_TYPE_LARGE].pof_files[0]); // magic file from retail
}
if (optional_string("$Briefing Icon Closeup Position:")) {
stuff_vec3d(&Asteroid_icon_closeup_position);
}
else {
vm_vec_make(&Asteroid_icon_closeup_position, 0.0f, 0.0f, -334.0f); // magic numbers from retail
}
if (optional_string("$Briefing Icon Closeup Zoom:")) {
stuff_float(&Asteroid_icon_closeup_zoom);
}
else {
Asteroid_icon_closeup_zoom = 0.5f; // magic number from retail
}
}
catch (const parse::ParseException& e)
{
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "asteroid.tbl", e.what()));
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "asteroid.tbl", rval));
return;
}
read_file_text("asteroid.tbl", CF_TYPE_TABLES);
reset_parse();
required_string("#Asteroid Types");
int tally = 0;
int max_asteroids =
NUM_DEBRIS_SIZES + Species_info.size() * NUM_DEBRIS_SIZES;
#ifndef NDEBUG
SCP_vector<SCP_string> parsed_asteroids;
#endif
// parse and tally each asteroid
while (required_string_either("#End","$Name:"))
{
asteroid_info new_asteroid;
asteroid_parse_section( &new_asteroid );
int species = tally / NUM_DEBRIS_SIZES;
if (tally >= max_asteroids)
{
#ifdef NDEBUG
// Bump the warning count in release so they get something
// even if the message never gets displayed.
Warning(LOCATION, "Ignoring extra asteroid/debris");
#else
SCP_string msg("Ignoring extra asteroid/debris '");
msg.append(new_asteroid.name);
msg.append("'\n");
Warning(LOCATION,msg.c_str());
parsed_asteroids.push_back(msg);
#endif
}
else
{
#ifndef NDEBUG
SCP_string msg;
msg.append("Parsing asteroid: '");
msg.append(new_asteroid.name);
msg.append("' as a '");
msg.append((species == 0)?"generic":Species_info[species-1].species_name);
msg.append("'");
switch(tally % NUM_DEBRIS_SIZES) {
case ASTEROID_TYPE_SMALL:
msg.append(" small\n");
break;
case ASTEROID_TYPE_MEDIUM:
msg.append(" medium\n");
break;
case ASTEROID_TYPE_LARGE:
msg.append(" large\n");
break;
default:
Error(LOCATION, "Get a coder! Math has broken!\n"
"Important numbers:\n"
"\ttally: %d\n"
"\tNUM_DEBRIS_SIZES: %d\n",
tally, NUM_DEBRIS_SIZES
);
msg.append(" unknown\n");
}
parsed_asteroids.push_back(msg);
#endif
Asteroid_info.push_back(new_asteroid);
}
tally++;
}
required_string("#End");
if (tally != max_asteroids)
{
#ifndef NDEBUG
for(SCP_vector<SCP_string>::iterator iter = parsed_asteroids.begin();
iter != parsed_asteroids.end(); ++iter)
{
mprintf(("Asteroid.tbl as parsed:\n"));
mprintf((iter->c_str()));
}
#endif
Error(LOCATION,
"Found %d asteroids/debris when %d expected\n\n"
"<Number expected> = <Number of species> * %d + %d generic asteroids\n"
"%d = %d*%d + %d\n\n"
#ifdef NDEBUG
"Run a debug build to see a list of all parsed asteroids\n",
#else
"See the debug.log for a listing of all parsed asteroids\n",
#endif
tally, max_asteroids,
NUM_DEBRIS_SIZES, NUM_DEBRIS_SIZES,
max_asteroids, Species_info.size(), NUM_DEBRIS_SIZES, NUM_DEBRIS_SIZES
);
}
Asteroid_impact_explosion_ani = -1;
required_string("$Impact Explosion:");
stuff_string(impact_ani_file, F_NAME, MAX_FILENAME_LEN);
if ( VALID_FNAME(impact_ani_file) ) {
int num_frames;
Asteroid_impact_explosion_ani = bm_load_animation( impact_ani_file, &num_frames, NULL, NULL, 1);
}
required_string("$Impact Explosion Radius:");
stuff_float(&Asteroid_impact_explosion_radius);
if (optional_string("$Briefing Icon Closeup Model:")) {
stuff_string(Asteroid_icon_closeup_model, F_NAME, NAME_LENGTH);
} else {
strcpy_s(Asteroid_icon_closeup_model, Asteroid_info[ASTEROID_TYPE_LARGE].pof_files[0]); // magic file from retail
}
if (optional_string("$Briefing Icon Closeup Position:")) {
stuff_vec3d(&Asteroid_icon_closeup_position);
} else {
vm_vec_make(&Asteroid_icon_closeup_position, 0.0f, 0.0f, -334.0f); // magic numbers from retail
}
if (optional_string("$Briefing Icon Closeup Zoom:")) {
stuff_float(&Asteroid_icon_closeup_zoom);
} else {
Asteroid_icon_closeup_zoom = 0.5f; // magic number from retail
}
}
/**
+5 -8
View File
@@ -12,14 +12,13 @@
#ifndef __ASTEROID_H__
#define __ASTEROID_H__
#include "globalincs/globals.h" // for NAME_LENGTH
#include "globalincs/pstypes.h"
#include "globalincs/globals.h" // for NAME_LENGTH
class object;
class polymodel;
struct collision_info_struct;
class draw_list;
#define MAX_ASTEROIDS 512
@@ -98,7 +97,6 @@ public:
typedef struct asteroid {
int flags;
int objnum;
int model_instance_num;
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
@@ -152,13 +150,12 @@ void asteroid_init();
void asteroid_level_init();
void asteroid_level_close();
void asteroid_create_all();
void asteroid_render_DEPRECATED( object *asteroid_objp );
void asteroid_render(object * obj, draw_list *scene);
void asteroid_render( object *asteroid_objp );
void asteroid_delete( object *asteroid_objp );
void asteroid_process_pre( object *asteroid_objp );
void asteroid_process_post( object *asteroid_objp);
void asteroid_process_pre( object *asteroid_objp, float frame_time);
void asteroid_process_post( object *asteroid_objp, float frame_time);
int asteroid_check_collision( object *asteroid_objp, object * other_obj, vec3d * hitpos, collision_info_struct *asteroid_hit_info=NULL );
void asteroid_hit( object *pasteroid_objp, object *other_objp, vec3d *hitpos, float damage );
void asteroid_hit( object *asteroid_objp, object *other_objp, vec3d *hitpos, float damage );
int asteroid_count();
int asteroid_collide_objnum(object *asteroid_objp);
float asteroid_time_to_impact(object *asteroid_objp);
+75 -76
View File
@@ -5,28 +5,28 @@
#include "autopilot/autopilot.h"
#include "ai/ai.h"
#include "ai/aigoals.h"
#include "asteroid/asteroid.h"
#include "autopilot/autopilot.h"
#include "camera/camera.h"
#include "cfile/cfile.h"
#include "freespace2/freespace.h"
#include "gamesnd/eventmusic.h"
#include "globalincs/def_files.h"
#include "globalincs/linklist.h"
#include "iff_defs/iff_defs.h"
#include "io/timer.h"
#include "localization/localize.h"
#include "mission/missionmessage.h"
#include "mission/missiontraining.h"
#include "ship/ship.h"
#include "object/object.h"
#include "object/objcollide.h"
#include "object/waypoint.h"
#include "parse/parselo.h"
#include "parse/sexp.h"
#include "ship/ship.h"
#include "freespace2/freespace.h"
#include "globalincs/linklist.h"
#include "iff_defs/iff_defs.h"
#include "sound/audiostr.h"
#include "mission/missiontraining.h"
#include "mission/missionmessage.h"
#include "io/timer.h"
#include "gamesnd/eventmusic.h"
#include "cfile/cfile.h"
#include "parse/parselo.h"
#include "globalincs/def_files.h"
#include "localization/localize.h"
#include "camera/camera.h"
#include "asteroid/asteroid.h"
#include <map>
// Extern functions/variables
@@ -243,9 +243,9 @@ bool StartAutopilot()
if (shipp->team != Player_ship->team)
continue;
Assertion((shipp->ship_info_index >= 0) && (shipp->ship_info_index < static_cast<int>(Ship_info.size())),
Assertion((shipp->ship_info_index >= 0) && (shipp->ship_info_index < MAX_SHIP_CLASSES),
"Ship '%s' does not have a valid pointer to a ship class. Pointer is %d, which is smaller than 0 or bigger than %d",
shipp->ship_name, shipp->ship_info_index, static_cast<int>(Ship_info.size()));
shipp->ship_name, shipp->ship_info_index, MAX_SHIP_CLASSES);
ship_info *sip = &Ship_info[shipp->ship_info_index];
if ( !(sip->flags & SIF_SUPPORT) )
@@ -1271,69 +1271,68 @@ void NavSystem_Init()
void parse_autopilot_table(char *filename)
{
int rval;
SCP_vector<SCP_string> lines;
try
if ((rval = setjmp(parse_abort)) != 0)
{
if (filename == NULL)
read_file_text_from_array(defaults_get_file("autopilot.tbl"));
else
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
required_string("#Autopilot");
// autopilot link distance
required_string("$Link Distance:");
stuff_int(&NavLinkDistance);
if (optional_string("$Interrupt autopilot if enemy within distance:"))
stuff_int(&AutopilotMinEnemyDistance);
else
AutopilotMinEnemyDistance = 5000;
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
stuff_int(&AutopilotMinAsteroidDistance);
else
AutopilotMinAsteroidDistance = 1000;
if (optional_string("$Lock Weapons During Autopilot:"))
stuff_boolean(&LockWeaponsDuringAutopilot);
else
LockWeaponsDuringAutopilot = false;
// optional no cutscene bars
if (optional_string("+No_Cutscene_Bars"))
UseCutsceneBars = false;
// optional no cutscene bars
if (optional_string("+No_Autopilot_Interrupt"))
Cmdline_autopilot_interruptable = 0;
// No Nav selected message
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
"$Support Present:", "$Support Working:" };
for (int i = 0; i < NP_NUM_MESSAGES; i++)
{
required_string(msg_tags[i]);
required_string("+Msg:");
stuff_string(NavMsgs[i].message, F_MESSAGE, 256);
required_string("+Snd File:");
stuff_string(NavMsgs[i].filename, F_NAME, 256);
}
required_string("#END");
}
catch (const parse::ParseException& e)
{
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : "<default autopilot.tbl>", e.what()));
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default autopilot.tbl>", rval));
return;
}
if (filename == NULL)
read_file_text_from_array(defaults_get_file("autopilot.tbl"));
else
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
required_string("#Autopilot");
// autopilot link distance
required_string("$Link Distance:");
stuff_int(&NavLinkDistance);
if (optional_string("$Interrupt autopilot if enemy within distance:"))
stuff_int(&AutopilotMinEnemyDistance);
else
AutopilotMinEnemyDistance = 5000;
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
stuff_int(&AutopilotMinAsteroidDistance);
else
AutopilotMinAsteroidDistance = 1000;
if (optional_string("$Lock Weapons During Autopilot:"))
stuff_boolean(&LockWeaponsDuringAutopilot);
else
LockWeaponsDuringAutopilot = false;
// optional no cutscene bars
if (optional_string("+No_Cutscene_Bars"))
UseCutsceneBars = false;
// optional no cutscene bars
if (optional_string("+No_Autopilot_Interrupt"))
Cmdline_autopilot_interruptable = 0;
// No Nav selected message
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
"$Support Present:", "$Support Working:" };
for (int i = 0; i < NP_NUM_MESSAGES; i++)
{
required_string(msg_tags[i]);
required_string("+Msg:");
stuff_string(NavMsgs[i].message, F_MESSAGE, 256);
required_string("+Snd File:");
stuff_string(NavMsgs[i].filename, F_NAME, 256);
}
required_string("#END");
}
-1
View File
@@ -9,7 +9,6 @@
#include "globalincs/pstypes.h"
#include "object/object.h"
#include <map>
// milliseconds between updates
+32 -4
View File
@@ -22,6 +22,34 @@
#endif
#include "bmpman/bmpman.h"
#include "globalincs/pstypes.h"
// Bitmap types
enum BM_TYPE
{
BM_TYPE_NONE = 0, //!< No type
BM_TYPE_USER, //!< in-memory
BM_TYPE_PCX, //!< PCX
BM_TYPE_TGA, //!< 16 or 32 bit targa
BM_TYPE_DDS, //!< generic identifier for DDS
BM_TYPE_PNG, //!< PNG
BM_TYPE_JPG, //!< 32 bit jpeg
BM_TYPE_ANI, //!< in-house ANI format
BM_TYPE_EFF, //!< specifies any type of animated image, the EFF itself is just text
// special types
BM_TYPE_RENDER_TARGET_STATIC, //!< 24/32 bit setup internally as a static render target
BM_TYPE_RENDER_TARGET_DYNAMIC, //!< 24/32 bit setup internally as a dynamic render target
// Compressed types (bitmap.c_type)
BM_TYPE_DXT1, //!< 24 bit with switchable alpha
BM_TYPE_DXT3, //!< 32 bit with 4 bit alpha
BM_TYPE_DXT5, //!< 32 bit with 8 bit alpha
BM_TYPE_CUBEMAP_DDS, //!< generic DDS cubemap (uncompressed cubemap surface)
BM_TYPE_CUBEMAP_DXT1, //!< 24-bit cubemap (compressed cubemap surface)
BM_TYPE_CUBEMAP_DXT3, //!< 32-bit cubemap (compressed cubemap surface)
BM_TYPE_CUBEMAP_DXT5 //!< 32-bit cubemap (compressed cubemap surface)
};
union bm_extra_info {
struct {
@@ -33,7 +61,7 @@ union bm_extra_info {
struct {
// stuff for static animations
BM_TYPE type; //!< type for individual images
ubyte type; //!< type for individual images
char filename[MAX_FILENAME_LEN]; //!< filename for individual images
} eff;
} ani;
@@ -55,14 +83,14 @@ struct bitmap_entry {
int handle; //!< Handle = id*MAX_BITMAPS + bitmapnum
int last_used; //!< When this bitmap was last used
BM_TYPE type; //!< PCX, USER, ANI, etc
BM_TYPE comp_type; //!< What sort of compressed type, BM_TYPE_NONE if not compressed
ubyte type; //!< PCX, USER, ANI, etc
ubyte comp_type; //!< What sort of compressed type, BM_TYPE_NONE if not compressed
signed char ref_count; //!< Number of locks on bitmap. Can't unload unless ref_count is 0.
int dir_type; //!< which directory this was loaded from (to skip other locations with same name)
// compressed bitmap stuff (.dds) - RT please take a look at this and tell me if we really need it
size_t mem_taken; //!< How much memory does this bitmap use? - UnknownPlayer
int mem_taken; //!< How much memory does this bitmap use? - UnknownPlayer
int num_mipmaps; //!< number of mipmap levels, we need to read all of them
// Stuff to keep track of usage
+186 -540
View File
File diff suppressed because it is too large. Load diff
+21 -65
View File
@@ -67,33 +67,6 @@
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1) //!< Texture is a dynamic type (animation)
#define BMP_FLAG_CUBEMAP (1<<2) //!< Texture is a cubemap
// Bitmap types
enum BM_TYPE
{
BM_TYPE_NONE = 0, //!< No type
BM_TYPE_USER, //!< in-memory
BM_TYPE_PCX, //!< PCX
BM_TYPE_TGA, //!< 16 or 32 bit targa
BM_TYPE_DDS, //!< generic identifier for DDS
BM_TYPE_PNG, //!< PNG
BM_TYPE_JPG, //!< 32 bit jpeg
BM_TYPE_ANI, //!< in-house ANI format
BM_TYPE_EFF, //!< specifies any type of animated image, the EFF itself is just text
// special types
BM_TYPE_RENDER_TARGET_STATIC, //!< 24/32 bit setup internally as a static render target
BM_TYPE_RENDER_TARGET_DYNAMIC, //!< 24/32 bit setup internally as a dynamic render target
// Compressed types (bitmap.c_type)
BM_TYPE_DXT1, //!< 24 bit with switchable alpha
BM_TYPE_DXT3, //!< 32 bit with 4 bit alpha
BM_TYPE_DXT5, //!< 32 bit with 8 bit alpha
BM_TYPE_CUBEMAP_DDS, //!< generic DDS cubemap (uncompressed cubemap surface)
BM_TYPE_CUBEMAP_DXT1, //!< 24-bit cubemap (compressed cubemap surface)
BM_TYPE_CUBEMAP_DXT3, //!< 32-bit cubemap (compressed cubemap surface)
BM_TYPE_CUBEMAP_DXT5 //!< 32-bit cubemap (compressed cubemap surface)
};
/**
* @}
*/
@@ -116,13 +89,6 @@ extern int bm_texture_ram; //!< how many bytes of textures are used.
extern int Bm_paging; //!< Bool type that indicates if BMPMAN is currently paging.
extern const BM_TYPE bm_type_list[]; //!< List of valid bitmap types
extern const char *bm_ext_list[]; //!< List of extensions for those types
extern const int BM_NUM_TYPES; //!< Calculated number of bitmap types
extern const BM_TYPE bm_ani_type_list[]; //!< List of valid bitmap animation types
extern const char *bm_ani_ext_list[]; //!< List of extensions for those types
extern const int BM_ANI_NUM_TYPES; //!< Calculated number of bitmap animation types
extern int GLOWMAP; //!< References a map that is a fully lit version of its index -Bobboau
extern int SPECMAP; //!< References a map that is for specular mapping -Bobboau
extern int ENVMAP; //!< References a map that is for environment mapping -Bobboau
@@ -174,26 +140,6 @@ void *bm_malloc(int handle, int size);
*/
void bm_update_memory_used(int n, int size);
class bitmap_lookup {
ubyte *Bitmap_data;
int Width;
int Height;
int Num_channels;
float map_texture_address(float address);
public:
bitmap_lookup(int bitmap_num);
~bitmap_lookup();
bool valid();
float get_channel_red(float u, float v);
float get_channel_green(float u, float v);
float get_channel_blue(float u, float v);
float get_channel_alpha(float u, float v);
};
/**
* @brief Loads a bitmap so we can draw with it later.
*
@@ -322,7 +268,7 @@ int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, i
* @details Also converts the bitmap to the appropriate format specified by bpp and flags. Only lock a bitmap when you
* need it!
*
* @param handle The number indexing the desired bitmap
* @param bitmapnum The number indexing the desired bitmap
* @param bpp The desired bpp of the bitmep
* @param flags The desired bitmap format
* @param nodebug
@@ -342,7 +288,7 @@ uint bm_get_signature(int handle);
/**
* @brief Returns the image type of the given bitmap handle
*/
BM_TYPE bm_get_type(int handle);
ubyte bm_get_type(int handle);
/**
* @brief Unlocks a bitmap
@@ -502,8 +448,10 @@ void bm_page_in_aabitmap(int bitmapnum, int num_frames = 1);
* @returns 0 If the bitmap had already been released, or
* @returns 0 If the handle is invalid, or
* @returns 1 If successful
*
* @todo The return type should be a bool
*/
bool bm_page_out(int handle);
int bm_page_out(int handle);
/**
* @brief Sets BMPMAN's memory mode
@@ -610,8 +558,10 @@ int bm_get_tcache_type(int handle);
/**
* @brief Gets the size, in bytes, taken up by the bitmap indexed by handle
*
* @todo retval should be a size_t
*/
size_t bm_get_size(int handle);
int bm_get_size(int handle);
/**
* @brief Gets the number of mipmaps of the indexed texture
@@ -622,8 +572,10 @@ int bm_get_num_mipmaps(int handle);
* @brief Checks to see if the indexed bitmap has an alpha channel
*
* @note Currently just checks if the bitmap is 32bpp and is not a .PCX
*
* @todo retval should be a bool
*/
bool bm_has_alpha_channel(int handle);
int bm_has_alpha_channel(int handle);
/**
* @brief (DEBUG) Prints all loaded bitmaps to an outwindow
@@ -651,10 +603,12 @@ int bm_is_render_target(int handle);
/**
* @brief (GR function) Calls gr_bm_set_render target for the given bitmap indexed by handle
*
* @returns true if successful, or
* @returns false if unsuccessful
* @returns 1 if successful, or
* @returns 0 if unsuccessful
*
* @todo retval should be a bool
*/
bool bm_set_render_target(int handle, int face = -1);
int bm_set_render_target(int handle, int face = -1);
/**
* @brief Loads and parses an .EFF
@@ -666,9 +620,11 @@ bool bm_set_render_target(int handle, int face = -1);
* @param[out] key (optional) If given, is set to the keyframe index of this .EFF
* @param[out] type (optional) If given, is set to the BM_TYPE of the .EFF
*
* @returns true If successful
* @returns false If not successful
* @returns 0 If successful,
* @returns -1 if not successful
*
* @todo retval should be a bool
*/
bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, BM_TYPE *type);
int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, ubyte *type);
#endif
+19 -29
View File
@@ -1,15 +1,17 @@
#include "camera/camera.h"
#include "globalincs/alphacolors.h"
#include "globalincs/linklist.h"
#include "globalincs/systemvars.h" //VM_FREECAMERA etc
#include "graphics/font.h"
#include "hud/hud.h" //hud_get_draw
#include "math/vecmat.h"
#include "mod_table/mod_table.h"
#include "model/model.h" //polymodel, model_get
#include "graphics/2d.h"
#include "globalincs/alphacolors.h"
#include "parse/parselo.h"
#include "physics/physics.h" //apply_physics
#include "globalincs/systemvars.h" //VM_FREECAMERA etc
#include "hud/hud.h" //hud_get_draw
#include "model/model.h" //polymodel, model_get
#include "playerman/player.h" //player_get_padlock_orient
#include "ship/ship.h" //compute_slew_matrix
#include "graphics/font.h"
#include "mod_table/mod_table.h"
#include "globalincs/linklist.h"
//*************************IMPORTANT GLOBALS*************************
float VIEWER_ZOOM_DEFAULT = 0.75f; // Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
@@ -80,7 +82,7 @@ void camera::reset()
void camera::set_name(char *in_name)
{
if(in_name != NULL)
if(name != NULL)
strncpy(name, in_name, NAME_LENGTH-1);
}
@@ -330,10 +332,8 @@ void camera::get_info(vec3d *position, matrix *orientation)
eyep = get_submodel_eye(pm, object_host_submodel);
if(eyep)
{
Assertion(objp->type == OBJ_SHIP, "This part of the code expects the object to be a ship");
vec3d c_pos_in;
find_submodel_instance_point_normal(&c_pos_in, &host_normal, Ships[objp->instance].model_instance_num, eyep->parent, &eyep->pnt, &eyep->norm);
find_submodel_instance_point_normal( &c_pos_in, &host_normal, objp, eyep->parent, &eyep->pnt, &eyep->norm);
vm_vec_unrotate(&c_pos, &c_pos_in, &objp->orient);
vm_vec_add2(&c_pos, &objp->pos);
}
@@ -540,15 +540,8 @@ void warp_camera::get_info(vec3d *position, matrix *orientation)
//*************************subtitle*************************
#define MAX_SUBTITLE_LINES 64
subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char* in_imageanim, float in_display_time,
float in_fade_time, const color *in_text_color, int in_text_fontnum, bool center_x, bool center_y, int in_width,
int in_height, bool in_post_shaded)
:display_time(-1.0f), fade_time(-1.0f), text_fontnum(-1), time_displayed(-1.0f), time_displayed_end(-1.0f),
post_shaded(false)
subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char* in_imageanim, float in_display_time, float in_fade_time, const color *in_text_color, int in_text_fontnum, bool center_x, bool center_y, int in_width, int in_height, bool in_post_shaded)
{
// Initialize color
gr_init_color(&text_color, 0, 0, 0);
SCP_string text_buf;
// basic init, this always has to be done
@@ -653,20 +646,20 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char*
//Center it?
if(center_x)
image_pos.x = (gr_screen.center_w - tw)/2 + gr_screen.center_offset_x;
image_pos.x = (gr_screen.max_w - tw)/2;
if(center_y)
image_pos.y = (gr_screen.center_h - th)/2 + gr_screen.center_offset_y;
image_pos.y = (gr_screen.max_h - th)/2;
}
if(in_x_pos < 0 && !center_x)
image_pos.x += gr_screen.center_offset_x + gr_screen.center_w + in_x_pos;
image_pos.x += gr_screen.max_w + in_x_pos;
else if(!center_x)
image_pos.x += gr_screen.center_offset_x + in_x_pos;
image_pos.x += in_x_pos;
if(in_y_pos < 0 && !center_y)
image_pos.y += gr_screen.center_offset_y + gr_screen.center_h + in_y_pos;
image_pos.y += gr_screen.max_h + in_y_pos;
else if(!center_y)
image_pos.y += gr_screen.center_offset_y + in_y_pos;
image_pos.y += in_y_pos;
image_pos.w = in_width;
image_pos.h = in_height;
@@ -873,9 +866,6 @@ void cam_close()
{
//Set Current_camera to nothing
Current_camera = camid();
for (auto ii = Cameras.begin(); ii != Cameras.end(); ++ii) {
delete * ii;
}
Cameras.clear();
}
@@ -1088,4 +1078,4 @@ eye* get_submodel_eye(polymodel *pm, int submodel_num)
}
}
return NULL;
}
}
+3 -3
View File
@@ -2,11 +2,11 @@
#ifndef _CAMERA_H
#define _CAMERA_H
#include "globalincs/globals.h"
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "object/object.h"
#include "globalincs/pstypes.h"
#include "globalincs/globals.h"
#include "physics/physics.h" //for avd
#include "object/object.h"
#include <string>
+198 -230
View File
@@ -29,10 +29,10 @@
#endif
#include "cfile/cfile.h"
#include "cfile/cfilearchive.h"
#include "cfile/cfilesystem.h"
#include "osapi/osapi.h"
#include "parse/encrypt.h"
#include "cfile/cfilesystem.h"
#include "cfile/cfilearchive.h"
#include "osapi/osapi.h"
char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
@@ -92,153 +92,135 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
#define CFILE_STACK_MAX 8
int cfile_inited = 0;
static int Cfile_stack_pos = 0;
int Cfile_stack_pos = 0;
static char Cfile_stack[CFILE_STACK_MAX][CFILE_ROOT_DIRECTORY_LEN];
char Cfile_stack[CFILE_STACK_MAX][CFILE_ROOT_DIRECTORY_LEN];
Cfile_block Cfile_block_list[MAX_CFILE_BLOCKS];
static CFILE Cfile_list[MAX_CFILE_BLOCKS];
CFILE Cfile_list[MAX_CFILE_BLOCKS];
static const char *Cfile_cdrom_dir = NULL;
const char *Cfile_cdrom_dir = NULL;
//
// Function prototypes for internally-called functions
//
static int cfget_cfile_block();
static CFILE *cf_open_fill_cfblock(const char* source, int line, FILE * fp, int type);
static CFILE *cf_open_packed_cfblock(const char* source, int line, FILE *fp, int type, int offset, int size);
int cfget_cfile_block();
CFILE *cf_open_fill_cfblock(FILE * fp, int type);
CFILE *cf_open_packed_cfblock(FILE *fp, int type, int offset, int size);
#if defined _WIN32
static CFILE *cf_open_mapped_fill_cfblock(const char* source, int line, HANDLE hFile, int type);
CFILE *cf_open_mapped_fill_cfblock(HANDLE hFile, int type);
#elif defined SCP_UNIX
static CFILE *cf_open_mapped_fill_cfblock(const char* source, int line, FILE *fp, int type);
CFILE *cf_open_mapped_fill_cfblock(FILE *fp, int type);
#endif
static void cf_chksum_long_init();
void cf_chksum_long_init();
static void dump_opened_files()
void cfile_close()
{
for (int i = 0; i < MAX_CFILE_BLOCKS; i++) {
auto cb = &Cfile_block_list[i];
if (cb->type != CFILE_BLOCK_UNUSED) {
mprintf((" %s:%d\n", cb->source_file, cb->line_num));
}
}
}
static void cfile_close()
{
mprintf(("Still opened files:\n"));
dump_opened_files();
cf_free_secondary_filelist();
}
#ifdef SCP_UNIX
#define MIN_NUM_PATH_COMPONENTS 2 /* Directory + file */
#else
#define MIN_NUM_PATH_COMPONENTS 3 /* Drive + directory + file */
#endif
/**
* @brief Determine if the given path is in the root directory
*
* @param exe_path Path to executable
*
* @return true if root directory, false if not
*/
static bool cfile_in_root_dir(const char *exe_path)
// determine if the given path is in a root directory (c:\ or c:\freespace2.exe or c:\fred2.exe etc)
int cfile_in_root_dir(const char *exe_path)
{
int new_token;
int token_count = 0;
const char *p = exe_path;
char path_copy[CFILE_ROOT_DIRECTORY_LEN] = "";
char *tok;
Assert(exe_path != NULL);
// bogus
if(exe_path == NULL){
return 1;
}
// copy the path
memset(path_copy, 0, CFILE_ROOT_DIRECTORY_LEN);
strncpy(path_copy, exe_path, CFILE_ROOT_DIRECTORY_LEN - 1);
// count how many slashes there are in the path
tok = strtok(path_copy, DIR_SEPARATOR_STR);
if(tok == NULL){
return 1;
}
do {
new_token = 0;
while (*p == DIR_SEPARATOR_CHAR) {
p++;
}
token_count++;
tok = strtok(NULL, DIR_SEPARATOR_STR);
} while(tok != NULL);
#ifdef SCP_UNIX
// /freespace works, / does not
if(token_count <= 1) {
#else
// C:/freespace works, C:/ does not
if(token_count <= 2){
#endif
return 1;
}
while ((*p != '\0') && (*p != DIR_SEPARATOR_CHAR)) {
new_token = 1;
p++;
}
token_count += new_token;
} while (*p != '\0');
return (token_count < MIN_NUM_PATH_COMPONENTS);
// not-root directory
return 0;
}
/**
* @brief Initialize the cfile system. Called once at application start.
*
* @param exe_dir Path to a file (not a directory)
* @param cdrom_dir Path to a CD drive mount point (may be NULL)
*
* @return 0 On success
* @return 1 On error
*/
// cfile_init() initializes the cfile system. Called once at application start.
//
// returns: success ==> 0
// error ==> non-zero
//
int cfile_init(const char *exe_dir, const char *cdrom_dir)
{
int i;
encrypt_init(); /* initialize encryption */
// initialize encryption
encrypt_init();
if (cfile_inited) {
return 0;
}
if ( !cfile_inited ) {
char buf[CFILE_ROOT_DIRECTORY_LEN];
char buf[CFILE_ROOT_DIRECTORY_LEN];
cfile_inited = 1;
strncpy(buf, exe_dir, CFILE_ROOT_DIRECTORY_LEN - 1);
buf[CFILE_ROOT_DIRECTORY_LEN - 1] = '\0';
i = strlen(buf);
memset(buf, 0, CFILE_ROOT_DIRECTORY_LEN);
strncpy(buf, exe_dir, CFILE_ROOT_DIRECTORY_LEN - 1);
i = strlen(buf);
/* Determine if we in a root directory? */
if (cfile_in_root_dir(buf)) {
MessageBox((HWND)NULL,
"FreeSpace2/Fred2 cannot be run from a drive root directory!",
"Error", MB_OK);
return 1;
}
// are we in a root directory?
if(cfile_in_root_dir(buf)){
MessageBox((HWND)NULL, "FreeSpace2/Fred2 cannot be run from a drive root directory!", "Error", MB_OK);
return 1;
}
// This needs to be set here because cf_build_secondary_filelist assumes it to be true
cfile_inited = 1;
while (i--) {
if (buf[i] == DIR_SEPARATOR_CHAR){
break;
}
}
/*
* Determine the executable's directory. Note that DIR_SEPARATOR_CHAR
* is guaranteed to be found in the string else cfile_in_root_dir()
* would have failed.
*/
if (i >= 2) {
buf[i] = 0;
cfile_chdir(buf);
} else {
MessageBox((HWND)NULL, "Error trying to determine executable root directory!", "Error", MB_OK);
return 1;
}
char *p;
p = strrchr(buf, DIR_SEPARATOR_CHAR);
*p = '\0';
cfile_chdir(buf);
// set root directory
strncpy(Cfile_root_dir, buf, CFILE_ROOT_DIRECTORY_LEN - 1);
// set root directory
strncpy(Cfile_root_dir, buf, CFILE_ROOT_DIRECTORY_LEN-1);
#ifdef SCP_UNIX
snprintf(Cfile_user_dir, CFILE_ROOT_DIRECTORY_LEN - 1, "%s/%s/",
detect_home(), Osreg_user_dir);
snprintf(Cfile_user_dir, CFILE_ROOT_DIRECTORY_LEN-1, "%s/%s/", detect_home(), Osreg_user_dir);
#endif
for (i = 0; i < MAX_CFILE_BLOCKS; i++) {
Cfile_block_list[i].type = CFILE_BLOCK_UNUSED;
for ( i = 0; i < MAX_CFILE_BLOCKS; i++ ) {
Cfile_block_list[i].type = CFILE_BLOCK_UNUSED;
}
// 32 bit CRC table init
cf_chksum_long_init();
Cfile_cdrom_dir = cdrom_dir;
cf_build_secondary_filelist(Cfile_cdrom_dir);
atexit( cfile_close );
}
// 32 bit CRC table init
cf_chksum_long_init();
Cfile_cdrom_dir = cdrom_dir;
cf_build_secondary_filelist(Cfile_cdrom_dir);
atexit(cfile_close);
return 0;
}
@@ -252,13 +234,13 @@ void cfile_refresh()
#ifdef _WIN32
// Changes to a drive if valid.. 1=A, 2=B, etc
// If flag, then changes to it.
// Returns 0 if not-valid, 1 if valid.
int cfile_chdrive( int DriveNum, int flag )
{
int Valid = 0;
#ifdef _WIN32
int n, org;
org = -1;
@@ -274,108 +256,99 @@ int cfile_chdrive( int DriveNum, int flag )
if ( (!flag) && (n != org) )
_chdrive( org );
#endif // _WIN32
return Valid;
}
#endif // _WIN32
/**
* @brief Common code for changing directory
*
* @param new_dir Directory to which to change
* @param cur_dir Current directory (only used on Windows)
*
* @retval 0 Success
* @retval 1 Failed to change to new directory's drive (Windows only)
* @retval 2 Failed to change to new directory
*/
static int _cfile_chdir(const char *new_dir, const char *cur_dir __UNUSED)
// push current directory on a 'stack' (so we can restore it) and change the directory
int cfile_push_chdir(int type)
{
int status;
const char *path = NULL;
const char no_dir[] = "\\.";
int e;
char dir[CFILE_ROOT_DIRECTORY_LEN];
char OriginalDirectory[CFILE_ROOT_DIRECTORY_LEN];
char *Path = NULL;
char NoDir[] = "\\.";
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN-1);
Assert(Cfile_stack_pos < CFILE_STACK_MAX);
if ( Cfile_stack_pos >= CFILE_STACK_MAX )
return -1;
strncpy(Cfile_stack[Cfile_stack_pos++], OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN-1);
cf_create_default_path_string( dir, sizeof(dir)-1, type, NULL );
#ifdef _WIN32
const char *colon = strchr(new_dir, ':');
char *colon_pos = strchr(dir, ':');
if (colon) {
if (!cfile_chdrive(tolower(*(colon - 1)) - 'a' + 1, 1))
if (colon_pos) {
if (!cfile_chdrive( tolower(*(colon_pos - 1)) - 'a' + 1, 1))
return 1;
path = colon + 1;
Path = colon_pos+1;
} else
#endif /* _WIN32 */
#endif // _WIN32
{
path = new_dir;
Path = dir;
}
if (*path == '\0') {
path = no_dir;
if (!(*Path)) {
Path = NoDir;
}
/* This chdir might get a critical error! */
status = _chdir(path);
if (status != 0) {
// This chdir might get a critical error!
e = _chdir( Path );
if (e) {
#ifdef _WIN32
cfile_chdrive(tolower(cur_dir[0]) - 'a' + 1, 1);
#endif /* _WIN32 */
cfile_chdrive( tolower(OriginalDirectory[0]) - 'a' + 1, 1 );
#endif // _WIN32
return 2;
}
return 0;
}
/**
* @brief Push current directory onto a 'stack' and change to a new directory
*
* The current directory is pushed onto a 'stack' so that it can be easily
* restored at a later time. The new directory is derived from @a type.
*
* @param type path type (CF_TYPE_xxx)
*
* @retval -1 'Stack' is full
* @retval 0 Success
* @retval 1 Failed to change to new directory's drive (Windows only)
* @retval 2 Failed to change to new directory
*/
int cfile_push_chdir(int type)
{
char dir[CFILE_ROOT_DIRECTORY_LEN];
char OriginalDirectory[CFILE_ROOT_DIRECTORY_LEN];
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN - 1);
Assert(Cfile_stack_pos < CFILE_STACK_MAX);
if (Cfile_stack_pos >= CFILE_STACK_MAX) {
return -1;
}
strncpy(Cfile_stack[Cfile_stack_pos++], OriginalDirectory,
CFILE_ROOT_DIRECTORY_LEN - 1);
cf_create_default_path_string(dir, sizeof(dir) - 1, type, NULL);
return _cfile_chdir(dir, OriginalDirectory);
}
/**
* @brief Change to the specified directory
*
* @param dir Directory
*
* @retval 0 Success
* @retval 1 Failed to change to new directory's drive (Windows only)
* @retval 2 Failed to change to new directory
*/
int cfile_chdir(const char *dir)
{
int e;
char OriginalDirectory[CFILE_ROOT_DIRECTORY_LEN];
const char *Path = NULL;
char NoDir[] = "\\.";
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN - 1);
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN-1);
return _cfile_chdir(dir, OriginalDirectory);
#ifdef _WIN32
const char *colon_pos = strchr(dir, ':');
if (colon_pos) {
if (!cfile_chdrive( tolower(*(colon_pos - 1)) - 'a' + 1, 1))
return 1;
Path = colon_pos+1;
} else
#endif // _WIN32
{
Path = dir;
}
if (!(*Path)) {
Path = NoDir;
}
// This chdir might get a critical error!
e = _chdir( Path );
if (e) {
#ifdef _WIN32
cfile_chdrive( tolower(OriginalDirectory[0]) - 'a' + 1, 1 );
#endif // _WIN32
return 2;
}
return 0;
}
int cfile_pop_dir()
@@ -428,7 +401,7 @@ int cfile_flush_dir(int dir_type)
for (unsigned int i = 0; i < globinfo.gl_pathc; i++) {
// Determine if this is a regular file
struct stat statbuf;
memset(&statbuf, 0, sizeof(statbuf));
stat(globinfo.gl_pathv[i], &statbuf);
if (S_ISREG(statbuf.st_mode)) {
// delete the file
@@ -472,24 +445,34 @@ char *cf_add_ext(const char *filename, const char *ext)
return path;
}
/**
* @brief Delete the specified file
*
* @param filename Name of file to delete
* @param path_type Path type (CF_TYPE_xxx)
*
* @return 0 on failure, 1 on success
*/
int cf_delete(const char *filename, int path_type)
// Deletes a file. Returns 0 if an error occurs, 1 on success
int cf_delete(const char *filename, int dir_type)
{
char longname[MAX_PATH_LEN];
Assert(CF_TYPE_SPECIFIED(path_type));
Assert( CF_TYPE_SPECIFIED(dir_type) );
cf_create_default_path_string(longname, sizeof(longname) - 1,
path_type, filename);
cf_create_default_path_string( longname, sizeof(longname)-1, dir_type, filename );
return (_unlink(longname) != -1);
FILE *fp = fopen(longname, "rb");
if (fp) {
// delete the file
fclose(fp);
if(_unlink(longname) == -1)
{
//ERROR - file is probably read only
return 0;
}
else
{
return 1;
}
}
else
{
//ERROR - file doesn't exist
return 0;
}
}
@@ -518,7 +501,7 @@ int cf_exists(const char *filename, int dir_type)
if ( (filename == NULL) || !strlen(filename) )
return 0;
return (cf_find_file_location(filename, dir_type, 0, NULL, NULL, &offset) && !offset);
return (cf_find_file_location(filename, dir_type, 0, NULL, &offset, NULL) && !offset);
}
// Goober5000
@@ -644,7 +627,7 @@ extern int game_cd_changed();
// error ==> NULL
//
CFILE *_cfopen(const char* source, int line, const char *file_path, const char *mode, int type, int dir_type, bool localize)
CFILE *cfopen(const char *file_path, const char *mode, int type, int dir_type, bool localize)
{
/* Bobboau, what is this doing here? 31 is way too short... - Goober5000
if( strlen(file_path) > 31 )
@@ -729,7 +712,7 @@ CFILE *_cfopen(const char* source, int line, const char *file_path, const char *
FILE *fp = fopen(longname, happy_mode);
if (fp) {
return cf_open_fill_cfblock(source, line, fp, dir_type);
return cf_open_fill_cfblock(fp, dir_type);
}
return NULL;
}
@@ -758,12 +741,12 @@ CFILE *_cfopen(const char* source, int line, const char *file_path, const char *
hFile = CreateFile(longname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
return cf_open_mapped_fill_cfblock(source, line, hFile, dir_type);
return cf_open_mapped_fill_cfblock(hFile, dir_type);
}
#elif defined SCP_UNIX
FILE *fp = fopen( longname, "rb" );
if (fp) {
return cf_open_mapped_fill_cfblock(source, line, fp, dir_type);
return cf_open_mapped_fill_cfblock(fp, dir_type);
}
#endif
}
@@ -775,10 +758,10 @@ CFILE *_cfopen(const char* source, int line, const char *file_path, const char *
if ( fp ) {
if ( offset ) {
// Found it in a pack file
return cf_open_packed_cfblock(source, line, fp, dir_type, offset, size );
return cf_open_packed_cfblock(fp, dir_type, offset, size );
} else {
// Found it in a normal file
return cf_open_fill_cfblock(source, line, fp, dir_type);
return cf_open_fill_cfblock(fp, dir_type);
}
}
}
@@ -799,7 +782,7 @@ CFILE *_cfopen(const char* source, int line, const char *file_path, const char *
// returns: success ==> address of CFILE structure
// error ==> NULL
//
CFILE *_cfopen_special(const char* source, int line, const char *file_path, const char *mode, const int size, const int offset, int dir_type)
CFILE *cfopen_special(const char *file_path, const char *mode, const int size, const int offset, int dir_type)
{
if ( !cfile_inited) {
Int3();
@@ -824,10 +807,10 @@ CFILE *_cfopen_special(const char* source, int line, const char *file_path, cons
if ( offset ) {
// it's in a pack file
return cf_open_packed_cfblock(source, line, fp, dir_type, offset, size);
return cf_open_packed_cfblock(fp, dir_type, offset, size);
} else {
// it's a normal file
return cf_open_fill_cfblock(source, line, fp, dir_type);
return cf_open_fill_cfblock(fp, dir_type);
}
}
@@ -846,7 +829,7 @@ CFILE *ctmpfile()
FILE *fp;
fp = tmpfile();
if ( fp )
return cf_open_fill_cfblock(LOCATION, fp, 0);
return cf_open_fill_cfblock(fp, 0);
else
return NULL;
}
@@ -859,7 +842,7 @@ CFILE *ctmpfile()
// returns: success ==> index in Cfile_block_list[] array
// failure ==> -1
//
static int cfget_cfile_block()
int cfget_cfile_block()
{
int i;
Cfile_block *cb;
@@ -876,13 +859,7 @@ static int cfget_cfile_block()
// If we've reached this point, a free Cfile_block could not be found
nprintf(("Warning","A free Cfile_block could not be found.\n"));
// Dump a list of all opened files
mprintf(("Out of cfile blocks! Currently opened files:\n"));
dump_opened_files();
Assertion(false, "There are no more free cfile blocks. This means that there are too many files opened by FSO.\n"
"This is probably caused by a programming or scripting error where a file does not get closed."); // out of free cfile blocks
Assert(0); // out of free cfile blocks
return -1;
}
@@ -960,7 +937,7 @@ int cf_is_valid(CFILE *cfile)
// returns: success ==> ptr to CFILE structure.
// error ==> NULL
//
static CFILE *cf_open_fill_cfblock(const char* source, int line, FILE *fp, int type)
CFILE *cf_open_fill_cfblock(FILE *fp, int type)
{
int cfile_block_index;
@@ -979,9 +956,6 @@ static CFILE *cf_open_fill_cfblock(const char* source, int line, FILE *fp, int t
cfbp->fp = fp;
cfbp->dir_type = type;
cfbp->max_read_len = 0;
cfbp->source_file = source;
cfbp->line_num = line;
int pos = ftell(fp);
if(pos == -1L)
@@ -999,7 +973,7 @@ static CFILE *cf_open_fill_cfblock(const char* source, int line, FILE *fp, int t
// returns: success ==> ptr to CFILE structure.
// error ==> NULL
//
static CFILE *cf_open_packed_cfblock(const char* source, int line, FILE *fp, int type, int offset, int size)
CFILE *cf_open_packed_cfblock(FILE *fp, int type, int offset, int size)
{
// Found it in a pack file
int cfile_block_index;
@@ -1021,9 +995,6 @@ static CFILE *cf_open_packed_cfblock(const char* source, int line, FILE *fp, int
cfbp->dir_type = type;
cfbp->max_read_len = 0;
cfbp->source_file = source;
cfbp->line_num = line;
cf_init_lowlevel_read_code(cfp,offset, size, 0 );
return cfp;
@@ -1039,9 +1010,9 @@ static CFILE *cf_open_packed_cfblock(const char* source, int line, FILE *fp, int
// returns: ptr CFILE structure.
//
#if defined _WIN32
static CFILE *cf_open_mapped_fill_cfblock(const char* source, int line, HANDLE hFile, int type)
CFILE *cf_open_mapped_fill_cfblock(HANDLE hFile, int type)
#elif defined SCP_UNIX
static CFILE *cf_open_mapped_fill_cfblock(const char* source, int line, FILE *fp, int type)
CFILE *cf_open_mapped_fill_cfblock(FILE *fp, int type)
#endif
{
int cfile_block_index;
@@ -1068,9 +1039,6 @@ static CFILE *cf_open_mapped_fill_cfblock(const char* source, int line, FILE *fp
#endif
cfbp->dir_type = type;
cfbp->source_file = source;
cfbp->line_num = line;
cf_init_lowlevel_read_code(cfp, 0, 0, 0 );
#if defined _WIN32
cfbp->hMapFile = CreateFileMapping(cfbp->hInFile, NULL, PAGE_READONLY, 0, 0, NULL);
@@ -1606,7 +1574,7 @@ char *cfgets(char *buf, int n, CFILE *cfile)
// CRC code for mission validation. given to us by Kevin Bentley on 7/20/98. Some sort of
// checksumming code that he wrote a while ago.
#define CRC32_POLYNOMIAL 0xEDB88320
static uint CRCTable[256];
uint CRCTable[256];
#define CF_CHKSUM_SAMPLE_SIZE 512
@@ -1643,7 +1611,7 @@ uint cf_add_chksum_long(uint seed, ubyte *buffer, int size)
return crc;
}
static void cf_chksum_long_init()
void cf_chksum_long_init()
{
int i, j;
uint crc;
@@ -1664,7 +1632,7 @@ static void cf_chksum_long_init()
// single function convenient to use for both short and long checksums
// NOTE : only one of chk_short or chk_long must be non-NULL (indicating which checksum to perform)
static int cf_chksum_do(CFILE *cfile, ushort *chk_short, uint *chk_long, int max_size)
int cf_chksum_do(CFILE *cfile, ushort *chk_short, uint *chk_long, int max_size)
{
ubyte cf_buffer[CF_CHKSUM_SAMPLE_SIZE];
int is_long;
+3 -6
View File
@@ -114,6 +114,7 @@ extern char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN];
#endif
//================= LOW-LEVEL FUNCTIONS ==================
// Call this once at the beginning of the program
int cfile_init(const char *exe_dir, const char *cdrom_dir=NULL);
// Call this if pack files got added or removed or the
@@ -129,15 +130,11 @@ int cf_get_dir_type(CFILE *cfile);
// Opens the file. If no path is given, use the extension to look into the
// default path. If mode is NULL, delete the file.
CFILE *_cfopen(const char* source_file, int line, const char *filename, const char *mode,
int type = CFILE_NORMAL, int dir_type = CF_TYPE_ANY, bool localize = false);
#define cfopen(...) _cfopen(LOCATION, __VA_ARGS__) // Pass source location to the function
CFILE *cfopen(const char *filename, const char *mode, int type = CFILE_NORMAL, int dir_type = CF_TYPE_ANY, bool localize = false);
// like cfopen(), but it accepts a fully qualified path only (ie, the result of a cf_find_file_location() call)
// NOTE: only supports reading files!!
CFILE *_cfopen_special(const char* source_file, int line, const char *file_path, const char *mode,
const int size, const int offset, int dir_type = CF_TYPE_ANY);
#define cfopen_special(...) _cfopen_special(LOCATION, __VA_ARGS__) // Pass source location to the function
CFILE *cfopen_special(const char *file_path, const char *mode, const int size, const int offset, int dir_type = CF_TYPE_ANY);
// Flush the open file buffer
int cflush(CFILE *cfile);
+1 -3
View File
@@ -39,13 +39,11 @@ typedef struct Cfile_block {
int size; // for packed files
size_t max_read_len; // max read offset, for special error handling
const char* source_file;
int line_num;
} Cfile_block;
#define MAX_CFILE_BLOCKS 64
extern Cfile_block Cfile_block_list[MAX_CFILE_BLOCKS];
extern CFILE Cfile_list[MAX_CFILE_BLOCKS];
// Called once to setup the low-level reading code.
void cf_init_lowlevel_read_code( CFILE * cfile, int lib_offset, int size, int pos );
+1 -1
View File
@@ -22,8 +22,8 @@
#include <winbase.h> /* needed for memory mapping of file functions */
#endif
#include "cfile/cfile.h"
#include "globalincs/pstypes.h"
#include "cfile/cfile.h"
void cf_sort_filenames( SCP_vector<SCP_string> &list, int sort, SCP_vector<file_list_info> *info )
+15 -17
View File
@@ -9,12 +9,13 @@
#include "globalincs/pstypes.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sstream>
#include <algorithm>
#ifdef _WIN32
#include <io.h>
@@ -32,13 +33,13 @@
#include <unistd.h>
#endif
#include "cmdline/cmdline.h"
#include "cfile/cfile.h"
#include "cfile/cfilesystem.h"
#include "cmdline/cmdline.h"
#include "globalincs/pstypes.h"
#include "localization/localize.h"
#define CF_ROOTTYPE_PATH 0
#define CF_ROOTTYPE_PACK 1
@@ -219,15 +220,19 @@ int cf_get_packfile_count(cf_root *root)
}
// packfile sort function
bool cf_packfile_sort_func(const cf_root_sort &r1, const cf_root_sort &r2)
int cf_packfile_sort_func(const void *elem1, const void *elem2)
{
cf_root_sort *r1, *r2;
r1 = (cf_root_sort*)elem1;
r2 = (cf_root_sort*)elem2;
// if the 2 directory types are the same, do a string compare
if (r1.cf_type == r2.cf_type) {
return (stricmp(r1.path, r2.path) < 0);
if(r1->cf_type == r2->cf_type){
return stricmp(r1->path, r2->path);
}
// otherwise return them in order of CF_TYPE_* precedence
return (r1.cf_type < r2.cf_type);
return (r1->cf_type < r2->cf_type) ? -1 : 1;
}
// Go through a root and look for pack files
@@ -336,7 +341,7 @@ void cf_build_pack_list( cf_root *root )
Assert(root_index == temp_root_count);
// sort the roots
std::sort(temp_roots_sort, temp_roots_sort + temp_root_count, cf_packfile_sort_func);
qsort(temp_roots_sort, temp_root_count, sizeof(cf_root_sort), cf_packfile_sort_func);
// now insert them all into the real root list properly
cf_root *new_root;
@@ -665,11 +670,7 @@ void cf_search_root_pack(int root_index)
VP_FILE_HEADER VP_header;
Assert( sizeof(VP_header) == 16 );
if (fread(&VP_header, sizeof(VP_header), 1, fp) != 1) {
mprintf(("Skipping VP file ('%s') because the header could not be read...\n", root->path));
fclose(fp);
return;
}
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
@@ -689,10 +690,7 @@ void cf_search_root_pack(int root_index)
for (i=0; i<VP_header.num_files; i++ ) {
VP_FILE find;
if (fread( &find, sizeof(VP_FILE), 1, fp ) != 1) {
mprintf(("Failed to read file entry (currently in directory %s)!\n", search_path));
break;
}
fread( &find, sizeof(VP_FILE), 1, fp );
find.offset = INTEL_INT( find.offset ); //-V570
find.size = INTEL_INT( find.size ); //-V570
+87 -205
View File
@@ -12,13 +12,13 @@
#include "camera/camera.h" //VIEWER_ZOOM_DEFAULT
#include "cmdline/cmdline.h"
#include "globalincs/linklist.h"
#include "globalincs/pstypes.h"
#include "globalincs/systemvars.h"
#include "globalincs/version.h"
#include "hud/hudconfig.h"
#include "network/multi.h"
#include "hud/hudconfig.h"
#include "parse/scripting.h"
#include "parse/sexp.h"
#include "globalincs/version.h"
#include "globalincs/pstypes.h"
#ifdef _WIN32
#include <io.h>
@@ -141,12 +141,13 @@ Flag exe_params[] =
{ "-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, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
{ "-soft_particles", "Enable soft particles", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT, EASY_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
{ "-no_deferred", "Disable Deferred Lighting", true, EASY_DEFAULT_MEM, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_deferred"},
{ "-enable_shadows", "Enable Shadows", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_shadows"},
{ "-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", },
{ "-no_fps_capping", "Don't limit frames-per-second", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_fps_capping", },
{ "-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", },
@@ -165,7 +166,6 @@ Flag exe_params[] =
{ "-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", },
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
{ "-no_enhanced_sound", "Disable enhanced sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_enhanced_sound", },
{ "-standalone", "Run as standalone 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", },
@@ -181,12 +181,14 @@ Flag exe_params[] =
{ "-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", },
{ "-disable_pbo", "Disable OpenGL Pixel Buffer Objects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_pbo", },
{ "-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://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ati_swap", },
{ "-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", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_di_mouse", },
@@ -194,12 +196,6 @@ Flag exe_params[] =
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-use_gldrawelements", },
{ "-old_collision", "Use old collision detection system", true, EASY_DEFAULT, EASY_ALL_ON, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-old_collision", },
{ "-gl_finish", "Fix input lag on some ATI+Linux systems", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gl_finish", },
{ "-no_batching", "Disable batched model rendering", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-no_geo_effects", "Disable geometry shader for effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-set_cpu_affinity", "Sets processor affinity to config value", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
#ifdef WIN32
{ "-fix_registry", "Use a different registry path", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
#endif
{ "-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", },
@@ -231,7 +227,6 @@ Flag exe_params[] =
{ "-profile_frame_time", "Profile engine subsystems", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_timings", },
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", },
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
{ "-benchmark_mode", "Puts the game into benchmark mode", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-benchmark_mode", },
};
// forward declaration
@@ -248,7 +243,6 @@ cmdline_parm allowbelow_arg("-allowbelow", "Ranks below this can join multi", AT
cmdline_parm standalone_arg("-standalone", NULL, AT_NONE);
cmdline_parm nosound_arg("-nosound", NULL, AT_NONE); // Cmdline_freespace_no_sound
cmdline_parm nomusic_arg("-nomusic", NULL, AT_NONE); // Cmdline_freespace_no_music
cmdline_parm noenhancedsound_arg("-no_enhanced_sound", NULL, AT_NONE); // Cmdline_no_enhanced_sound
cmdline_parm startgame_arg("-startgame", NULL, AT_NONE); // Cmdline_start_netgame
cmdline_parm gameclosed_arg("-closed", NULL, AT_NONE); // Cmdline_closed_game
cmdline_parm gamerestricted_arg("-restricted", NULL, AT_NONE); // Cmdline_restricted_game
@@ -311,10 +305,6 @@ cmdline_parm fxaa_preset_arg("-fxaa_preset", "FXAA quality (0-9), requires -post
cmdline_parm fb_explosions_arg("-fb_explosions", NULL, AT_NONE);
cmdline_parm flightshaftsoff_arg("-nolightshafts", NULL, AT_NONE);
cmdline_parm brieflighting_arg("-brief_lighting", NULL, AT_NONE);
cmdline_parm no_batching("-no_batching", NULL, AT_NONE);
cmdline_parm shadow_quality_arg("-shadow_quality", NULL, AT_INT);
cmdline_parm enable_shadows_arg("-enable_shadows", NULL, AT_NONE);
cmdline_parm no_deferred_lighting_arg("-no_deferred", NULL, AT_NONE); // Cmdline_no_deferred
float Cmdline_clip_dist = Default_min_draw_distance;
float Cmdline_fov = 0.75f;
@@ -338,18 +328,17 @@ bool Cmdline_fxaa = false;
int Cmdline_fxaa_preset = 6;
extern int Fxaa_preset_last_frame;
bool Cmdline_fb_explosions = 0;
bool Cmdline_no_batching = false;
extern bool ls_force_off;
bool Cmdline_brief_lighting = 0;
int Cmdline_shadow_quality = 0;
int Cmdline_no_deferred_lighting = 0;
// Game Speed related
cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL, AT_NONE); // Cmdline_cache_bitmaps
cmdline_parm img2dds_arg("-img2dds", NULL, AT_NONE); // Cmdline_img2dds
cmdline_parm no_fpscap("-no_fps_capping", "Don't limit frames-per-second", AT_NONE); // Cmdline_NoFPSCap
cmdline_parm no_vsync_arg("-no_vsync", NULL, AT_NONE); // Cmdline_no_vsync
int Cmdline_cache_bitmaps = 0; // caching of bitmaps between missions (faster loads, can hit swap on reload with <512 Meg RAM though) - taylor
int Cmdline_img2dds = 0;
int Cmdline_NoFPSCap = 0; // Disable FPS capping - kazan
int Cmdline_no_vsync = 0;
@@ -389,7 +378,6 @@ cmdline_parm voice_recognition_arg("-voicer", NULL, AT_NONE); // Cmdline_voice_r
int Cmdline_query_speech = 0;
int Cmdline_snd_preload = 0; // preload game sounds during mission load
int Cmdline_voice_recognition = 0;
int Cmdline_no_enhanced_sound = 0;
// MOD related
cmdline_parm mod_arg("-mod", "List of folders to overwrite/add-to the default data", AT_STRING, true); // Cmdline_mod -- DTP modsupport
@@ -414,6 +402,7 @@ int Cmdline_objupd = 3; // client object updates on LAN by default
// Troubleshooting
cmdline_parm loadallweapons_arg("-loadallweps", NULL, AT_NONE); // Cmdline_load_all_weapons
cmdline_parm htl_arg("-nohtl", NULL, AT_NONE); // Cmdline_nohtl -- don't use HT&L
cmdline_parm noibx_arg("-noibx", NULL, AT_NONE); // Cmdline_noibx
cmdline_parm nomovies_arg("-nomovies", NULL, AT_NONE); // Cmdline_nomovies -- Allows video streaming
cmdline_parm no_set_gamma_arg("-no_set_gamma", NULL, AT_NONE); // Cmdline_no_set_gamma
cmdline_parm no_vbo_arg("-novbo", NULL, AT_NONE); // Cmdline_novbo
@@ -423,19 +412,16 @@ cmdline_parm noglsl_arg("-no_glsl", NULL, AT_NONE); // Cmdline_noglsl -- disa
cmdline_parm mipmap_arg("-mipmap", NULL, AT_NONE); // Cmdline_mipmap
cmdline_parm atiswap_arg("-ati_swap", NULL, AT_NONE); // Cmdline_atiswap - Fix ATI color swap issue for screenshots.
cmdline_parm no3dsound_arg("-no_3d_sound", NULL, AT_NONE); // Cmdline_no_3d_sound - Disable use of full 3D sounds
cmdline_parm no_glsl_models_arg("-disable_glsl_model", NULL, AT_NONE); // Cmdline_no_glsl_model_rendering -- switches model rendering to fixed pipeline
cmdline_parm no_di_mouse_arg("-disable_di_mouse", "Disable DirectInput mouse code (Windows only)", AT_NONE); // Cmdline_no_di_mouse -- Disables directinput use for mouse control
cmdline_parm no_drawrangeelements("-use_gldrawelements", NULL, AT_NONE); // Cmdline_drawelements -- Uses glDrawElements instead of glDrawRangeElements
cmdline_parm keyboard_layout("-keyboard_layout", "Specify keyboard layout (qwertz or azerty)", AT_STRING);
cmdline_parm old_collision_system("-old_collision", NULL, AT_NONE); // Cmdline_old_collision_sys
cmdline_parm gl_finish ("-gl_finish", NULL, AT_NONE);
cmdline_parm no_geo_sdr_effects("-no_geo_effects", NULL, AT_NONE);
cmdline_parm set_cpu_affinity("-set_cpu_affinity", NULL, AT_NONE);
#ifdef WIN32
cmdline_parm fix_registry("-fix_registry", NULL, AT_NONE);
#endif
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
@@ -444,15 +430,11 @@ int Cmdline_no_pbo = 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;
bool Cmdline_gl_finish = false;
bool Cmdline_no_geo_sdr_effects = false;
bool Cmdline_set_cpu_affinity = false;
#ifdef WIN32
bool Cmdline_alternate_registry_path = false;
#endif
// Developer/Testing related
cmdline_parm start_mission_arg("-start_mission", "Skip mainhall and run this mission", AT_STRING); // Cmdline_start_mission
@@ -472,7 +454,6 @@ cmdline_parm debug_window_arg("-debug_window", NULL, AT_NONE); // Cmdline_debug_
cmdline_parm window_arg("-window", NULL, AT_NONE); // Cmdline_window
cmdline_parm fullscreen_window_arg("-fullscreen_window", "Fullscreen/borderless window (Windows only)", AT_NONE);
cmdline_parm res_arg("-res", "Resolution, formatted like 1600x900", AT_STRING);
cmdline_parm center_res_arg("-center_res", "Resolution of center monitor, formatted like 1600x900", AT_STRING);
cmdline_parm verify_vps_arg("-verify_vps", NULL, AT_NONE); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, "Ignore any cmdline_fso.cfg files", AT_NONE);
#ifdef SCP_UNIX
@@ -482,8 +463,6 @@ cmdline_parm reparse_mainhall_arg("-reparse_mainhall", NULL, AT_NONE); //Cmdline
cmdline_parm frame_profile_arg("-profile_frame_time", NULL, AT_NONE); //Cmdline_frame_profile
cmdline_parm frame_profile_write_file("-profile_write_file", NULL, AT_NONE); // Cmdline_profile_write_file
cmdline_parm no_unfocused_pause_arg("-no_unfocused_pause", NULL, AT_NONE); //Cmdline_no_unfocus_pause
cmdline_parm benchmark_mode_arg("-benchmark_mode", NULL, AT_NONE); //Cmdline_benchmark_mode
char *Cmdline_start_mission = NULL;
int Cmdline_old_collision_sys = 0;
@@ -502,7 +481,6 @@ int Cmdline_debug_window = 0;
int Cmdline_window = 0;
int Cmdline_fullscreen_window = 0;
char *Cmdline_res = 0;
char *Cmdline_center_res = 0;
int Cmdline_verify_vps = 0;
#ifdef SCP_UNIX
int Cmdline_no_grab = 0;
@@ -511,7 +489,6 @@ int Cmdline_reparse_mainhall = 0;
bool Cmdline_frame_profile = false;
bool Cmdline_profile_write_file = false;
bool Cmdline_no_unfocus_pause = false;
bool Cmdline_benchmark_mode = false;
// Other
cmdline_parm get_flags_arg("-get_flags", "Output the launcher flags file", AT_NONE);
@@ -855,21 +832,20 @@ void os_init_cmdline(char *cmdline)
size_t len = filelength( fileno(fp) ) + 2;
buf = new char [len];
if (fgets(buf, len-1, fp) != nullptr)
{
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
*p = '\0';
}
fgets(buf, len-1, fp);
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
*p = '\0';
}
#ifdef SCP_UNIX
// append a space for the os_parse_parms() check
strcat_s(buf, len, " ");
// append a space for the os_parse_parms() check
strcat_s(buf, len, " ");
#endif
os_parse_parms(buf);
os_validate_parms(buf);
}
os_parse_parms(buf);
os_validate_parms(buf);
delete [] buf;
fclose(fp);
}
@@ -894,20 +870,18 @@ void os_init_cmdline(char *cmdline)
size_t len = filelength( fileno(fp) ) + 2;
buf = new char [len];
if (fgets(buf, len-1, fp) != nullptr)
{
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
*p = '\0';
}
fgets(buf, len-1, fp);
// append a space for the os_parse_parms() check
strcat_s(buf, len, " ");
os_parse_parms(buf);
os_validate_parms(buf);
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
*p = '\0';
}
// append a space for the os_parse_parms() check
strcat_s(buf, len, " ");
os_parse_parms(buf);
os_validate_parms(buf);
delete [] buf;
fclose(fp);
}
@@ -1042,100 +1016,6 @@ char *cmdline_parm::str()
return args;
}
#ifdef SCP_UNIX
// Return a vector with all filesystem names of "parent/dir" relative to parent.
// dir must not contain a slash.
static SCP_vector<SCP_string> unix_get_single_dir_names(SCP_string parent, SCP_string dir)
{
SCP_vector<SCP_string> ret;
DIR *dp;
if ((dp = opendir(parent.c_str())) == NULL) {
Warning(LOCATION, "Can't open directory '%s' when searching mod paths. Ignoring. errno=%d", parent.c_str(), errno);
return ret;
}
dirent *dirp;
while ((dirp = readdir(dp)) != NULL) {
if (!stricmp(dirp->d_name, dir.c_str())) {
ret.push_back(dirp->d_name);
}
}
(void)closedir(dp);
return ret;
}
// Return a vector with all filesystem names of "parent/dir" relative to parent.
// Recurses to deal with slashes in dir.
static SCP_vector<SCP_string> unix_get_dir_names(SCP_string parent, SCP_string dir)
{
size_t slash = dir.find_first_of("/\\");
// no subdirectories, no need to recurse
if (slash == std::string::npos) {
return unix_get_single_dir_names(parent, dir);
}
// get the names of the first component of dir
SCP_vector<SCP_string> this_dir_names = unix_get_single_dir_names(parent, dir.substr(0, slash));
SCP_string rest = dir.substr(slash + 1);
SCP_vector<SCP_string> ret;
// search for the rest of dir in each of these
SCP_vector<SCP_string>::iterator ii, end = this_dir_names.end();
for (ii = this_dir_names.begin(); ii != end; ++ii) {
SCP_string this_dir_path = parent + "/" + *ii;
SCP_vector<SCP_string> mod_path = unix_get_dir_names(this_dir_path, rest);
// add all found paths relative to parent
SCP_vector<SCP_string>::iterator ii2, end2 = mod_path.end();
for (ii2 = mod_path.begin(); ii2 != end2; ++ii2) {
ret.push_back(*ii + "/" + *ii2);
}
}
return ret;
}
// For case sensitive filesystems (e.g. Linux/BSD) perform case-insensitive dir matches.
static void handle_unix_modlist(char **modlist, int *len)
{
// search filesystem for given paths
SCP_vector<SCP_string> mod_paths;
for (char *cur_mod = strtok(*modlist, ","); cur_mod != NULL; cur_mod = strtok(NULL, ","))
{
SCP_vector<SCP_string> this_mod_paths = unix_get_dir_names(".", cur_mod);
if (this_mod_paths.empty()) {
ReleaseWarning(LOCATION, "Can't find mod '%s'. Ignoring.", cur_mod);
}
mod_paths.insert(mod_paths.end(), this_mod_paths.begin(), this_mod_paths.end());
}
// create new char[] to replace modlist
size_t total_len = 0;
SCP_vector<SCP_string>::iterator ii, end = mod_paths.end();
for (ii = mod_paths.begin(); ii != end; ++ii) {
total_len += ii->length() + 1;
}
char *new_modlist = new char[total_len + 1];
memset(new_modlist, 0, total_len + 1);
end = mod_paths.end();
for (ii = mod_paths.begin(); ii != end; ++ii) {
strcat_s(new_modlist, total_len + 1, ii->c_str());
strcat_s(new_modlist, total_len + 1, ","); // replace later with NUL
}
// make the rest of the modlist manipulation unaware that anything happened here
delete [] *modlist;
*modlist = new_modlist;
*len = total_len;
}
#endif /* SCP_UNIX */
// external entry point into this modules
bool SetCmdlineParams()
@@ -1270,11 +1150,6 @@ bool SetCmdlineParams()
Cmdline_freespace_no_music = 1;
}
// Disable enhanced sound
if (noenhancedsound_arg.found()) {
Cmdline_no_enhanced_sound = 1;
}
// should we start a network game
if ( startgame_arg.found() ) {
Cmdline_use_last_pilot = 1;
@@ -1372,9 +1247,6 @@ bool SetCmdlineParams()
if(res_arg.found()){
Cmdline_res = res_arg.str();
}
if(center_res_arg.found()){
Cmdline_center_res = center_res_arg.str();
}
if(almission_arg.found()){//DTP for autoload mission // developer oritentated
Cmdline_almission = almission_arg.str();
Cmdline_use_last_pilot = 1;
@@ -1418,8 +1290,47 @@ bool SetCmdlineParams()
strcpy_s(modlist, len+2, Cmdline_mod);
#ifdef SCP_UNIX
// handle case-insensitive searching
handle_unix_modlist(&modlist, &len);
// for case sensitive filesystems (e.g. Linux/BSD) perform case-insensitive dir matches
DIR *dp;
dirent *dirp;
char *cur_pos, *temp;
char cur_dir[CF_MAX_PATHNAME_LENGTH], delim[] = ",";
SCP_vector<SCP_string> temp_modlist;
size_t total_len = 0;
if ( !_getcwd(cur_dir, CF_MAX_PATHNAME_LENGTH ) ) {
Error(LOCATION, "Can't get current working directory -- %d", errno );
}
for (cur_pos = strtok(modlist, delim); cur_pos != NULL; cur_pos = strtok(NULL, delim))
{
if ((dp = opendir(cur_dir)) == NULL) {
Error(LOCATION, "Can't open directory '%s' -- %d", cur_dir, errno );
}
while ((dirp = readdir(dp)) != NULL) {
if (!stricmp(dirp->d_name, cur_pos)) {
temp_modlist.push_back(dirp->d_name);
total_len += (strlen(dirp->d_name) + 1);
}
}
(void)closedir(dp);
}
// create new char[] to replace modlist
char *new_modlist = new char[total_len+1];
memset( new_modlist, 0, total_len + 1 );
SCP_vector<SCP_string>::iterator ii, end = temp_modlist.end();
for (ii = temp_modlist.begin(); ii != end; ++ii) {
strcat_s(new_modlist, total_len+1, ii->c_str());
strcat_s(new_modlist, total_len+1, ","); // replace later with NUL
}
// make the rest of the function unaware that anything happened here
temp = modlist;
modlist = new_modlist;
delete [] temp;
len = total_len;
#endif
// null terminate each individual
@@ -1545,6 +1456,10 @@ bool SetCmdlineParams()
Cmdline_noglsl = 1;
}
if (no_glsl_models_arg.found() ) {
Cmdline_no_glsl_model_rendering = 1;
}
if (fxaa_arg.found() ) {
Cmdline_fxaa = true;
@@ -1559,6 +1474,9 @@ bool SetCmdlineParams()
Cmdline_no_di_mouse = 1;
}
if ( img2dds_arg.found() )
Cmdline_img2dds = 1;
if ( glow_arg.found() )
Cmdline_glow = 0;
@@ -1616,22 +1534,6 @@ bool SetCmdlineParams()
Cmdline_gl_finish = true;
}
if ( no_geo_sdr_effects.found() )
{
Cmdline_no_geo_sdr_effects = true;
}
if (set_cpu_affinity.found())
{
Cmdline_set_cpu_affinity = true;
}
#ifdef WIN32
if (fix_registry.found()) {
Cmdline_alternate_registry_path = true;
}
#endif
if ( snd_preload_arg.found() )
{
Cmdline_snd_preload = 1;
@@ -1658,6 +1560,10 @@ bool SetCmdlineParams()
if(dis_weapons.found())
Cmdline_dis_weapons = 1;
if ( noibx_arg.found() ) {
Cmdline_noibx = 1;
}
if ( no_fbo_arg.found() ) {
Cmdline_no_fbo = 1;
}
@@ -1710,11 +1616,6 @@ bool SetCmdlineParams()
Cmdline_fb_explosions = 1;
}
if ( no_batching.found() )
{
Cmdline_no_batching = true;
}
if ( brieflighting_arg.found() )
{
Cmdline_brief_lighting = 1;
@@ -1740,20 +1641,6 @@ bool SetCmdlineParams()
Cmdline_reparse_mainhall = 1;
}
if( enable_shadows_arg.found() )
{
Cmdline_shadow_quality = 2;
if( shadow_quality_arg.found() )
{
Cmdline_shadow_quality = shadow_quality_arg.get_int();
}
}
if( no_deferred_lighting_arg.found() )
{
Cmdline_no_deferred_lighting = 1;
}
if (frame_profile_arg.found() )
{
Cmdline_frame_profile = true;
@@ -1769,11 +1656,6 @@ bool SetCmdlineParams()
{
Cmdline_no_unfocus_pause = true;
}
if (benchmark_mode_arg.found())
{
Cmdline_benchmark_mode = true;
}
//Deprecated flags - CommanderDJ
if( deprecated_spec_arg.found() )
+3 -11
View File
@@ -48,7 +48,6 @@ extern int Cmdline_use_last_pilot;
extern int Cmdline_window;
extern int Cmdline_fullscreen_window;
extern char *Cmdline_res;
extern char *Cmdline_center_res;
// FSO OPTIONS -------------------------------------------------
@@ -77,12 +76,10 @@ extern int Cmdline_bloom_intensity;
extern bool Cmdline_fxaa;
extern int Cmdline_fxaa_preset;
extern bool Cmdline_fb_explosions;
extern bool Cmdline_no_batching;
extern int Cmdline_shadow_quality;
extern int Cmdline_no_deferred_lighting;
// Game Speed related
extern int Cmdline_cache_bitmaps;
extern int Cmdline_img2dds;
extern int Cmdline_NoFPSCap;
extern int Cmdline_no_vsync;
@@ -105,7 +102,6 @@ extern int Cmdline_stretch_menu;
extern int Cmdline_query_speech;
extern int Cmdline_snd_preload;
extern int Cmdline_voice_recognition;
extern int Cmdline_no_enhanced_sound;
// MOD related
extern char *Cmdline_mod; // DTP for mod support
@@ -120,6 +116,7 @@ extern int Cmdline_objupd;
// Troubleshooting
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;
@@ -129,15 +126,11 @@ 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;
extern bool Cmdline_gl_finish;
extern bool Cmdline_no_geo_sdr_effects;
extern bool Cmdline_set_cpu_affinity;
#ifdef WIN32
extern bool Cmdline_alternate_registry_path;
#endif
// Developer/Testing related
extern char *Cmdline_start_mission;
@@ -162,6 +155,5 @@ extern int Cmdline_reparse_mainhall;
extern bool Cmdline_frame_profile;
extern bool Cmdline_profile_write_file;
extern bool Cmdline_no_unfocus_pause;
extern bool Cmdline_benchmark_mode;
#endif
+6 -7
View File
@@ -10,18 +10,17 @@
#include "cmeasure/cmeasure.h"
#include "gamesnd/gamesnd.h"
#include "hud/hud.h"
#include "math/staticrand.h"
#include "mission/missionparse.h"
#include "network/multimsgs.h"
#include "object/object.h"
#include "ship/ship.h"
#include "math/staticrand.h"
#include "object/object.h"
#include "weapon/weapon.h"
#include "hud/hud.h"
#include "gamesnd/gamesnd.h"
#include "network/multimsgs.h"
#include "mission/missionparse.h"
int Cmeasures_homing_check = 0;
int Countermeasures_enabled = 1; // Debug, set to 0 means no one can fire countermeasures.
const float CMEASURE_DETONATE_DISTANCE = 40.0f;
//Used to set a countermeasure velocity after being launched from a ship as a countermeasure
//ie not as a primary or secondary.
-1
View File
@@ -22,7 +22,6 @@ class object;
// 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
extern const float CMEASURE_DETONATE_DISTANCE;
extern int Cmeasures_homing_check;
extern int Countermeasures_enabled;
+36 -59
View File
@@ -10,26 +10,26 @@
#include "controlconfig/controlsconfig.h"
#include "debugconsole/console.h"
#include "freespace2/freespace.h"
#include "gamehelp/contexthelp.h"
#include "controlconfig/controlsconfig.h"
#include "gamesequence/gamesequence.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/alphacolors.h"
#include "graphics/font.h"
#include "hud/hudsquadmsg.h"
#include "io/joy.h"
#include "io/key.h"
#include "io/timer.h"
#include "ui/ui.h"
#include "io/joy.h"
#include "gamesnd/gamesnd.h"
#include "missionui/missionscreencommon.h"
#include "graphics/font.h"
#include "pilotfile/pilotfile.h"
#include "gamehelp/contexthelp.h"
#include "popup/popup.h"
#include "ui/uidefs.h"
#include "globalincs/alphacolors.h"
#include "network/multi_pmsg.h"
#include "network/multiutil.h"
#include "parse/scripting.h"
#include "pilotfile/pilotfile.h"
#include "popup/popup.h"
#include "ui/ui.h"
#include "ui/uidefs.h"
#include "debugconsole/console.h"
#ifndef NDEBUG
@@ -393,10 +393,21 @@ int control_config_detect_axis()
void control_config_conflict_check()
{
int i, j;
int i, j, shift = -1, alt = -1;
for (i=0; i<CCFG_MAX; i++) {
Conflicts[i].key = Conflicts[i].joy = -1;
switch (Control_config[i].key_id) {
case KEY_LSHIFT:
case KEY_RSHIFT:
shift = i;
break;
case KEY_LALT:
case KEY_RALT:
alt = i;
break;
}
}
for (i=0; i<NUM_TABS; i++) {
@@ -457,12 +468,15 @@ void control_config_conflict_check()
// do list setup required prior to rendering and checking for the controls listing. Called when list changes
void control_config_list_prepare()
{
int j, y, z;
int j, k, y, z;
int font_height = gr_get_font_height();
Num_cc_lines = y = z = 0;
while (z < CCFG_MAX) {
if (Control_config[z].tab == Tab && !Control_config[z].disabled) {
k = Control_config[z].key_id;
j = Control_config[z].joy_id;
if (Control_config[z].hasXSTR) {
Cc_lines[Num_cc_lines].label = XSTR(Control_config[z].text, CONTROL_CONFIG_XSTR + z);
} else {
@@ -652,7 +666,7 @@ void control_config_bind_axis(int i, int axis)
int control_config_remove_binding()
{
int z;
int z, j, k;
config_item_undo *ptr;
if (Selected_line < 0) {
@@ -682,6 +696,7 @@ int control_config_remove_binding()
return -1;
}
j = k = -1;
ptr = get_undo_block(1);
ptr->index[0] = z;
ptr->list[0] = Control_config[z];
@@ -1424,8 +1439,8 @@ void control_config_close()
void control_config_do_frame(float frametime)
{
const char *str;
char buf[256];
int i, j, k, w, x, y, z, line, conflict;
char buf[256], *jptr;
int i, j, k, w, x, y, z, len, line, conflict;
int font_height = gr_get_font_height();
int select_tease_line = -1; // line mouse is down on, but won't be selected until button released
static float timer = 0.0f;
@@ -1984,6 +1999,7 @@ void control_config_do_frame(float frametime)
k = Control_config[z].key_id;
j = Control_config[z].joy_id;
x = Control_list_key_x[gr_screen.res];
jptr = NULL;
*buf = 0;
if ((k < 0) && (j < 0)) {
@@ -2010,6 +2026,7 @@ void control_config_do_frame(float frametime)
gr_printf_menu(x, y, buf);
len = strlen(buf);
Cc_lines[line].kx = x - Control_list_coords[gr_screen.res][CONTROL_X_COORD];
gr_get_string_size(&w, NULL, buf);
Cc_lines[line].kw = w;
@@ -2090,45 +2107,6 @@ void control_config_do_frame(float frametime)
List_buttons[i++].disable();
}
// If multiple controls presets are provided, display which one is in use
if (Control_config_presets.size() > 1) {
SCP_string preset_str;
int matching_preset = -1;
for (i=0; i<(int)Control_config_presets.size(); i++) {
bool this_preset_matches = true;
config_item *this_preset = Control_config_presets[i];
for (j=0; j<CCFG_MAX; j++) {
if (!Control_config[j].disabled && Control_config[j].key_id != this_preset[j].key_default) {
this_preset_matches = false;
break;
}
}
if (this_preset_matches) {
matching_preset = i;
break;
}
}
if (matching_preset >= 0) {
sprintf(preset_str, "Controls: %s", Control_config_preset_names[matching_preset].c_str());
} else {
sprintf(preset_str, "Controls: custom");
}
gr_get_string_size(&w, NULL, preset_str.c_str());
gr_set_color_fast(&Color_text_normal);
if (gr_screen.res == GR_640) {
gr_string(16, (24 - font_height) / 2, preset_str.c_str(), GR_RESIZE_MENU);
} else {
gr_string(24, (40 - font_height) / 2, preset_str.c_str(), GR_RESIZE_MENU);
}
}
// blit help overlay if active
help_overlay_maybe_blit(Control_config_overlay_id, gr_screen.res);
@@ -2187,7 +2165,7 @@ void control_check_indicate()
#ifndef NDEBUG
if (Show_controls_info) {
gr_set_color_fast(&HUD_color_debug);
gr_printf_no_resize(gr_screen.center_offset_x + gr_screen.center_w - 154, gr_screen.center_offset_y + 5, NOX("Ctrls checked: %d"), Control_check_count);
gr_printf_no_resize(gr_screen.max_w - 154, 5, NOX("Ctrls checked: %d"), Control_check_count);
}
#endif
@@ -2257,8 +2235,7 @@ int check_control_used(int id, int key)
return 0;
}
if ((Control_config[id].key_id == key) || joy_down_count(Control_config[id].joy_id, 1) ||
((Control_config[id].joy_id >= 0) && (Control_config[id].joy_id < MOUSE_NUM_BUTTONS) && mouse_down_count(1 << Control_config[id].joy_id))) {
if ((Control_config[id].key_id == key) || joy_down_count(Control_config[id].joy_id, 1) || mouse_down_count(1 << Control_config[id].joy_id)) {
//mprintf(("Key used %d", key));
control_used(id);
return 1;
+2 -4
View File
@@ -8,11 +8,11 @@
*/
#include "globalincs/pstypes.h"
#ifndef CONTROLS_CONFIG_H
#define CONTROLS_CONFIG_H
#include "globalincs/pstypes.h"
#define CONTROL_CONFIG_XSTR 507
/*!
@@ -292,12 +292,10 @@ extern int Control_config_overlay_id;
extern config_item Control_config[]; //!< Stores the keyboard configuration
extern SCP_vector<config_item*> Control_config_presets; // tabled control presets; pointers to config_item arrays
extern SCP_vector<SCP_string> Control_config_preset_names; // names for Control_config_presets (identical order of items)
extern char **Scan_code_text;
extern char **Joy_button_text;
void control_config_common_init(); //!< initialize common control config stuff - call at game startup after localization has been initialized
void control_config_common_close(); //!< close common control config stuff - call at game shutdown
void control_config_init();
void control_config_do_frame(float frametime);
+3 -25
View File
@@ -12,12 +12,12 @@
#include "cfile/cfile.h"
#include "controlconfig/controlsconfig.h"
#include "globalincs/def_files.h"
#include "globalincs/systemvars.h"
#include "io/joy.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"
// z64: These enumerations MUST equal to those in controlsconfig.cpp...
// z64: Really need a better way than this.
@@ -404,7 +404,6 @@ char **Scan_code_text = Scan_code_text_english;
char **Joy_button_text = Joy_button_text_english;
SCP_vector<config_item*> Control_config_presets;
SCP_vector<SCP_string> Control_config_preset_names;
void set_modifier_status()
{
@@ -610,16 +609,6 @@ void control_config_common_init()
}
}
/*
* @brief close any common control config stuff, called at game_shutdown()
*/
void control_config_common_close()
{
// only need to worry control presets for now
for (auto ii = Control_config_presets.cbegin(); ii != Control_config_presets.cend(); ++ii) {
delete[] * ii;
}
}
#include <map>
@@ -822,14 +811,6 @@ void control_config_common_load_overrides()
std::copy(Control_config, Control_config + CCFG_MAX + 1, cfg_preset);
Control_config_presets.push_back(cfg_preset);
SCP_string preset_name;
if (optional_string("$Name:")) {
stuff_string_line(preset_name);
} else {
preset_name = "<unnamed preset>";
}
Control_config_preset_names.push_back(preset_name);
while (required_string_either("#End","$Bind Name:")) {
const int iBufferLength = 64;
char szTempBuffer[iBufferLength];
@@ -899,9 +880,6 @@ void control_config_common_load_overrides()
if (optional_string("+Disable")) {
r_ccConfig.disabled = true;
}
if (optional_string("$Disable:")) {
stuff_boolean(&r_ccConfig.disabled);
}
// Nerf the buffer now.
szTempBuffer[0] = '\0';
+60 -62
View File
@@ -10,17 +10,17 @@
#include "cutscene/cutscenes.h"
#include "freespace2/freespace.h"
#include "gamesequence/gamesequence.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/alphacolors.h"
#include "io/key.h"
#include "localization/localize.h"
#include "menuui/mainhallmenu.h"
#include "movie.h"
#include "parse/parselo.h"
#include "popup/popup.h"
#include "ui/ui.h"
#include "gamesnd/gamesnd.h"
#include "gamesequence/gamesequence.h"
#include "freespace2/freespace.h"
#include "io/key.h"
#include "movie.h"
#include "popup/popup.h"
#include "menuui/mainhallmenu.h"
#include "globalincs/alphacolors.h"
#include "localization/localize.h"
#include "parse/parselo.h"
extern int Cmdline_nomovies;
@@ -52,61 +52,59 @@ void cutscene_init()
{
atexit(cutscene_close);
char buf[MULTITEXT_LENGTH];
cutscene_info cutinfo;
int rval;
cutscene_info cutinfo;
try
{
read_file_text("cutscenes.tbl", CF_TYPE_TABLES);
reset_parse();
// parse in all the cutscenes
Cutscenes.clear();
skip_to_string("#Cutscenes");
ignore_white_space();
bool isFirstCutscene = true;
while (required_string_either("#End", "$Filename:"))
{
required_string("$Filename:");
stuff_string(cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN);
required_string("$Name:");
stuff_string(cutinfo.name, F_NAME, NAME_LENGTH);
required_string("$Description:");
stuff_string(buf, F_MULTITEXT, sizeof(buf));
drop_white_space(buf);
compact_multitext_string(buf);
cutinfo.description = vm_strdup(buf);
if (optional_string("$cd:"))
stuff_int(&cutinfo.cd);
else
cutinfo.cd = 0;
cutinfo.viewable = false;
if (isFirstCutscene) {
isFirstCutscene = false;
// The original code assumes the first movie is the intro, so always viewable
cutinfo.viewable = true;
}
if (optional_string("$Always Viewable:")) {
stuff_boolean(&cutinfo.viewable);
}
Cutscenes.push_back(cutinfo);
}
required_string("#End");
}
catch (const parse::ParseException& e)
{
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "cutscenes.tbl", e.what()));
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "cutscenes.tbl", rval));
return;
}
read_file_text("cutscenes.tbl", CF_TYPE_TABLES);
reset_parse();
// parse in all the cutscenes
Cutscenes.clear();
skip_to_string("#Cutscenes");
ignore_white_space();
bool isFirstCutscene = true;
while ( required_string_either("#End", "$Filename:") )
{
required_string("$Filename:");
stuff_string( cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN );
required_string("$Name:");
stuff_string( cutinfo.name, F_NAME, NAME_LENGTH );
required_string("$Description:");
stuff_string(buf, F_MULTITEXT, sizeof(buf));
drop_white_space(buf);
compact_multitext_string(buf);
cutinfo.description = vm_strdup(buf);
if (optional_string("$cd:"))
stuff_int( &cutinfo.cd );
else
cutinfo.cd = 0;
cutinfo.viewable = false;
if (isFirstCutscene) {
isFirstCutscene = false;
// The original code assumes the first movie is the intro, so always viewable
cutinfo.viewable = true;
}
if (optional_string("$Always Viewable:")) {
stuff_boolean(&cutinfo.viewable);
}
Cutscenes.push_back(cutinfo);
}
required_string("#End");
}
// function to return 0 based index of which CD a particular movie is on
+3 -3
View File
@@ -15,7 +15,7 @@ static void genLoopkupTable();
void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, unsigned char *pData, int dataRemain)
{
ubyte *pOrig, *pOffData, op;
ubyte *pOrig, *pOffData, *pEnd, op;
ushort offset;
int length = 0, i, j, xb, yb;
@@ -32,6 +32,7 @@ void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, unsigned char *pDa
offset = pData[0]|(pData[1]<<8);
pOffData = pData + offset;
pEnd = pData + offset;
pData += 2;
@@ -54,8 +55,7 @@ void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, unsigned char *pDa
}
if ((length-(pData-pOrig)) != 0) {
nprintf(("MVE", "DEBUG: junk left over: " PTRDIFF_T_ARG ",%d," PTRDIFF_T_ARG "\n",
(pData-pOrig), length, (length-(pData-pOrig))));
nprintf(("MVE", "DEBUG: junk left over: %d,%d,%d\n", (pData-pOrig), length, (length-(pData-pOrig))));
}
}
+9 -10
View File
@@ -13,21 +13,18 @@
#include <windows.h>
#endif
#include "cfile/cfile.h"
#include "cmdline/cmdline.h"
#include "cutscene/cutscenes.h" // cutscene_mark_viewable()
#include "graphics/2d.h"
#include "globalincs/systemvars.h"
#include "cutscene/movie.h"
#include "osapi/osapi.h"
#include "cmdline/cmdline.h"
#include "cfile/cfile.h"
#include "cutscene/cutscenes.h" // cutscene_mark_viewable()
#include "cutscene/mvelib.h"
#include "cutscene/oggplayer.h"
#include "globalincs/systemvars.h"
#include "graphics/2d.h"
#include "osapi/osapi.h"
extern int Game_mode;
const char *movie_ext_list[] = { ".ogg", ".mve" };
const int NUM_MOVIE_EXT = sizeof(movie_ext_list) / sizeof(char*);
#define MOVIE_NONE -1
#define MOVIE_OGG 0
@@ -45,6 +42,8 @@ int movie_find(char *filename, char *out_name)
char full_path[MAX_PATH];
char tmp_name[MAX_PATH];
int size, offset = 0;
const int NUM_EXT = 2;
const char *movie_ext[NUM_EXT] = { ".ogg", ".mve" };
if (out_name == NULL)
return MOVIE_NONE;
@@ -58,7 +57,7 @@ int movie_find(char *filename, char *out_name)
char *p = strrchr(tmp_name, '.');
if ( p ) *p = 0;
int rc = cf_find_file_location_ext(tmp_name, NUM_MOVIE_EXT, movie_ext_list, CF_TYPE_ANY, sizeof(full_path) - 1, full_path, &size, &offset, 0);
int rc = cf_find_file_location_ext(tmp_name, NUM_EXT, movie_ext, CF_TYPE_ANY, sizeof(full_path) - 1, full_path, &size, &offset, 0);
if (rc == MOVIE_NONE)
return MOVIE_NONE;
-3
View File
@@ -12,9 +12,6 @@
#ifndef _MOVIE_HEADER_FILE
#define _MOVIE_HEADER_FILE
extern const char *movie_ext_list[];
extern const int NUM_MOVIE_EXT;
bool movie_play(char *name);
void movie_play_two(char *name1, char *name2);
+2 -2
View File
@@ -1,8 +1,8 @@
#include "cfile/cfile.h"
#include "cutscene/mvelib.h"
#include "globalincs/pstypes.h"
#include "cutscene/mvelib.h"
#include "cfile/cfile.h"
static const char MVE_HEADER[] = "Interplay MVE File\x1A";
+42 -23
View File
@@ -6,21 +6,21 @@
#include <sys/time.h>
#endif
#include "bmpman/bmpman.h"
#include "cutscene/movie.h"
#include "cutscene/mvelib.h"
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "graphics/gropengl.h"
#include "graphics/gropengldraw.h"
#include "graphics/gropengltexture.h"
#include "graphics/gropenglextension.h"
#include "graphics/gropenglstate.h"
#include "graphics/gropengltexture.h"
#include "globalincs/pstypes.h"
#include "cutscene/mvelib.h"
#include "cutscene/movie.h"
#include "graphics/2d.h"
#include "io/key.h"
#include "io/timer.h"
#include "osapi/osapi.h"
#include "sound/openal.h"
#include "io/timer.h"
#include "sound/sound.h"
#include "sound/openal.h"
#include "bmpman/bmpman.h"
extern int Cmdline_noscalevid;
@@ -228,7 +228,7 @@ void mve_audio_createbuf(ubyte minor, ubyte *data)
return;
}
int flags, sample_rate;
int flags, desired_buffer, sample_rate;
mas = (mve_audio_t *) vm_malloc ( sizeof(mve_audio_t) );
memset(mas, 0, sizeof(mve_audio_t));
@@ -237,6 +237,7 @@ void mve_audio_createbuf(ubyte minor, ubyte *data)
flags = mve_get_ushort(data + 2);
sample_rate = mve_get_ushort(data + 4);
desired_buffer = mve_get_int(data + 6);
mas->channels = (flags & 0x0001) ? 2 : 1;
mas->bitsize = (flags & 0x0002) ? 16 : 8;
@@ -418,10 +419,16 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
}
short w, h;
short truecolor;
short count, truecolor;
w = mve_get_short(data);
h = mve_get_short(data+2);
if (minor > 0) {
count = mve_get_short(data+4);
} else {
count = 1;
}
if (minor > 1) {
truecolor = mve_get_short(data+6);
} else {
@@ -452,13 +459,13 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
if (gr_screen.mode == GR_OPENGL) {
GLfloat scale_by = 1.0f;
float screen_ratio = (float)gr_screen.center_w / (float)gr_screen.center_h;
float screen_ratio = (float)gr_screen.max_w / (float)gr_screen.max_h;
float movie_ratio = (float)g_width / (float)g_height;
if (screen_ratio > movie_ratio) {
scale_by = (float)gr_screen.center_h / (float)g_height;
scale_by = (float)gr_screen.max_h / (float)g_height;
} else {
scale_by = (float)gr_screen.center_w / (float)g_width;
scale_by = (float)gr_screen.max_w / (float)g_width;
}
// don't bother setting anything if we aren't going to need it
@@ -472,12 +479,12 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
}
if (mve_scale_video) {
g_screenX = ((ceil((gr_screen.center_w / scale_by) - 0.5f) - g_width) / 2) + ceil((gr_screen.center_offset_x / scale_by) - 0.5f);
g_screenY = ((ceil((gr_screen.center_h / scale_by) - 0.5f) - g_height) / 2) + ceil((gr_screen.center_offset_y / scale_by) - 0.5f);
g_screenX = ((ceil((gr_screen.max_w / scale_by) - 0.5f) - g_width) / 2);
g_screenY = ((ceil((gr_screen.max_h / scale_by) - 0.5f) - g_height) / 2);
} else {
// centers on 1024x768, fills on 640x480
g_screenX = ((float)(gr_screen.center_w - g_width) / 2.0f) + gr_screen.center_offset_x;
g_screenY = ((float)(gr_screen.center_h - g_height) / 2.0f) + gr_screen.center_offset_y;
g_screenX = ((float)(gr_screen.max_w - g_width) / 2.0f);
g_screenY = ((float)(gr_screen.max_h - g_height) / 2.0f);
}
// set additional values for screen width/height and UV coords
@@ -511,12 +518,12 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
GL_state.Array.BindArrayBuffer(0);
vertex_layout vertex_def;
GL_state.Array.EnableClientVertex();
GL_state.Array.VertexPointer(2, GL_FLOAT, sizeof(glVertices[0]), glVertices);
vertex_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
vertex_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
opengl_bind_vertex_layout(vertex_def);
GL_state.Array.SetActiveClientUnit(0);
GL_state.Array.EnableClientTexture();
GL_state.Array.TexPointer(2, GL_FLOAT, sizeof(glVertices[0]), &(glVertices[0][2]));
}
return 1;
@@ -718,9 +725,18 @@ void mve_video_codemap(ubyte *data, int len)
void mve_video_data(ubyte *data, int len)
{
short nFrameHot, nFrameCold;
short nXoffset, nYoffset;
short nXsize, nYsize;
ushort nFlags;
ubyte *temp;
nFrameHot = mve_get_short(data);
nFrameCold = mve_get_short(data+2);
nXoffset = mve_get_short(data+4);
nYoffset = mve_get_short(data+6);
nXsize = mve_get_short(data+8);
nYsize = mve_get_short(data+10);
nFlags = mve_get_ushort(data+12);
if (nFlags & 1) {
@@ -781,6 +797,9 @@ void mve_play(MVESTREAM *mve)
void mve_shutdown()
{
if (gr_screen.mode == GR_OPENGL) {
GL_state.Array.DisableClientVertex();
GL_state.Array.DisableClientTexture();
if (mve_scale_video) {
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
+75 -30
View File
@@ -9,23 +9,22 @@
#include <errno.h>
#endif
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "cutscene/oggplayer.h"
#include "globalincs/def_files.h"
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "globalincs/def_files.h"
#include "cfile/cfile.h"
#include "graphics/gropengl.h"
#include "graphics/gropengldraw.h"
#include "graphics/gropengltexture.h"
#include "graphics/gropenglextension.h"
#include "graphics/gropenglshader.h"
#include "graphics/gropenglstate.h"
#include "graphics/gropengltexture.h"
#include "graphics/2d.h"
#include "io/key.h"
#include "io/timer.h"
#include "osapi/osapi.h"
#include "sound/openal.h"
#include "sound/sound.h"
#include "sound/openal.h"
#include "bmpman/bmpman.h"
#include "cutscene/oggplayer.h"
#include "io/timer.h"
#include "theora/theora.h"
#include "vorbis/codec.h"
@@ -332,6 +331,8 @@ static void OGG_video_init(theora_info *tinfo)
{
float scale_by = 0.0f;
GLhandleARB shader_id = 0;
if (video_inited)
return;
@@ -345,7 +346,7 @@ 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(!is_minimum_GLSL_version())
if(!Use_GLSL)
use_shaders = false;
if(use_shaders) {
@@ -364,11 +365,52 @@ static void OGG_video_init(theora_info *tinfo)
return;
}
int sdr_handle = gr_maybe_create_shader(SDR_TYPE_VIDEO_PROCESS, 0);
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";
if ( sdr_handle >= 0)
opengl_shader_set_current(sdr_handle);
else
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;
}
@@ -435,13 +477,13 @@ static void OGG_video_init(theora_info *tinfo)
// 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.center_w / (float)gr_screen.center_h;
float screen_ratio = (float)gr_screen.max_w / (float)gr_screen.max_h;
float movie_ratio = (float)g_screenWidth / (float)g_screenHeight;
if (screen_ratio > movie_ratio)
scale_by = (float)gr_screen.center_h / (float)g_screenHeight;
scale_by = (float)gr_screen.max_h / (float)g_screenHeight;
else
scale_by = (float)gr_screen.center_w / (float)g_screenWidth;
scale_by = (float)gr_screen.max_w / (float)g_screenWidth;
// don't bother setting anything if we aren't going to need it
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
@@ -470,12 +512,12 @@ static void OGG_video_init(theora_info *tinfo)
if (scale_video) {
g_screenX = ((fl2i(gr_screen.center_w / scale_by + 0.5f) - g_screenWidth) / 2) + fl2i(gr_screen.center_offset_x / scale_by + 0.5f);
g_screenY = ((fl2i(gr_screen.center_h / scale_by + 0.5f) - g_screenHeight) / 2) + fl2i(gr_screen.center_offset_y / scale_by + 0.5f);
g_screenX = ((fl2i(gr_screen.max_w / scale_by + 0.5f) - g_screenWidth) / 2);
g_screenY = ((fl2i(gr_screen.max_h / scale_by + 0.5f) - g_screenHeight) / 2);
} else {
// centers on 1024x768, fills on 640x480
g_screenX = ((gr_screen.center_w - g_screenWidth) / 2) + gr_screen.center_offset_x;
g_screenY = ((gr_screen.center_h - g_screenHeight) / 2) + gr_screen.center_offset_y;
g_screenX = ((gr_screen.max_w - g_screenWidth) / 2);
g_screenY = ((gr_screen.max_h - g_screenHeight) / 2);
}
// set additional values for screen width/height and UV coords
@@ -490,9 +532,9 @@ static void OGG_video_init(theora_info *tinfo)
gl_screenU = i2fl(tinfo->frame_width-1) / i2fl(2048) ;
gl_screenV = i2fl(tinfo->frame_height-1) / i2fl(2048);
GL_state.Texture.SetShaderMode(GL_TRUE);
GL_state.Uniform.setUniformi("ytex", 0);
GL_state.Uniform.setUniformi("utex", 1);
GL_state.Uniform.setUniformi("vtex", 2);
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "ytex"), 0 );
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "utex"), 1 );
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "vtex"), 2 );
}
glVertices[0][0] = (GLfloat)g_screenX;
@@ -517,12 +559,12 @@ static void OGG_video_init(theora_info *tinfo)
GL_state.Array.BindArrayBuffer(0);
vertex_layout vert_def;
GL_state.Array.EnableClientVertex();
GL_state.Array.VertexPointer(2, GL_FLOAT, sizeof(glVertices[0]), glVertices);
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
opengl_bind_vertex_layout(vert_def);
GL_state.Array.SetActiveClientUnit(0);
GL_state.Array.EnableClientTexture();
GL_state.Array.TexPointer(2, GL_FLOAT, sizeof(glVertices[0]), &(glVertices[0][2]));
}
if(!use_shaders && tinfo->frame_height > 450) {
mprintf(("VIDEO: No shader support and hd video is beeing played this can get choppy."));
@@ -537,6 +579,9 @@ static void OGG_video_close()
}
if (gr_screen.mode == GR_OPENGL) {
GL_state.Array.DisableClientVertex();
GL_state.Array.DisableClientTexture();
if (scale_video) {
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
@@ -559,7 +604,7 @@ static void OGG_video_close()
ytex = utex = vtex = 0;
GLtex = 0;
GL_state.Texture.SetShaderMode(GL_FALSE);
opengl_shader_set_current();
opengl_shader_set_current( 0 );
}
if (pixelbuf != NULL) {
+2 -2
View File
@@ -36,7 +36,7 @@ int dds_read_header(const char *filename, CFILE *img_cfp, int *width, int *heigh
int retval = DDS_ERROR_NONE;
int ct = DDS_UNCOMPRESSED;
int bits = 0;
int i, is_cubemap = 0;
int i, trash, is_cubemap = 0;
int d_width = 0, d_height = 0, d_depth = 0, d_size = 0;
@@ -80,7 +80,7 @@ int dds_read_header(const char *filename, CFILE *img_cfp, int *width, int *heigh
// skip over the crap we don't care about
for (i = 0; i < 11; i++)
cfread_uint(ddsfile);
trash = cfread_uint(ddsfile);
dds_header.ddpfPixelFormat.dwSize = cfread_uint(ddsfile);
dds_header.ddpfPixelFormat.dwFlags = cfread_uint(ddsfile);
+37 -94
View File
@@ -9,26 +9,26 @@
#include "cmdline/cmdline.h"
#include "debris/debris.h"
#include "render/3d.h"
#include "fireball/fireballs.h"
#include "freespace2/freespace.h"
#include "radar/radar.h"
#include "gamesnd/gamesnd.h"
#include "object/objectsnd.h"
#include "globalincs/linklist.h"
#include "particle/particle.h"
#include "freespace2/freespace.h"
#include "object/objcollide.h"
#include "io/timer.h"
#include "species_defs/species_defs.h"
#include "ship/ship.h"
#include "ship/shipfx.h"
#include "radar/radarsetup.h"
#include "network/multi.h"
#include "network/multimsgs.h"
#include "network/multiutil.h"
#include "object/objcollide.h"
#include "object/objectsnd.h"
#include "particle/particle.h"
#include "radar/radar.h"
#include "radar/radarsetup.h"
#include "render/3d.h"
#include "ship/ship.h"
#include "ship/shipfx.h"
#include "species_defs/species_defs.h"
#include "weapon/weapon.h"
#include "cmdline/cmdline.h"
#define MAX_LIFE 10.0f
#define MIN_RADIUS_FOR_PERSISTANT_DEBRIS 50 // ship radius at which debris from it becomes persistant
@@ -147,7 +147,7 @@ MONITOR(NumHullDebrisRend)
/**
* Render debris
*/
void debris_render_DEPRECATED(object * obj)
void debris_render(object * obj)
{
int i, num, swapped;
polymodel *pm;
@@ -191,10 +191,10 @@ void debris_render_DEPRECATED(object * obj)
if ( db->is_hull ) {
MONITOR_INC(NumHullDebrisRend,1);
submodel_render_DEPRECATED( db->model_num, db->submodel_num, &obj->orient, &obj->pos );
submodel_render( db->model_num, db->submodel_num, &obj->orient, &obj->pos );
} else {
MONITOR_INC(NumSmallDebrisRend,1);
submodel_render_DEPRECATED( db->model_num, db->submodel_num, &obj->orient, &obj->pos, MR_NO_LIGHTING );
submodel_render( db->model_num, db->submodel_num, &obj->orient, &obj->pos, MR_NO_LIGHTING );
}
if (tbase != NULL && (swapped!=-1) && pm) {
@@ -563,7 +563,6 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
db->is_hull = hull_flag;
db->source_objnum = parent_objnum;
db->source_sig = source_obj->signature;
db->damage_type_idx = shipp->debris_damage_type_idx;
db->ship_info_index = shipp->ship_info_index;
db->team = shipp->team;
db->fire_timeout = 0; // if not changed, timestamp_elapsed() will return false
@@ -704,7 +703,7 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
// 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_cross ( &vel_from_rotvel, &world_rotvel, &to_center );
vm_vec_crossprod ( &vel_from_rotvel, &world_rotvel, &to_center );
vm_vec_scale ( &vel_from_rotvel, DEBRIS_ROTVEL_SCALE);
vm_vec_add (&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel);
@@ -844,18 +843,18 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
}
// debris ship collision -- use debris_hit_info to calculate physics
object *pship_obj = other_obj;
Assert( pship_obj->type == OBJ_SHIP );
object *ship_obj = other_obj;
Assert( ship_obj->type == OBJ_SHIP );
object *heavy = debris_hit_info->heavy;
object *lighter = debris_hit_info->light;
object *light = debris_hit_info->light;
object *heavy_obj = heavy;
object *light_obj = lighter;
object *light_obj = light;
vec3d zero, p0, p1;
vm_vec_zero(&zero);
vm_vec_sub(&p0, &lighter->last_pos, &heavy->last_pos);
vm_vec_sub(&p1, &lighter->pos, &heavy->pos);
vm_vec_sub(&p0, &light->last_pos, &heavy->last_pos);
vm_vec_sub(&p1, &light->pos, &heavy->pos);
mc.pos = &zero; // The object's position
mc.p0 = &p0; // Point 1 of ray to check
@@ -876,15 +875,15 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
vm_vec_scale(&debris_hit_info->light_rel_vel, 1/flFrametime);
} else {
debris_hit_info->collide_rotate = 0;
vm_vec_sub(&debris_hit_info->light_rel_vel, &lighter->phys_info.vel, &heavy->phys_info.vel);
vm_vec_sub(&debris_hit_info->light_rel_vel, &light->phys_info.vel, &heavy->phys_info.vel);
}
int mc_ret_val = 0;
if ( debris_hit_info->heavy == pship_obj ) { // ship is heavier, so debris is sphere. Check sphere collision against ship poly model
mc.model_instance_num = Ships[pship_obj->instance].model_instance_num;
mc.model_num = Ship_info[Ships[pship_obj->instance].ship_info_index].model_num; // Fill in the model to check
mc.orient = &pship_obj->orient; // The object's orient
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;
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
@@ -898,8 +897,11 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE;
SCP_vector<int> submodel_vector;
polymodel *pm;
polymodel_instance *pmi;
ship_model_start(ship_obj);
if (model_collide(&mc)) {
// Set earliest hit time
@@ -913,6 +915,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
model_get_rotating_submodel_list(&submodel_vector, 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
@@ -923,10 +926,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
// 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;
if (Ship_info[Ships[pship_obj->instance].ship_info_index].collision_lod > -1) {
mc.lod = Ship_info[Ships[pship_obj->instance].ship_info_index].collision_lod;
}
// check each submodel in turn
for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
// turn on submodel for collision test
@@ -937,10 +936,10 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
// 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, pmi, *smv, &heavy_obj->last_orient, &heavy_obj->last_pos);
world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, *smv, &heavy_obj->last_orient, &heavy_obj->last_pos);
pmi->submodel[*smv].angs = copy_angles;
world_find_model_instance_point(&p1, &light_obj->pos, pmi, *smv, &heavy_obj->orient, &heavy_obj->pos);
world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, *smv, &heavy_obj->orient, &heavy_obj->pos);
mc.p0 = &p0;
mc.p1 = &p1;
@@ -954,18 +953,18 @@ 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_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
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);
// 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, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient);
model_instance_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_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
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);
}
}
// Don't look at this submodel again
@@ -989,7 +988,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, Ships[heavy_obj->instance].model_instance_num, mc.hit_submodel, &heavy_obj->orient);
model_instance_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
@@ -1008,7 +1007,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
mc.submodel_num = Debris[num].submodel_num;
model_clear_instance( mc.model_num );
mc.orient = &pdebris->orient; // The object's orient
mc.radius = model_get_core_radius(Ship_info[Ships[pship_obj->instance].ship_info_index].model_num);
mc.radius = model_get_core_radius(Ship_info[Ships[ship_obj->instance].ship_info_index].model_num);
// check for collision between debris model and ship sphere
mc.flags = (MC_CHECK_MODEL | MC_SUBMODEL | MC_CHECK_SPHERELINE);
@@ -1095,59 +1094,3 @@ void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs
pi->I_body_inv.vec.fvec.xyz.y = 0.0f;
pi->I_body_inv.vec.fvec.xyz.z = 12.0f / (pi->mass * (dx*dx + dy*dy));
}
void debris_render(object * obj, draw_list *scene)
{
int i, num, swapped;
polymodel *pm;
debris *db;
swapped = -1;
pm = NULL;
num = obj->instance;
Assert(num >= 0 && num < MAX_DEBRIS_PIECES);
db = &Debris[num];
Assert(db->flags & DEBRIS_USED);
texture_info *tbase = NULL;
model_clear_instance( db->model_num );
// Swap in a different texture depending on the species
if (db->species >= 0)
{
pm = model_get( db->model_num );
//WMC - Someday, we should have glowing debris.
if ( pm != NULL && (pm->n_textures == 1) ) {
tbase = &pm->maps[0].textures[TM_BASE_TYPE];
swapped = tbase->GetTexture();
tbase->SetTexture(Species_info[db->species].debris_texture.bitmap_id);
}
}
// Only render electrical arcs if within 500m of the eye (for a 10m piece)
if ( vm_vec_dist_quick( &obj->pos, &Eye_position ) < obj->radius*50.0f ) {
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
if ( timestamp_valid( db->arc_timestamp[i] ) ) {
model_add_arc( db->model_num, db->submodel_num, &db->arc_pts[i][0], &db->arc_pts[i][1], MARC_TYPE_NORMAL );
}
}
}
model_render_params render_info;
if ( !db->is_hull ) {
render_info.set_flags(MR_NO_LIGHTING);
}
MONITOR_INC(NumHullDebrisRend,1);
submodel_render_queue( &render_info, scene, db->model_num, db->submodel_num, &obj->orient, &obj->pos );
if (tbase != NULL && (swapped!=-1) && pm) {
tbase->SetTexture(swapped);
}
}
+1 -4
View File
@@ -16,7 +16,6 @@
class object;
struct CFILE;
class draw_list;
#define MAX_DEBRIS_ARCS 8 // Must be less than MAX_ARC_EFFECTS in model.h
@@ -25,7 +24,6 @@ typedef struct debris {
int flags; // See DEBRIS_??? defines
int source_objnum; // What object this came from
int source_sig; // Signature of the source object
int damage_type_idx; // Damage type of this debris
int ship_info_index; // Ship info index of the ship type debris came from
int team; // Team of the ship where the debris came from
int objnum; // What object this is linked to
@@ -63,8 +61,7 @@ extern int Num_debris_pieces;
struct collision_info_struct;
void debris_init();
void debris_render_DEPRECATED( object * obj );
void debris_render(object * obj, draw_list *scene);
void debris_render( object * obj );
void debris_delete( object * obj );
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 );
+14 -12
View File
@@ -9,12 +9,15 @@
#include "debugconsole/console.h"
#include "debugconsole/consoleparse.h"
#include "globalincs/alphacolors.h"
#include "globalincs/pstypes.h"
#include "globalincs/version.h"
#include "globalincs/vmallocator.h"
#include "graphics/2d.h"
#include "graphics/font.h"
#include "io/key.h"
#include "io/timer.h"
#include "io/key.h"
#include "osapi/osapi.h"
#include <algorithm>
@@ -101,8 +104,7 @@ void dc_draw(bool show_prompt);
/**
* Draws the cursor
* @param [in] cmd_string The formatted command string displayed by dc_draw_window
* @param [in] x The x screen position of the command string
* @param [in] y The y screen position of the command string
* @param [in] x y The x and y screen position of the command string
*/
void dc_draw_cursor( SCP_string &cmd_string, int x, int y );
@@ -187,7 +189,7 @@ void dc_draw(bool show_prompt = FALSE)
gr_clear();
gr_set_font(dc_font);
gr_set_color_fast( &Color_bright );
gr_string( 0x8000, gr_screen.center_offset_y + 3, dc_title.c_str(), GR_RESIZE_NONE );
gr_string( 0x8000, 3, dc_title.c_str(), GR_RESIZE_NONE );
gr_set_color_fast( &Color_normal );
@@ -207,7 +209,7 @@ void dc_draw_cursor( SCP_string &cmd_string, int x, int y )
w %= (DCOLS * Current_font->w);
//gr_string( w, debug_y*16, "_" );
gr_rect(gr_screen.center_offset_x + (x + (w + 1)), gr_screen.center_offset_y + (y + (h + 1)), 2, Current_font->h, GR_RESIZE_NONE);
gr_rect((x + (w + 1)), (y + (h + 1)), 2, Current_font->h, GR_RESIZE_NONE);
}
}
@@ -243,7 +245,7 @@ void dc_draw_window(bool show_prompt)
// Draw the buffer strings
for (i = 0; i < buffer_lines; ++i) {
if ((i + dc_scroll_y) < dc_buffer.size()) {
gr_string(gr_screen.center_offset_x, gr_screen.center_offset_y + ((i * row_height) + row_height), dc_buffer[i + dc_scroll_y].substr(dc_scroll_x).c_str(), GR_RESIZE_NONE);
gr_string(0, ((i * row_height) + row_height), dc_buffer[i + dc_scroll_y].substr(dc_scroll_x).c_str(), GR_RESIZE_NONE);
}
}
@@ -261,7 +263,7 @@ void dc_draw_window(bool show_prompt)
++j;
}
}
gr_string(gr_screen.center_offset_x, gr_screen.center_offset_y + ((i * row_height) + row_height), out_str.c_str(), GR_RESIZE_NONE);
gr_string(0, ((i * row_height) + row_height), out_str.c_str(), GR_RESIZE_NONE);
dc_draw_cursor(out_str, 0, ((i * row_height)));
gr_set_color_fast(&Color_normal);
@@ -282,8 +284,8 @@ void dc_init(void)
col_width = Current_font->w; // Col/Character width, in pixels
dc_scroll_x = 0;
dc_scroll_y = 0;
DCOLS = (gr_screen.center_w / col_width) - 1; // Subtract as needed. Windowed mode has some quirks with the resolution
DROWS = (gr_screen.center_h / row_height) - 2;
DCOLS = (gr_screen.max_w / col_width) - 1; // Subtract as needed. Windowed mode has some quirks with the resolution
DROWS = (gr_screen.max_h / row_height) - 2;
DBCOLS = DCOLS;
DBROWS = 2 * DROWS;
@@ -389,7 +391,7 @@ void dc_putc(char c)
temp_str.push_back(c);
gr_get_string_size(&w, NULL, temp_str.c_str());
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.center_w)) {
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.max_w)) {
c = '\n';
} else {
@@ -413,7 +415,7 @@ void dc_putc(char c)
temp_str.append(i, ' ');
gr_get_string_size(&w, NULL, temp_str.c_str());
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.center_w)) {
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.max_w)) {
c = '\n';
} else {
@@ -456,7 +458,7 @@ void dc_putc(char c)
temp_str.push_back(c);
gr_get_string_size(&w, NULL, temp_str.c_str());
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.center_w)) {
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.max_w)) {
/**
* Word wrapping
* Save the word, clear the line of the word, push new line with the word on it
+2
View File
@@ -19,6 +19,8 @@
#include "debugconsole/console.h"
#include "debugconsole/consoleparse.h"
#include "globalincs/pstypes.h"
#include "globalincs/vmallocator.h"
#include "io/key.h"
#include <algorithm>
+5 -3
View File
@@ -12,8 +12,10 @@
// @todo Make a fast version of the parse_long, parse_ulong, etc. That just checks the first 1-3 characters. The fast version will be used in retail builds while the slow/safe version will be in debug's
// @todo Maybe make parser functions case-insensitive
////////////////
#include "debugconsole/consoleparse.h"
#include "debugconsole/console.h"
#include "globalincs/pstypes.h"
#include "parse/parselo.h"
#include <algorithm>
@@ -88,7 +90,7 @@ void dc_get_token_no_advance(SCP_string &out_str);
* @param[in] ch Points to the start of the string to parse
* @param[in] type The expected type. is thrown along with ch when an unexpected/malformed float is found
*
* @return The value of the parsed token
* @ret The value of the parsed token
* @details
* The returned double may be cast to a single-precision float, but be sure to check it before doing so!
*/
@@ -1065,7 +1067,7 @@ void dc_stuff_float(float *f)
value_d = dc_parse_double(token.c_str(), DCT_FLOAT); // Parse and convert
// Stuff value if within bounds
if ((std::abs(value_d) < FLT_MAX) && (std::abs(value_d) > FLT_MIN)) {
if ((abs(value_d) < FLT_MAX) && (abs(value_d) > FLT_MIN)) {
*f = static_cast<float>(value_d);
} else {
throw errParse(token.c_str(), DCT_FLOAT);
-1
View File
@@ -14,7 +14,6 @@
* @details A lot of functions here are blatently copied from parselo.h :D
*/
#include "debugconsole/console.h"
#include "globalincs/pstypes.h"
#include <cstdarg>
+239
View File
@@ -0,0 +1,239 @@
/*
* Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
*
* You may not sell or otherwise commercially exploit the source or things you
* created based on the source.
*
*/
/*
* This module is intended as a debug tool to measure the speed of blocks of code and display
* that information as coloured bars across the top of the screen.
*
* This allows interactive measuring of components of the code, very useful for optimisztion.
*/
#ifdef _WIN32
#include <windows.h>
#include <winbase.h>
#endif
#include "timerbar.h"
#include "globalincs/pstypes.h"
// Internal structure for handling frame data
typedef struct
{
LARGE_INTEGER start_value;
LARGE_INTEGER total_value;
LARGE_INTEGER average;
LARGE_INTEGER frame_total;
} timerbar_profile;
timerbar_profile profiles[MAX_NUM_TIMERBARS];
int timerbar_current_profile = 0;
LARGE_INTEGER timerbar_ultimate_start_value;
LARGE_INTEGER timerbar_last_start_value;
// Data needed for push and pop functionality
const int MAX_TB_STACK_SIZE = 100;
int timerbar_stack[MAX_TB_STACK_SIZE];
int timerbar_current_stack_layer = 0;
/**
* Pssst, hey, you. Ya wanna timerbar? Real cheap.
*
* @param value Index count value (?)
*/
void timerbar_push(int value)
{
if(timerbar_current_stack_layer >= MAX_TB_STACK_SIZE)
{
// To many pushs, this must be a bug
// Someone is letting code miss the pops, check for early retuns
Assert(!(timerbar_current_stack_layer >= MAX_TB_STACK_SIZE));
return;
}
timerbar_stack[timerbar_current_stack_layer] = timerbar_current_profile;
timerbar_current_stack_layer++;
timerbar_switch_type(value);
}
/*
*/
void timerbar_pop()
{
timerbar_current_stack_layer--;
if(timerbar_current_stack_layer < 0)
{
Assert(!(timerbar_current_stack_layer < 0));
timerbar_current_stack_layer = 0;
return;
}
timerbar_switch_type(timerbar_stack[timerbar_current_stack_layer]);
}
/**
* This pointer holds the draw function to use or NULL
*
* @param colour Colour index (>=0)
* @param x Coordinate position
* @param y Coordinate position
* @param w element width
* @param h element height
*/
void (*draw_func_ptr)(int colour, float x, float y, float w, float h) = NULL;
/*
*/
void timerbar_start_frame()
{
timerbar_current_stack_layer = 0;
timerbar_current_profile = 0;
if(QueryPerformanceCounter(&timerbar_ultimate_start_value) == FALSE)
{
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
draw_func_ptr = NULL;
}
timerbar_last_start_value = timerbar_ultimate_start_value;
}
// Constants need for timerbar_conv_and_draw calculations
const int WIDTH = 480;
const float WIDTHF = ((float) WIDTH) * 1.01f;
/**
* Internal conversion function to convert draw data into bars for the screen
*
* @param 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
*/
void timerbar_conv_and_draw(int colour, int xpos, int xwidth, int yrow)
{
float fxpos = (float) xpos;
float fxwidth = (float) xwidth;
draw_func_ptr(colour,
fxpos / WIDTHF,
yrow * 0.01f,
fxwidth / WIDTHF,
0.005f);
}
/*
*/
void timerbar_end_frame()
{
// Now we want to draw the bars
if(draw_func_ptr == NULL)
{
// we have not been given a draw function so we are going to have to quit
return;
}
timerbar_switch_type(-1);
int last_xpos = 0;
int y_pos = 0;
for(int i = 0; i < MAX_NUM_TIMERBARS; i++)
{
// Nothing to render this frame
if(profiles[i].frame_total.QuadPart == 0)
{
continue;
}
int xsize = (int) profiles[i].frame_total.QuadPart / 90;
// break condition in else
while(1)
{
// if bar runs over
if(last_xpos + xsize > WIDTH)
{
int rem_len = WIDTH - last_xpos;
// Draw from current position to the end of the bar
timerbar_conv_and_draw(i, last_xpos, rem_len, y_pos);
xsize -= rem_len;
last_xpos = 0;
y_pos++;
}
else
{
// Draw whats left and break for the next bar
timerbar_conv_and_draw(i,last_xpos, xsize, y_pos);
last_xpos += xsize;
break;
}
}
// reset for next frame
profiles[i].frame_total.QuadPart = 0;
}
}
/**
* Not entirely sure what this does.
*
* @param num Probably a pretend boolean
*/
void timerbar_switch_type(int num)
{
if(num >= MAX_NUM_TIMERBARS)
{
return;
}
// Calculate old profile's total
LARGE_INTEGER now;
if(QueryPerformanceCounter(&now) == FALSE)
{
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
}
profiles[timerbar_current_profile].frame_total.QuadPart +=
(now.QuadPart - timerbar_last_start_value.QuadPart);
if(num != -1)
{
// Switch to new profile
timerbar_current_profile = num;
}
// Update time to count from
if(QueryPerformanceCounter(&timerbar_last_start_value) == FALSE)
{
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
}
}
/**
* Clears the instance of the timer bar
*
* Look at the parameters for "void (*draw_func_ptr)"
* They directly equate the new_draw_func_ptr, but we can't
* place params for a double stuffed function like this.
*/
void timerbar_set_draw_func(void (*new_draw_func_ptr)(int colour, float x, float y, float w, float h))
{
draw_func_ptr = new_draw_func_ptr;
}
+30
View File
@@ -0,0 +1,30 @@
/*
* Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
*
* You may not sell or otherwise commercially exploit the source or things you
* created based on the source.
*
*/
#ifndef _TIMERBAR_HEADER_
#define _TIMERBAR_HEADER_
const int MAX_NUM_TIMERBARS = 20;
#include "cmdline/cmdline.h"
// These functions should never be used directly, always use macros below
void timerbar_start_frame();
void timerbar_end_frame();
void timerbar_set_draw_func(void (*new_draw_func_ptr)(int colour, float x, float y, float w, float h));
void timerbar_push(int value);
void timerbar_pop();
// This function shouldnt not be used any more or it will break push and pop calls
void timerbar_switch_type(int num);
#endif
+82 -161
View File
@@ -9,17 +9,18 @@
#include "asteroid/asteroid.h"
#include "cmdline/cmdline.h"
#include "fireball/fireballs.h"
#include "gamesnd/gamesnd.h"
#include "graphics/tmapper.h"
#include "localization/localize.h"
#include "render/3d.h"
#include "model/model.h"
#include "object/object.h"
#include "parse/parselo.h"
#include "render/3d.h"
#include "ship/ship.h"
#include "gamesnd/gamesnd.h"
#include "localization/localize.h"
#include "cmdline/cmdline.h"
#include "parse/parselo.h"
#include "globalincs/pstypes.h"
#include "asteroid/asteroid.h"
#include <stdlib.h>
@@ -75,7 +76,7 @@ void fireball_play_warphole_open_sound(int ship_class, fireball *fb)
if(fb->warp_open_sound_index > -1) {
sound_index = fb->warp_open_sound_index;
} else if ((ship_class >= 0) && (ship_class < static_cast<int>(Ship_info.size()))) {
} else if((ship_class >= 0) && (ship_class < Num_ship_classes)){
if ( Ship_info[ship_class].flags & SIF_HUGE_SHIP ) {
sound_index = SND_CAPITAL_WARP_IN;
fb->flags |= FBF_WARP_CAPITAL_SIZE;
@@ -158,93 +159,84 @@ static void fireball_set_default_color(int idx)
*/
void parse_fireball_tbl(const char *filename)
{
int rval;
lod_checker lod_check;
color fb_color;
try
{
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
required_string("#Start");
while (required_string_either("#End", "$Name:")) {
memset(&lod_check, 0, sizeof(lod_checker));
// base filename
required_string("$Name:");
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
lod_check.override = -1;
// these entries should only be in TBMs, and it has to include at least one
if (Parsing_modular_table) {
if (optional_string("+Explosion_Medium")) {
lod_check.override = FIREBALL_EXPLOSION_MEDIUM;
}
else if (optional_string("+Warp_Effect")) {
lod_check.override = FIREBALL_WARP;
}
else if (optional_string("+Knossos_Effect")) {
lod_check.override = FIREBALL_KNOSSOS;
}
else if (optional_string("+Asteroid")) {
lod_check.override = FIREBALL_ASTEROID;
}
else if (optional_string("+Explosion_Large1")) {
lod_check.override = FIREBALL_EXPLOSION_LARGE1;
}
else if (optional_string("+Explosion_Large2")){
lod_check.override = FIREBALL_EXPLOSION_LARGE2;
}
else {
required_string("+Custom_Fireball");
stuff_int(&lod_check.override);
}
}
lod_check.num_lods = 1;
// Do we have an LOD num
if (optional_string("$LOD:")) {
stuff_int(&lod_check.num_lods);
}
if (lod_check.num_lods > MAX_FIREBALL_LOD) {
lod_check.num_lods = MAX_FIREBALL_LOD;
}
// check for particular lighting color
if (optional_string("$Light color:")) {
int r, g, b;
stuff_int(&r);
stuff_int(&g);
stuff_int(&b);
CLAMP(r, 0, 255);
CLAMP(g, 0, 255);
CLAMP(b, 0, 255);
gr_init_color(&fb_color, r, g, b);
}
else {
// to keep things simple, we just use 0 alpha to indicate that a default value should be used
memset(&fb_color, 0, sizeof(color));
}
// we may use one filename for multiple entries so we'll have to handle dupes post parse
LOD_checker.push_back(lod_check);
LOD_color.push_back(fb_color);
}
required_string("#End");
}
catch (const parse::ParseException& e)
{
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
return;
}
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
required_string("#Start");
while (required_string_either("#End", "$Name:")) {
memset( &lod_check, 0, sizeof(lod_checker) );
// base filename
required_string("$Name:");
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
lod_check.override = -1;
// these entries should only be in TBMs, and it has to include at least one
if ( Parsing_modular_table ) {
if (optional_string("+Explosion_Medium")) {
lod_check.override = FIREBALL_EXPLOSION_MEDIUM;
} else if (optional_string("+Warp_Effect")) {
lod_check.override = FIREBALL_WARP;
} else if (optional_string("+Knossos_Effect")) {
lod_check.override = FIREBALL_KNOSSOS;
} else if (optional_string("+Asteroid")) {
lod_check.override = FIREBALL_ASTEROID;
} else if (optional_string("+Explosion_Large1")) {
lod_check.override = FIREBALL_EXPLOSION_LARGE1;
} else if (optional_string("+Explosion_Large2")){
lod_check.override = FIREBALL_EXPLOSION_LARGE2;
} else {
required_string("+Custom_Fireball");
stuff_int(&lod_check.override);
}
}
lod_check.num_lods = 1;
// Do we have an LOD num
if (optional_string("$LOD:")) {
stuff_int(&lod_check.num_lods);
}
if (lod_check.num_lods > MAX_FIREBALL_LOD) {
lod_check.num_lods = MAX_FIREBALL_LOD;
}
// check for particular lighting color
if ( optional_string("$Light color:") ) {
int r, g, b;
stuff_int(&r);
stuff_int(&g);
stuff_int(&b);
CLAMP(r, 0, 255);
CLAMP(g, 0, 255);
CLAMP(b, 0, 255);
gr_init_color(&fb_color, r, g, b);
} else {
// to keep things simple, we just use 0 alpha to indicate that a default value should be used
memset( &fb_color, 0, sizeof(color) );
}
// we may use one filename for multiple entries so we'll have to handle dupes post parse
LOD_checker.push_back(lod_check);
LOD_color.push_back(fb_color);
}
required_string("#End");
}
void fireball_parse_tbl()
@@ -374,7 +366,7 @@ void fireball_init()
MONITOR( NumFireballsRend )
void fireball_render_DEPRECATED(object * obj)
void fireball_render(object * obj)
{
int num;
vertex p;
@@ -1051,74 +1043,3 @@ float fireball_wormhole_intensity( object *obj )
}
return rad;
}
void fireball_render(object* obj, draw_list *scene)
{
int num;
vertex p;
fireball *fb;
MONITOR_INC( NumFireballsRend, 1 );
num = obj->instance;
fb = &Fireballs[num];
if ( Fireballs[num].current_bitmap < 0 )
return;
if ( Cmdline_nohtl ) {
g3_rotate_vertex(&p, &obj->pos );
} else {
g3_transfer_vertex(&p, &obj->pos);
}
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
);
}
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
);
}
break;
case FIREBALL_WARP_EFFECT: {
float percent_life = fb->time_elapsed / fb->total_time;
float rad;
// Code to make effect grow/shrink.
float t = fb->time_elapsed;
if ( t < WARPHOLE_GROW_TIME ) {
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
} 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;
}
warpin_queue_render(scene, obj, &obj->orient, &obj->pos, Fireballs[num].current_bitmap, rad, percent_life, obj->radius, (Fireballs[num].flags & FBF_WARP_3D) );
}
break;
default:
Int3();
}
}
+1 -5
View File
@@ -13,7 +13,6 @@
#define _FIREBALLS_H
#include "globalincs/pstypes.h"
#include "model/modelrender.h"
class object;
class ship_info;
@@ -77,8 +76,7 @@ typedef struct fireball {
// end move
void fireball_init();
void fireball_render_DEPRECATED(object * obj);
void fireball_render(object* obj, draw_list *scene);
void fireball_render(object * obj);
void fireball_delete( object * obj );
void fireball_process_post(object * obj, float frame_time);
@@ -116,8 +114,6 @@ 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 );
extern void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d);
extern int Warp_model;
// Goober5000
+13 -177
View File
@@ -10,15 +10,17 @@
#include "cmdline/cmdline.h"
#include "globalincs/pstypes.h"
#include "graphics/tmapper.h"
#include "math/vecmat.h"
#include "mission/missionparse.h"
#include "model/model.h"
#include "nebula/neb.h"
#include "graphics/tmapper.h"
#include "render/3d.h"
#include "fireball/fireballs.h"
#include "mission/missionparse.h"
#include "nebula/neb.h"
#include "globalincs/pstypes.h"
#include "model/model.h"
#include "ship/ship.h"
#include "cmdline/cmdline.h"
extern int Warp_model;
extern int Warp_glow_bitmap;
@@ -45,25 +47,6 @@ void draw_face( vertex *v1, vertex *v2, vertex *v3 )
}
void warpin_batch_draw_face( int texture, 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 ) {
vertlist[0] = *v3;
vertlist[1] = *v2;
vertlist[2] = *v1;
} else {
vertlist[0] = *v1;
vertlist[1] = *v2;
vertlist[2] = *v3;
}
batch_add_tri(texture, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, vertlist, 1.0f);
}
void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
{
vec3d center;
@@ -126,18 +109,15 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
}
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
model_render_params render_info;
vec3d scale;
scale.xyz.z = scale.xyz.y = scale.xyz.x = radius / 25.0f;
render_info.set_warp_params(texture_bitmap_num, radius/max_radius, scale);
float scale = radius / 25.0f;
model_set_warp_globals(scale, scale, scale, texture_bitmap_num, (radius/max_radius) );
float dist = vm_vec_dist_quick( pos, &Eye_position );
render_info.set_detail_level_lock((int)(dist / (radius * 10.0f)));
model_set_detail_level((int)(dist / (radius * 10.0f)));
render_info.set_flags(MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL | MR_NO_BATCH);
model_render( Warp_model, orient, pos, MR_LOCK_DETAIL | MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL );
model_render_immediate( &render_info, Warp_model, orient, pos );
model_set_warp_globals();
} else {
float Grid_depth = radius/2.5f;
@@ -217,147 +197,3 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
gr_zbuffer_set( saved_gr_zbuffering );
}
void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
{
vec3d center;
vec3d vecs[5];
vertex verts[5];
vm_vec_scale_add( &center, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
if (Warp_glow_bitmap >= 0) {
float r = radius;
bool render_it = true;
#define OUT_PERCENT1 0.80f
#define OUT_PERCENT2 0.90f
#define IN_PERCENT1 0.10f
#define IN_PERCENT2 0.20f
if (Cmdline_warp_flash)
{
if ( (life_percent >= IN_PERCENT1) && (life_percent < IN_PERCENT2) ) {
r *= (life_percent - IN_PERCENT1) / (IN_PERCENT2 - IN_PERCENT1);
//render_it = true;
} else if ( (life_percent >= OUT_PERCENT1) && (life_percent < OUT_PERCENT2) ) {
r *= (OUT_PERCENT2 - life_percent) / (OUT_PERCENT2 - OUT_PERCENT1);
//render_it = true;
}
}
if (render_it) {
// Add in noise
int noise_frame = fl2i(Missiontime/15.0f) % NOISE_NUM_FRAMES;
r *= (0.40f + Noise[noise_frame] * 0.30f);
// Bobboau's warp thingie, toggled by cmdline
if (Cmdline_warp_flash) {
r += powf((2.0f * life_percent) - 1.0f, 24.0f) * max_radius * 1.5f;
}
vecs[4] = center;
verts[4].texture_position.u = 0.5f; verts[4].texture_position.v = 0.5f;
if (Cmdline_nohtl) {
g3_rotate_vertex( &verts[4], &vecs[4] );
} else {
g3_transfer_vertex( &verts[4], &vecs[4] );
}
float alpha = (The_mission.flags & MISSION_FLAG_FULLNEB) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
batch_add_bitmap(Warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, &verts[4], 0, r, alpha);
}
}
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
model_render_params render_info;
float scale = radius / 25.0f;
vec3d warp_scale;
warp_scale.xyz.x = warp_scale.xyz.y = warp_scale.xyz.z = scale;
float dist = vm_vec_dist_quick( pos, &Eye_position );
render_info.set_warp_params(texture_bitmap_num, radius/max_radius, warp_scale);
render_info.set_detail_level_lock((int)(dist / (radius * 10.0f)));
render_info.set_flags(MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL | MR_NO_BATCH);
model_render_queue( &render_info, scene, Warp_model, orient, pos);
} else {
float Grid_depth = radius/2.5f;
// gr_set_bitmap( texture_bitmap_num, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
vm_vec_scale_add( &vecs[0], &center, &orient->vec.uvec, radius );
vm_vec_scale_add2( &vecs[0], &orient->vec.rvec, -radius );
vm_vec_scale_add2( &vecs[0], &orient->vec.fvec, Grid_depth );
vm_vec_scale_add( &vecs[1], &center, &orient->vec.uvec, radius );
vm_vec_scale_add2( &vecs[1], &orient->vec.rvec, radius );
vm_vec_scale_add2( &vecs[1], &orient->vec.fvec, Grid_depth );
vm_vec_scale_add( &vecs[2], &center, &orient->vec.uvec, -radius );
vm_vec_scale_add2( &vecs[2], &orient->vec.rvec, radius );
vm_vec_scale_add2( &vecs[2], &orient->vec.fvec, Grid_depth );
vm_vec_scale_add( &vecs[3], &center, &orient->vec.uvec, -radius );
vm_vec_scale_add2( &vecs[3], &orient->vec.rvec, -radius );
vm_vec_scale_add2( &vecs[3], &orient->vec.fvec, Grid_depth );
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
vecs[4] = center;
verts[0].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;
if (Cmdline_nohtl) {
g3_rotate_vertex( &verts[0], &vecs[0] );
g3_rotate_vertex( &verts[1], &vecs[1] );
g3_rotate_vertex( &verts[2], &vecs[2] );
g3_rotate_vertex( &verts[3], &vecs[3] );
g3_rotate_vertex( &verts[4], &vecs[4] );
} else {
g3_transfer_vertex( &verts[0], &vecs[0] );
g3_transfer_vertex( &verts[1], &vecs[1] );
g3_transfer_vertex( &verts[2], &vecs[2] );
g3_transfer_vertex( &verts[3], &vecs[3] );
g3_transfer_vertex( &verts[4], &vecs[4] );
}
warpin_batch_draw_face( texture_bitmap_num, &verts[0], &verts[4], &verts[1] );
warpin_batch_draw_face( texture_bitmap_num, &verts[1], &verts[4], &verts[2] );
warpin_batch_draw_face( texture_bitmap_num, &verts[4], &verts[3], &verts[2] );
warpin_batch_draw_face( texture_bitmap_num, &verts[0], &verts[3], &verts[4] );
}
if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
//flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
flash_ball warp_ball(20, .1f,.25f, &orient->vec.fvec, pos, 4.0f, 0.5f);
float adg = (2.0f * life_percent) - 1.0f;
float pct = (powf(adg, 4.0f) - powf(adg, 128.0f)) * 4.0f;
if (pct > 0.00001f) {
warp_ball.render(Warp_ball_bitmap, max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
}
}
}
+4 -4
View File
@@ -124,14 +124,14 @@ BOOL AltShipClassDlg::OnInitDialog()
m_set_from_ship_class.AddString("Set From Variable");
}
count = 0;
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
for (i=0; i<Num_ship_classes; i++)
{
if (player_ships_only && !(it->flags & SIF_PLAYER_SHIP)) {
if (player_ships_only && !(Ship_info[i].flags & SIF_PLAYER_SHIP)) {
continue;
}
ship_class_indices[count++] = std::distance(Ship_info.cbegin(), it);
m_set_from_ship_class.AddString(it->name);
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
+9 -34
View File
@@ -59,27 +59,10 @@ BOOL FictionViewerDlg::OnInitDialog()
box->AddString(Spooled_music[i].name);
}
// make sure we have at least one stage
if (Fiction_viewer_stages.empty())
{
fiction_viewer_stage stage;
memset(&stage, 0, sizeof(fiction_viewer_stage));
stage.formula = Locked_sexp_true;
Fiction_viewer_stages.push_back(stage);
}
else if (Fiction_viewer_stages.size() > 1)
{
MessageBox("You have multiple fiction viewer stages defined for this mission. At present, FRED will only allow you to edit the first stage.");
}
// init fields based on first fiction viewer stage
fiction_viewer_stage *stagep = &Fiction_viewer_stages.at(0);
m_story_file = _T(stagep->story_filename);
m_font_file = _T(stagep->font_filename);
m_voice_file = _T(stagep->voice_filename);
// music is managed through the mission
// init variables
m_story_file = _T(fiction_file());
m_font_file = _T(fiction_font());
m_voice_file = _T(fiction_voice());
m_fiction_music = Mission_music[SCORE_FICTION_VIEWER] + 1;
CDialog::OnInitDialog();
@@ -91,15 +74,9 @@ void FictionViewerDlg::OnOK()
{
UpdateData(TRUE);
// store the fields in the data structure
fiction_viewer_stage *stagep = &Fiction_viewer_stages.at(0);
strcpy_s(stagep->story_filename, (LPCSTR)m_story_file);
strcpy_s(stagep->font_filename, (LPCSTR)m_font_file);
strcpy_s(stagep->voice_filename, (LPCSTR)m_voice_file);
// if we don't have a story file, remove this stage (stage 0)
if (strlen(stagep->story_filename) == 0)
Fiction_viewer_stages.erase(Fiction_viewer_stages.begin());
// load it up
fiction_viewer_reset();
fiction_viewer_load((const char *)(LPCSTR)m_story_file, (const char *)(LPCSTR)m_font_file, (const char *)(LPCSTR)m_voice_file);
// set music
Mission_music[SCORE_FICTION_VIEWER] = m_fiction_music - 1;
@@ -137,8 +114,6 @@ void FictionViewerDlg::OnClose()
int FictionViewerDlg::query_modified()
{
fiction_viewer_stage *stagep = &Fiction_viewer_stages.at(0);
return strcmp(m_story_file, stagep->story_filename) || strcmp(m_font_file, stagep->font_filename) ||
strcmp(m_voice_file, stagep->voice_filename) || m_fiction_music != (Mission_music[SCORE_FICTION_VIEWER] + 1);
return strcmp(m_story_file, fiction_file()) || strcmp(m_font_file, fiction_font()) ||
strcmp(m_voice_file, fiction_voice()) || m_fiction_music != (Mission_music[SCORE_FICTION_VIEWER] + 1);
}
-3
View File
@@ -22,9 +22,6 @@ public:
// Dialog Data
//{{AFX_DATA(FictionViewerDlg)
enum { IDD = IDD_FICTION_VIEWER };
CString m_fiction_background_640;
CString m_fiction_background_1024;
int m_fiction_ui;
CString m_story_file;
CString m_font_file;
CString m_voice_file;
+1 -1
View File
@@ -440,7 +440,7 @@ void asteroid_editor::update_init()
for (k = 0; k < MAX_ACTIVE_DEBRIS_TYPES; k++)
{
box_index = ((CComboBox*)GetDlgItem(Dlg_id[k]))->AddString("None");
((CComboBox*)GetDlgItem(Dlg_id[k]))->SetItemData(box_index, static_cast<DWORD_PTR>(-1));
((CComboBox*)GetDlgItem(Dlg_id[k]))->SetItemData(box_index, -1);
}
// now add each kind of debris to each box
+63 -66
View File
@@ -229,17 +229,17 @@ void bg_bitmap_dlg::create()
angles skybox_angles;
vm_extract_angles_matrix(&skybox_angles, &The_mission.skybox_orientation);
m_skybox_pitch = fl2ir(fl_degrees(skybox_angles.p));
m_skybox_bank = fl2ir(fl_degrees(skybox_angles.b));
m_skybox_heading = fl2ir(fl_degrees(skybox_angles.h));
m_skybox_pitch = (int) fl_degrees(skybox_angles.p);
m_skybox_bank = (int) fl_degrees(skybox_angles.b);
m_skybox_heading = (int) fl_degrees(skybox_angles.h);
//make sure angle values are in the 0-359 degree range
if (m_skybox_pitch < 0)
m_skybox_pitch = m_skybox_pitch + 360;
m_skybox_pitch = m_skybox_pitch + 359;
if (m_skybox_bank < 0)
m_skybox_bank = m_skybox_bank + 360;
m_skybox_bank = m_skybox_bank + 359;
if (m_skybox_heading < 0)
m_skybox_heading = m_skybox_heading + 360;
m_skybox_heading = m_skybox_heading + 359;
for(i=0; i<MAX_NEB2_BITMAPS; i++){
@@ -730,9 +730,9 @@ void bg_bitmap_dlg::OnSunChange()
starfield_list_entry *sle = &background->suns[s_index];
s_name = CString(sle->filename);
s_pitch = fl2ir(fl_degrees(sle->ang.p) + delta);
s_bank = fl2ir(fl_degrees(sle->ang.b) + delta);
s_heading = fl2ir(fl_degrees(sle->ang.h) + delta);
s_pitch = (int) (fl_degrees(sle->ang.p) + delta);
s_bank = (int) (fl_degrees(sle->ang.b) + delta);
s_heading = (int) (fl_degrees(sle->ang.h) + delta);
s_scale = sle->scale_x;
// stuff back into the controls
@@ -894,9 +894,9 @@ void bg_bitmap_dlg::OnBitmapChange()
starfield_list_entry *sle = &background->bitmaps[b_index];
b_name = CString(sle->filename);
b_pitch = fl2ir(fl_degrees(sle->ang.p) + delta);
b_bank = fl2ir(fl_degrees(sle->ang.b) + delta);
b_heading = fl2ir(fl_degrees(sle->ang.h) + delta);
b_pitch = (int) (fl_degrees(sle->ang.p) + delta);
b_bank = (int) (fl_degrees(sle->ang.b) + delta);
b_heading = (int) (fl_degrees(sle->ang.h) + delta);
b_scale_x = sle->scale_x;
b_scale_y = sle->scale_y;
b_div_x = sle->div_x;
@@ -1267,7 +1267,7 @@ void bg_bitmap_dlg::OnImportBackground()
{
CFileDialog cfd(TRUE, ".fs2", NULL, 0, "FreeSpace2 Missions (*.fs2)|*.fs2||\0");
char filename[256], error_str[1024];
int temp, count;
int rval, temp, count;
char *saved_mp;
//warn on pressing the button
@@ -1280,62 +1280,59 @@ void bg_bitmap_dlg::OnImportBackground()
strcpy_s(filename, cfd.GetPathName());
try
{
// parse in the new file
read_file_text(filename);
reset_parse();
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("BGBITMAPDLG: Unable to parse '%s'! Error code = %i.\n", filename, rval));
sprintf(error_str, "Could not parse file: %s", filename);
if (!skip_to_start_of_string("#Background bitmaps"))
return;
// skip beginning stuff
required_string("#Background bitmaps");
required_string("$Num stars:");
stuff_int(&temp);
required_string("$Ambient light level:");
stuff_int(&temp);
saved_mp = Mp;
// see if we have more than one background in this mission
count = 0;
while (skip_to_string("$Bitmap List:"))
count++;
Mp = saved_mp;
// pick one (if count is 0, it's retail with just one background)
if (count > 0)
{
int i, which = 0;
if (count > 1)
{
BackgroundChooser dlg(count);
if (dlg.DoModal() == IDCANCEL)
return;
which = dlg.GetChosenBackground();
}
for (i = 0; i < which + 1; i++)
skip_to_string("$Bitmap List:");
}
// now parse the background we've selected
parse_one_background(&Backgrounds[get_active_background()]);
reinitialize_lists();
}
catch (const parse::ParseException& e)
{
mprintf(("BGBITMAPDLG: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
sprintf(error_str, "Could not parse file: %s\n\nError message: %s", filename, e.what());
MessageBox((LPCTSTR)error_str, (LPCTSTR) "Unable to import mission background!", MB_ICONERROR | MB_OK);
MessageBox((LPCTSTR) error_str, (LPCTSTR) "Unable to import mission background!", MB_ICONERROR | MB_OK);
return;
}
// parse in the new file
read_file_text(filename);
reset_parse();
if (!skip_to_start_of_string("#Background bitmaps"))
return;
// skip beginning stuff
required_string("#Background bitmaps");
required_string("$Num stars:");
stuff_int(&temp);
required_string("$Ambient light level:");
stuff_int(&temp);
saved_mp = Mp;
// see if we have more than one background in this mission
count = 0;
while(skip_to_string("$Bitmap List:"))
count++;
Mp = saved_mp;
// pick one (if count is 0, it's retail with just one background)
if (count > 0)
{
int i, which = 0;
if (count > 1)
{
BackgroundChooser dlg(count);
if (dlg.DoModal() == IDCANCEL)
return;
which = dlg.GetChosenBackground();
}
for (i = 0; i < which + 1; i++)
skip_to_string("$Bitmap List:");
}
// now parse the background we've selected
parse_one_background(&Backgrounds[get_active_background()]);
reinitialize_lists();
}
void bg_bitmap_dlg::reinitialize_lists()
+8 -8
View File
@@ -196,8 +196,8 @@ void briefing_editor_dlg::create()
box->AddString(Iff_info[i].iff_name);
box = (CComboBox *) GetDlgItem(IDC_SHIP_TYPE);
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
box->AddString(it->name);
for (i=0; i<Num_ship_classes; i++)
box->AddString(Ship_info[i].name);
box = (CComboBox *) GetDlgItem(IDC_BRIEFING_MUSIC);
box->AddString("None");
@@ -1127,11 +1127,11 @@ void briefing_editor_dlg::OnMakeIcon()
else if(jnp != Jump_nodes.end()){
// find the first navbuoy
iconp->ship_class = -1;
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
for (int i = 0; i < Num_ship_classes; i++)
{
if (it->flags & SIF_NAVBUOY)
if (Ship_info[i].flags & SIF_NAVBUOY)
{
iconp->ship_class = std::distance(Ship_info.cbegin(), it);
iconp->ship_class = i;
break;
}
}
@@ -1141,11 +1141,11 @@ void briefing_editor_dlg::OnMakeIcon()
else {
// find the first navbuoy
iconp->ship_class = -1;
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
for (int i = 0; i < Num_ship_classes; i++)
{
if (it->flags & SIF_NAVBUOY)
if (Ship_info[i].flags & SIF_NAVBUOY)
{
iconp->ship_class = std::distance(Ship_info.cbegin(), it);
iconp->ship_class = i;
break;
}
}
+1 -12
View File
@@ -672,10 +672,6 @@ void event_editor::OnButtonNewEvent()
return;
}
// before we do anything, we must check and save off any data from the current event (e.g
// the repeat count and interval count)
save();
reset_event(m_num_events++, TVI_LAST);
}
@@ -689,11 +685,6 @@ void event_editor::OnInsert()
return;
}
// before we do anything, we must check and save off any data from the current event (e.g
// the repeat count and interval count)
save();
if(cur_event < 0 || m_num_events == 0)
{
//There are no events yet, so just create one
@@ -759,8 +750,6 @@ void event_editor::reset_event(int num, HTREEITEM after)
m_event_tree.item_index = index;
m_event_tree.add_operator("do-nothing");
update_cur_event();
m_event_tree.SelectItem(h);
// GetDlgItem(IDC_CHAIN_DELAY) -> EnableWindow(FALSE);
if (num >= MAX_MISSION_EVENTS){
@@ -1310,7 +1299,7 @@ void event_editor::OnDeleteMsg()
char buf[256];
// handle this case somewhat gracefully
Assertion((m_cur_msg >= -1) && (m_cur_msg < m_num_messages), "Unexpected m_cur_msg value (%d); expected either -1, or between 0-%d. Get a coder!\n", m_cur_msg, m_num_messages - 1);
Assert((m_cur_msg >= 0) && (m_cur_msg < m_num_messages));
if((m_cur_msg < 0) || (m_cur_msg >= m_num_messages)){
return;
}
+234 -232
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -25,6 +25,7 @@
#include "object/object.h"
#include "editor.h"
#include "ai/ai.h"
#include "ai/ailocal.h"
#include "cfile/cfile.h"
#include "cfile/cfilesystem.h"
+1
View File
@@ -12,6 +12,7 @@
#ifndef _FREDDOC_H
#define _FREDDOC_H
#include "ai/ailocal.h"
#include "MissionSave.h"
#define MISSION_BACKUP_NAME "Backup"
+37 -43
View File
@@ -34,6 +34,7 @@
#include "model/model.h"
#include "palman/palman.h"
#include "editor.h"
#include "ai/ailocal.h"
#include "ship/ship.h"
#include "cfile/cfile.h"
#include "mission/missionparse.h"
@@ -140,7 +141,8 @@ color colour_yellow;
void fred_enable_htl()
{
gr_set_proj_matrix((4.0f/9.0f) * PI * (Briefing_dialog ? Briefing_window_FOV : FRED_DEFAULT_HTL_FOV), gr_screen.aspect*(float)gr_screen.clip_width/(float)gr_screen.clip_height, 1.0f, FRED_DEAFULT_HTL_DRAW_DIST);
if (!Briefing_dialog) gr_set_proj_matrix( (4.0f/9.0f) * PI * FRED_DEFAULT_HTL_FOV, gr_screen.aspect*(float)gr_screen.clip_width/(float)gr_screen.clip_height, 1.0f, FRED_DEAFULT_HTL_DRAW_DIST);
if (Briefing_dialog) gr_set_proj_matrix( Briefing_window_FOV, gr_screen.aspect*(float)gr_screen.clip_width/(float)gr_screen.clip_height, 1.0f, FRED_DEAFULT_HTL_DRAW_DIST);
gr_set_view_matrix(&Eye_position, &Eye_matrix);
}
@@ -700,7 +702,6 @@ void render_one_model_briefing_screen(object *objp)
void render_one_model_nohtl(object *objp)
{
int j, z;
uint debug_flags = 0;
object *o2;
Assert(objp->type != OBJ_NONE);
@@ -754,11 +755,11 @@ void render_one_model_nohtl(object *objp)
}
if(Show_dock_points){
debug_flags |= MR_DEBUG_BAY_PATHS;
j |= MR_BAY_PATHS;
}
if(Show_paths_fred){
debug_flags |= MR_DEBUG_PATHS;
j |= MR_SHOW_PATHS;
}
z = objp->instance;
@@ -767,19 +768,12 @@ void render_one_model_nohtl(object *objp)
// if (!viewpoint || OBJ_INDEX(objp) != cur_object_index)
{
model_render_params render_info;
if (Fred_outline) {
render_info.set_flags(j | MR_SHOW_OUTLINE | MR_NO_TEXTURING | MR_NO_LIGHTING);
render_info.set_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
model_set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j | MR_SHOW_OUTLINE, -1, -1, Ships[z].ship_replacement_textures);
} else {
render_info.set_flags(j);
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j, -1, -1, Ships[z].ship_replacement_textures);
}
render_info.set_debug_flags(debug_flags);
render_info.set_replacement_textures(Ships[z].ship_replacement_textures);
model_render_immediate(&render_info, Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos);
}
} else {
@@ -837,7 +831,6 @@ void render_one_model_nohtl(object *objp)
void render_one_model_htl(object *objp)
{
int j, z;
uint debug_flags = 0;
object *o2;
Assert(objp->type != OBJ_NONE);
@@ -885,15 +878,18 @@ void render_one_model_htl(object *objp)
// build flags
if ((Show_ship_models || Show_outlines) && ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START))){
g3_start_instance_matrix(&Eye_position, &Eye_matrix, 0);
j = MR_NORMAL;
if (Show_ship_models){
j = MR_NORMAL;
} else {
j = MR_NO_POLYS;
}
if(Show_dock_points){
debug_flags |= MR_DEBUG_BAY_PATHS;
j |= MR_BAY_PATHS;
}
if(Show_paths_fred){
debug_flags |= MR_DEBUG_PATHS;
j |= MR_SHOW_PATHS;
}
z = objp->instance;
@@ -909,23 +905,13 @@ void render_one_model_htl(object *objp)
j |= MR_FULL_DETAIL;
}
model_render_params render_info;
render_info.set_debug_flags(debug_flags);
render_info.set_replacement_textures(Ships[z].ship_replacement_textures);
if (Fred_outline) {
render_info.set_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
render_info.set_flags(j | MR_SHOW_OUTLINE_HTL | MR_NO_LIGHTING | MR_NO_POLYS | MR_NO_TEXTURING);
model_render_immediate(&render_info, Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos);
model_set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
j |= MR_SHOW_OUTLINE_HTL;
}
g3_done_instance(0);
if ( Show_ship_models ) {
render_info.set_flags(j);
model_render_immediate(&render_info, Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos);
}
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j, -1, -1, Ships[z].ship_replacement_textures);
} else {
int r = 0, g = 0, b = 0;
@@ -1140,7 +1126,7 @@ void draw_orient_sphere(object *obj, int r, int g, int b)
if ((obj->type != OBJ_WAYPOINT) && (obj->type != OBJ_POINT))
{
flag = (vm_vec_dot(&eye_orient.vec.fvec, &obj->orient.vec.fvec) < 0.0f);
flag = (vm_vec_dotprod(&eye_orient.vec.fvec, &obj->orient.vec.fvec) < 0.0f);
v1 = v2 = obj->pos;
vm_vec_scale_add2(&v1, &obj->orient.vec.fvec, size);
vm_vec_scale_add2(&v2, &obj->orient.vec.fvec, size * 1.5f);
@@ -1176,7 +1162,7 @@ void draw_orient_sphere2(int col, object *obj, int r, int g, int b)
if ((obj->type != OBJ_WAYPOINT) && (obj->type != OBJ_POINT))
{
flag = (vm_vec_dot(&eye_orient.vec.fvec, &obj->orient.vec.fvec) < 0.0f);
flag = (vm_vec_dotprod(&eye_orient.vec.fvec, &obj->orient.vec.fvec) < 0.0f);
v1 = v2 = obj->pos;
vm_vec_scale_add2(&v1, &obj->orient.vec.fvec, size);
@@ -1373,11 +1359,11 @@ void process_controls(vec3d *pos, matrix *orient, float frametime, int key, int
vm_angles_2_matrix(&rotmat, &rotangs);
if (rotangs.h && Universal_heading)
vm_transpose(orient);
vm_transpose_matrix(orient);
vm_matrix_x_matrix(&newmat, orient, &rotmat);
*orient = newmat;
if (rotangs.h && Universal_heading)
vm_transpose(orient);
vm_transpose_matrix(orient);
}
}
@@ -1503,7 +1489,11 @@ void render_frame()
gr_set_font(FONT1);
light_reset();
g3_set_view_matrix(&eye_pos, &eye_orient, (Briefing_dialog ? Briefing_window_FOV : FRED_DEFAULT_HTL_FOV));
if (Briefing_dialog) {
g3_set_view_matrix(&eye_pos, &eye_orient, Briefing_window_FOV);
} else {
g3_set_view_matrix(&eye_pos, &eye_orient, 0.5f);
}
Viewer_pos = eye_pos; // for starfield code
fred_enable_htl();
@@ -1608,7 +1598,11 @@ void render_frame()
gr_set_clip(0, 0, True_rw, True_rh);
g3_start_frame(0); // ** Accounted for
g3_set_view_matrix(&eye_pos, &eye_orient, (Briefing_dialog ? Briefing_window_FOV : FRED_DEFAULT_HTL_FOV));
if (Briefing_dialog) {
g3_set_view_matrix(&eye_pos, &eye_orient, Briefing_window_FOV);
} else {
g3_set_view_matrix(&eye_pos, &eye_orient, 0.5f);
}
}
void game_do_frame()
@@ -1659,7 +1653,7 @@ void game_do_frame()
leader = &Objects[cur_object_index];
leader_old_pos = leader->pos; // save original position
leader_orient = leader->orient; // save original orientation
vm_copy_transpose(&leader_transpose, &leader_orient);
vm_copy_transpose_matrix(&leader_transpose, &leader_orient);
process_controls(&leader->pos, &leader->orient, f2fl(Frametime), key);
vm_vec_sub(&delta_pos, &leader->pos, &leader_old_pos); // get position change
@@ -1676,7 +1670,7 @@ void game_do_frame()
// change rotation matrix to rotate in opposite direction. This rotation
// matrix is what the leader ship has rotated by.
vm_copy_transpose(&rot_trans, &view_physics.last_rotmat);
vm_copy_transpose_matrix(&rot_trans, &view_physics.last_rotmat);
// get point relative to our point of rotation (make POR the origin). Since
// only the leader has been moved yet, and not the objects, we have to use
@@ -2027,7 +2021,7 @@ void render_compass(void)
v.xyz.x = 1.0f;
v.xyz.y = v.xyz.z = 0.0f;
if (vm_vec_dot(&eye, &v) < 0.0f)
if (vm_vec_dotprod(&eye, &v) < 0.0f)
gr_set_color(159, 20, 20);
else
gr_set_color(255, 32, 32);
@@ -2035,7 +2029,7 @@ void render_compass(void)
v.xyz.y = 1.0f;
v.xyz.x = v.xyz.z = 0.0f;
if (vm_vec_dot(&eye, &v) < 0.0f)
if (vm_vec_dotprod(&eye, &v) < 0.0f)
gr_set_color(20, 159, 20);
else
gr_set_color(32, 255, 32);
@@ -2043,7 +2037,7 @@ void render_compass(void)
v.xyz.z = 1.0f;
v.xyz.x = v.xyz.y = 0.0f;
if (vm_vec_dot(&eye, &v) < 0.0f)
if (vm_vec_dotprod(&eye, &v) < 0.0f)
gr_set_color(20, 20, 159);
else
gr_set_color(32, 32, 255);
+1 -1
View File
@@ -230,7 +230,7 @@ void set_time_compression(float multiplier, float change_time){}
fix game_get_overall_frametime() { return 0; }
//WMC
void game_level_init(){}
void game_level_init(int seed){}
void game_post_level_init(){}
camid game_render_frame_setup(){return camid();}
void game_render_frame(camid cid){}
+8 -7
View File
@@ -27,6 +27,7 @@
#include "math/fvi.h" // For find_plane_line_intersection
#include "math/vecmat.h"
#include "io/key.h"
#include "ai/ailocal.h"
#include "ai/ai.h"
#include "ai/aigoals.h"
#include "ship/ship.h" // for ship names
@@ -773,7 +774,7 @@ int drag_rotate_objects()
leader = &Objects[cur_object_index];
leader_orient = leader->orient; // save original orientation
vm_copy_transpose(&leader_transpose, &leader_orient);
vm_copy_transpose_matrix(&leader_transpose, &leader_orient);
vm_angles_2_matrix(&rotmat, &a);
vm_matrix_x_matrix(&newmat, &leader->orient, &rotmat);
@@ -789,7 +790,7 @@ int drag_rotate_objects()
// change rotation matrix to rotate in opposite direction. This rotation
// matrix is what the leader ship has rotated by.
vm_copy_transpose(&rot_trans, &rotmat);
vm_copy_transpose_matrix(&rot_trans, &rotmat);
// get point relative to our point of rotation (make POR the origin).
vm_vec_sub(&tmpv1, &objp->pos, &leader->pos);
@@ -1467,9 +1468,9 @@ void CFREDView::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
(UINT) species_submenu[i].m_hMenu, Species_info[i].species_name);
}
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
species_submenu[it->species].AppendMenu(MF_STRING |
MF_ENABLED, SHIP_TYPES + i, it->name);
for (i=0; i<Num_ship_classes; i++)
species_submenu[Ship_info[i].species].AppendMenu(MF_STRING |
MF_ENABLED, SHIP_TYPES + i, Ship_info[i].name);
pPopup->AppendMenu(MF_STRING | MF_POPUP | MF_ENABLED,
(UINT) shipPopup.m_hMenu, "New Object Type");
@@ -1619,7 +1620,7 @@ BOOL CFREDView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO*
int id = (int) nID;
if (!pHandlerInfo) {
if ((id >= SHIP_TYPES) && (id < SHIP_TYPES + static_cast<int>(Ship_info.size()) + 3)) {
if ((id >= SHIP_TYPES) && (id < SHIP_TYPES + Num_ship_classes + 3)) {
if (nCode == CN_COMMAND) {
cur_model_index = id - SHIP_TYPES;
m_new_ship_type_combo_box.SetCurSelNEW(cur_model_index);
@@ -2453,7 +2454,7 @@ int CFREDView::global_error_check()
}
z = Ships[i].ship_info_index;
if ((z < 0) || (z >= static_cast<int>(Ship_info.size()))){
if ((z < 0) || (z >= Num_ship_classes)){
return internal_error("A ship has an illegal class");
}
+10 -11
View File
@@ -55,7 +55,7 @@ END_MESSAGE_MAP()
BOOL InitialShips::OnInitDialog()
{
int i;
int i, j;
CDialog::OnInitDialog();
@@ -63,13 +63,12 @@ BOOL InitialShips::OnInitDialog()
// change the window text, get the index into the array, and check the box for either the ships
// or weapons
if ( m_initial_items == INITIAL_SHIPS ) {
for ( auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it ) {
if ( it->flags & SIF_PLAYER_SHIP ) {
i = std::distance(Ship_info.cbegin(), it);
m_initial_list.AddString( it->name );
for ( i = 0; i < Num_ship_classes; i++ ) {
if ( Ship_info[i].flags & SIF_PLAYER_SHIP ) {
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(it->name, "Myrmidon") ) { //-V805
} else if ( (strlen(Campaign.filename) == 0) && strstr(Ship_info[i].name, "Myrmidon") ) { //-V805
m_initial_list.SetCheck(m_list_count, 1);
} else {
m_initial_list.SetCheck(m_list_count, 0);
@@ -87,11 +86,11 @@ BOOL InitialShips::OnInitDialog()
int allowed_weapons[MAX_WEAPON_TYPES];
memset( allowed_weapons, 0, sizeof(allowed_weapons) );
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it) {
if ( it->flags & SIF_PLAYER_SHIP ) {
for ( i = 0; i < MAX_WEAPON_TYPES; i++ ) {
if ( it->allowed_weapons[i] )
allowed_weapons[i] = 1;
for (i = 0; i < Num_ship_classes; i++ ) {
if ( Ship_info[i].flags & SIF_PLAYER_SHIP ) {
for ( j = 0; j < MAX_WEAPON_TYPES; j++ ) {
if ( Ship_info[i].allowed_weapons[j] )
allowed_weapons[j] = 1;
}
}
}
+1 -1
View File
@@ -848,7 +848,7 @@ void initial_status::list_dockees(int dock_types)
// add "nothing"
z = cboDockees->AddString("Nothing");
cboDockees->SetItemData(z, static_cast<DWORD_PTR>(-1));
cboDockees->SetItemData(z, -1);
// add ships
for (object *objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp))
+10 -9
View File
@@ -344,6 +344,7 @@ void CMainFrame::OnClose()
void CMainFrame::init_tools()
{
int i;
//int highest_terran_index;
//char ship_name[256];
//int ship_index;
@@ -358,14 +359,14 @@ void CMainFrame::init_tools()
return;
}
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it){
for (i=0; i<Num_ship_classes; i++){
// don't add the pirate ship
if(it->flags & SIF_NO_FRED){
if(Ship_info[i].flags & SIF_NO_FRED){
m_new_ship_type_combo_box.AddString("");
continue;
}
m_new_ship_type_combo_box.AddString(it->name);
m_new_ship_type_combo_box.AddString(Ship_info[i].name);
}
// m_new_ship_type_combo_box.AddString("Player Start");
@@ -406,7 +407,7 @@ void color_combo_box::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
// I think we need to do a lookup by ship name here
if(lpDrawItemStruct->itemID >= Ship_info.size()){
if(lpDrawItemStruct->itemID >= (uint)Num_ship_classes){
z = lpDrawItemStruct->itemID;
} else {
memset(ship_name, 0, 256);
@@ -422,7 +423,7 @@ void color_combo_box::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
COLORREF newTextColor = RGB(0x80, 0x80, 0x80); // light gray
if (!fDisabled)
{
if (z >= static_cast<int>(Ship_info.size()))
if (z >= Num_ship_classes)
newTextColor = RGB(0, 0, 0);
else
{
@@ -497,7 +498,7 @@ void color_combo_box::MeasureItem(LPMEASUREITEMSTRUCT)
int color_combo_box::SetCurSelNEW(int model_index)
{
if((model_index < 0) || (model_index >= static_cast<int>(Ship_info.size()))){
if((model_index < 0) || (model_index >= Num_ship_classes)){
return SetCurSel(model_index);
}
@@ -512,9 +513,9 @@ int color_combo_box::GetCurSelNEW()
char ship_name[256];
char *hmmm = ship_name;
// see if we have a special item (>= Ship_info.size())
// see if we have a special item (>= Num_ship_classes)
cur_sel = GetCurSel();
if(cur_sel >= static_cast<int>(Ship_info.size())){
if(cur_sel >= Num_ship_classes){
return cur_sel;
}
@@ -524,7 +525,7 @@ int color_combo_box::GetCurSelNEW()
return CB_ERR;
}
ship_info = ship_info_lookup(ship_name);
if((ship_info < 0) || (ship_info >= static_cast<int>(Ship_info.size()))){
if((ship_info < 0) || (ship_info >= Num_ship_classes)){
return CB_ERR;
}
return ship_info;
+8 -10
View File
@@ -15,6 +15,7 @@
#include "FREDDoc.h"
#include "FREDView.h"
#include "FredRender.h"
#include "ai/ailocal.h"
#include "ai/aigoals.h"
#include "ship/ship.h"
#include "globalincs/linklist.h"
@@ -135,7 +136,6 @@ int query_ship_name_duplicate(int ship);
char *reg_read_string( char *section, char *name, char *default_value );
extern int Nmodel_num;
extern int Nmodel_instance_num;
extern matrix Nmodel_orient;
extern int Nmodel_bitmap;
@@ -410,7 +410,6 @@ bool fred_init()
armor_init();
weapon_init();
parse_medal_tbl(); // get medal names for sexpression usage
glowpoint_init();
ship_init();
parse_init();
techroom_intel_init();
@@ -444,9 +443,9 @@ bool fred_init()
// Get the default player ship
Default_player_model = cur_model_index = get_default_player_ship_index();
Id_select_type_start = Ship_info.size() + 2;
Id_select_type_jump_node = Ship_info.size() + 1;
Id_select_type_waypoint = Ship_info.size();
Id_select_type_start = Num_ship_classes + 2;
Id_select_type_jump_node = Num_ship_classes + 1;
Id_select_type_waypoint = Num_ship_classes;
Fred_main_wnd -> init_tools();
return true;
}
@@ -719,9 +718,9 @@ int create_object(vec3d *pos, int waypoint_instance)
obj = create_player(Player_starts, pos, NULL, Default_player_model);
} else if (cur_model_index == Id_select_type_jump_node) {
CJumpNode jnp(pos);
obj = jnp.GetSCPObjectNumber();
Jump_nodes.push_back(std::move(jnp));
CJumpNode* jnp = new CJumpNode(pos);
obj = jnp->GetSCPObjectNumber();
Jump_nodes.push_back(*jnp);
} else if(Ship_info[cur_model_index].flags & SIF_NO_FRED){
obj = -1;
} else { // creating a ship
@@ -886,7 +885,7 @@ void clear_mission()
// of ships for all teams
for (i=0; i<MAX_TVT_TEAMS; i++) {
count = 0;
for ( j = 0; j < static_cast<int>(Ship_info.size()); j++ ) {
for ( j = 0; j < MAX_SHIP_CLASSES; j++ ) {
if (Ship_info[j].flags & SIF_DEFAULT_PLAYER_SHIP) {
Team_data[i].ship_list[count] = j;
strcpy_s(Team_data[i].ship_list_variables[count], "");
@@ -956,7 +955,6 @@ void clear_mission()
Nmodel_flags = DEFAULT_NMODEL_FLAGS;
Nmodel_num = -1;
Nmodel_instance_num = -1;
vm_set_identity(&Nmodel_orient);
Nmodel_bitmap = -1;
-2
View File
@@ -297,8 +297,6 @@ int CMessageEditorDlg::find_event()
for (i=0; i<Num_mission_events; i++) {
node = Mission_events[i].formula;
Assertion(node >= 0, "Can't have a formula point to sexp node -1!");
if ( get_operator_const(CTEXT(node)) == OP_WHEN || get_operator_const(CTEXT(node)) == OP_EVERY_TIME
|| get_operator_const(CTEXT(node)) == OP_WHEN_ARGUMENT || get_operator_const(CTEXT(node)) == OP_EVERY_TIME_ARGUMENT
|| get_operator_const(CTEXT(node)) == OP_IF_THEN_ELSE || get_operator_const(CTEXT(node)) == OP_PERFORM_ACTIONS )
+130 -127
View File
@@ -96,20 +96,30 @@ void CFred_mission_save::convert_special_tags_to_retail()
}
}
void CFred_mission_save::save_mission_internal(const char *pathname)
int CFred_mission_save::save_mission_file(char *pathname)
{
char backup_name[256], savepath[MAX_PATH_LEN], *p;
CTime t;
t = CTime::GetCurrentTime();
strcpy_s(The_mission.modified, t.Format("%x at %X"));
strcpy_s(savepath, "");
p = strrchr(pathname, '\\');
if ( p ) {
*p = '\0';
strcpy_s(savepath, pathname);
*p = '\\';
strcat_s(savepath, "\\");
}
strcat_s(savepath, "saving.xxx");
reset_parse();
fred_parse_flag = 0;
fp = cfopen(pathname, "wt", CFILE_NORMAL, CF_TYPE_MISSIONS);
fp = cfopen(savepath, "wt", CFILE_NORMAL);
if (!fp) {
nprintf(("Error", "Can't open mission file to save.\n"));
err = -1;
return;
return -1;
}
// Goober5000
@@ -164,27 +174,10 @@ void CFred_mission_save::save_mission_internal(const char *pathname)
}
cfclose(fp);
if (err)
if (err) {
mprintf(("Mission saving error code #%d\n", err));
}
int CFred_mission_save::save_mission_file(char *pathname)
{
char backup_name[256], savepath[MAX_PATH_LEN], *p;
strcpy_s(savepath, "");
p = strrchr(pathname, '\\');
if ( p ) {
*p = '\0';
strcpy_s(savepath, pathname);
*p = '\\';
strcat_s(savepath, "\\");
}
strcat_s(savepath, "saving.xxx");
save_mission_internal(savepath);
if (!err) {
} else {
strcpy_s(backup_name, pathname);
if (backup_name[strlen(backup_name) - 4] == '.')
backup_name[strlen(backup_name) - 4] = 0;
@@ -203,6 +196,10 @@ int CFred_mission_save::autosave_mission_file(char *pathname)
{
char backup_name[256], name2[256];
int i, len;
CTime t;
t = CTime::GetCurrentTime();
strcpy_s(The_mission.modified, t.Format("%x at %X"));
len = strlen(pathname);
strcpy_s(backup_name, pathname);
@@ -216,8 +213,68 @@ int CFred_mission_save::autosave_mission_file(char *pathname)
}
strcpy(backup_name + len, ".001");
reset_parse();
fred_parse_flag = 0;
fp = cfopen(backup_name, "wt", CFILE_NORMAL, CF_TYPE_MISSIONS);
if (!fp) {
nprintf(("Error", "Can't open mission file to save.\n"));
return -1;
}
save_mission_internal(backup_name);
// Goober5000
convert_special_tags_to_retail();
if (save_mission_info())
err = -2;
else if (save_plot_info())
err = -3;
else if (save_variables())
err = -3;
// else if (save_briefing_info())
// err = -4;
else if (save_fiction())
err = -3;
else if (save_cutscenes())
err = -4;
else if (save_cmd_briefs())
err = -4;
else if (save_briefing())
err = -4;
else if (save_debriefing())
err = -5;
else if (save_players())
err = -6;
else if (save_objects())
err = -7;
else if (save_wings())
err = -8;
else if (save_events())
err = -9;
else if (save_goals())
err = -10;
else if (save_waypoints())
err = -11;
else if (save_messages())
err = -12;
else if (save_reinforcements())
err = -13;
else if (save_bitmaps())
err = -14;
else if (save_asteroid_fields())
err = -15;
else if (save_music())
err = -16;
else {
required_string_fred("#End");
parse_comments(2);
token_found = NULL;
parse_comments();
fout("\n");
}
cfclose(fp);
if (err)
mprintf(("Mission saving error code #%d\n", err));
return err;
}
@@ -478,7 +535,19 @@ int CFred_mission_save::save_mission_info()
}
}
save_custom_bitmap("$Load Screen 640:", "$Load Screen 1024:", The_mission.loading_screen[GR_640], The_mission.loading_screen[GR_1024], 1);
// Phreak's loading screen stuff
if (Format_fs2_open != FSO_FORMAT_RETAIL) //-V581
{
if (strlen(The_mission.loading_screen[GR_640]) > 0) //-V805
{
fout("\n\n$Load Screen 640:\t%s",The_mission.loading_screen[GR_640]);
}
if (strlen(The_mission.loading_screen[GR_1024]) > 0) //-V805
{
fout("\n$Load Screen 1024:\t%s",The_mission.loading_screen[GR_1024]);
}
}
// Phreak's skybox stuff
if (strlen(The_mission.skybox_model) > 0) //-V805
@@ -704,74 +773,40 @@ int CFred_mission_save::save_fiction()
if (Format_fs2_open != FSO_FORMAT_RETAIL)
{
if (optional_string_fred("#Fiction Viewer"))
parse_comments(2);
parse_comments();
else
fout("\n\n#Fiction Viewer");
// we have multiple stages now, so save them all
for (SCP_vector<fiction_viewer_stage>::iterator stage = Fiction_viewer_stages.begin(); stage != Fiction_viewer_stages.end(); ++stage)
fout("\n");
// save file
required_string_fred("$File:");
parse_comments();
fout(" %s", fiction_file());
// save font
if (strlen(fiction_font()) > 0) //-V805
{
fout("\n");
// save file
required_string_fred("$File:");
parse_comments();
fout(" %s", stage->story_filename);
// save font
if (strlen(stage->font_filename) > 0) //-V805
{
if (optional_string_fred("$Font:"))
parse_comments();
else
fout("\n$Font:");
fout(" %s", stage->font_filename);
}
if (optional_string_fred("$Font:"))
parse_comments();
else
optional_string_fred("$Font:");
// save voice
if (strlen(stage->voice_filename) > 0) //-V805
{
if (optional_string_fred("$Voice:"))
parse_comments();
else
fout("\n$Voice:");
fout(" %s", stage->voice_filename);
}
else
optional_string_fred("$Voice:");
// save UI
if (strlen(stage->ui_name) > 0)
{
if (optional_string_fred("$UI:"))
parse_comments();
else
fout("\n$UI:");
fout(" %s", stage->ui_name);
}
else
optional_string_fred("$UI:");
// save background
save_custom_bitmap("$Background 640:", "$Background 1024:", stage->background[GR_640], stage->background[GR_1024]);
// save sexp formula if we have one
if (stage->formula >= 0 && stage->formula != Locked_sexp_true)
{
SCP_string sexp_out;
convert_sexp_to_string(sexp_out, stage->formula, SEXP_SAVE_MODE);
if (optional_string_fred("$Formula:"))
parse_comments();
else
fout("\n$Formula:");
fout(" %s", sexp_out.c_str());
}
else
optional_string_fred("$Formula:");
fout("\n$Font:");
fout(" %s", fiction_font());
}
else
optional_string_fred("$Font:");
// save voice
if (strlen(fiction_voice()) > 0) //-V805
{
if (optional_string_fred("$Voice:"))
parse_comments();
else
fout("\n$Voice:");
fout(" %s", fiction_voice());
}
else
optional_string_fred("$Voice:");
}
else
{
@@ -795,8 +830,6 @@ int CFred_mission_save::save_cmd_brief()
if (The_mission.game_type & MISSION_TYPE_MULTI)
return err; // no command briefings allowed in multiplayer missions.
save_custom_bitmap("$Background 640:", "$Background 1024:", Cur_cmd_brief->background[GR_640], Cur_cmd_brief->background[GR_1024], 1);
for (stage=0; stage<Cur_cmd_brief->num_stages; stage++) {
required_string_fred("$Stage Text:");
parse_comments(2);
@@ -850,10 +883,6 @@ int CFred_mission_save::save_briefing()
required_string_fred("$start_briefing");
parse_comments();
save_custom_bitmap("$briefing_background_640:", "$briefing_background_1024:", Briefings[nb].background[GR_640], Briefings[nb].background[GR_1024]);
save_custom_bitmap("$ship_select_background_640:", "$ship_select_background_1024:", Briefings[nb].ship_select_background[GR_640], Briefings[nb].ship_select_background[GR_1024]);
save_custom_bitmap("$weapon_select_background_640:", "$weapon_select_background_1024:", Briefings[nb].weapon_select_background[GR_640], Briefings[nb].weapon_select_background[GR_1024]);
Assert(Briefings[nb].num_stages <= MAX_BRIEF_STAGES);
required_string_fred("$num_stages:");
parse_comments();
@@ -1026,8 +1055,6 @@ int CFred_mission_save::save_debriefing()
required_string_fred("#Debriefing_info");
parse_comments(2);
save_custom_bitmap("$Background 640:", "$Background 1024:", Debriefing->background[GR_640], Debriefing->background[GR_1024], 1);
required_string_fred("$Num stages:");
parse_comments(2);
fout(" %d", Debriefing->num_stages);
@@ -1724,8 +1751,6 @@ int CFred_mission_save::save_objects()
fout(" \"scramble-messages\"");
if (!(objp->flags & OF_COLLIDES))
fout(" \"no-collide\"");
if (shipp->flags2 & SF2_NO_DISABLED_SELF_DESTRUCT)
fout(" \"no-disabled-self-destruct\"");
fout(" )");
}
// -----------------------------------------------------------
@@ -2977,7 +3002,7 @@ int CFred_mission_save::fout_version(char *format, ...)
str_scp.append(fso_ver_comment.back().c_str());
str_scp.append(" ");
cfputs(str_scp.c_str(), fp);
cfputs(const_cast<char*>(str_scp.c_str()), fp);
str_scp = "";
}
@@ -3004,7 +3029,7 @@ int CFred_mission_save::fout_version(char *format, ...)
if (first_line) {
first_line = false;
} else {
cfputs(fso_ver_comment.back().c_str(), fp);
cfputs(const_cast<char*>(fso_ver_comment.back().c_str()), fp);
cfputs(" ", fp);
}
@@ -3016,7 +3041,7 @@ int CFred_mission_save::fout_version(char *format, ...)
if (first_line) {
first_line = false;
} else {
cfputs(fso_ver_comment.back().c_str(), fp);
cfputs(const_cast<char*>(fso_ver_comment.back().c_str()), fp);
cfputs(" ", fp);
}
@@ -3030,7 +3055,7 @@ int CFred_mission_save::fout_version(char *format, ...)
// be sure to account for any ending elements too
if ( strlen(str_p) ) {
cfputs(fso_ver_comment.back().c_str(), fp);
cfputs(const_cast<char*>(fso_ver_comment.back().c_str()), fp);
cfputs(" ", fp);
cfputs(str_p, fp);
}
@@ -3059,7 +3084,7 @@ int CFred_mission_save::fout(char *format, ...)
vsprintf(str, format, args);
va_end(args);
cfputs(str.c_str(), fp);
cfputs(const_cast<char*>(str.c_str()), fp);
return 0;
}
@@ -3124,7 +3149,7 @@ int CFred_mission_save::fout_ext(char *pre_str, char *format, ...)
if (first_line) {
first_line = false;
} else {
cfputs(fso_ver_comment.back().c_str(), fp);
cfputs(const_cast<char*>(fso_ver_comment.back().c_str()), fp);
cfputs(" ", fp);
}
@@ -3136,7 +3161,7 @@ int CFred_mission_save::fout_ext(char *pre_str, char *format, ...)
if (first_line) {
first_line = false;
} else {
cfputs(fso_ver_comment.back().c_str(), fp);
cfputs(const_cast<char*>(fso_ver_comment.back().c_str()), fp);
cfputs(" ", fp);
}
@@ -3150,7 +3175,7 @@ int CFred_mission_save::fout_ext(char *pre_str, char *format, ...)
// be sure to account for any ending elements too
if ( strlen(str_p) ) {
cfputs(fso_ver_comment.back().c_str(), fp);
cfputs(const_cast<char*>(fso_ver_comment.back().c_str()), fp);
cfputs(" ", fp);
cfputs(str_p, fp);
}
@@ -3858,28 +3883,6 @@ int CFred_mission_save::save_music()
return err;
}
void CFred_mission_save::save_custom_bitmap(const char *expected_string_640, const char *expected_string_1024, const char *string_field_640, const char *string_field_1024, int blank_lines)
{
if (Format_fs2_open != FSO_FORMAT_RETAIL)
{
if ((*string_field_640 != '\0') || (*string_field_1024 != '\0'))
{
while (blank_lines-- > 0)
fout("\n");
}
if (*string_field_640 != '\0')
{
fout("\n%s %s", expected_string_640, string_field_640);
}
if (*string_field_1024 != '\0')
{
fout("\n%s %s", expected_string_1024, string_field_1024);
}
}
}
void CFred_mission_save::save_turret_info(ship_subsys *ptr, int ship)
{
int i, z;
+1 -4
View File
@@ -15,6 +15,7 @@
#include <stdio.h>
#include "mission/missionparse.h"
#include "parse/parselo.h"
#include "ai/ailocal.h"
#include "ai/ai.h"
#include "cfile/cfile.h"
#include "ship/ship.h"
@@ -56,15 +57,11 @@ private:
int save_music();
void save_campaign_sexp(int node, int link);
void save_single_dock_instance(ship *shipp, dock_instance *dock_ptr);
void save_custom_bitmap(const char *expected_string_640, const char *expected_string_1024, const char *string_field_640, const char *string_field_1024, int blank_lines = 0);
void convert_special_tags_to_retail(char *text, int max_len);
void convert_special_tags_to_retail(SCP_string &text);
void convert_special_tags_to_retail();
void save_mission_internal(const char *pathname);
public:
void save_turret_info(ship_subsys *ptr, int ship);
int save_bitmaps();
+4 -5
View File
@@ -283,10 +283,9 @@ void player_start_editor::reset_controls()
// create a checklistbox for each "player" ship type
m_ship_list.ResetContent();
ct = 0;
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it) {
if (it->flags & SIF_PLAYER_SHIP) {
i = std::distance(Ship_info.cbegin(), it);
m_ship_list.AddString(it->name);
for (i=0; i<Num_ship_classes; i++) {
if (Ship_info[i].flags & SIF_PLAYER_SHIP) {
m_ship_list.AddString(Ship_info[i].name);
// if the ship currently has pool entries or was set by a variable, check it
if((static_ship_pool[selected_team][i] > 0) || (static_ship_variable_pool[selected_team][i] != -1)) {
@@ -809,7 +808,7 @@ void player_start_editor::OnOK()
// Now we deal with the loadout ships that are statically assigned by class
for (idx = 0; idx < static_cast<int>(Ship_info.size()); idx++) {
for(idx=0; idx<Num_ship_classes; idx++) {
// if we have ships here
if(static_ship_pool[i][idx] > 0 || static_ship_variable_pool[i][idx] > -1) {
Team_data[i].ship_list[num_choices] = idx;
-1
View File
@@ -1180,7 +1180,6 @@
#define IDC_MISSION_LOG_1ST_TRIGGER 1641
#define IDC_MISSION_LOG_LAST_TRIGGER 1642
#define IDC_NO_COLLIDE 1643
#define IDC_NO_DISABLED_SELF_DESTRUCT 1644
#define ID_FILE_MISSIONNOTES 32771
#define ID_DUPLICATE 32774
#define ID_VIEW_ROTATE 32775
Executable → Regular
+11 -8
View File
@@ -2797,7 +2797,7 @@ int sexp_tree::query_default_argument_available(int op, int i)
return (sexp_variable_count() > 0) ? 1 : 0;
case OPF_SSM_CLASS:
return (Ssm_info.size() > 0) ? 1 : 0;
return (Ssm_info_count > 0) ? 1 : 0;
case OPF_MISSION_MOOD:
return Builtin_moods.empty() ? 0 : 1;
@@ -5040,15 +5040,16 @@ sexp_list_item *sexp_tree::get_listing_opf_ai_class()
sexp_list_item *sexp_tree::get_listing_opf_support_ship_class()
{
int i;
sexp_list_item head;
head.add_data("<species support ship class>");
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
for (i=0; i<Num_ship_classes; i++)
{
if (it->flags & SIF_SUPPORT)
if (Ship_info[i].flags & SIF_SUPPORT)
{
head.add_data(it->name);
head.add_data(Ship_info[i].name);
}
}
@@ -5057,11 +5058,12 @@ sexp_list_item *sexp_tree::get_listing_opf_support_ship_class()
sexp_list_item *sexp_tree::get_listing_opf_ssm_class()
{
int i;
sexp_list_item head;
for (auto it = Ssm_info.cbegin(); it != Ssm_info.cend(); ++it)
for (i=0; i<Ssm_info_count; i++)
{
head.add_data(it->name);
head.add_data(Ssm_info[i].name);
}
return head.next;
@@ -5696,10 +5698,11 @@ sexp_list_item *sexp_tree::get_listing_opf_intel_name()
sexp_list_item *sexp_tree::get_listing_opf_ship_class_name()
{
int i;
sexp_list_item head;
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
head.add_data(it->name);
for (i=0; i<Num_ship_classes; i++)
head.add_data(Ship_info[i].name);
return head.next;
}
+2 -2
View File
@@ -87,8 +87,8 @@ BOOL shield_sys_dlg::OnInitDialog()
box = (CComboBox *) GetDlgItem(IDC_TYPE);
box->ResetContent();
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
box->AddString(it->name);
for (i=0; i<Num_ship_classes; i++)
box->AddString(Ship_info[i].name);
box = (CComboBox *) GetDlgItem(IDC_TEAM);
box->ResetContent();
+6 -15
View File
@@ -17,6 +17,7 @@
#include "render/3d.h"
#include "physics/physics.h"
#include "editor.h"
#include "ai/ailocal.h"
#include "ai/aigoals.h"
#include "parse/parselo.h"
#include "Management.h"
@@ -263,8 +264,8 @@ BOOL CShipEditorDlg::Create()
ptr = (CComboBox *) GetDlgItem(IDC_SHIP_CLASS);
ptr->ResetContent();
for (auto it = Ship_info.cbegin(); it != Ship_info.end(); ++it){
ptr->AddString(it->name);
for (i=0; i<Num_ship_classes; i++){
ptr->AddString(Ship_info[i].name);
}
ptr = (CComboBox *) GetDlgItem(IDC_AI_CLASS);
@@ -586,7 +587,7 @@ void CShipEditorDlg::initialize_data(int full_update)
m_score.init(Ships[i].score);
m_assist_score.init((int)(Ships[i].assist_score_pct*100));
m_persona = Ships[i].persona_index;
m_persona = Ships[i].persona_index + 1;
// we use final_death_time member of ship structure for holding the amount of time before a mission
// to destroy this ship
@@ -624,8 +625,8 @@ void CShipEditorDlg::initialize_data(int full_update)
m_hotkey = -1;
}
if ( Ships[i].persona_index != m_persona ){
m_persona = -2;
if ( Ships[i].persona_index != (m_persona-1) ){
m_persona = -1;
}
if (Ships[i].wingnum != wing){
@@ -677,16 +678,6 @@ void CShipEditorDlg::initialize_data(int full_update)
}
}
m_persona++;
if (m_persona > 0) {
int persona_index = 0;
for (int i = 0; i < m_persona; i++) {
if (Personas[i].flags & PERSONA_FLAG_WINGMAN)
persona_index++;
}
m_persona = persona_index;
}
} else { // no ships selected, 0 or more player ships selected
if (player_count > 1) { // multiple player ships selected
Assert(base_player >= 0);
+18 -48
View File
@@ -74,10 +74,9 @@ void ship_flags_dlg::DoDataExchange(CDataExchange* pDX)
DDX_Control(pDX, IDC_HIDE_SHIP_NAME, m_hide_ship_name);
DDX_Control(pDX, IDC_DISABLE_ETS, m_disable_ets);
DDX_Control(pDX, IDC_CLOAKED, m_cloaked);
DDX_Control(pDX, IDC_NO_COLLIDE, m_no_collide);
DDX_Control(pDX, IDC_SET_CLASS_DYNAMICALLY, m_set_class_dynamically);
DDX_Control(pDX, IDC_SCRAMBLE_MESSAGES, m_scramble_messages);
DDX_Control(pDX, IDC_NO_COLLIDE, m_no_collide);
DDX_Control(pDX, IDC_NO_DISABLED_SELF_DESTRUCT, m_no_disabled_self_destruct);
//}}AFX_DATA_MAP
if (pDX->m_bSaveAndValidate) { // get dialog control values
@@ -143,7 +142,6 @@ BEGIN_MESSAGE_MAP(ship_flags_dlg, CDialog)
ON_BN_CLICKED(IDC_CLOAKED, OnCloaked)
ON_BN_CLICKED(IDC_SCRAMBLE_MESSAGES, OnScrambleMessages)
ON_BN_CLICKED(IDC_NO_COLLIDE, OnNoCollide)
ON_BN_CLICKED(IDC_NO_DISABLED_SELF_DESTRUCT, OnNoDisabledSelfDestruct)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
@@ -164,7 +162,7 @@ BOOL ship_flags_dlg::OnInitDialog()
int hidden_from_sensors = 0, primitive_sensors = 0, no_subspace_drive = 0, affected_by_gravity = 0;
int toggle_subsystem_scanning = 0, scannable = 0, kamikaze = 0, no_dynamic = 0, red_alert_carry = 0;
int special_warpin = 0, disable_messages = 0, guardian = 0, vaporize = 0, stealth = 0, friendly_stealth_invisible = 0;
int no_death_scream = 0, always_death_scream = 0, scramble_messages = 0, no_disabled_self_destruct = 0;
int no_death_scream = 0, always_death_scream = 0, scramble_messages = 0;
int nav_carry = 0, nav_needslink = 0, hide_ship_name = 0, set_class_dynamically = 0, no_ets = 0, cloaked = 0, no_collide = 0;
object *objp;
@@ -215,7 +213,6 @@ BOOL ship_flags_dlg::OnInitDialog()
cloaked = (shipp->flags2 & SF2_CLOAKED) ? 1 : 0;
scramble_messages = (shipp->flags2 & SF2_SCRAMBLE_MESSAGES) ? 1 : 0;
no_collide = (objp->flags & OF_COLLIDES) ? 0 : 1;
no_disabled_self_destruct = (shipp->flags2 & SF2_NO_DISABLED_SELF_DESTRUCT) ? 1 : 0;
destroy_before_mission = (shipp->flags & SF_KILL_BEFORE_MISSION) ? 1 : 0;
m_destroy_value.init(shipp->final_death_time);
@@ -277,7 +274,6 @@ BOOL ship_flags_dlg::OnInitDialog()
cloaked = tristate_set(shipp->flags2 & SF2_CLOAKED, cloaked);
scramble_messages = tristate_set(shipp->flags2 & SF2_SCRAMBLE_MESSAGES, scramble_messages);
no_collide = tristate_set(!(objp->flags & OF_COLLIDES), no_collide);
no_disabled_self_destruct = tristate_set(shipp->flags2 & SF2_NO_DISABLED_SELF_DESTRUCT, no_disabled_self_destruct);
// check the final death time and set the internal variable according to whether or not
// the final_death_time is set. Also, the value in the edit box must be set if all the
@@ -353,7 +349,6 @@ BOOL ship_flags_dlg::OnInitDialog()
m_cloaked.SetCheck(cloaked);
m_scramble_messages.SetCheck(scramble_messages);
m_no_collide.SetCheck(no_collide);
m_no_disabled_self_destruct.SetCheck(no_disabled_self_destruct);
m_kdamage.setup(IDC_KDAMAGE, this);
m_destroy_value.setup(IDC_DESTROY_VALUE, this);
@@ -971,6 +966,22 @@ void ship_flags_dlg::update_ship(int shipnum)
break;
}
switch (m_no_collide.GetCheck()) {
case 1:
if ( objp->flags & OF_COLLIDES )
set_modified();
objp->flags &= ~OF_COLLIDES;
break;
case 0:
if (!(objp->flags & OF_COLLIDES))
set_modified();
objp->flags |= OF_COLLIDES;
break;
}
switch (m_guardian.GetCheck()) {
case 1:
if ( !(shipp->ship_guardian_threshold) )
@@ -1051,38 +1062,6 @@ void ship_flags_dlg::update_ship(int shipnum)
break;
}
switch (m_no_collide.GetCheck()) {
case 1:
if (objp->flags & OF_COLLIDES)
set_modified();
objp->flags &= ~OF_COLLIDES;
break;
case 0:
if (!(objp->flags & OF_COLLIDES))
set_modified();
objp->flags |= OF_COLLIDES;
break;
}
switch (m_no_disabled_self_destruct.GetCheck()) {
case 1:
if (!(shipp->flags2 & SF2_NO_DISABLED_SELF_DESTRUCT))
set_modified();
shipp->flags2 |= SF2_NO_DISABLED_SELF_DESTRUCT;
break;
case 0:
if (shipp->flags2 & SF2_NO_DISABLED_SELF_DESTRUCT)
set_modified();
shipp->flags2 &= ~SF2_NO_DISABLED_SELF_DESTRUCT;
break;
}
shipp->respawn_priority = 0;
if(The_mission.game_type & MISSION_TYPE_MULTI) {
@@ -1461,12 +1440,3 @@ void ship_flags_dlg::OnNoCollide()
m_no_collide.SetCheck(1);
}
}
void ship_flags_dlg::OnNoDisabledSelfDestruct()
{
if (m_no_disabled_self_destruct.GetCheck() == 1) {
m_no_disabled_self_destruct.SetCheck(0);
} else {
m_no_disabled_self_destruct.SetCheck(1);
}
}
+1 -3
View File
@@ -65,10 +65,9 @@ public:
CButton m_hide_ship_name;
CButton m_disable_ets;
CButton m_cloaked;
CButton m_no_collide;
CButton m_set_class_dynamically;
CButton m_scramble_messages;
CButton m_no_collide;
CButton m_no_disabled_self_destruct;
CSpinButtonCtrl m_destroy_spin;
numeric_edit_control m_kdamage;
@@ -129,7 +128,6 @@ protected:
afx_msg void OnCloaked();
afx_msg void OnScrambleMessages();
afx_msg void OnNoCollide();
afx_msg void OnNoDisabledSelfDestruct();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
+1 -1
View File
@@ -718,7 +718,7 @@ int VoiceActingManager::fout(char *format, ...)
vsprintf(str, format, args);
va_end(args);
cfputs(str.c_str(), fp);
cfputs(const_cast<char*>(str.c_str()), fp);
return 0;
}
+12 -60
View File
@@ -87,11 +87,7 @@ void WeaponEditorDlg::DoDataExchange(CDataExchange* pDX)
if (pDX->m_bSaveAndValidate) {
GetDlgItem(IDC_AMMO1)->GetWindowText(str);
if (save_number((char *) (LPCSTR) str, &m_ammo1)) {
if (m_missile1 <= 0) {
m_ammo_max1 = 0;
} else {
m_ammo_max1 = (m_cur_item == 0) ? get_max_ammo_count_for_bank(m_ship_class, 0, m_missile1 + First_secondary_index - 1) : get_max_ammo_count_for_turret_bank(cur_weapon, 0, m_missile1 + First_secondary_index - 1);
}
m_ammo_max1 = (m_missile1 <= 0) ? 0 : get_max_ammo_count_for_bank(m_ship_class, 0, m_missile1 + First_secondary_index - 1);
if (m_ammo1 < 0)
m_ammo1 = 0;
if (m_ammo1 > m_ammo_max1)
@@ -100,11 +96,7 @@ void WeaponEditorDlg::DoDataExchange(CDataExchange* pDX)
GetDlgItem(IDC_AMMO2)->GetWindowText(str);
if (save_number((char *) (LPCSTR) str, &m_ammo2)) {
if (m_missile2 <= 0) {
m_ammo_max2 = 0;
} else {
m_ammo_max2 = (m_cur_item == 0) ? get_max_ammo_count_for_bank(m_ship_class, 1, m_missile2 + First_secondary_index - 1) : get_max_ammo_count_for_turret_bank(cur_weapon, 1, m_missile2 + First_secondary_index - 1);
}
m_ammo_max2 = (m_missile2 <= 0) ? 0 : get_max_ammo_count_for_bank(m_ship_class, 1, m_missile2 + First_secondary_index - 1);
if (m_ammo2 < 0)
m_ammo2 = 0;
if (m_ammo2 > m_ammo_max2)
@@ -113,11 +105,7 @@ void WeaponEditorDlg::DoDataExchange(CDataExchange* pDX)
GetDlgItem(IDC_AMMO3)->GetWindowText(str);
if (save_number((char *) (LPCSTR) str, &m_ammo3)) {
if (m_missile3 <= 0) {
m_ammo_max3 = 0;
} else {
m_ammo_max3 = (m_cur_item == 0) ? get_max_ammo_count_for_bank(m_ship_class, 2, m_missile3 + First_secondary_index - 1) : get_max_ammo_count_for_turret_bank(cur_weapon, 2, m_missile3 + First_secondary_index - 1);
}
m_ammo_max3 = (m_missile3 <= 0) ? 0 : get_max_ammo_count_for_bank(m_ship_class, 2, m_missile3 + First_secondary_index - 1);
if (m_ammo3 < 0)
m_ammo3 = 0;
if (m_ammo3 > m_ammo_max3)
@@ -126,11 +114,7 @@ void WeaponEditorDlg::DoDataExchange(CDataExchange* pDX)
GetDlgItem(IDC_AMMO4)->GetWindowText(str);
if (save_number((char *) (LPCSTR) str, &m_ammo4)) {
if (m_missile4 <= 0) {
m_ammo_max4 = 0;
} else {
m_ammo_max4 = (m_cur_item == 0) ? get_max_ammo_count_for_bank(m_ship_class, 3, m_missile4 + First_secondary_index - 1) : get_max_ammo_count_for_turret_bank(cur_weapon, 3, m_missile4 + First_secondary_index - 1);
}
m_ammo_max4 = (m_missile4 <= 0) ? 0 : get_max_ammo_count_for_bank(m_ship_class, 3, m_missile4 + First_secondary_index - 1);
if (m_ammo4 < 0)
m_ammo4 = 0;
if (m_ammo4 > m_ammo_max4)
@@ -419,11 +403,7 @@ void WeaponEditorDlg::change_selection()
if (cur_weapon->num_secondary_banks > 0) {
m_missile1 = cur_weapon->secondary_bank_weapons[0] + 1;
if (m_missile1 > 0) {
if (m_cur_item == 0) {
m_ammo_max1 = get_max_ammo_count_for_bank(m_ship_class, 0, m_missile1 - 1);
} else {
m_ammo_max1 = get_max_ammo_count_for_turret_bank(cur_weapon, 0, m_missile1 - 1);
}
m_ammo_max1 = get_max_ammo_count_for_bank(m_ship_class, 0, m_missile1 - 1);
if (cur_weapon->secondary_bank_ammo[0] != BLANK_FIELD)
m_ammo1 = cur_weapon->secondary_bank_ammo[0] * m_ammo_max1 / 100;
m_missile1 -= First_secondary_index;
@@ -442,11 +422,7 @@ void WeaponEditorDlg::change_selection()
if (cur_weapon->num_secondary_banks > 1) {
m_missile2 = cur_weapon->secondary_bank_weapons[1] + 1;
if (m_missile2 > 0) {
if (m_cur_item == 0) {
m_ammo_max2 = get_max_ammo_count_for_bank(m_ship_class, 1, m_missile2 - 1);
} else {
m_ammo_max2 = get_max_ammo_count_for_turret_bank(cur_weapon, 1, m_missile2 - 1);
}
m_ammo_max2 = get_max_ammo_count_for_bank(m_ship_class, 1, m_missile2 - 1);
if (cur_weapon->secondary_bank_ammo[1] != BLANK_FIELD)
m_ammo2 = cur_weapon->secondary_bank_ammo[1] * m_ammo_max2 / 100;
m_missile2 -= First_secondary_index;
@@ -465,11 +441,7 @@ void WeaponEditorDlg::change_selection()
if (cur_weapon->num_secondary_banks > 2) {
m_missile3 = cur_weapon->secondary_bank_weapons[2] + 1;
if (m_missile3 > 0) {
if (m_cur_item == 0) {
m_ammo_max3 = get_max_ammo_count_for_bank(m_ship_class, 2, m_missile3 - 1);
} else {
m_ammo_max3 = get_max_ammo_count_for_turret_bank(cur_weapon, 2, m_missile3 - 1);
}
m_ammo_max3 = get_max_ammo_count_for_bank(m_ship_class, 2, m_missile3 - 1);
if (cur_weapon->secondary_bank_ammo[2] != BLANK_FIELD)
m_ammo3 = cur_weapon->secondary_bank_ammo[2] * m_ammo_max3 / 100;
m_missile3 -= First_secondary_index;
@@ -488,11 +460,7 @@ void WeaponEditorDlg::change_selection()
if (cur_weapon->num_secondary_banks > 3) {
m_missile4 = cur_weapon->secondary_bank_weapons[3] + 1;
if (m_missile4 > 0) {
if (m_cur_item == 0) {
m_ammo_max4 = get_max_ammo_count_for_bank(m_ship_class, 3, m_missile4 - 1);
} else {
m_ammo_max4 = get_max_ammo_count_for_turret_bank(cur_weapon, 3, m_missile4 - 1);
}
m_ammo_max4 = get_max_ammo_count_for_bank(m_ship_class, 3, m_missile4 - 1);
if (cur_weapon->secondary_bank_ammo[3] != BLANK_FIELD)
m_ammo4 = cur_weapon->secondary_bank_ammo[3] * m_ammo_max4 / 100;
m_missile4 -= First_secondary_index;
@@ -585,11 +553,7 @@ void WeaponEditorDlg::OnSelchangeMissile1()
{
UpdateData(TRUE);
UpdateData(TRUE);
if (m_cur_item == 0) {
m_ammo_max1 = get_max_ammo_count_for_bank(m_ship_class, 0, m_missile1 + First_secondary_index - 1);
} else {
m_ammo_max1 = get_max_ammo_count_for_turret_bank(cur_weapon, 0, m_missile1 + First_secondary_index - 1);
}
m_ammo_max1 = get_max_ammo_count_for_bank(m_ship_class, 0, m_missile1 + First_secondary_index - 1);
m_ammo1 = m_ammo_max1 ? (m_ammo_max1) : 0;
change_selection();
}
@@ -598,11 +562,7 @@ void WeaponEditorDlg::OnSelchangeMissile2()
{
UpdateData(TRUE);
UpdateData(TRUE);
if (m_cur_item == 0) {
m_ammo_max2 = get_max_ammo_count_for_bank(m_ship_class, 1, m_missile2 + First_secondary_index - 1);
} else {
m_ammo_max2 = get_max_ammo_count_for_turret_bank(cur_weapon, 1, m_missile2 + First_secondary_index - 1);
}
m_ammo_max2 = get_max_ammo_count_for_bank(m_ship_class, 0, m_missile2 + First_secondary_index - 1);
m_ammo2 = m_ammo_max2 ? (m_ammo_max2) : 0;
change_selection();
}
@@ -611,11 +571,7 @@ void WeaponEditorDlg::OnSelchangeMissile3()
{
UpdateData(TRUE);
UpdateData(TRUE);
if (m_cur_item == 0) {
m_ammo_max3 = get_max_ammo_count_for_bank(m_ship_class, 2, m_missile3 + First_secondary_index - 1);
} else {
m_ammo_max3 = get_max_ammo_count_for_turret_bank(cur_weapon, 2, m_missile3 + First_secondary_index - 1);
}
m_ammo_max3 = get_max_ammo_count_for_bank(m_ship_class, 0, m_missile3 + First_secondary_index - 1);
m_ammo3 = m_ammo_max3 ? (m_ammo_max3) : 0;
change_selection();
}
@@ -624,11 +580,7 @@ void WeaponEditorDlg::OnSelchangeMissile4()
{
UpdateData(TRUE);
UpdateData(TRUE);
if (m_cur_item == 0) {
m_ammo_max4 = get_max_ammo_count_for_bank(m_ship_class, 3, m_missile4 + First_secondary_index - 1);
} else {
m_ammo_max4 = get_max_ammo_count_for_turret_bank(cur_weapon, 3, m_missile4 + First_secondary_index - 1);
}
m_ammo_max4 = get_max_ammo_count_for_bank(m_ship_class, 0, m_missile4 + First_secondary_index - 1);
m_ammo4 = m_ammo_max4 ? (m_ammo_max4) : 0;
change_selection();
}
+1
View File
@@ -17,6 +17,7 @@
#include "physics/physics.h"
#include "object/object.h"
#include "editor.h"
#include "ai/ailocal.h"
#include "ship/ship.h"
#include "math/vecmat.h"
#include "Management.h"
+11 -10
View File
@@ -405,7 +405,7 @@ void wing_editor::initialize_data_safe(int full_update)
for (i=0; i<Wings[cur_wing].wave_count; i++)
ptr->AddString(Ships[Wings[cur_wing].ship_index[i]].ship_name);
m_threshold_spin.SetRange(0, static_cast<short>(calc_max_wave_treshold()));
m_threshold_spin.SetRange(0, (short) Wings[cur_wing].wave_count - 1);
for (i=0; i<Num_reinforcements; i++)
if (!stricmp(Reinforcements[i].name, Wings[cur_wing].name))
break;
@@ -754,8 +754,16 @@ void wing_editor::update_data_safe()
if (cur_wing < 0)
return;
if (m_threshold > calc_max_wave_treshold()) {
m_threshold = calc_max_wave_treshold();
if (m_threshold >= Wings[cur_wing].wave_count) {
m_threshold = Wings[cur_wing].wave_count - 1;
if (!bypass_errors) {
sprintf(buf, "Wave threshold is set too high. Value has been lowered to %d", (int) m_threshold);
MessageBox(buf);
}
}
if (m_threshold + Wings[cur_wing].wave_count > MAX_SHIPS_PER_WING) {
m_threshold = MAX_SHIPS_PER_WING - Wings[cur_wing].wave_count;
if (!bypass_errors) {
sprintf(buf, "Wave threshold is set too high. Value has been lowered to %d", (int) m_threshold);
MessageBox(buf);
@@ -1351,11 +1359,4 @@ void wing_editor::OnRestrictDeparture()
dlg.m_path_mask = &Wings[cur_wing].departure_path_mask;
dlg.DoModal();
}
int wing_editor::calc_max_wave_treshold()
{
const int treshold1 = Wings[cur_wing].wave_count - 1; // At least 1 ship must have died before allowing respawn
const int treshold2 = MAX_SHIPS_PER_WING - Wings[cur_wing].wave_count; // Maximum MAX_SHIPS_PER_WING ships can be alive at any given time
return min(treshold1, treshold2);
}
-3
View File
@@ -106,7 +106,4 @@ protected:
afx_msg void OnRestrictDeparture();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Aux functions
int calc_max_wave_treshold();
};
+214 -131
View File
@@ -26,6 +26,7 @@
#include "asteroid/asteroid.h"
#include "autopilot/autopilot.h"
#include "bmpman/bmpman.h"
#include "camera/camera.h"
#include "cfile/cfile.h"
#include "cmdline/cmdline.h"
#include "cmeasure/cmeasure.h"
@@ -39,26 +40,24 @@
#include "freespace2/freespace.h"
#include "freespace2/freespaceresource.h"
#include "freespace2/levelpaging.h"
#include "fs2netd/fs2netd_client.h"
#include "gamehelp/contexthelp.h"
#include "gamehelp/gameplayhelp.h"
#include "gamesequence/gamesequence.h"
#include "gamesnd/eventmusic.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/alphacolors.h"
#include "globalincs/mspdb_callstack.h"
#include "globalincs/version.h"
#include "globalincs/mspdb_callstack.h"
#include "graphics/font.h"
#include "graphics/shadows.h"
#include "hud/hud.h"
#include "hud/hudconfig.h"
#include "hud/hudescort.h"
#include "hud/hudlock.h"
#include "hud/hudmessage.h"
#include "hud/hudparse.h"
#include "hud/hudshield.h"
#include "hud/hudsquadmsg.h"
#include "hud/hudtargetbox.h"
#include "hud/hudparse.h"
#include "hud/hudsquadmsg.h"
#include "iff_defs/iff_defs.h"
#include "io/joy.h"
#include "io/joy_ff.h"
@@ -130,7 +129,6 @@
#include "parse/scripting.h"
#include "parse/sexp.h"
#include "particle/particle.h"
#include "pilotfile/pilotfile.h"
#include "playerman/managepilot.h"
#include "playerman/player.h"
#include "popup/popup.h"
@@ -159,18 +157,16 @@
#include "weapon/muzzleflash.h"
#include "weapon/shockwave.h"
#include "weapon/weapon.h"
#include "fs2netd/fs2netd_client.h"
#include "pilotfile/pilotfile.h"
#include "globalincs/pstypes.h"
#include <stdexcept>
extern int Om_tracker_flag; // needed for FS2OpenPXO config
#ifdef WIN32
// According to AMD and NV, these _should_ force their drivers into high-performance mode
extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif
#ifdef NDEBUG
#ifdef FRED
@@ -311,6 +307,8 @@ int last_single_step=0;
int game_zbuffer = 1;
static int Game_paused;
int Game_level_seed;
#define EXPIRE_BAD_CHECKSUM 1
#define EXPIRE_BAD_TIME 2
@@ -460,7 +458,7 @@ fs_builtin_mission Game_builtin_mission_list[MAX_BUILTIN_MISSIONS] = {
// Internal function prototypes
void game_maybe_draw_mouse(float frametime);
void init_animating_pointer();
void load_animating_pointer(char *filename);
void load_animating_pointer(char *filename, int dx, int dy);
void unload_animating_pointer();
void game_do_training_checks();
void game_shutdown(void);
@@ -576,7 +574,7 @@ void game_framerate_check_init()
extern float Framerate;
void game_framerate_check()
{
int y_start = gr_screen.center_offset_y + 100;
int y_start = 100;
// if the current framerate is above the critical level, add frametime
if(Framerate >= Gf_critical){
@@ -590,7 +588,7 @@ void game_framerate_check()
// display if we're above the critical framerate
if(Framerate < Gf_critical){
gr_set_color_fast(&Color_bright_red);
gr_string(gr_screen.center_offset_x + 200, y_start, "Framerate warning", GR_RESIZE_NONE);
gr_string(200, y_start, "Framerate warning", GR_RESIZE_NONE);
y_start += 10;
}
@@ -605,7 +603,7 @@ void game_framerate_check()
gr_set_color_fast(&Color_bright_red);
}
gr_printf_no_resize(gr_screen.center_offset_x + 200, y_start, "%d%%", (int)pct);
gr_printf_no_resize(200, y_start, "%d%%", (int)pct);
y_start += 10;
}
@@ -750,9 +748,7 @@ void game_sunspot_process(float frametime)
// check
for(idx=0; idx<n_lights; idx++) {
bool in_shadow = shipfx_eye_in_shadow(&Eye_position, Viewer_obj, idx);
if ( (ls_on && !ls_force_off) || !in_shadow ) {
if ( (ls_on && !ls_force_off) || !shipfx_eye_in_shadow( &Eye_position, Viewer_obj, idx ) ) {
vec3d light_dir;
light_get_global_dir(&light_dir, idx);
@@ -762,10 +758,10 @@ void game_sunspot_process(float frametime)
Sun_spot_goal += (float)pow(dot,85.0f);
}
}
if ( !in_shadow ) {
// draw the glow for this sun
stars_draw_sun_glow(idx);
}
if (!shipfx_eye_in_shadow( &Eye_position, Viewer_obj, idx ) ) {
// draw the glow for this sun
stars_draw_sun_glow(idx);
}
}
Sun_drew = 0;
@@ -947,18 +943,28 @@ uint load_post_level_init;
*
* @return 0 on failure, 1 on success
*/
void game_level_init()
void game_level_init(int seed)
{
game_busy( NOX("** starting game_level_init() **") );
load_gl_init = (uint) time(NULL);
// seed the random number generator
if ( seed == -1 ) {
// if no seed was passed, seed the generator either from the time value, or from the
// netgame security flags -- ensures that all players in multiplayer game will have the
// same randon number sequence (with static rand functions)
if ( Game_mode & GM_NORMAL ) {
Game_level_seed = (int) time(NULL);
} else {
Game_level_seed = Netgame.security;
}
} else {
Assert( !(Game_mode & GM_MULTIPLAYER) );
Game_level_seed = seed;
}
srand( Game_level_seed );
// seed the random number generator in multiplayer
if ( Game_mode & GM_MULTIPLAYER ) {
// seed the generator from the netgame security flags -- ensures that all players in
// multiplayer will have the same random number sequence (with static rand functions)
srand( Netgame.security );
// semirand function needs to get re-initted every time in multiplayer
// semirand function needs to get re-initted every time in multiplayer
if ( Game_mode & GM_MULTIPLAYER ){
init_semirand();
}
@@ -1253,7 +1259,7 @@ void game_loading_callback_close()
// Make sure bar shows all the way over.
game_loading_callback(COUNT_ESTIMATE);
int real_count __UNUSED = game_busy_callback( NULL );
int real_count = game_busy_callback( NULL );
Mouse_hidden = 0;
Game_loading_callback_inited = 0;
@@ -1417,7 +1423,7 @@ int game_start_mission()
{
mprintf(( "=================== STARTING LEVEL LOAD ==================\n" ));
int s1 __UNUSED = timer_get_milliseconds();
int s1 = timer_get_milliseconds();
// clear post processing settings
gr_post_process_set_defaults();
@@ -1474,9 +1480,9 @@ int game_start_mission()
bm_print_bitmaps();
int e1 __UNUSED = timer_get_milliseconds();
int e1 = timer_get_milliseconds();
mprintf(("Level load took %f seconds.\n", (e1 - s1) / 1000.0f ));
printf("Level load took %f seconds.\n", (e1 - s1) / 1000.0f );
return 1;
}
@@ -1604,6 +1610,8 @@ DCF(show_cpu,"Toggles showing cpu usage")
#endif
int Game_init_seed;
DCF(use_joy_mouse,"Makes joystick move mouse cursor")
{
bool process = true;
@@ -1731,7 +1739,7 @@ char full_path[1024];
*/
void game_init()
{
int s1 __UNUSED, e1 __UNUSED;
int s1, e1;
const char *ptr;
char whee[MAX_PATH_LEN];
@@ -1740,8 +1748,8 @@ void game_init()
// Moved from rand32, if we're gonna break, break immediately.
Assert(RAND_MAX == 0x7fff || RAND_MAX >= 0x7ffffffd);
// seed the random number generator
int game_init_seed = (int) time(NULL);
srand( game_init_seed );
Game_init_seed = (int) time(NULL);
srand( Game_init_seed );
Framerate_delay = 0;
@@ -2012,8 +2020,7 @@ void game_init()
armor_init();
ai_init();
ai_profiles_init(); // Goober5000
weapon_init();
glowpoint_init();
weapon_init();
ship_init(); // read in ships.tbl
player_init();
@@ -2041,7 +2048,7 @@ void game_init()
pilot_load_pic_list();
pilot_load_squad_pic_list();
load_animating_pointer(NOX("cursor"));
load_animating_pointer(NOX("cursor"), 0, 0);
if(!Cmdline_reparse_mainhall)
{
@@ -2151,11 +2158,11 @@ void game_show_framerate()
for ( pss = GET_FIRST(&shipp->subsys_list); pss !=END_OF_LIST(&shipp->subsys_list); pss = GET_NEXT(pss) ) {
if (pss->system_info->type == SUBSYSTEM_TURRET) {
if(pss->turret_enemy_objnum == -1)
gr_printf_no_resize(gr_screen.center_offset_x + 10, gr_screen.center_offset_y + (t*line_height), "Turret %d: <None>", t);
gr_printf_no_resize(10, t*line_height, "Turret %d: <None>", t);
else if (Objects[pss->turret_enemy_objnum].type == OBJ_SHIP)
gr_printf_no_resize(gr_screen.center_offset_x + 10, gr_screen.center_offset_y + (t*line_height), "Turret %d: %s", t, Ships[Objects[pss->turret_enemy_objnum].instance].ship_name);
gr_printf_no_resize(10, t*line_height, "Turret %d: %s", t, Ships[Objects[pss->turret_enemy_objnum].instance].ship_name);
else
gr_printf_no_resize(gr_screen.center_offset_x + 10, gr_screen.center_offset_y + (t*line_height), "Turret %d: <Object %d>", t, pss->turret_enemy_objnum);
gr_printf_no_resize(10, t*line_height, "Turret %d: <Object %d>", t, pss->turret_enemy_objnum);
t++;
}
@@ -2168,14 +2175,14 @@ void game_show_framerate()
gr_set_color_fast(&HUD_color_debug);
if (Cmdline_frame_profile) {
gr_string(gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 100 + line_height, profile_output.c_str(), GR_RESIZE_NONE);
gr_string(20, 100 + line_height, profile_output, GR_RESIZE_NONE);
}
if (Show_framerate) {
if (frametotal != 0.0f)
gr_printf_no_resize( gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 100, "FPS: %0.1f", Framerate );
gr_printf_no_resize( 20, 100, "FPS: %0.1f", Framerate );
else
gr_string( gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 100, "FPS: ?", GR_RESIZE_NONE );
gr_string( 20, 100, "FPS: ?", GR_RESIZE_NONE );
}
}
@@ -2189,10 +2196,6 @@ void game_show_framerate()
#ifdef _WIN32
if (Cmdline_show_stats && HUD_draw) {
int sx,sy;
sx = gr_screen.center_offset_x + 20;
sy = gr_screen.center_offset_y + 100 + (line_height * 2);
char mem_buffer[50];
MEMORYSTATUS mem_stats;
@@ -2204,27 +2207,22 @@ void game_show_framerate()
else
sprintf(mem_buffer,"Using Physical: %d Meg",(Mem_starttime_phys - mem_stats.dwAvailPhys)/1024/1024);
gr_string( sx, sy, mem_buffer, GR_RESIZE_NONE);
sy += line_height;
gr_string( 20, 100 + (line_height * 2), mem_buffer, GR_RESIZE_NONE);
sprintf(mem_buffer,"Using Pagefile: %d Meg",(Mem_starttime_pagefile - mem_stats.dwAvailPageFile)/1024/1024);
gr_string( sx, sy, mem_buffer, GR_RESIZE_NONE);
sy += line_height;
gr_string( 20, 100 + (line_height * 3), mem_buffer, GR_RESIZE_NONE);
sprintf(mem_buffer,"Using Virtual: %d Meg",(Mem_starttime_virtual - mem_stats.dwAvailVirtual)/1024/1024);
gr_string( sx, sy, mem_buffer, GR_RESIZE_NONE);
sy += line_height * 2;
gr_string( 20, 100 + (line_height * 4), mem_buffer, GR_RESIZE_NONE);
if ( ((int)mem_stats.dwAvailPhys == -1) || ((int)mem_stats.dwTotalPhys == -1) )
sprintf(mem_buffer, "Physical Free: *** / *** (>4G)");
else
sprintf(mem_buffer,"Physical Free: %d / %d Meg",mem_stats.dwAvailPhys/1024/1024, mem_stats.dwTotalPhys/1024/1024);
gr_string( sx, sy, mem_buffer, GR_RESIZE_NONE);
sy += line_height;
gr_string( 20, 100 + (line_height * 6), mem_buffer, GR_RESIZE_NONE);
sprintf(mem_buffer,"Pagefile Free: %d / %d Meg",mem_stats.dwAvailPageFile/1024/1024, mem_stats.dwTotalPageFile/1024/1024);
gr_string( sx, sy, mem_buffer, GR_RESIZE_NONE);
sy += line_height;
gr_string( 20, 100 + (line_height * 7), mem_buffer, GR_RESIZE_NONE);
sprintf(mem_buffer,"Virtual Free: %d / %d Meg",mem_stats.dwAvailVirtual/1024/1024, mem_stats.dwTotalVirtual/1024/1024);
gr_string( sx, sy, mem_buffer, GR_RESIZE_NONE);
gr_string( 20, 100 + (line_height * 8), mem_buffer, GR_RESIZE_NONE);
}
#endif
@@ -2232,8 +2230,8 @@ void game_show_framerate()
if ( Show_cpu == 1 ) {
int sx,sy;
sx = gr_screen.center_offset_x + gr_screen.center_w - 154;
sy = gr_screen.center_offset_y + 15;
sx = gr_screen.max_w - 154;
sy = 15;
gr_set_color_fast(&HUD_color_debug);
@@ -2279,8 +2277,8 @@ void game_show_framerate()
if ( Show_mem ) {
int sx,sy;
sx = gr_screen.center_offset_x + gr_screen.center_w - 154;
sy = gr_screen.center_offset_y + 15;
sx = gr_screen.max_w - 154;
sy = 15;
gr_set_color_fast(&HUD_color_debug);
@@ -2313,8 +2311,8 @@ void game_show_framerate()
if ( Show_player_pos ) {
int sx, sy;
sx = gr_screen.center_offset_x + 320;
sy = gr_screen.center_offset_y + 100;
sx = 320;
sy = 100;
gr_printf_no_resize(sx, sy, NOX("Player Pos: (%d,%d,%d)"), fl2i(Player_obj->pos.xyz.x), fl2i(Player_obj->pos.xyz.y), fl2i(Player_obj->pos.xyz.z));
}
@@ -2346,11 +2344,11 @@ void game_show_framerate()
short_name++;
sprintf(mem_buffer,"%s:\t%d K", short_name, size);
gr_string( gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 100 + (line_height * 12) + (mi*line_height), mem_buffer, GR_RESIZE_NONE);
gr_string( 20, 100 + (line_height * 12) + (mi*line_height), mem_buffer, GR_RESIZE_NONE);
}
sprintf(mem_buffer,"Total RAM:\t%d K", TotalRam / 1024);
gr_string( gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 100 + (line_height * 13) + (mi*line_height), mem_buffer, GR_RESIZE_NONE);
gr_string( 20, 100 + (line_height * 13) + (mi*line_height), mem_buffer, GR_RESIZE_NONE);
}
#endif
@@ -2385,7 +2383,7 @@ void game_show_eye_pos(camid cid)
gr_set_color_fast(&HUD_color_debug);
//Position
gr_printf_no_resize(gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 100 - font_height, "X:%f Y:%f Z:%f", cam_pos.xyz.x, cam_pos.xyz.y, cam_pos.xyz.z);
gr_printf_no_resize(20, 100 - font_height, "X:%f Y:%f Z:%f", cam_pos.xyz.x, cam_pos.xyz.y, cam_pos.xyz.z);
font_height -= font_height/2;
//Orientation
@@ -2393,7 +2391,7 @@ void game_show_eye_pos(camid cid)
rot_angles.p *= (180/PI);
rot_angles.b *= (180/PI);
rot_angles.h *= (180/PI);
gr_printf_no_resize(gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 100 - font_height, "Xr:%f Yr:%f Zr:%f", rot_angles.p, rot_angles.b, rot_angles.h);
gr_printf_no_resize(20, 100 - font_height, "Xr:%f Yr:%f Zr:%f", rot_angles.p, rot_angles.b, rot_angles.h);
}
void game_show_standalone_framerate()
@@ -2443,7 +2441,7 @@ void game_show_time_left()
diff = 0;
hud_set_default_color();
gr_printf_no_resize( gr_screen.center_offset_x + 5, gr_screen.center_offset_y + 40, XSTR( "Mission time remaining: %d seconds", 179), diff );
gr_printf_no_resize( 5, 40, XSTR( "Mission time remaining: %d seconds", 179), diff );
}
//========================================================================================
@@ -2811,7 +2809,7 @@ void game_tst_mark(object *objp, ship *shipp)
}
// bogus
if((objp == NULL) || (shipp == NULL) || (shipp->ship_info_index < 0) || (shipp->ship_info_index >= static_cast<int>(Ship_info.size()))){
if((objp == NULL) || (shipp == NULL) || (shipp->ship_info_index < 0) || (shipp->ship_info_index >= Num_ship_classes)){
return;
}
sip = &Ship_info[shipp->ship_info_index];
@@ -3263,16 +3261,16 @@ void setup_environment_mapping(camid cid)
// face 3 (py / up)
memset( &new_orient, 0, sizeof(matrix) );
new_orient.vec.fvec.xyz.y = (gr_screen.mode == GR_OPENGL) ? 1.0f : -1.0f;
new_orient.vec.uvec.xyz.z = (gr_screen.mode == GR_OPENGL) ? -1.0f : 1.0f;
new_orient.vec.fvec.xyz.y = (gr_screen.mode == GR_OPENGL) ? -1.0f : 1.0f;
new_orient.vec.uvec.xyz.z = (gr_screen.mode == GR_OPENGL) ? 1.0f : -1.0f;
new_orient.vec.rvec.xyz.x = 1.0f;
render_environment(i, &cam_pos, &new_orient, new_zoom);
i++; // bump!
// face 4 (ny / down)
memset( &new_orient, 0, sizeof(matrix) );
new_orient.vec.fvec.xyz.y = (gr_screen.mode == GR_OPENGL) ? -1.0f : 1.0f;
new_orient.vec.uvec.xyz.z = (gr_screen.mode == GR_OPENGL) ? 1.0f : -1.0f;
new_orient.vec.fvec.xyz.y = (gr_screen.mode == GR_OPENGL) ? 1.0f : -1.0f;
new_orient.vec.uvec.xyz.z = (gr_screen.mode == GR_OPENGL) ? -1.0f : 1.0f;
new_orient.vec.rvec.xyz.x = 1.0f;
render_environment(i, &cam_pos, &new_orient, new_zoom);
i++; // bump!
@@ -3668,8 +3666,7 @@ DCF_BOOL( subspace, Game_subspace_effect )
void clip_frame_view();
// Does everything needed to render a frame
extern SCP_vector<object*> effect_ships;
extern SCP_vector<object*> transparent_objects;
extern SCP_vector<object*> effect_ships;
void game_render_frame( camid cid )
{
@@ -3718,7 +3715,7 @@ void game_render_frame( camid cid )
// Note: environment mapping gets disabled when rendering to texture; if you change
// this, make sure that the current render target gets restored right afterwards!
if ( Cmdline_env && !Env_cubemap_drawn && gr_screen.rendering_to_texture == -1 ) {
PROFILE("Environment Mapping", setup_environment_mapping(cid));
setup_environment_mapping(cid);
if ( !Dynamic_environment ) {
Env_cubemap_drawn = true;
@@ -3743,13 +3740,15 @@ void game_render_frame( camid cid )
stars_draw(1,1,1,0,0);
}
PROFILE("Build Shadow Map", shadows_render_all(Proj_fov, &Eye_matrix, &Eye_position));
PROFILE("Render Scene", obj_render_queue_all());
bool draw_viewer_last = false;
obj_render_all(obj_render, &draw_viewer_last);
// Why do we not show the shield effect in these modes? Seems ok.
//if (!(Viewer_mode & (VM_EXTERNAL | VM_SLEWED | VM_CHASE | VM_DEAD_VIEW))) {
render_shields();
//}
PROFILE("Trails", trail_render_all()); // render missilie trails after everything else.
PROFILE("Particles", particle_render_all()); // render particles after everything else.
PROFILE("Particles", particle_render_all()); // render particles after everything else.
#ifdef DYN_CLIP_DIST
if(!Cmdline_nohtl)
@@ -3762,6 +3761,8 @@ void game_render_frame( camid cid )
#endif
beam_render_all(); // render all beam weapons
PROFILE("Trails", trail_render_all()); // render missilie trails after everything else.
// render nebula lightning
nebl_render_all();
@@ -3769,25 +3770,14 @@ void game_render_frame( camid cid )
// render local player nebula
neb2_render_player();
gr_copy_effect_texture();
// render all ships with shader effects on them
SCP_vector<object*>::iterator obji = effect_ships.begin();
for(;obji != effect_ships.end();++obji)
{
obj_render(*obji);
}
ship_render(*obji);
effect_ships.clear();
batch_render_distortion_map_bitmaps();
Shadow_override = true;
//Draw the viewer 'cause we didn't before.
//This is so we can change the minimum clipping distance without messing everything up.
if ( Viewer_obj
&& (Viewer_obj->type == OBJ_SHIP)
&& (Ship_info[Ships[Viewer_obj->instance].ship_info_index].flags2 & SIF2_SHOW_SHIP_MODEL)
&& (!Viewer_mode || (Viewer_mode & VM_PADLOCK_ANY) || (Viewer_mode & VM_OTHER_SHIP) || (Viewer_mode & VM_TRACK)) )
if(draw_viewer_last && Viewer_obj)
{
gr_post_process_save_zbuffer();
ship_render_show_ship_cockpit(Viewer_obj);
@@ -3823,10 +3813,10 @@ void game_render_frame( camid cid )
gr_end_proj_matrix();
gr_end_view_matrix();
}
Shadow_override = false;
//================ END OF 3D RENDERING STUFF ====================
PROFILE("Post Process", gr_scene_texture_end());
gr_scene_texture_end();
extern int Multi_display_netinfo;
if(Multi_display_netinfo){
@@ -3840,7 +3830,7 @@ void game_render_frame( camid cid )
do_timing_test(flFrametime);
extern int OO_update_index;
multi_rate_display(OO_update_index, gr_screen.center_offset_x + 375, gr_screen.center_offset_y);
multi_rate_display(OO_update_index, 375, 0);
// test
extern void oo_display();
@@ -3883,6 +3873,97 @@ void john_debug_stuff(vec3d *eye_pos, matrix *eye_orient)
}
#endif
// following function for dumping frames for purposes of building trailers.
#ifndef NDEBUG
// function to toggle state of dumping every frame into PCX when playing the game
DCF(dump_frames, "Toggles On/off frame dumping at 15 hz")
{
if ( Debug_dump_frames == 0 ) {
// Turn it on
Debug_dump_frames = 15;
Debug_dump_trigger = 0;
gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
dc_printf( "Frame dumping at 15 hz is now ON\n" );
} else {
// Turn it off
Debug_dump_frames = 0;
Debug_dump_trigger = 0;
gr_dump_frame_stop();
dc_printf( "Frame dumping is now OFF\n" );
}
}
DCF(dump_frames_trigger, "Starts/stop frame dumping at 15 hz")
{
if ( Debug_dump_frames == 0 ) {
// Turn it on
Debug_dump_frames = 15;
Debug_dump_trigger = 1;
gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
dc_printf( "Frame dumping at 15 hz is now ON\n" );
} else {
// Turn it off
Debug_dump_frames = 0;
Debug_dump_trigger = 0;
gr_dump_frame_stop();
dc_printf( "Frame dumping is now OFF\n" );
}
}
DCF(dump_frames30, "Starts/stop frame dumping at 30 hz")
{
if ( Debug_dump_frames == 0 ) {
// Turn it on
Debug_dump_frames = 30;
Debug_dump_trigger = 0;
gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
dc_printf( "Frame dumping at 30 hz is now ON\n" );
} else {
// Turn it off
Debug_dump_frames = 0;
Debug_dump_trigger = 0;
gr_dump_frame_stop();
dc_printf( "Frame dumping is now OFF\n" );
}
}
DCF(dump_frames30_trigger, "Starts/stop frame dumping at 30 hz")
{
if ( Debug_dump_frames == 0 ) {
// Turn it on
Debug_dump_frames = 30;
Debug_dump_trigger = 1;
gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
dc_printf( "Triggered frame dumping at 30 hz is now ON\n" );
} else {
// Turn it off
Debug_dump_frames = 0;
Debug_dump_trigger = 0;
gr_dump_frame_stop();
dc_printf( "Triggered frame dumping is now OFF\n" );
}
}
void game_maybe_dump_frame()
{
if ( !Debug_dump_frames ){
return;
}
if( Debug_dump_trigger && !keyd_pressed[KEY_Q] ){
return;
}
game_stop_time();
gr_dump_frame();
Debug_dump_frame_num++;
game_start_time();
}
#endif
extern int Player_dead_state;
// Flip the page and time how long it took.
@@ -3923,7 +4004,7 @@ void game_simulation_frame()
ship_info *sip;
while((moveup != END_OF_LIST(&Ship_obj_list)) && (moveup != NULL)){
// bogus
if((moveup->objnum < 0) || (moveup->objnum >= MAX_OBJECTS) || (Objects[moveup->objnum].type != OBJ_SHIP) || (Objects[moveup->objnum].instance < 0) || (Objects[moveup->objnum].instance >= MAX_SHIPS) || (Ships[Objects[moveup->objnum].instance].ship_info_index < 0) || (Ships[Objects[moveup->objnum].instance].ship_info_index >= static_cast<int>(Ship_info.size()))){
if((moveup->objnum < 0) || (moveup->objnum >= MAX_OBJECTS) || (Objects[moveup->objnum].type != OBJ_SHIP) || (Objects[moveup->objnum].instance < 0) || (Objects[moveup->objnum].instance >= MAX_SHIPS) || (Ships[Objects[moveup->objnum].instance].ship_info_index < 0) || (Ships[Objects[moveup->objnum].instance].ship_info_index >= Num_ship_classes)){
moveup = GET_NEXT(moveup);
continue;
}
@@ -4343,6 +4424,7 @@ void game_frame(bool paused)
}
#endif
// start timing frame
timing_frame_start();
profile_begin("Main Frame");
DEBUG_GET_TIME( total_time1 )
@@ -4507,7 +4589,11 @@ void game_frame(bool paused)
// maybe render and process the dead popup
game_maybe_do_dead_popup(flFrametime);
// start timing frame
timing_frame_stop();
// timing_display(30, 10);
// If a regular popup is active, don't flip (popup code flips)
if( !popup_running_state() ){
DEBUG_GET_TIME( flip_time1 )
@@ -4515,6 +4601,9 @@ void game_frame(bool paused)
DEBUG_GET_TIME( flip_time2 )
}
#ifndef NDEBUG
game_maybe_dump_frame(); // used to dump pcx files for building trailers
#endif
} else {
game_show_standalone_framerate();
}
@@ -4684,7 +4773,7 @@ void game_set_frametime(int state)
fix frame_speed = F1_0 / Debug_dump_frames;
if (Frametime > frame_speed ){
nprintf(("warning","slow frame: %x\n",(int)Frametime));
nprintf(("warning","slow frame: %x\n",Frametime));
} else {
do {
thistime = timer_get_fixed_seconds();
@@ -4758,9 +4847,7 @@ void game_set_frametime(int state)
Last_frame_timestamp = timestamp();
flFrametime = f2fl(Frametime);
auto frametime_ms = f2i(fixmul(Frametime, F1_0 * TIMESTAMP_FREQUENCY));
timestamp_inc(frametime_ms);
timestamp_inc(flFrametime);
// wrap overall frametime if needed
if ( FrametimeOverall > (INT_MAX - F1_0) )
@@ -5653,10 +5740,6 @@ void game_leave_state( int old_state, int new_state )
snd_aav_init();
freespace_stop_mission();
if (Cmdline_benchmark_mode) {
gameseq_post_event( GS_EVENT_QUIT_GAME );
}
}
break;
@@ -5859,10 +5942,6 @@ void game_leave_state( int old_state, int new_state )
case GS_STATE_FICTION_VIEWER:
fiction_viewer_close();
common_select_close();
if (new_state == GS_STATE_MAIN_MENU) {
freespace_stop_mission();
}
break;
case GS_STATE_LAB:
@@ -6946,7 +7025,7 @@ int game_main(char *cmdline)
// check if networking should be disabled, this could probably be done later but the sooner the better
// TODO: remove this when multi is fixed to handle more than MAX_SHIP_CLASSES_MULTI
if ( Ship_info.size() > MAX_SHIP_CLASSES_MULTI ) {
if ( Num_ship_classes > MAX_SHIP_CLASSES_MULTI ) {
Networking_disabled = 1;
}
@@ -7334,7 +7413,6 @@ void game_shutdown(void)
// free left over memory from table parsing
player_tips_close();
control_config_common_close();
joy_close();
audiostream_close();
@@ -7427,15 +7505,17 @@ void init_animating_pointer()
//
// input: filename => filename of animation file that holds the animation
//
void load_animating_pointer(char *filename)
void load_animating_pointer(char *filename, int dx, int dy)
{
int fps;
animating_obj *am;
init_animating_pointer();
//TEMP
mprintf(("loading animated cursor \"%s\"\n", filename));
am = &Animating_mouse;
am->first_frame = bm_load_animation(filename, &am->num_frames, &fps);
if ( am->first_frame == -1 )
@@ -7674,13 +7754,13 @@ void game_show_event_debug(float frametime)
gr_clear();
gr_set_color_fast(&Color_bright);
gr_set_font(FONT1);
gr_printf_no_resize(0x8000, gr_screen.center_offset_y + 15, NOX("EVENT DEBUG VIEW"));
gr_printf_no_resize(0x8000, 15, NOX("EVENT DEBUG VIEW"));
gr_set_color_fast(&Color_normal);
gr_set_font(FONT1);
gr_get_string_size(&font_width, &font_height, NOX("test"));
y_max = gr_screen.center_offset_y + gr_screen.center_h - font_height - 5;
y_index = gr_screen.center_offset_y + 45;
y_max = gr_screen.max_h - font_height - 5;
y_index = 45;
k = scroll_offset;
while (k < ED_count) {
@@ -7730,7 +7810,7 @@ void game_show_event_debug(float frametime)
}
}
gr_printf_no_resize(gr_screen.center_offset_x + 10, y_index, buf);
gr_printf_no_resize(10, y_index, buf);
y_index += font_height;
k++;
}
@@ -7839,11 +7919,8 @@ void Time_model( int modelnum )
g3_set_view_matrix( &eye_pos, &eye_orient, VIEWER_ZOOM_DEFAULT );
model_clear_instance( modelnum );
model_render_params render_info;
render_info.set_detail_level_lock(0);
model_set_detail_level(0); // use highest detail level
model_render_immediate( &render_info, modelnum, &model_orient, &model_pos ); //|MR_NO_POLYS );
model_render( modelnum, &model_orient, &model_pos, MR_LOCK_DETAIL); //|MR_NO_POLYS );
g3_end_frame();
// gr_flip();
@@ -7891,7 +7968,9 @@ void Do_model_timings_test()
}
// Load them all
for (auto sip = Ship_info.begin(); sip != Ship_info.end(); ++sip ) {
for (i=0; i<Num_ship_classes; i++ ) {
ship_info *sip = &Ship_info[i];
sip->model_num = model_load(sip->pof_file, 0, NULL);
model_used[sip->model_num % MAX_POLYGON_MODELS]++;
@@ -8457,8 +8536,8 @@ int detect_lang()
detect = NULL;
// now compare the checksum/filesize against known #'s
for (idx=0; idx < NUM_BUILTIN_LANGUAGES; idx++) {
if (Lcl_builtin_languages[idx].checksum == (int)file_checksum) {
for (idx=0; idx < (int)Lcl_languages.size(); idx++) {
if (Lcl_languages[idx].checksum == (int)file_checksum) {
mprintf(( "AutoLang: Language auto-detection successful...\n" ));
return idx;
}
@@ -8688,6 +8767,8 @@ void game_title_screen_display()
}
*/
//Script_system.SetHookVar("SplashScreenImage", 's', Game_title_screen_fname[gr_screen.res]);
//Script_system.SetHookVar("SplashScreenLogo", 's', Game_logo_screen_fname[gr_screen.res]);
bool globalhook_override = Script_system.IsOverride(Script_splashhook);
bool condhook_override = Script_system.IsConditionOverride(CHA_SPLASHSCREEN);
mprintf(("SCRIPTING: Splash screen overrides checked\n"));
@@ -8732,6 +8813,8 @@ void game_title_screen_display()
Script_system.RunCondition(CHA_SPLASHSCREEN);
mprintf(("SCRIPTING: Splash screen conditional hook has been run\n"));
Script_system.RemHookVars(2, "SplashScreenImage", "SplashScreenLogo");
// flip
gr_flip();
+1 -1
View File
@@ -219,7 +219,7 @@ void game_unpause();
//WMC - Stuff for scripting, these make the game go
extern camid Main_camera;
extern void game_level_init();
extern void game_level_init(int seed = -1);
extern void game_post_level_init();
extern camid game_render_frame_setup();
extern void game_render_frame(camid cid);
+5 -5
View File
@@ -336,8 +336,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,7,5,000000
PRODUCTVERSION 3,7,5,000000
FILEVERSION 3,7,2,11329
PRODUCTVERSION 3,7,2,11329
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -354,12 +354,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Volition Inc."
VALUE "FileDescription", "FreeSpace 2 Open"
VALUE "FileVersion", "3.7.5.000000"
VALUE "FileVersion", "3.7.2.11329"
VALUE "InternalName", "FreeSpace 2 Open"
VALUE "LegalCopyright", "Copyright © 1998"
VALUE "OriginalFilename", "fs2.exe"
VALUE "ProductName", "FreeSpace 2 Open"
VALUE "ProductVersion", "3.7.5"
VALUE "ProductVersion", "3.7.2"
END
END
BLOCK "VarFileInfo"
@@ -448,5 +448,5 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
//
#ifdef FS2_VOICER
IDR_CMD_CFG SRGRAMMAR DISCARDABLE "phrases.cfg"
IDR_CMD_CFG SRGRAMMAR DISCARDABLE "..\..\code\sound\phrases.cfg"
#endif
+19 -19
View File
@@ -9,30 +9,30 @@
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "cfile/cfilesystem.h"
#include "cmdline/cmdline.h"
#include "globalincs/pstypes.h"
#include "fs2netd/fs2netd_client.h"
#include "fs2netd/tcp_client.h"
#include "cfile/cfile.h"
#include "network/multi_log.h"
#include "osapi/osregistry.h"
#include "popup/popup.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/alphacolors.h"
#include "globalincs/pstypes.h"
#include "network/multi.h"
#include "playerman/player.h"
#include "io/timer.h"
#include "network/multiutil.h"
#include "network/multiui.h"
#include "network/stand_gui.h"
#include "network/multi_pxo.h"
#include "bmpman/bmpman.h"
#include "graphics/2d.h"
#include "graphics/font.h"
#include "io/timer.h"
#include "mod_table/mod_table.h"
#include "network/multi.h"
#include "network/multi_log.h"
#include "globalincs/alphacolors.h"
#include "network/multi_options.h"
#include "network/multi_pxo.h"
#include "cmdline/cmdline.h"
#include "cfile/cfilesystem.h"
#include "network/multimsgs.h"
#include "network/multiui.h"
#include "network/multiutil.h"
#include "network/stand_gui.h"
#include "osapi/osregistry.h"
#include "playerman/player.h"
#include "popup/popup.h"
#include "mod_table/mod_table.h"
#ifndef WIN32
#include <cstdio>
@@ -737,7 +737,7 @@ static void fs2netd_handle_messages()
case PCKT_SLIST_REPLY: {
int numServers = 0;
int svr_flags __UNUSED; // gcc [-Wunused-but-set-variable] doesn't like MACROs
int svr_flags __attribute__((__unused__)); // gcc [-Wunused-but-set-variable] doesn't like MACROs
ushort svr_port;
char svr_ip[16];
active_game ag;
@@ -1207,7 +1207,7 @@ void fs2netd_update_ban_list()
if (banlist_cfg != NULL) {
for (SCP_vector<SCP_string>::iterator bl = FS2NetD_ban_list.begin(); bl != FS2NetD_ban_list.end(); ++bl) {
cfputs( bl->c_str(), banlist_cfg );
cfputs( const_cast<char*>(bl->c_str()), banlist_cfg );
}
cfclose(banlist_cfg);
Loaded 100 of 545 files, more files were not shown because too many files have changed in this diff. Show more