Compare commits

..
4 Commits
528 changed files with 63845 additions and 43656 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
-54
View File
@@ -1,54 +0,0 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
/**
* @file bm_examples.cpp
* This file contains example code for using bmpman.
*/
#include "bmpman/bmpman.h"
#include "graphics/2d.h"
void bm_create_example() {
static int test_inited = 0;
static int test_bmp;
static uint test_bmp_data[128 * 64];
if (!test_inited) {
test_inited = 1;
// Create the new bitmap and fill in its data.
// When you're done with it completely, call
// bm_release to free up the bitmap handle
test_bmp = bm_create(32, 128, 64, test_bmp_data);
int i, j;
for (i = 0; i < 64; i++) {
for (j = 0; j < 64; j++) {
uint r = i * 4;
test_bmp_data[j + i * 128] = r;
}
}
}
// page out the data, so that the next bm_lock will convert the new data to
// the correct bpp
bm_unload(test_bmp);
// put in new data
int x, y;
gr_reset_clip();
for (y = 0; y < 64; y++) {
for (x = 0; x < 128; x++) {
test_bmp_data[y * 128 + x] = 15;
}
}
// Draw the bitmap, the upper left corner is the origin (0, 0)
gr_set_bitmap(test_bmp);
gr_bitmap(0, 0);
}
+84 -52
View File
@@ -1,91 +1,121 @@
#ifndef __BM_INTERNAL_H__
#define __BM_INTERNAL_H__
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
* Copyright (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.
*
*/
/**
* @file bm_internal.h
* These are functions and types used by bmpman and a few others.
*
* @details It is a "protected" header that requires BMPMAN_INTERNAL to be defined before it can be included. This is to
* provide a small measure of safety since this functions can cause problems if not used correctly
*/
#ifndef BMPMAN_INTERNAL
#error The file header "bmpman/bm_internal.h" is protected. Make sure you know what you are doing!
#endif
#ifndef __BM_INTERNAL_H__
#define __BM_INTERNAL_H__
// extra check to make sure this stuff doesn't end up in normal files
// don't use any of this unless BMPMAN_INTERNAL is defined
#ifdef BMPMAN_INTERNAL
#include "globalincs/pstypes.h"
#include "bmpman/bmpman.h"
union bm_extra_info {
// no-type ( used in: bm_bitmaps[i].type )
#define BM_TYPE_NONE 0
// in-memory type ( used in: bm_bitmaps[i].type )
#define BM_TYPE_USER 1
// file-type types ( used in: bm_bitmaps[i].type )
#define BM_TYPE_PCX 2
#define BM_TYPE_TGA 3 // 16 or 32 bit targa
#define BM_TYPE_DDS 4 // generic identifier for DDS
#define BM_TYPE_PNG 5 // PNG
#define BM_TYPE_JPG 6 // 32 bit jpeg
#define BM_TYPE_ANI 7 // in-house ANI format
#define BM_TYPE_EFF 8 // specifies any type of animated image, the EFF itself is just text
// c-type types ( used in: bm_bitmaps[i].c_type )
#define BM_TYPE_DXT1 9 // 24 bit with switchable alpha (compressed)
#define BM_TYPE_DXT3 10 // 32 bit with 4 bit alpha (compressed)
#define BM_TYPE_DXT5 11 // 32 bit with 8 bit alpha (compressed)
#define BM_TYPE_CUBEMAP_DDS 12 // generic DDS cubemap (uncompressed cubemap surface)
#define BM_TYPE_CUBEMAP_DXT1 13 // 24-bit cubemap (compressed cubemap surface)
#define BM_TYPE_CUBEMAP_DXT3 14 // 32-bit cubemap (compressed cubemap surface)
#define BM_TYPE_CUBEMAP_DXT5 15 // 32-bit cubemap (compressed cubemap surface)
// special types ( used in: bm_bitmaps[i].type )
#define BM_TYPE_RENDER_TARGET_STATIC 16 // 24/32 bit setup internally as a static render target
#define BM_TYPE_RENDER_TARGET_DYNAMIC 17 // 24/32 bit setup internally as a dynamic render target
/// Moved from cpp file ///////////////////
// Consider these 'protected' structures and functions that should only be used by special bitmap functions
typedef union bm_extra_info {
struct {
// Stuff needed for animations
int first_frame; //!< used for animations -- points to index of first frame
int num_frames; //!< used for animations -- number of frames in the animation
int keyframe; //!< used for animations -- keyframe info
ubyte fps; //!< used for animations -- frames per second
int first_frame; // used for animations -- points to index of first frame
int num_frames; // used for animation -- number of frames in the animation
int keyframe; // used for animation -- keyframe info
ubyte fps; // used for animation -- frames per second
struct {
// stuff for static animations
BM_TYPE type; //!< type for individual images
char filename[MAX_FILENAME_LEN]; //!< filename for individual images
ubyte type; // type for individual images
char filename[MAX_FILENAME_LEN]; // filename for individual images
} eff;
} ani;
struct {
// Stuff needed for user bitmaps
void* data; //!< For user bitmaps, this is where the data comes from
ubyte bpp; //!< For user bitmaps, this is what format the data is
ubyte flags; //!< For user bitmaps, Flags passed to bm_create
void *data; // For user bitmaps, this is where the data comes from
ubyte bpp; // For user bitmaps, this is what format the data is
ubyte flags; // Flags passed to bm_create
} user;
};
} bm_extra_info;
struct bitmap_entry {
typedef struct bitmap_entry {
// identification
char filename[MAX_FILENAME_LEN]; //!< filename for this bitmap
char filename[MAX_FILENAME_LEN]; // filename for this bitmap
uint signature; //!< a unique signature identifying the data
uint palette_checksum; //!< checksum used to be sure bitmap is in current palette
int handle; //!< Handle = id*MAX_BITMAPS + bitmapnum
int last_used; //!< When this bitmap was last used
uint signature; // a unique signature identifying the data
uint palette_checksum; // checksum used to be sure bitmap is in current palette
int handle; // Handle = id*MAX_BITMAPS + bitmapnum
int last_used; // When this bitmap was last used
BM_TYPE type; //!< PCX, USER, ANI, etc
BM_TYPE 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.
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)
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 num_mipmaps; //!< number of mipmap levels, we need to read all of them
int mem_taken; // How much memory does this bitmap use? - UnknownPlayer
int num_mipmaps; // number of mipmap levels, we need to read all of them
// Stuff to keep track of usage
ubyte preloaded; //!< If set, then this was loaded from the lst file
int preload_count; //!< how many times this gets used in game, for unlocking
ubyte used_flags; //!< What flags it was accessed thru
int load_count;
ubyte preloaded; // If set, then this was loaded from the lst file
int preload_count; // how many times this gets used in game, for unlocking
ubyte used_flags; // What flags it was accessed thru
int load_count;
bitmap bm; //!< Bitmap info
// Bitmap info
bitmap bm;
bm_extra_info info; //!< Data for animations and user bitmaps
// Data for animations and user bitmaps
bm_extra_info info;
#ifdef BMPMAN_NDEBUG
// bookeeping
ubyte used_last_frame; // If set, then it was used last frame
ubyte used_this_frame; // If set, then it was used this frame
int data_size; // How much data this bitmap uses
int used_count; // How many times it was accessed
ubyte used_last_frame; // If set, then it was used last frame
ubyte used_this_frame; // If set, then it was used this frame
int data_size; // How much data this bitmap uses
int used_count; // How many times it was accessed
#endif
};
} bitmap_entry;
extern bitmap_entry bm_bitmaps[MAX_BITMAPS];
// image specific lock functions
void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
@@ -96,4 +126,6 @@ void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
#endif // BMPMAN_INTERNAL
#endif // __BM_INTERNAL_H__
+2573 -2722
View File
File diff suppressed because it is too large. Load diff
+204 -590
View File
@@ -1,674 +1,288 @@
#ifndef _BMPMAN_H
#define _BMPMAN_H
/*
* 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
* 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.
*
*/
*/
/**
* @file bmpman.h
* Header file for the bitmap manager (bmpman)
*/
/**
* @example bm_examples.cpp
* @brief This containes examples of bmpman usage
*/
#include "cfile/cfile.h"
#ifndef _BMPMAN_H
#define _BMPMAN_H
#include "globalincs/pstypes.h"
#include "cfile/cfile.h"
#ifndef NDEBUG
#define BMPMAN_NDEBUG //!< Enables BMPMAN debugging code
#define BMPMAN_NDEBUG
#endif
/**
* @defgroup BMPMAN_CONSTANTS Macro constants used in/with bmpman.h
*
* @{
*/
#define MAX_BITMAPS 4750 // How many bitmaps the game can handle
// NOTE: MAX_BITMAPS shouldn't need to be bumped again. With the fixed bm_release() and it's
// proper use even the largest missions should stay under this number. With the largest retail
// missions and wasteful content we should still have about 20% of the slots free. If it still
// goes over then it's something the artists need to fix. For instance the Terran Mara fighter,
// with -spec and -glow and using the Shinepack, needs 117 bitmap slots alone. 111 of those is
// just for the glowmaps. This number can be greatly reduced if the number of ani frames for
// another LOD than LOD0 has fewer or no ani frames. A 37 frame glow ani for LOD2 is little
// more than a waste of resources. Future reports of texture corruption should be initially
// approached with content as the cause and not code. If anything we could/should reduce
// MAX_BITMAPS in the future. Where it's at now should accomidate even the largest mods.
// -- Taylor
/**
* @brief How many bitmaps the game can handle
*
* @attention MAX_BITMAPS shouldn't need to be bumped again. With the fixed bm_release() and it's proper use even the
* largest missions should stay under this number. With the largest retail missions and wasteful content we should
* still have about 20% of the slots free. If it still goes over then it's something the artists need to fix.
* For instance the Terran Mara fighter, with -spec and -glow and using the Shinepack, needs 117 bitmap slots alone.
* 111 of those is just for the glowmaps. This number can be greatly reduced if the number of ani frames for another
* LOD than LOD0 has fewer or no ani frames. A 37 frame glow ani for LOD2 is little more than a waste of resources.
* Future reports of texture corruption should be initially approached with content as the cause and not code.
* If anything we could/should reduce MAX_BITMAPS in the future. Where it's at now should accomidate even the
* largest mods. -- Taylor
*/
#define MAX_BITMAPS 4750
// Flag positions for bitmap.flags
#define BMP_AABITMAP (1<<0) // antialiased bitmap
#define BMP_TEX_XPARENT (1<<1) // transparent texture
#define BMP_TEX_OTHER (1<<2) // so we can identify all "normal" textures
#define BMP_TEX_DXT1 (1<<3) // dxt1 compressed 8r8g8b1a (24bit)
#define BMP_TEX_DXT3 (1<<4) // dxt3 compressed 8r8g8b4a (32bit)
#define BMP_TEX_DXT5 (1<<5) // dxt5 compressed 8r8g8b8a (32bit)
#define BMP_TEX_CUBEMAP (1<<6) // a texture made for cubic environment map
// ***** NOTE: bitmap.flags is an 8-bit value, no more BMP_TEX_* flags can be added unless the type is changed!! ******
#define BMP_AABITMAP (1<<0) //!< antialiased bitmap
#define BMP_TEX_XPARENT (1<<1) //!< transparent texture
#define BMP_TEX_OTHER (1<<2) //!< so we can identify all "normal" textures
#define BMP_TEX_DXT1 (1<<3) //!< dxt1 compressed 8r8g8b1a (24bit)
#define BMP_TEX_DXT3 (1<<4) //!< dxt3 compressed 8r8g8b4a (32bit)
#define BMP_TEX_DXT5 (1<<5) //!< dxt5 compressed 8r8g8b8a (32bit)
#define BMP_TEX_CUBEMAP (1<<6) //!< a texture made for cubic environment map
// Combined flags
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 ) //!< Compressed textures
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER ) //!< Non-compressed textures
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP ) //!< Any texture
//compressed texture types
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 )
// Flag positions for bitmap.type
#define BMP_FLAG_RENDER_TARGET_STATIC (1<<0) //!< Texture is a static type
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1) //!< Texture is a dynamic type (animation)
#define BMP_FLAG_CUBEMAP (1<<2) //!< Texture is a cubemap
//non compressed textures
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER )
// 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
// any texture type
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP )
// 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
#define BMP_FLAG_RENDER_TARGET_STATIC (1<<0)
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1)
#define BMP_FLAG_CUBEMAP (1<<2)
// 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)
};
typedef struct bitmap {
short w, h; // Width and height
short rowsize; // What you need to add to go to next row
ubyte bpp; // How many bits per pixel it is. (7,8,15,16,24,32) (what is requested)
ubyte true_bpp; // How many bits per pixel the image actually is.
ubyte flags; // See the BMP_???? defines for values (this isn't for the BMP_FLAG_* stuff)
ptr_u data; // Pointer to data, or maybe offset into VRAM.
ubyte *palette; // If bpp==8, this is pointer to palette. If the BMP_NO_PALETTE_MAP flag
// is not set, this palette just points to the screen palette. (gr_palette)
} bitmap;
/**
* @}
*/
struct bitmap
{
short w; //!< Width, in number of pixels
short h; //!< Height, in number of pixels
short rowsize; //!< What you need to add to go to next row
ubyte bpp; //!< Requested bitdepth of each pixel. ( 7, 8, 15, 16, 24, 32)
ubyte true_bpp; //!< The image's actual bitdepth
ubyte flags; //!< Various texture type flags. @see BMPMAN_CONSTANTS
ptr_u data; //!< Pointer to data, or maybe offset into VRAM.
ubyte *palette; /**< @brief Pointer to this bitmap's palette (if it has one).
* @details If BMP_NO_PALETTE_MAP flag is cleared, this palette just points to the screen palette. (gr_palette)
*/
};
extern int Bm_paging;
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
extern int NORMMAP; //!< Normal mapping
extern int HEIGHTMAP; //!< Height map for normal mapping
extern int MISCMAP; //!< Utility map, to be utilized for various things shader authors can come up with
/**
* @brief Initilizes the bitmap manager
*/
void bm_init();
/**
* @brief Closes the bitmap manager, freeing any allocated memory used by bitmaps. Is called at program close.
*/
void bm_close();
/**
* Gets the cache slot of the bitmap indexed by handle.
*
* @details if the bitmap is an ani, gets the first frame
*
* @returns The cache slot index of the bitmap if handle is valid
*
* @note If the handle is invalid, an Assert() fails
*/
int bm_get_cache_slot(int bitmap_id, int separate_ani_frames);
int bm_get_cache_slot( int bitmap_id, int separate_ani_frames );
/**
* @brief Gets the next available bitmap slot.
*/
int bm_get_next_handle();
/**
* @brief Allocates memory for the given handle.
*
* @returns A pointer to the allocated vm if successful,
* @returns Null, if unsuccessful
*
* @note z64 - This function looks fishy. Not only is handle not used in release builds, but bm_bitmaps[handle].size
* and bm_texture_size aren't modified unless this is a debug build
*/
void *bm_malloc(int handle, int size);
void *bm_malloc(int n, int size);
/**
* @brief (DEBUG) Similar to bm_malloc, but only updates how much memory is used
*
* @note z64 - Also fishy (see bm_malloc)
*/
void bm_update_memory_used(int n, int size);
class bitmap_lookup {
ubyte *Bitmap_data;
// how many bytes of textures are used.
extern int bm_texture_ram;
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.
*
* @param filename
*
* @returns The bitmap number if successful, else
* @returns a negative value if not
*/
// This loads a bitmap so we can draw with it later.
// It returns a negative number if it couldn't load
// the bitmap. On success, it returns the bitmap
// number.
int bm_load(const char* filename);
/**
* @brief Loads a bitmap so we can draw with it later. (Preferred version)
*
* @param filename
*
* @returns The bitmap number if successful, else
* @returns a negative value if not
*/
int bm_load(const SCP_string& filename);
/**
* @brief Reloads a bitmap as a duplicate.
*
* @details This function basically allows you to load a bitmap which already exists (by filename). This is useful
* because in some cases we need to have a bitmap which is locked in screen format _and_ texture format, such as
* the pilot pics and squad logos
*
* @param filename
*
* @returns The bitmap number if successful, else
* @returns a negative value if not
*/
// special load function. basically allows you to load a bitmap which already exists (by filename).
// this is useful because in some cases we need to have a bitmap which is locked in screen format
// _and_ texture format, such as pilot pics and squad logos
int bm_load_duplicate(const char *filename);
/**
* Loads a bitmap which exists somewhere in the RAM.
*
* @param bpp The bitdepth of the bitmap
* @param w The width of the bitmap
* @param h The height of the bitmap
* @param[in] data The bitmap's data glob
* @param flags
*
* @note The used RAM cannot be freed until bm_release is called on the created bitmap
*/
int bm_create(int bpp, int w, int h, void *data = NULL, int flags = 0);
// Creates a bitmap that exists in RAM somewhere, instead
// of coming from a disk file. You pass in a pointer to a
// block of data. The data can be in the following formats:
// 8 bpp (mapped into game palette)
// 32 bpp
// On success, it returns the bitmap number. You cannot
// free that RAM until bm_release is called on that bitmap.
// See example at bottom of this file
int bm_create( int bpp, int w, int h, void *data = NULL, int flags = 0);
/**
* @brief Unloads a bitmap's data, but not the bitmap info
*
* @details The bm number (n) may be reused once this function has been called on it. However, it will have to be paged
* in the next time it is locked.
// Frees up a bitmap's data, but bitmap number 'n' can
// still be used, it will just have to be paged in next
// time it is locked.
int bm_unload( int n, int clear_render_targets = 0, bool nodebug = false);
* @param handle The index number of the bitmap to free
* @param clear_render_targets If true, release a render target
* @param nodebug If true, exclude certain debug messages
*
* @returns 0 if not successful,
* @returns 1 if successful
*/
int bm_unload(int handle, int clear_render_targets = 0, bool nodebug = false);
// like bm_unload() except that it's safe to use to free data without worrying about
// load_count so it's safe to use in relation to bm_release() and in gr_*_texture functions
int bm_unload_fast( int n, int clear_render_targets = 0 );
/**
* @brief Quickly unloads a bitmap's data, ignoring the load_count
*
* @details Similar to bm_unload(), except that it can be safely used to free data without worrying about load_count.
* It's safe to use in relation to bm_release() and in gr_*_texture functions
*
* @param handle The bm number of the bitmap to free
* @param clear_render_targets If true, release a render target
*
* @note bm_free_data_fast() is used here and NOT bm_free_data()
*/
int bm_unload_fast(int handle, int clear_render_targets = 0);
// Frees up a bitmap's data, and it's slot, so bitmap
// number 'n' cannot be used anymore, and bm_load or
// bm_create might reuse the slot.
int bm_release( int n, int clear_render_targets = 0 );
/**
* @brief Frees both a bitmap's data and it's associated slot.
*
* @details Once called, the bm number 'n' cannot be used until bm_load or bm_create is re-inits the slot.
*
* @param handle The index number of the bitmap to release
* @param clear_render_targets If nonzero, also release render targets
*
* @returns 1 on success,
* @returns 0 otherwise
*
* @note If the passed handle is that of an ANI, it frees EVERY frame. Be sure to only pass the handle of the first frame!
*
* @todo upgrade return type and clear_render_targets type to bools
*/
int bm_release(int handle, int clear_render_targets = 0);
// This loads a bitmap sequence so we can draw with it later.
// It returns a negative number if it couldn't load
// the bitmap. On success, it returns the bitmap
// number of the first frame and nframes is set.
extern int bm_load_animation( const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY );
/**
* @brief Loads a bitmap sequance so we can draw with it.
*
* @param[in] filename
* @param[out] nframes If non-null, set to the number of frames the animation has
* @param[out] fps If non-null, set to the fps of this animation
* @param[out] keyframe if non null, set to the keyframe index of this animation
* @param[in] can_drop_frames If set, allows dropped frames
* @param[in] dir_type Directory type
*
* @returns The bm number of the first bitmap in the sequence if successful, or
* @returns A negative value if unsuccessful
*/
int bm_load_animation(const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
//Loads either animation (bm_load_animation) or still image (bm_load)
extern int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
/**
* @brief Loads either animation (bm_load_animation) or still image (bm_load)
*
* @param[in] filename
* @param[out] nframes If non-null and loading was successful, set to the number of frames the animation has
* @param[out] fps If non-null and loading was successful, set to the fps of this animation
* @param[out] keyframe if non null and loading was successful, set to the keyframe index of this animation
* @param[in] can_drop_frames
* @param[in] dir_type
*
* @returns The bm number of the first bitmap in the sequence if successful, or
* @returns A negative value if unsuccessful
*/
int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
// This locks down a bitmap and returns a pointer to a bitmap
// that can be accessed until you call bm_unlock. Only lock
// a bitmap when you need it! This will convert it into the
// appropriate format also.
extern bitmap * bm_lock( int bitmapnum, ubyte bpp, ubyte flags, bool nodebug = false);
/**
* @brief Locks down the bitmap indexed by bitmapnum.
*
* @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 bpp The desired bpp of the bitmep
* @param flags The desired bitmap format
* @param nodebug
// The signature is a field that gets filled in with
// a unique signature for each bitmap. The signature for each bitmap
// will also change when the bitmap's data changes.
extern uint bm_get_signature( int bitmapnum);
* @returns A pointer to the bitmap that's valid until bm_unlock is called if successful, or
* @returns NULL if unsuccessful
*/
bitmap* bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug = false);
//gets the image type
ubyte bm_get_type(int handle);
/**
* @brief Returns a unique signiature for the bitmap indexed by handle
*
* @details A signature will change when the bitmap's data changes
*/
uint bm_get_signature(int handle);
// Unlocks a bitmap
extern void bm_unlock( int bitmapnum );
/**
* @brief Returns the image type of the given bitmap handle
*/
BM_TYPE bm_get_type(int handle);
//WMC - Returns 0 if invalid, nonzero if valid
extern int bm_is_valid(int handle);
/**
* @brief Unlocks a bitmap
*
* @details Decrements the ref_count member of the bitmap_entry struct, A bitmap can only be unloaded when the
* ref_count is 0
*/
void bm_unlock(int handle);
// Gets info. w,h,or flags,nframes or fps can be NULL if you don't care.
//WMC - Returns -1 on failure, handle or first frame handle on success.
int bm_get_info( int bitmapnum, int *w=NULL, int * h=NULL, ubyte * flags=NULL, int *nframes=NULL, int *fps=NULL );
/**
* @brief Checks if the bitmap indexed by handle is valid
*
* @details Some early known false or out of range handles (such as negative) are checked within
* an initial routine pass, followed by a more thorough check routine to ensure the
* series of bitmaps within the bm_bitmaps[] structure have not become invalid.
*
* @returns Nonzero if valid, else
* @returns Zero otherwise
*
* @todo z64 - Returned value is essentially a bool type, need to check all caller functions to see if it can safely
* be updated to reflect this
*/
int bm_is_valid(int handle);
// get filename
extern void bm_get_filename(int bitmapnum, char *filename);
/**
* @brief Gets info on the bitmap indexed by handle.
*
* @param[out] w If non-null, gets the width
* @param[out] h If non-null, gets the heigth
* @param[out] flags If non-null, gets the flags
* @param[out] nframs If non-null, gets the nframes
* @param[out] fps If non-null, gets the fps
*
* @returns The handle on success, or
* @returns The handle to the first frame on success, or
* @returns -1 on failure
*/
int bm_get_info(int handle, int *w = NULL, int * h = NULL, ubyte * flags = NULL, int *nframes = NULL, int *fps = NULL);
// call to load all data for all bitmaps that have been requested to be loaded
extern void bm_gfx_load_all();
extern void bm_unload_all();
/**
* @brief Gets the filename of the bitmap indexed by handle
*
* @param[out] filename The filename of the bitmap, if successful. Is set to an empty string if unseccessful
*
* @todo z64 - maybe deprecate this in favor of an SCP_string version
*/
void bm_get_filename(int bitmapnum, char *filename);
// call to get the palette for a bitmap
void bm_get_palette(int n, ubyte *pal, char *name);
/**
* @brief Gets the filename of the bitmap indexed by handle, which must exist.
*
* @details If the bitmap does not exist (i.e. the handle is invalid), then an Assertion halts program execution.
*
* @returns A const char* to the filename of the bitmap
*
* @todo z64 - maybe deprecate this in favor of an SCP_string version.
* @todo z64 - maybe combine this with the other bm_get_filename function like so:
* void bm_get_filename(int handle, SCP_string *filename, bool must_exist = false);
*/
const char *bm_get_filename(int handle);
// Hacked function to get a pixel from a bitmap.
// Only works good in 8bpp mode.
void bm_gfx_get_pixel( int bitmap, float u, float v, ubyte *r, ubyte *g, ubyte *b );
/**
* @brief Loads all data for all bitmaps that have been requested to be loaded
*
* @note This function is not defined.
*/
void bm_gfx_load_all();
/**
* @brief Unloads all used bitmaps, should only ever be called by game_shutdown()
*
* @todo Maybe move this declaration into bmpman.cpp and then extern this function within game_shutdown() to
* ensure it only ever gets called there.
*/
void bm_unload_all();
/**
* @brief Gets the palette for a given bitmap indexed by handle, and optionally the filename
*
* @param[out] pal Is set to reference the bitmap's palette
* @param[out] name (optional) Is set to the bitmap's filename
*
* @todo Maybe get rid of the optional filename and have the callers call bm_get_filename. Less efficient, however.
*/
void bm_get_palette(int handle, ubyte *pal, char *name);
/**
* @brief Hack to get a pixel from a bitmap
*
* @details only works good in 8bpp mode
*
* @note This function is not defined.
*/
void bm_gfx_get_pixel(int bitmap, float u, float v, ubyte *r, ubyte *g, ubyte *b);
/**
* @brief (DEBUG) Gets memory size, in bytes, of the locked bitmaps
*
* @details Both params are non-optional, and must be non-null. There's currently no safety checks on either.
*
* @param ntotal[out] Memory size, in bytes, of the locked bitmaps
* @param nnew[out] Memory size, in bytes, of the bitmaps that were locked since the last frame
*
* @note This is a debug function, and is undefined within release builds
*/
// Returns number of bytes of bitmaps locked this frame
// ntotal = number of bytes of bitmaps locked this frame
// nnew = number of bytes of bitmaps locked this frame that weren't locked last frame
void bm_get_frame_usage(int *ntotal, int *nnew);
/**
* @brief Reloads an existing bmpman slot with different bitmap
*
* @param[in] filename The filename of the image to load
*
* @returns The bitmap handle on success, or
* @returns A negative value on failure
*
* @note This should only be used if you are certain the new picture is the same type, has same dimensions, etc.
*/
// Reload a different image into an existing bmpman slot
int bm_reload(int bitmap_handle, const char* filename);
/**
* @brief Tells bmpman to start keeping track of what bitmaps are used where
*/
void bm_page_in_start();
/*
* Example on using bm_create
*
{
static int test_inited = 0;
static int test_bmp;
static uint test_bmp_data[128*64];
/**
* @brief Tells bmpman to stop paging (?)
*/
if ( !test_inited ) {
test_inited = 1;
// Create the new bitmap and fill in its data.
// When you're done with it completely, call
// bm_release to free up the bitmap handle
test_bmp = bm_create( 32, 128, 64, test_bmp_data );
int i,j;
for (i=0; i<64; i++ ) {
for (j=0; j<64; j++ ) {
uint r=i*4;
test_bmp_data[j+i*128] = r;
}
}
}
bm_unload(test_bmp); // this pages out the data, so that the
// next bm_lock will convert the new data to the
// correct bpp
// put in new data
int x,y;
gr_reset_clip();
for (y=0; y<64; y++)
for (x=0; x<128; x++ )
test_bmp_data[y*128+x] = 15;
// Draw the bitmap to upper left corner
gr_set_bitmap(test_bmp);
gr_bitmap( 0,0 );
}
*/
//============================================================================
// Paging stuff
//============================================================================
void bm_page_in_start();
void bm_page_in_stop();
// Paging code in a library should call these functions
// in its page in function.
/**
* @brief Marks a texture as being used for this level
*
* @param[in] num_frames If specified, assumes this is an animated texture
*/
void bm_page_in_texture(int bitmapnum, int num_frames = 0);
// Marks a texture as being used for this level
// If num_frames is passed, assume this is an animation
void bm_page_in_texture( int bitmapnum, int num_frames = 0 );
/**
* @brief Marks a textures as being used for level and is transparant
*
* @param[in] num_frames If specified, assumes this is an animated texture
*/
void bm_page_in_xparent_texture(int bitmapnum, int num_frames = 1);
// marks a texture as being a transparent textyre used for this level
// Marks a texture as being used for this level
// If num_frames is passed, assume this is an animation
void bm_page_in_xparent_texture( int bitmapnum, int num_frames=1 );
/**
* @brief Marks a texture as being used for this level, and is anti-aliased
*
* @param[in] num_frames If specified, assumes this is an animated texture
*/
void bm_page_in_aabitmap(int bitmapnum, int num_frames = 1);
// Marks an aabitmap as being used for this level
// If num_frames is passed, assume this is an animation
void bm_page_in_aabitmap( int bitmapnum, int num_frames=1 );
/**
* @brief Unloads the bitmap indexed by handle that was previously paged-in
*
* @returns 0 If the bitmap had already been released, or
* @returns 0 If the handle is invalid, or
* @returns 1 If successful
*/
bool bm_page_out(int handle);
// unload a texture that was paged in
int bm_page_out( int handle );
/**
* @brief Sets BMPMAN's memory mode
*
* @details 0 = High memory;
* 1 = Low memory (loads every other frame of ani's);
* 2 = Debug low memory (only use first frame of each ani)
*
* @todo This should use an enum, or instead allow an arbitrary number to drop frames (like 1/2, 1/3, etc.)
*/
void bm_set_low_mem(int mode);
//
// Mode: 0 = High memory
// 1 = Low memory ( every other frame of ani's)
// 2 = Debug low memory ( only use first frame of each ani )
void bm_set_low_mem( int mode );
const char *bm_get_filename(int handle);
/**
* @brief Sets bm_set_components and bm_get_components to reference screen format functions
*/
void BM_SELECT_SCREEN_FORMAT();
/**
* @brief Sets bm_set_components and bm_get_components to reference texture format functions
*/
void BM_SELECT_TEX_FORMAT();
/**
* @brief Sets bm_set_components and bm_get_components to reference texture format functions (with alpha)
*/
void BM_SELECT_ALPHA_TEX_FORMAT();
/**
* @brief Functional pointer that references any of the bm_set_components functions.
*
* @details The bm_set_components functions packs the RGBA values into the ubyte array referenced by pixel, whose
* format differs according to its bpp value and presence of an alpha channel. The RGBA values are scaled accordingly.
*
* @param[out] pixel The pixel to set
* @param[in] r Red value (may not be NULL)
* @param[in] g Green value (may not be NULL)
* @param[in] b Blue value (may not be NULL)
* @param[in] a Alpha value (currently ignored)
*
* @note z64 - These functions were made predating the introduction of C++ classes, and are basically the equivalent
* of Pixel::set(ubyte *r, ubyte *b, ubyte *g). The original comment mentions that any of the rgba params may be
* NULL, but this is by far _NOT_ the case, as a NULL value will cause undefined behavior (really really bad chroma
* corruption)
*
* @note These functions assume the incoming bitdepth will always be >= to the outgoing bitdepth of the pixel. Should
* the incoming bitdepth be lower, the outgoing values will appear darker than they should be
*/
extern void(*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
// set the rgba components of a pixel, any of the parameters can be NULL
extern void (*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
extern void (*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
void bm_set_components_argb_d3d_16_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
void bm_set_components_argb_d3d_32_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
void bm_set_components_argb_d3d_16_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
void bm_set_components_argb_d3d_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Functional pointer that references any of the bm_set_components_32 functions.
*
* @details The bm_set_components functions packs the RGBA values into the ubyte array referenced by pixel, whose
* format differs according to its bpp value and presence of an alpha channel. The RGBA values are scaled accordingly.
*
* @see bm_set_components
*/
extern void(*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Sets the 16bpp screen pixel to the specified RGBA value
*
* @see bm_set_components
*/
void bm_set_components_argb_16_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Sets the 32bpp screen pixel to the specified RGBA value
*
* @see bm_set_components
*/
void bm_set_components_argb_32_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Sets the 16bpp texture pixel to the specified RGBA value
*
* @see bm_set_components
*/
void bm_set_components_argb_16_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Sets the 32bpp texture pixel to the specified RGBA value
*
* @see bm_set_components
*/
void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Gets the RGBA components of a pixel according to the selected mode
*
* @see BM_SELECT_SCREEN_FORMAT() BM_SELECT_TEX_FORMAT() BM_SELECT_ALPHA_TEX_FORMAT()
*/
// get the rgba components of a pixel, any of the parameters can be NULL
void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Returns the compression type of the bitmap indexed by handle
*/
int bm_is_compressed(int handle);
extern int GLOWMAP; //this holds a reference to a map that is a fully lit version of its index -Bobboau
extern int SPECMAP; //this holds a reference to a map that is for specular mapping -Bobboau
extern int ENVMAP; //this holds a reference to a map that is for environment mapping -Bobboau
extern int NORMMAP; // normal mapping
extern int HEIGHTMAP; // height map for normal mapping
extern int MISCMAP; // Utility map, to be utilized for various things shader authors can come up with
/**
* @brief Gets the correct TCACHE_TYPE for compressed graphics (uncompressed are assumed TCACHE_TYPE_NORMAL)
*/
int bm_get_tcache_type(int handle);
int bm_is_compressed(int num);
int bm_get_tcache_type(int num);
int bm_get_size(int num);
int bm_get_num_mipmaps(int num);
int bm_has_alpha_channel(int handle);
/**
* @brief Gets the size, in bytes, taken up by the bitmap indexed by handle
*/
size_t bm_get_size(int handle);
/**
* @brief Gets the number of mipmaps of the indexed texture
*/
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
*/
bool bm_has_alpha_channel(int handle);
/**
* @brief (DEBUG) Prints all loaded bitmaps to an outwindow
*/
void bm_print_bitmaps();
/**
* @brief Creates a render target as close to the desired resolution as possible.
*
* @returns the handle of an avilable render target if successful, or
* @returns -1 if not successful
*
* @note BM_FLAG_RENDER_TARGET_STATIC are drawn once/infrequently, while BM_FLAG_RENDER_TARGET_DYNAMIC are drawn roughly once every frame
*/
int bm_make_render_target(int width, int height, int flags);
/**
* @brief Checks to see if the given bitmap indexed by handle is a render target
*
* @returns The render type (BM_TYPE) if it is a render target, or
* @returns 0 if it is not
*/
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
*/
bool bm_set_render_target(int handle, int face = -1);
/**
* @brief Loads and parses an .EFF
*
* @param[in] filename The filename of the .EFF
* @param[in] dir_type
* @param[out] nframes (optional) If given, is set to the number of frames this .EFF has
* @param[out] nfps (optional) If given, is set to the fps of this .EFF
* @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
*/
bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, BM_TYPE *type);
int bm_make_render_target( int width, int height, int flags );
int bm_is_render_target(int bitmap_id);
int bm_set_render_target(int handle, int face = -1);
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
+96 -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", },
@@ -221,6 +217,7 @@ Flag exe_params[] =
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
{ "-output_sexps", "Output SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
{ "-output_scripting", "Output scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
{ "-output_json_data", "Output table objects to [table].json", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_json_data", },
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-save_render_target", },
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
@@ -231,7 +228,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 +244,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 +306,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 +329,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 +379,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 +403,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 +413,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 +431,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 +455,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 +464,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 +482,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,12 +490,14 @@ 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);
cmdline_parm output_sexp_arg("-output_sexps", NULL, AT_NONE); //WMC - outputs all SEXPs to sexps.html
cmdline_parm output_scripting_arg("-output_scripting", NULL, AT_NONE); //WMC
cmdline_parm output_json_data_arg("-output_json_data", "Output table objects to [table].json", AT_NONE); //chief1983, Cmdline_output_json_data
bool Cmdline_output_json_data = false;
// Deprecated flags - CommanderDJ
cmdline_parm deprecated_spec_arg("-spec", "Deprecated", AT_NONE);
@@ -855,21 +836,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 +874,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 +1020,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 +1154,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 +1251,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 +1294,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 +1460,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 +1478,9 @@ bool SetCmdlineParams()
Cmdline_no_di_mouse = 1;
}
if ( img2dds_arg.found() )
Cmdline_img2dds = 1;
if ( glow_arg.found() )
Cmdline_glow = 0;
@@ -1591,6 +1513,11 @@ bool SetCmdlineParams()
output_sexps("sexps.html");
}
if ( output_json_data_arg.found() )
{
Cmdline_output_json_data = true;
}
if ( no_vbo_arg.found() )
{
Cmdline_novbo = 1;
@@ -1616,22 +1543,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 +1569,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 +1625,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 +1650,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 +1665,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() )
+4 -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,6 @@ 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;
extern bool Cmdline_output_json_data;
#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>
+13 -9
View File
@@ -9,11 +9,15 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////
// @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
// Testing Goals
// Breakpoints are set at places that need testing:
// * the value of endptr strtol and strtoul needs to investigated, according to cplusplus.com, *endptr = end of the string that was successfully converted
// 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
////////////////
#include "debugconsole/consoleparse.h"
#include "debugconsole/console.h"
#include "globalincs/pstypes.h"
#include "parse/parselo.h"
#include <algorithm>
@@ -88,7 +92,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!
*/
@@ -462,7 +466,7 @@ void dc_required_string(char *pstr)
dc_ignore_gray_space();
if (strncmp(pstr, Cp, strlen(pstr)) == 0) {
if (strnicmp(pstr, Cp, strlen(pstr))) {
str_found = pstr;
}
@@ -488,10 +492,10 @@ int dc_required_string_either(char *str1, char *str2)
dc_ignore_gray_space();
if (strncmp(str1, Cp, strlen(str1)) == 0) {
if (strncmp(str1, Cp, strlen(str1) == 0)) {
str_found = str1;
i = 0;
} else if (strncmp(str2, Cp, strlen(str2)) == 0) {
} else if (strncmp(str2, Cp, strlen(str2) == 0)) {
str_found = str2;
i = 1;
}
@@ -559,7 +563,7 @@ bool dc_optional_string(const char *pstr)
{
dc_ignore_gray_space();
if (strncmp(pstr, Cp, strlen(pstr)) != 0) {
if (strncmp(pstr, Cp, strlen(pstr) != 0)) {
return false;
} // Else, optional string was found
@@ -1065,7 +1069,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;
}
+97 -95
View File
@@ -18,11 +18,13 @@
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@@ -114,7 +116,7 @@ IDB_DATA_95 BITMAP "res\\data95.bmp"
// Toolbar
//
IDR_MAINFRAME TOOLBAR 23, 23
IDR_MAINFRAME TOOLBAR 23, 23
BEGIN
BUTTON ID_SELECT
BUTTON ID_SELECT_AND_MOVE
@@ -150,7 +152,7 @@ END
// Menu
//
IDR_MAINMENU MENU
IDR_MAINMENU MENU
BEGIN
POPUP "&File"
BEGIN
@@ -332,7 +334,7 @@ BEGIN
END
END
IDR_MENU_SHIP_POPUP MENU
IDR_MENU_SHIP_POPUP MENU
BEGIN
POPUP "Properties"
BEGIN
@@ -342,7 +344,7 @@ BEGIN
END
END
IDR_MENU_EDIT_POPUP MENU
IDR_MENU_EDIT_POPUP MENU
BEGIN
POPUP "EDIT"
BEGIN
@@ -367,7 +369,7 @@ BEGIN
END
END
IDR_MENU_CAMPAIGN MENU
IDR_MENU_CAMPAIGN MENU
BEGIN
POPUP "&File"
BEGIN
@@ -389,7 +391,7 @@ BEGIN
END
END
IDR_MENU_EDIT_SEXP_TREE MENU
IDR_MENU_EDIT_SEXP_TREE MENU
BEGIN
POPUP "Edit sexp tree"
BEGIN
@@ -439,7 +441,7 @@ BEGIN
END
END
IDR_WING_EDIT_MENU MENU
IDR_WING_EDIT_MENU MENU
BEGIN
POPUP "&Select Wing"
BEGIN
@@ -447,7 +449,7 @@ BEGIN
END
END
IDR_SHIP_EDIT_MENU MENU
IDR_SHIP_EDIT_MENU MENU
BEGIN
POPUP "&Select Ship"
BEGIN
@@ -455,7 +457,7 @@ BEGIN
END
END
IDR_PLAYER_EDIT_MENU MENU
IDR_PLAYER_EDIT_MENU MENU
BEGIN
POPUP "Select Team"
BEGIN
@@ -468,7 +470,7 @@ BEGIN
END
END
IDR_WAYPOINT_PATH_EDIT_MENU MENU
IDR_WAYPOINT_PATH_EDIT_MENU MENU
BEGIN
POPUP "&Select Waypoint Path"
BEGIN
@@ -476,7 +478,7 @@ BEGIN
END
END
IDR_ASTEROID_FIELD_MENU MENU
IDR_ASTEROID_FIELD_MENU MENU
BEGIN
POPUP "Select Field"
BEGIN
@@ -484,7 +486,7 @@ BEGIN
END
END
IDR_CPGN_VIEW_OFF MENU
IDR_CPGN_VIEW_OFF MENU
BEGIN
POPUP "Blah"
BEGIN
@@ -493,7 +495,7 @@ BEGIN
END
END
IDR_CPGN_VIEW_ON MENU
IDR_CPGN_VIEW_ON MENU
BEGIN
POPUP "Blah"
BEGIN
@@ -509,7 +511,7 @@ END
// Accelerator
//
IDR_MAINFRAME ACCELERATORS
IDR_MAINFRAME ACCELERATORS
BEGIN
"1", ID_SPEED1, VIRTKEY, NOINVERT
"1", ID_GROUP1, VIRTKEY, CONTROL, NOINVERT
@@ -600,7 +602,7 @@ BEGIN
"Z", ID_ZOOM_EXTENTS, VIRTKEY, SHIFT, NOINVERT
END
IDR_ACC_CAMPAIGN ACCELERATORS
IDR_ACC_CAMPAIGN ACCELERATORS
BEGIN
"H", ID_ERROR_CHECKER, VIRTKEY, ALT, NOINVERT
"N", ID_CPGN_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
@@ -615,13 +617,13 @@ END
// Dialog
//
IDD_ABOUTBOX DIALOG 0, 0, 284, 89
IDD_ABOUTBOX DIALOG 0, 0, 284, 89
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About FRED2"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,10,17,20,20,SS_REALSIZEIMAGE
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.7.5 OpenGL",IDC_STATIC,39,8,184,10,SS_NOPREFIX
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.7.1 OpenGL",IDC_STATIC,39,8,184,10,SS_NOPREFIX
LTEXT "Copyright © 1999 Volition, Inc. All Rights Reserved",IDC_STATIC,39,17,164,8
DEFPUSHBUTTON "OK",IDOK,229,7,48,14,WS_GROUP
LTEXT """Fred2 is the omega of all giant unwieldy pieces of code. Its big, its horrifying, and it just doesn't care. View it at your own risk."" - Dave Baranec",IDC_STATIC,39,62,238,20
@@ -696,7 +698,7 @@ BEGIN
GROUPBOX "Message Properties",IDC_STATIC,7,184,184,60
END
IDD_SHIP_GOALS_EDITOR DIALOG 0, 0, 412, 221
IDD_SHIP_GOALS_EDITOR DIALOG 0, 0, 412, 221
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Initial Orders"
FONT 8, "MS Sans Serif"
@@ -880,7 +882,7 @@ BEGIN
CONTROL "Mission End to Mainhall",IDC_END_TO_MAINHALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,190,142,10
END
IDD_PREFERENCES DIALOG 0, 0, 333, 81
IDD_PREFERENCES DIALOG 0, 0, 333, 81
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Preferences"
FONT 8, "MS Sans Serif"
@@ -1015,7 +1017,7 @@ BEGIN
LTEXT "Missile bank 4",IDC_STATIC,232,64,46,8
END
IDD_SHIP_MARKINGS DIALOG 0, 0, 252, 140
IDD_SHIP_MARKINGS DIALOG 0, 0, 252, 140
STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION
CAPTION "Ship Markings"
FONT 8, "MS Sans Serif"
@@ -1040,7 +1042,7 @@ BEGIN
EDITTEXT IDC_GOAL_SCORE,293,82,73,14,ES_AUTOHSCROLL | ES_NUMBER
COMBOBOX IDC_OBJ_TEAM,293,98,73,71,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "Objective Invalid",IDC_GOAL_INVALID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,239,117,69,10
CONTROL "Don't Play Completion Music",IDC_NO_MUSIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,239,127,107,10
CONTROL "Don't Play Completion Sound",IDC_NO_MUSIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,239,127,107,10
PUSHBUTTON "New Obj.",IDC_BUTTON_NEW_GOAL,233,146,44,14,0,WS_EX_STATICEDGE,HIDC_BUTTON_NEW_GOAL
PUSHBUTTON "OK",ID_OK,281,146,44,14
PUSHBUTTON "Cancel",IDCANCEL,329,146,44,14
@@ -1148,7 +1150,7 @@ BEGIN
PUSHBUTTON "Restrict Departure Paths",IDC_RESTRICT_DEPARTURE,160,223,121,14,0,WS_EX_STATICEDGE
END
IDD_OPERATOR_ARGUMENT_TYPES DIALOG 0, 0, 235, 50
IDD_OPERATOR_ARGUMENT_TYPES DIALOG 0, 0, 235, 50
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Select Argument Types"
FONT 8, "MS Sans Serif"
@@ -1197,7 +1199,7 @@ BEGIN
LTEXT "Set Amount From Variable",IDC_STATIC,179,234,93,10
END
IDD_ORIENT_EDITOR DIALOG 0, 0, 229, 119
IDD_ORIENT_EDITOR DIALOG 0, 0, 229, 119
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Object Orientation Editor"
FONT 8, "MS Sans Serif"
@@ -1419,7 +1421,7 @@ BEGIN
LTEXT "Delay After Arrival",IDC_STATIC,7,99,57,8
END
IDD_REINFORCEMENT_SELECT DIALOG 0, 0, 156, 132
IDD_REINFORCEMENT_SELECT DIALOG 0, 0, 156, 132
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Select Reinforcement Unit"
FONT 8, "MS Sans Serif"
@@ -1429,7 +1431,7 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,99,111,50,14
END
IDD_WAYPOINT_PATH_EDITOR DIALOG 0, 0, 145, 29
IDD_WAYPOINT_PATH_EDITOR DIALOG 0, 0, 145, 29
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Waypoint Path/Jump Node Editor"
MENU IDR_WAYPOINT_PATH_EDIT_MENU
@@ -1439,7 +1441,7 @@ BEGIN
EDITTEXT IDC_NAME,32,7,106,14,ES_AUTOHSCROLL
END
IDD_WING_CREATE DIALOG 0, 0, 119, 68
IDD_WING_CREATE DIALOG 0, 0, 119, 68
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Create Wing"
FONT 8, "MS Sans Serif"
@@ -1490,7 +1492,7 @@ BEGIN
LTEXT "Team Color Setting:",IDC_STATIC,16,308,66,8
END
IDD_ASTEROID_EDITOR DIALOG 0, 0, 376, 210
IDD_ASTEROID_EDITOR DIALOG 0, 0, 376, 210
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Debris Field Editor"
FONT 8, "MS Sans Serif"
@@ -1588,7 +1590,7 @@ BEGIN
LTEXT "Debriefing persona index",IDC_STATIC,148,176,79,8
END
IDD_TEXT_VIEW DIALOG 0, 0, 324, 285
IDD_TEXT_VIEW DIALOG 0, 0, 324, 285
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ship TBL Data"
FONT 8, "MS Sans Serif"
@@ -1653,7 +1655,7 @@ BEGIN
CONTROL "Use Cargo Icon",IDC_USE_CARGO_ICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,233,394,65,10
END
IDD_IGNORE_ORDERS DIALOG 0, 0, 120, 217
IDD_IGNORE_ORDERS DIALOG 0, 0, 120, 217
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ignore Orders"
FONT 8, "MS Sans Serif"
@@ -1703,7 +1705,7 @@ BEGIN
COMBOBOX IDC_FAILED_MISSION_TRACK,445,294,80,180,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
END
IDD_ADJUST_GRID DIALOG 0, 0, 153, 94
IDD_ADJUST_GRID DIALOG 0, 0, 153, 94
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Adjust Grid"
FONT 8, "MS Sans Serif"
@@ -1725,7 +1727,7 @@ BEGIN
LTEXT "X Level",IDC_STATIC,69,50,25,8
END
IDD_SHIELD_SYS DIALOG 0, 0, 192, 106
IDD_SHIELD_SYS DIALOG 0, 0, 192, 106
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Shield System Editor"
FONT 8, "MS Sans Serif"
@@ -1742,7 +1744,7 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,134,86,50,14
END
IDD_INITIAL_SHIPS DIALOG 0, 0, 127, 210
IDD_INITIAL_SHIPS DIALOG 0, 0, 127, 210
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Initial Ships Allowed"
FONT 8, "MS Sans Serif"
@@ -1832,15 +1834,13 @@ BEGIN
CONTROL "Laser Protect Ship",IDC_LASER_PROTECT_SHIP,"Button",BS_3STATE | WS_TABSTOP,12,110,80,8
CONTROL "Missile Protect Ship",IDC_MISSILE_PROTECT_SHIP,"Button",BS_3STATE | WS_TABSTOP,12,118,80,8
GROUPBOX "Turret Threats",IDC_STATIC,7,83,102,48
CONTROL "Does Not Move",IDC_IMMOBILE,"Button",BS_3STATE | WS_TABSTOP,7,274,66,10
CONTROL "Cloaked",IDC_CLOAKED,"Button",BS_3STATE | WS_TABSTOP,165,167,42,10
CONTROL "Scramble Messages",IDC_SCRAMBLE_MESSAGES,"Button",BS_3STATE | WS_TABSTOP,165,177,79,10
CONTROL "No Collisions",IDC_NO_COLLIDE,"Button",BS_3STATE | WS_TABSTOP,165,188,66,10
CONTROL "No Disabled Self-Destruct",IDC_NO_DISABLED_SELF_DESTRUCT,
"Button",BS_3STATE | WS_TABSTOP,165,199,114,10
END
IDD_ADD_VARIABLE DIALOG 0, 0, 422, 102
CONTROL "Does Not Move",IDC_IMMOBILE,"Button",BS_3STATE | WS_TABSTOP,7,274,66,10
CONTROL "Cloaked",IDC_CLOAKED,"Button",BS_3STATE | WS_TABSTOP,165,167,42,10
CONTROL "Scramble Messages",IDC_SCRAMBLE_MESSAGES,"Button",BS_3STATE | WS_TABSTOP,165,177,79,10
CONTROL "No Collisions",IDC_NO_COLLIDE,"Button",BS_3STATE | WS_TABSTOP,165,188,66,10
END
IDD_ADD_VARIABLE DIALOG 0, 0, 422, 102
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Add Variable"
FONT 8, "MS Sans Serif"
@@ -1860,7 +1860,7 @@ BEGIN
CONTROL "Network-Variable",IDC_TYPE_NETWORK_VARIABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,71,84,11
END
IDD_MODIFY_VARIABLE DIALOG 0, 0, 422, 102
IDD_MODIFY_VARIABLE DIALOG 0, 0, 422, 102
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Modify Variable"
FONT 8, "MS Sans Serif"
@@ -1882,7 +1882,7 @@ BEGIN
CONTROL "Network-Variable",IDC_TYPE_NETWORK_VARIABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,138,72,84,11
END
IDD_SPECIAL_DAMAGE DIALOG 0, 0, 234, 129
IDD_SPECIAL_DAMAGE DIALOG 0, 0, 234, 129
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Special Explosion"
FONT 8, "MS Sans Serif"
@@ -1908,7 +1908,7 @@ BEGIN
LTEXT "Duration (msecs):",IDC_STATIC,30,111,56,8
END
IDD_DUMP_STATS DIALOG 0, 0, 577, 375
IDD_DUMP_STATS DIALOG 0, 0, 577, 375
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Mission Stats"
FONT 8, "MS Sans Serif"
@@ -1918,7 +1918,7 @@ BEGIN
EDITTEXT IDC_STATS_TEXT,7,7,563,333,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | ES_WANTRETURN | ES_NUMBER | WS_VSCROLL
END
IDD_SHIP_TEXTURES DIALOG 0, 0, 296, 56
IDD_SHIP_TEXTURES DIALOG 0, 0, 296, 56
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ship Texture Replace"
FONT 8, "MS Sans Serif"
@@ -1928,10 +1928,10 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,239,35,50,14
LTEXT "Old texture:",IDC_LABEL1,7,7,44,9
LTEXT "New texture:",IDC_LABEL2,152,7,44,9
COMBOBOX IDC_OLD_TEXTURE_LIST,7,16,137,85,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_OLD_TEXTURE_LIST,7,16,137,85,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
END
IDD_SPECIAL_HITPOINTS DIALOG 0, 0, 234, 85
IDD_SPECIAL_HITPOINTS DIALOG 0, 0, 234, 85
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Special Hitpoints"
FONT 8, "MS Sans Serif"
@@ -1948,7 +1948,7 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,106,10
END
IDD_SET_GLOBAL_SHIP_FLAGS DIALOG 0, 0, 114, 79
IDD_SET_GLOBAL_SHIP_FLAGS DIALOG 0, 0, 114, 79
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Set Global Ship Flags"
FONT 8, "MS Sans Serif"
@@ -1959,7 +1959,7 @@ BEGIN
PUSHBUTTON "Global Affected-By-Gravity",IDC_AFFECTED_BY_GRAVITY,7,58,100,14
END
IDD_VOICE_MANAGER DIALOG 0, 0, 407, 218
IDD_VOICE_MANAGER DIALOG 0, 0, 407, 218
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Voice Acting Manager"
FONT 8, "MS Sans Serif"
@@ -2004,7 +2004,7 @@ BEGIN
"Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,166,159,100,19
END
IDD_BRIEFING_PERSONAS DIALOG 0, 0, 320, 201
IDD_BRIEFING_PERSONAS DIALOG 0, 0, 320, 201
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Sans Serif"
@@ -2013,7 +2013,7 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,263,24,50,14
END
IDD_CUSTOM_WING_NAMES DIALOG 0, 0, 390, 54
IDD_CUSTOM_WING_NAMES DIALOG 0, 0, 390, 54
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Custom Wing Names"
FONT 8, "MS Sans Serif"
@@ -2035,7 +2035,7 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,333,24,50,14
END
IDD_RESTRICT_PATHS DIALOG 0, 0, 241, 87
IDD_RESTRICT_PATHS DIALOG 0, 0, 241, 87
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Restrict Paths"
FONT 8, "MS Sans Serif"
@@ -2046,7 +2046,7 @@ BEGIN
LTEXT "Restrict departure paths to the following:",IDC_RESTRICT_PATHS_LABEL,7,7,127,11
END
IDD_BACKGROUND_CHOOSER DIALOG 0, 0, 152, 45
IDD_BACKGROUND_CHOOSER DIALOG 0, 0, 152, 45
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Choose a background"
FONT 8, "MS Sans Serif"
@@ -2103,8 +2103,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,7,1,0
PRODUCTVERSION 3,7,1,0
FILEVERSION 3,7,1,000000
PRODUCTVERSION 3,7,1,000000
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -2121,12 +2121,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Volition Inc."
VALUE "FileDescription", "Fred 2 Open"
VALUE "FileVersion", "3.7.5.000000"
VALUE "FileVersion", "3.7.1.000000"
VALUE "InternalName", "Fred 2 Open"
VALUE "LegalCopyright", "Copyright © 1998"
VALUE "OriginalFilename", "fred2.exe"
VALUE "ProductName", "Fred 2 Open"
VALUE "ProductVersion", "3.7.5"
VALUE "ProductVersion", "3.7.1"
END
END
BLOCK "VarFileInfo"
@@ -2142,7 +2142,7 @@ END
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
@@ -2696,19 +2696,19 @@ IDC_CURSOR2 CURSOR "res\\cursor2.cur"
// String Table
//
STRINGTABLE
STRINGTABLE
BEGIN
IDR_MAINFRAME "FRED2_OPEN 3.7.5 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
IDR_MAINFRAME "FRED2_OPEN 3.7.1 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
END
STRINGTABLE
STRINGTABLE
BEGIN
AFX_IDS_APP_TITLE "FRED2"
AFX_IDS_IDLEMESSAGE "For Help, press F1"
AFX_IDS_HELPMODEMESSAGE "Select an object on which to get Help"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_FILE_NEW "Create a new campaign\nNew"
ID_FILE_OPEN "Open an existing campaign\nOpen"
@@ -2721,7 +2721,7 @@ BEGIN
ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
ID_APP_EXIT "Exit the campaign editor\nExit"
@@ -2732,7 +2732,7 @@ BEGIN
ID_HELP "Display help for current task or command\nHelp"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_FILE_MRU_FILE1 "Open this document"
ID_FILE_MRU_FILE2 "Open this document"
@@ -2752,18 +2752,18 @@ BEGIN
ID_FILE_MRU_FILE16 "Open this document"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_EDIT_CLEAR "Erase the selection\nErase"
ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
@@ -2778,13 +2778,13 @@ BEGIN
ID_EDIT_REDO "Redo the previously undone action\nRedo"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
END
STRINGTABLE
STRINGTABLE
BEGIN
AFX_IDS_SCSIZE "Change the window size"
AFX_IDS_SCMOVE "Change the window position"
@@ -2795,24 +2795,24 @@ BEGIN
AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
END
STRINGTABLE
STRINGTABLE
BEGIN
AFX_IDS_SCRESTORE "Restore the window to normal size"
AFX_IDS_SCTASKLIST "Activate Task List"
END
STRINGTABLE
STRINGTABLE
BEGIN
AFX_IDS_PREVIEW_CLOSE "Close print preview mode\nCancel Preview"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_FILE_MISSIONNOTES "Displays designer notes and mission properties\nMission Specs"
ID_SELECT "Select objects mode\nSelect (S)"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_VIEW_FIGHTERS "Show/Hide Fighter objects"
ID_VIEW_CAPITALSHIPS "Show/Hide Capital Ship objects"
@@ -2830,7 +2830,7 @@ BEGIN
ID_EDITORS_SHIPS "Open ship editor dialog window to edit ship"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_EDITORS_GOALS "Activates Mission Goal Editor\nMission Goal Editor"
ID_EDITORS_WAYPOINTS "Activates Waypoint Editor\nWaypoint Editor"
@@ -2841,7 +2841,7 @@ BEGIN
ID_PROPERTIES_ONE "This is Mike's prompt!"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_INDICATOR_EXT "EXT"
ID_INDICATOR_CAPS "CAP"
@@ -2855,7 +2855,7 @@ BEGIN
ID_INDICATOR_MODIFIED "MODIFIED"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_MISCSTUFF_SHOWSHIPSASICONS "This is the (help?) prompt!"
ID_EDIT_POPUP_SHOW_SHIP_MODELS
@@ -2864,7 +2864,7 @@ BEGIN
"Display ship names and ship types for visible ships"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_ADD_MISSION_TIME "Evaluates to elapsed time into mission in seconds"
ID_ADD_EQUALS "Evaluates to true if numbers or objects are the same"
@@ -2879,7 +2879,7 @@ BEGIN
ID_ADD_FALSE "Evaluates to a boolean value of false"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_EDIT_POPUP_SHOW_COMPASS
"Display a 3 dimentional compass in the upper right corner of window"
@@ -2893,7 +2893,7 @@ BEGIN
ID_ADD_MINUS "Evaluates to difference between first subexpression and remaining subexpressions"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_SHOW_GRID_POSITIONS "Show position on grid for all visible objects"
ID_SHOW_COORDINATES "Display the coordinates of objects/waypoints."
@@ -2908,7 +2908,7 @@ BEGIN
ID_DISSOLVE_WING "Remove selected ships from Wing(s)\nRemove from Wing"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_SELECT_AND_MOVE "Select and Move objects\nSelect and Move (M)"
ID_SELECT_AND_ROTATE "Select and Rotate objects\nSelect and Rotate (R)"
@@ -2923,7 +2923,7 @@ BEGIN
ID_FIND_DISTANCE "Find Distance between two objects\nFind Distance"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_BUTTON32944 "Constrain to YZ axis\nYZ Constraint"
ID_BUTTON32945 "Constrain to XY axis\nXY Constraint"
@@ -2938,27 +2938,27 @@ BEGIN
ID_SHOW_HORIZON "Show the horizon line"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_EDITORS_PLAYER "Edit loadout information for all teams"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_REVERT "Revert changes by reloading mission from last save\nRevert"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_ERROR_CHECKER "Checks campaign for errors"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_LOOKAT_OBJ "Rotate camera around selected object\nRotate around object (Ctrl+V)"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_EDITORS_ADJUST_GRID "Adjust the orientation and level of the grid."
ID_EDITORS_SHIELD_SYS "Editor for availability of shield system for ships."
@@ -2966,7 +2966,7 @@ BEGIN
ID_MARK_WING "Mark entire wing selected object is a member of."
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_CONTROL_OBJ "Movement keys control marked objects instead of camera."
ID_CHECKOUT "Checks out the mission from Source Safe"
@@ -2974,35 +2974,37 @@ BEGIN
ID_AA_GRIDLINES "Toggle Gridlines being drawn anti-aliased or not."
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_FORMAT_FS2_OPEN "Save missions with SCP features"
ID_FORMAT_FS2_RETAIL "Save missions compatible with FS2 retail"
ID_FORMAT_FS1 "Save missions compatible with FS1 retail"
END
STRINGTABLE
STRINGTABLE
BEGIN
ID_FORMAT_FS1_RETAIL "Save missions compatible with FS1 retail"
END
#endif // English (United States) resources
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (United Kingdom) resources
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ALT_SHIP_CLASS DIALOG 0, 0, 312, 212
IDD_ALT_SHIP_CLASS DIALOG 0, 0, 312, 212
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Alternate Ship Class Editor"
FONT 8, "MS Sans Serif"
@@ -3029,7 +3031,7 @@ END
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
GUIDELINES DESIGNINFO
BEGIN
IDD_ALT_SHIP_CLASS, DIALOG
BEGIN
@@ -3041,7 +3043,7 @@ BEGIN
END
#endif // APSTUDIO_INVOKED
#endif // English (United Kingdom) resources
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
+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();
};
+221 -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;
}
@@ -7048,6 +7127,13 @@ int game_main(char *cmdline)
return 0;
}
// maybe output parsed table objects, and exit
if (Cmdline_output_json_data) {
ship_output_json("ships.json");
weapons_output_json("weapons.json");
game_shutdown();
return 0;
}
// maybe spew VP CRCs, and exit
if (Cmdline_verify_vps) {
@@ -7334,7 +7420,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 +7512,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 +7761,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 +7817,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 +7926,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 +7975,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 +8543,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 +8774,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 +8820,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,1,000000
PRODUCTVERSION 3,7,1,000000
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.1.000000"
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.1"
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
Loaded 100 of 528 files, more files were not shown because too many files have changed in this diff. Show more