mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-09 13:01:29 -10:00
Compare commits
78
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbbb4f96ac | ||
|
|
3b7ae521a9 | ||
|
|
54aaad33a3 | ||
|
|
cc80807f13 | ||
|
|
a351c7b721 | ||
|
|
1ebb04d419 | ||
|
|
d51e897ead | ||
|
|
06c355ddf0 | ||
|
|
8bb6f7f68e | ||
|
|
5b8176bb4b | ||
|
|
80cce2377c | ||
|
|
e0c9583a3b | ||
|
|
0cf3e4b408 | ||
|
|
d06b09dfd2 | ||
|
|
7151887f2e | ||
|
|
3fd955efe5 | ||
|
|
6c65202e9e | ||
|
|
2f2d33dae9 | ||
|
|
f2283dc4f3 | ||
|
|
b92dd314df | ||
|
|
cdbae474e0 | ||
|
|
c4eafa628f | ||
|
|
b8282cf074 | ||
|
|
8517ec180c | ||
|
|
1d345eb946 | ||
|
|
e981522f8a | ||
|
|
1ad8ae9b1c | ||
|
|
f67f6fb331 | ||
|
|
9627408f3a | ||
|
|
8f667bcfce | ||
|
|
6fff633d64 | ||
|
|
66c1c6b9d3 | ||
|
|
135e12df6a | ||
|
|
ff71992449 | ||
|
|
bd8a44c273 | ||
|
|
5f884aea5e | ||
|
|
c6adace344 | ||
|
|
27e6a4ca7a | ||
|
|
d516b8495e | ||
|
|
1f55d2499f | ||
|
|
8b72e3fb3b | ||
|
|
db9c33ce71 | ||
|
|
c3141364b2 | ||
|
|
c0730d572f | ||
|
|
dd0230d33b | ||
|
|
ab7663889e | ||
|
|
0461fe36c5 | ||
|
|
d09cfc624a | ||
|
|
1907fe08f8 | ||
|
|
4b11575f3f | ||
|
|
9c31fc6749 | ||
|
|
c6e3495605 | ||
|
|
4e06e5d033 | ||
|
|
a1d7d9a7d8 | ||
|
|
5591189a46 | ||
|
|
1e9d9326f7 | ||
|
|
76ce3e3a2b | ||
|
|
0f4d46a997 | ||
|
|
e151e54d9e | ||
|
|
f31301db4c | ||
|
|
930e50fa9d | ||
|
|
aad2cc2842 | ||
|
|
fba51c734f | ||
|
|
9d5a177d1a | ||
|
|
fcab17c9ea | ||
|
|
4ce7e50ad7 | ||
|
|
21cd34df25 | ||
|
|
ccfffdf5bd | ||
|
|
e18022b96a | ||
|
|
a68f03eedc | ||
|
|
e4a8b212ab | ||
|
|
d2d3585a8c | ||
|
|
1992c48b80 | ||
|
|
5aa587ad8d | ||
|
|
d30416cb51 | ||
|
|
0cf1863c22 | ||
|
|
991ca99a42 | ||
|
|
443d1671fb |
No files matched your search
@@ -1,4 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*.{h,cpp}]
|
||||
indent_style = tab
|
||||
-283
@@ -1,283 +0,0 @@
|
||||
*.o
|
||||
*.a
|
||||
.dirstamp
|
||||
libtool
|
||||
ltmain.sh
|
||||
m4/libtool.m4
|
||||
m4/ltoptions.m4
|
||||
m4/ltsugar.m4
|
||||
m4/ltversion.m4
|
||||
m4/lt~obsolete.m4
|
||||
compile
|
||||
.deps/
|
||||
code/.deps/
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.*
|
||||
code/fs2_open_*
|
||||
code/wxFRED2_*
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
.svn
|
||||
*.layout
|
||||
projects/Xcode/Frameworks/
|
||||
|
||||
#========
|
||||
|
||||
#OS junk files
|
||||
[Tt]humbs.db
|
||||
*.DS_Store
|
||||
|
||||
#Visual Studio files
|
||||
*.[Oo]bj
|
||||
*.user
|
||||
*.aps
|
||||
*.pch
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ncb
|
||||
*.suo
|
||||
*.tlb
|
||||
*.tlh
|
||||
*.bak
|
||||
*.[Cc]ache
|
||||
*.ilk
|
||||
*.log
|
||||
*.lib
|
||||
*.sbr
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.unsuccessfulbuild
|
||||
ipch/
|
||||
[Oo]bj/
|
||||
[Bb]in
|
||||
[Dd]ebug*/
|
||||
[Rr]elease*/
|
||||
Ankh.NoLoad
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
#MonoDevelop
|
||||
*.pidb
|
||||
*.userprefs
|
||||
|
||||
#Tooling
|
||||
_ReSharper*/
|
||||
*.resharper
|
||||
[Tt]est[Rr]esult*
|
||||
*.sass-cache
|
||||
|
||||
#Project files
|
||||
[Bb]uild/
|
||||
|
||||
#Subversion files
|
||||
.svn
|
||||
|
||||
# Office Temp Files
|
||||
~$*
|
||||
|
||||
# vim Temp Files
|
||||
*~
|
||||
|
||||
#NuGet
|
||||
packages/
|
||||
*.nupkg
|
||||
|
||||
#ncrunch
|
||||
*ncrunch*
|
||||
*crunch*.local.xml
|
||||
|
||||
# visual studio database projects
|
||||
*.dbmdl
|
||||
|
||||
#Test files
|
||||
*.testsettings
|
||||
|
||||
#===========
|
||||
|
||||
#########################
|
||||
# .gitignore file for Xcode4 and Xcode5 Source projects
|
||||
#
|
||||
# Apple bugs, waiting for Apple to fix/respond:
|
||||
#
|
||||
# 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation?
|
||||
#
|
||||
# Version 2.1
|
||||
# For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects
|
||||
#
|
||||
# 2013 updates:
|
||||
# - fixed the broken "save personal Schemes"
|
||||
# - added line-by-line explanations for EVERYTHING (some were missing)
|
||||
#
|
||||
# NB: if you are storing "built" products, this WILL NOT WORK,
|
||||
# and you should use a different .gitignore (or none at all)
|
||||
# This file is for SOURCE projects, where there are many extra
|
||||
# files that we want to exclude
|
||||
#
|
||||
#########################
|
||||
|
||||
#####
|
||||
# OS X temporary files that should never be committed
|
||||
#
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
.DS_Store
|
||||
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
.Trashes
|
||||
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
*.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
|
||||
# from source-control, but YMMV
|
||||
|
||||
*.lock
|
||||
|
||||
#
|
||||
# profile - REMOVED temporarily (on double-checking, this seems incorrect; I can't find it in OS X docs?)
|
||||
#profile
|
||||
|
||||
|
||||
####
|
||||
# Xcode temporary files that should never be committed
|
||||
#
|
||||
# NB: NIB/XIB files still exist even on Storyboard projects, so we want this...
|
||||
|
||||
*~.nib
|
||||
|
||||
|
||||
####
|
||||
# Xcode build files -
|
||||
#
|
||||
# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData"
|
||||
|
||||
DerivedData/
|
||||
|
||||
# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build"
|
||||
|
||||
build/
|
||||
|
||||
|
||||
#####
|
||||
# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups)
|
||||
#
|
||||
# This is complicated:
|
||||
#
|
||||
# SOMETIMES you need to put this file in version control.
|
||||
# Apple designed it poorly - if you use "custom executables", they are
|
||||
# saved in this file.
|
||||
# 99% of projects do NOT use those, so they do NOT want to version control this file.
|
||||
# ..but if you're in the 1%, comment out the line "*.pbxuser"
|
||||
|
||||
# .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html
|
||||
|
||||
*.pbxuser
|
||||
|
||||
# .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
|
||||
|
||||
*.mode1v3
|
||||
|
||||
# .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
|
||||
|
||||
*.mode2v3
|
||||
|
||||
# .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file
|
||||
|
||||
*.perspectivev3
|
||||
|
||||
# NB: also, whitelist the default ones, some projects need to use these
|
||||
!default.pbxuser
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.perspectivev3
|
||||
|
||||
|
||||
####
|
||||
# Xcode 4 - semi-personal settings
|
||||
#
|
||||
#
|
||||
# OPTION 1: ---------------------------------
|
||||
# throw away ALL personal settings (including custom schemes!
|
||||
# - unless they are "shared")
|
||||
#
|
||||
# NB: this is exclusive with OPTION 2 below
|
||||
xcuserdata
|
||||
|
||||
# OPTION 2: ---------------------------------
|
||||
# get rid of ALL personal settings, but KEEP SOME OF THEM
|
||||
# - NB: you must manually uncomment the bits you want to keep
|
||||
#
|
||||
# NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X,
|
||||
# or manually install git over the top of the OS X version
|
||||
# NB: this is exclusive with OPTION 1 above
|
||||
#
|
||||
#xcuserdata/**/*
|
||||
|
||||
# (requires option 2 above): Personal Schemes
|
||||
#
|
||||
#!xcuserdata/**/xcschemes/*
|
||||
|
||||
####
|
||||
# XCode 4 workspaces - more detailed
|
||||
#
|
||||
# Workspaces are important! They are a core feature of Xcode - don't exclude them :)
|
||||
#
|
||||
# Workspace layout is quite spammy. For reference:
|
||||
#
|
||||
# /(root)/
|
||||
# /(project-name).xcodeproj/
|
||||
# project.pbxproj
|
||||
# /project.xcworkspace/
|
||||
# contents.xcworkspacedata
|
||||
# /xcuserdata/
|
||||
# /(your name)/xcuserdatad/
|
||||
# UserInterfaceState.xcuserstate
|
||||
# /xcsshareddata/
|
||||
# /xcschemes/
|
||||
# (shared scheme name).xcscheme
|
||||
# /xcuserdata/
|
||||
# /(your name)/xcuserdatad/
|
||||
# (private scheme).xcscheme
|
||||
# xcschememanagement.plist
|
||||
#
|
||||
#
|
||||
|
||||
####
|
||||
# Xcode 4 - Deprecated classes
|
||||
#
|
||||
# Allegedly, if you manually "deprecate" your classes, they get moved here.
|
||||
#
|
||||
# We're using source-control, so this is a "feature" that we do not want!
|
||||
|
||||
*.moved-aside
|
||||
|
||||
# .xccheckout
|
||||
#
|
||||
# Per http://stackoverflow.com/questions/18340453/should-xccheckout-files-in-xcode5-be-ignored-under-vcs
|
||||
#
|
||||
|
||||
*.xccheckout
|
||||
|
||||
####
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
|
||||
####
|
||||
# Documentation
|
||||
#
|
||||
documentation/doxygen/*
|
||||
!documentation/doxygen/.gitkeep
|
||||
|
||||
|
||||
.idea/*
|
||||
projects/*
|
||||
@@ -1,6 +0,0 @@
|
||||
[submodule "cmake/external/cotire"]
|
||||
path = cmake/external/cotire
|
||||
url = https://github.com/sakra/cotire.git
|
||||
[submodule "cmake/external/rpavlik-cmake-modules"]
|
||||
path = cmake/external/rpavlik-cmake-modules
|
||||
url = https://github.com/asarium/cmake-modules.git
|
||||
-94
@@ -1,94 +0,0 @@
|
||||
language: generic
|
||||
sudo: required
|
||||
dist: trusty
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/cmake
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- ninja-build
|
||||
- libopenal-dev
|
||||
- libogg-dev
|
||||
- libvorbis-dev
|
||||
- libtheora-dev
|
||||
- libreadline6-dev
|
||||
- libpng12-dev
|
||||
- libjpeg62-dev
|
||||
- liblua5.1-0-dev
|
||||
- libjansson-dev
|
||||
- libsdl2-dev
|
||||
- valgrind
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "scp-fs2open/fs2open.github.com"
|
||||
notification_email: [email protected]
|
||||
build_command: "ci/travis/script.sh"
|
||||
# must match TRAVIS_BRANCH check below
|
||||
branch_pattern: coverity_scan
|
||||
deploy:
|
||||
- provider: releases
|
||||
api_key:
|
||||
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: "/tmp/builds/*"
|
||||
on:
|
||||
condition: '"$RELEASE_BUILD" == true'
|
||||
tags: true
|
||||
|
||||
- provider: bintray
|
||||
user: sirknightly
|
||||
key:
|
||||
secure: "CZtvDW/zPf1Nxru21i8Wd+9hgiBRA8VowWBX0gmCOGgRq9WHISttKQQmBWGHuyVZ3rYvtE4Va2bR+2qRN+TFNkUUuOCOQkdBJTCal9nS3G/LprEmsOashG0Q5PTfMMBnlKzKxaxGJW6UhFj2GySmHEAjsFLVpuNWGJeeZgZQ3UE="
|
||||
file: ci/bintray.json
|
||||
on:
|
||||
condition: '"$NIGHTLY_BUILD" == true'
|
||||
tags: true
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
# also note that fork's don't get access to secure keys
|
||||
# you have to test using a branch in the main repo
|
||||
- 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" CC=clang CXX=clang++
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env: CONFIGURATION="Debug"
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: CONFIGURATION="Release"
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: CONFIGURATION="Release" CC=clang CXX=clang++
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env: CONFIGURATION="Release"
|
||||
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
|
||||
- source "./ci/travis/check_release.sh"
|
||||
- "./ci/travis/before_install.sh"
|
||||
install:
|
||||
- "./ci/travis/install.sh"
|
||||
- export PATH=$HOME/cmake/bin:$PATH
|
||||
before_script:
|
||||
- "./ci/travis/before_script.sh"
|
||||
script:
|
||||
- if [ "$BUILD_DEPLOYMENT" = true ] ; then ./ci/travis/release.sh ; else ./ci/travis/script.sh ; fi
|
||||
before_deploy:
|
||||
- "./ci/travis/before_deploy.sh"
|
||||
-198
@@ -1,198 +0,0 @@
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# Make sure the source and binary directory are not the sample
|
||||
if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
message(FATAL_ERROR "Binary and source directory can not be the same! Choose another build directory.")
|
||||
endif()
|
||||
|
||||
include(cmake/util.cmake)
|
||||
|
||||
# Set a few policies
|
||||
set_policy(CMP0051 OLD)
|
||||
set_policy(CMP0053 NEW)
|
||||
set_policy(CMP0054 NEW)
|
||||
|
||||
SET(FSO_PROJECT_DESCRIPTION "Open source project based on the original FreeSpace 2 source code.")
|
||||
|
||||
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE PATH "Executable output path")
|
||||
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE PATH "Library output path")
|
||||
|
||||
# CMAKE_INSTALL_PREFIX is defined but also overwritten by the PROJECT command so we need to set it later
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(RESET_INSTALL_PREFIX TRUE)
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
|
||||
# Reset this variable
|
||||
SET(TARGET_COPY_FILES "" CACHE INTERNAL "" FORCE)
|
||||
SET(TARGET_COPY_DIRS "" CACHE INTERNAL "" FORCE)
|
||||
|
||||
### Define options and editable variables in the section below:
|
||||
# This is only needed for single configuration generators so don't annoy others
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Default build configuration used." FORCE)
|
||||
message(WARNING "CMAKE_BUILD_TYPE was not specified, defaulting to Release configuration.")
|
||||
endif(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
|
||||
|
||||
# Override standard CMake configurations
|
||||
set(CMAKE_CONFIGURATION_TYPES Debug Release FastDebug CACHE STRING "Available configurations" FORCE)
|
||||
|
||||
PROJECT(FS2_Open)
|
||||
|
||||
IF(CMAKE_CROSSCOMPILING)
|
||||
SET(IMPORT_EXE_DIR "IMPORT_EXE_DIR-NOTFOUND" CACHE FILEPATH "Required for a cross compiling build, point to binary directory of a cmake build for the real OS")
|
||||
INCLUDE(${IMPORT_EXE_DIR}/ImportExecutables.cmake)
|
||||
ENDIF(CMAKE_CROSSCOMPILING)
|
||||
|
||||
# Check if the external modules exists
|
||||
IF(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/external/rpavlik-cmake-modules/launcher-templates")
|
||||
message(FATAL_ERROR "External submodules could not be found. Please make sure you have updated your submodules.")
|
||||
endif()
|
||||
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/finder")
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/external/rpavlik-cmake-modules")
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/external/cotire/CMake")
|
||||
|
||||
IF(RESET_INSTALL_PREFIX)
|
||||
IF(NOT $ENV{FS2PATH} STREQUAL "")
|
||||
IF(NOT IS_DIRECTORY $ENV{FS2PATH})
|
||||
MESSAGE(WARNING "The path '$ENV{FS2PATH}' of the environment variable FS2PATH does not point to a directory! Install prefix wasn't set.")
|
||||
ELSE(NOT IS_DIRECTORY $ENV{FS2PATH})
|
||||
SET(CMAKE_INSTALL_PREFIX "$ENV{FS2PATH}" CACHE FILEPATH "Install path" FORCE)
|
||||
FILE(TO_CMAKE_PATH ${CMAKE_INSTALL_PREFIX} CMAKE_INSTALL_PREFIX)
|
||||
ENDIF(NOT IS_DIRECTORY $ENV{FS2PATH})
|
||||
ELSE(NOT $ENV{FS2PATH} STREQUAL "")
|
||||
MESSAGE(STATUS "NO FS2PATH environment variable found, you can define this to point to your freespace install but it is not required.")
|
||||
ENDIF(NOT $ENV{FS2PATH} STREQUAL "")
|
||||
ENDIF(RESET_INSTALL_PREFIX)
|
||||
|
||||
IF (WIN32)
|
||||
OPTION(FSO_USE_SPEECH "Use Windows specific text-to-speach libraries" ON)
|
||||
|
||||
OPTION(FSO_USE_VOICEREC "Enable voice recognition support" ON)
|
||||
|
||||
OPTION(FSO_BUILD_FRED2 "Build FRED2 binary" ON)
|
||||
elseif(UNIX)
|
||||
option(FSO_BUILD_APPIMAGE "Build an AppImage package" OFF)
|
||||
set(APPIMAGE_ASSISTANT "" CACHE STRING "The root directory of an AppImage clone.")
|
||||
ENDIF(WIN32)
|
||||
|
||||
OPTION(FSO_BUILD_TOOLS "Build tools related to FSO" OFF)
|
||||
|
||||
OPTION(FSO_BUILD_TESTS "Build unit tests" OFF)
|
||||
|
||||
OPTION(FSO_DEVELOPMENT_MODE "Generate binaries in development mode, only use if you know what you're doing!" OFF)
|
||||
|
||||
OPTION(FSO_BUILD_WXFRED2 "Build wxFRED2 binary" OFF)
|
||||
|
||||
IF(WIN32 OR APPLE)
|
||||
# On windows and mac the default should be to always build the included libraries
|
||||
SET(FSO_BUILD_INCLUDED_LIBS_DEFAULT ON)
|
||||
ELSE()
|
||||
SET(FSO_BUILD_INCLUDED_LIBS_DEFAULT OFF)
|
||||
ENDIF()
|
||||
|
||||
OPTION(FSO_BUILD_INCLUDED_LIBS "Build and use the included libraries istead of using the system headers and libraries" ${FSO_BUILD_INCLUDED_LIBS_DEFAULT})
|
||||
|
||||
OPTION(FSO_USE_LUAJIT "Use LuaJIT for Lua scripting, needs a working internet connection!" OFF)
|
||||
|
||||
OPTION(FSO_USE_OPENALSOFT "Download and build OpenAL Soft instead of using the system libraries" OFF)
|
||||
|
||||
OPTION(FSO_FATAL_WARNINGS "Determines if warnings in the build are considered fatal errors, primarily used for CI" OFF)
|
||||
|
||||
SET(FSO_FREESPACE_PATH "${CMAKE_INSTALL_PREFIX}" CACHE FILEPATH "The path of the FreeSpace directory you want to use. Please note that you will have to change CMAKE_INSTALL_PREFIX if you change this at some point.")
|
||||
|
||||
SET(FSO_RUN_ARGUMENTS "" CACHE STRING "Additional arguments passed to a generated executable when run with the generated build files.")
|
||||
|
||||
option(FSO_INSTALL_DEBUG_FILES "Install some debug files (currently only PDB files on windows)" OFF)
|
||||
|
||||
set(DEFAULT_VAL OFF)
|
||||
if(MSVC)
|
||||
# MSVC has been tested
|
||||
set(DEFAULT_VAL ON)
|
||||
endif()
|
||||
|
||||
OPTION(COTIRE_ENABLE "Enable cotire, this speeds up builds but may cause issues while developing (default = OFF)" ${DEFAULT_VAL})
|
||||
|
||||
MARK_AS_ADVANCED(FORCE FSO_CMAKE_DEBUG)
|
||||
MARK_AS_ADVANCED(FORCE FSO_BUILD_INCLUDED_LIBS)
|
||||
MARK_AS_ADVANCED(FORCE FSO_USE_OPENALSOFT)
|
||||
MARK_AS_ADVANCED(FORCE FSO_USE_LUAJIT)
|
||||
MARK_AS_ADVANCED(FORCE FSO_DEVELOPMENT_MODE)
|
||||
MARK_AS_ADVANCED(FORCE FSO_FATAL_WARNINGS)
|
||||
MARK_AS_ADVANCED(FORCE COTIRE_ENABLE)
|
||||
mark_as_advanced(FORCE FSO_INSTALL_DEBUG_FILES)
|
||||
|
||||
IF(COTIRE_ENABLE)
|
||||
# Include cotire file from https://github.com/sakra/cotire/
|
||||
include(cotire)
|
||||
ENDIF(COTIRE_ENABLE)
|
||||
|
||||
INCLUDE(globals)
|
||||
INCLUDE(toolchain)
|
||||
INCLUDE(platforms)
|
||||
include(version)
|
||||
|
||||
INCLUDE(headers)
|
||||
|
||||
SET(GENERATED_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated_source)
|
||||
|
||||
include(generateHeaders)
|
||||
|
||||
if(FSO_BUILD_APPIMAGE)
|
||||
include(appimage)
|
||||
endif()
|
||||
|
||||
# This includes source code for some tools, either used in the build or also for something else
|
||||
ADD_SUBDIRECTORY(tools)
|
||||
|
||||
ADD_SUBDIRECTORY(lib)
|
||||
|
||||
ADD_SUBDIRECTORY(code)
|
||||
|
||||
ADD_SUBDIRECTORY(freespace2)
|
||||
|
||||
IF(FSO_BUILD_FRED2)
|
||||
ADD_SUBDIRECTORY(fred2)
|
||||
ENDIF(FSO_BUILD_FRED2)
|
||||
|
||||
IF(FSO_BUILD_WXFRED2)
|
||||
ADD_SUBDIRECTORY(wxfred2)
|
||||
ENDIF(FSO_BUILD_WXFRED2)
|
||||
|
||||
if(FSO_BUILD_TESTS)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_VERSION}" VERSION_GREATER "3.5")
|
||||
# Default to using Freespace2 as startup project if CMake supports it.
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Freespace2)
|
||||
endif()
|
||||
|
||||
IF(MSVC_USE_RUNTIME_DLL)
|
||||
SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "${BINARY_DESTINATION}")
|
||||
|
||||
IF(FSO_BUILD_FRED2)
|
||||
SET(CMAKE_INSTALL_MFC_LIBRARIES ON)
|
||||
ENDIF(FSO_BUILD_FRED2)
|
||||
|
||||
INCLUDE(InstallRequiredSystemLibraries)
|
||||
ENDIF(MSVC_USE_RUNTIME_DLL)
|
||||
|
||||
include(package)
|
||||
|
||||
include(doxygen)
|
||||
|
||||
# Print used options to log
|
||||
IF (WIN32)
|
||||
message(STATUS "Building FRED2: ${FSO_BUILD_FRED2}")
|
||||
message(STATUS "Using text to speech: ${FSO_USE_SPEECH}")
|
||||
message(STATUS "Using voice recogition: ${FSO_USE_VOICEREC}")
|
||||
elseif(UNIX)
|
||||
message(STATUS "Building AppImage: ${FSO_BUILD_APPIMAGE}")
|
||||
ENDIF()
|
||||
message(STATUS "Building FSO tools: ${FSO_BUILD_TOOLS}")
|
||||
message(STATUS "Building wxFRED: ${FSO_BUILD_WXFRED2}")
|
||||
message(STATUS "Fatal warnings: ${FSO_FATAL_WARNINGS}")
|
||||
@@ -1,26 +1,6 @@
|
||||
ChangeLog for fs2_open. All times are UTC.
|
||||
Updated 2002-10-31 03:46
|
||||
|
||||
Features: September 2013
|
||||
http://www.hard-light.net/forums/index.php?topic=85700.0
|
||||
|
||||
- show-subtitle-text can now display messages as well as raw text - Goober5000
|
||||
- toggle subsytem scanning, scannable, cargo revealed, hidden from sensors, stealth and friendly stealth added to the alter-ship-flag sexp - karajorma
|
||||
- Support added to add more languages besides English, French, German and Polish, leading the way to better localization! - karajorma
|
||||
- event.log can now snapshot events checked in a frame and record the status of an event the previous time it was checked as well as the current state - karajorma
|
||||
- added a player-is-cheating sexp - The E
|
||||
- allow a user-specified number of credit images - Goober5000
|
||||
- allow the specification of the positions of medals, callsigns and labels on the medal screen. - Goober5000
|
||||
- lua function to check if a ship is warp capable, and access to a ship's auto-aim FOV - zookeeper
|
||||
- is-facing now works for things that aren't ships (like waypoints!) - zookeeper
|
||||
- experimental configurations to make AVX builds (see this post for more explainations) - The E
|
||||
- new ship flag to enable smarter AI use of afterburners. Now it can use them while flying waypoints or attacking capital ships (use the free-afterburner-use flag with alter-ship-flag) - Admiral MS
|
||||
- the number of medals is now dynamic! - Goober5000
|
||||
- frame profiling code, see what exactly is slowing down FreeSpace. (Mostly for devs or coders) - Swifty + The E
|
||||
- allowing fade-in and fade-out sexps to use any color, not just black, white and red. - Goober5000
|
||||
|
||||
==================================================================
|
||||
( massive gap in updates, maybe this will be filled in someday...)
|
||||
==================================================================
|
||||
|
||||
2002-10-30 22:57 randomtiger
|
||||
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
# Makefile.am for fs2_open (top level)
|
||||
#
|
||||
# This file uses GNU Automake to generate makefiles
|
||||
|
||||
SUBDIRS = code
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
FS2OpenSCPReadMe.doc \
|
||||
projects/MSVC_2005/Freespace2.sln \
|
||||
projects/MSVC_2005/Freespace2.vcproj \
|
||||
projects/MSVC_2005/code.vcproj \
|
||||
projects/MSVC_6/Fred2.dsp \
|
||||
projects/MSVC_6/Freespace2.dsp \
|
||||
projects/MSVC_6/Freespace2.dsw \
|
||||
projects/MSVC_6/code.dsp \
|
||||
projects/MSVC_6/libjpeg.dsp \
|
||||
projects/MSVC_6/liblua.dsp \
|
||||
projects/MSVC_6/wxFRED2.dsp \
|
||||
projects/Xcode/English.lproj/InfoPlist.strings \
|
||||
projects/Xcode/FS2_Open.icns \
|
||||
projects/Xcode/FS2_Open.xcodeproj/project.pbxproj \
|
||||
projects/Xcode/Frameworks.tgz \
|
||||
projects/Xcode/Info-debug.plist \
|
||||
projects/Xcode/Info.plist \
|
||||
projects/Xcode/README.Xcode \
|
||||
projects/Xcode/SDLMain.h \
|
||||
projects/Xcode/SDLMain.m
|
||||
|
||||
|
||||
# D_ variants are defaults and should always be used
|
||||
AM_CXXFLAGS = -I./code @D_CFLAGS@
|
||||
AM_LDFLAGS = @D_LDFLAGS@
|
||||
|
||||
EXTRA_PROGRAMS = cfilearchiver cfileextractor
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin utilitites
|
||||
##
|
||||
|
||||
# cfilearchiver -- to create VPs
|
||||
cfilearchiver_SOURCES = \
|
||||
code/cfilearchiver/cfilearchiver.cpp
|
||||
|
||||
# cfileextractor -- to extract files from VPs
|
||||
cfileextractor_SOURCES = \
|
||||
code/cfileextractor/cfileextractor.cpp
|
||||
|
||||
# catch all to build utilitites
|
||||
tools: cfilearchiver cfileextractor
|
||||
|
||||
# cleaning
|
||||
clean-tools:
|
||||
-test -z "$(EXTRA_PROGRAMS)" || rm -f $(EXTRA_PROGRAMS)
|
||||
|
||||
##
|
||||
## End utilitites
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
|
||||
# make sure we get this stuff cleaned up
|
||||
clean-generic: clean-tools
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
The "projects" directory contains ready projects for:
|
||||
Microsoft Visual C++ 6
|
||||
Microsoft Visual C++ 2005
|
||||
Microsoft Visual C++ 2008
|
||||
Micrsofot Visual C++ 2010
|
||||
Apple Xcode
|
||||
Code::Blocks
|
||||
|
||||
|
||||
See the ChangeLog to see what's new.
|
||||
See the INSTALL file for instructions on how to build fs2_open.
|
||||
@@ -1,38 +0,0 @@
|
||||
FreeSpace2 *S*ource *C*ode *P*roject
|
||||
==
|
||||
[](https://travis-ci.org/scp-fs2open/fs2open.github.com)
|
||||
[](https://scan.coverity.com/projects/870)
|
||||
|
||||
Building
|
||||
--
|
||||
For building you will need [CMake](http://www.cmake.org/cmake/resources/software.html). Version 3.4 is required. Once you have installed CMake you should create a build directory where the project/make files should be created, **do not create them inside the source tree!**<br>
|
||||
<br>
|
||||
On Windows you can use the `cmake-gui` executable to get a nice GUI, on Unix just use `cmake`. Use the newly created directory as build directory (change to this directory on Unix) and run cmake. On Windows this can be done by clicking the `Configure` button. Choose your compiler version and hit `Generate` when configuring is done. <br>
|
||||
Depending on the makefile generator used build the `all` or `ALL_BUILD` target to compile the project.<br>
|
||||
|
||||
### Available variables to control the build
|
||||
* `FSO_BUILD_WXFRED2`: Build the wxfred2 project, requires wxWidgets
|
||||
* `FSO_FREESPACE_PATH`: Sets the path of your FreeSpace install, can be used to automatically run the generated executables with the correct working directory, this is an optional variable. By default this will use the value of the `FS2PATH` environment variable.
|
||||
* `FSO_BUILD_TOOLS`: Build some tools related to FSO
|
||||
|
||||
#### Windows only variables
|
||||
* `FSO_BUILD_FRED2`: Build FRED2, requires a Visual Studio version that ships with MFC
|
||||
* `FSO_USE_SPEECH`: Build a binary with text-to-speech support
|
||||
* `FSO_USE_VOICEREC`: Build a binary with voice recognition support
|
||||
|
||||
#### Advanced variables
|
||||
You should only use these variables if you know what you're doing
|
||||
* `FSO_CMAKE_DEBUG`: Print CMake debugging informations
|
||||
* `FSO_BUILD_INCLUDED_LIBS`: Build libraries from the included source
|
||||
* `FSO_USE_OPENALSOFT`: Use [OpenALSoft](http://kcat.strangesoft.net/openal.html) for OpenAL support
|
||||
* `FSO_USE_LUAJIT`: Use [luajit](http://luajit.org/) as a replacement for lua
|
||||
* `FSO_DEVELOPMENT_MODE`: Toggles some development behavior, only use if you really need it.
|
||||
* `FSO_RUN_ARGUMENTS`: If you run an executable from within the project, these arguments will also be passed to the executable
|
||||
* `FSO_BUILD_POSTFIX`: Sets a postfix to be added to the executable name, may be useful for release candidates.
|
||||
|
||||
#### Visual Studio specific variables
|
||||
* `MSVC_USE_RUNTIME_DLL`: Use the DLL version of the runtime, experimental and not well tested.
|
||||
* `MSVC_SIMD_INSTRUCTIONS`: The instruction set the executables will be optimized for.
|
||||
|
||||
### Generating an installation package
|
||||
CMake can automaticall generate installation packages of the project. To do this you will just need to run the `package` target of the build system and the package will be placed inside your build directory. On Windows you will have to install [NSIS](http://nsis.sourceforge.net/Main_Page) to use this.
|
||||
+889
@@ -0,0 +1,889 @@
|
||||
# Configure paths for SDL
|
||||
# Sam Lantinga 9/21/99
|
||||
# stolen from Manish Singh
|
||||
# stolen back from Frank Belew
|
||||
# stolen from Manish Singh
|
||||
# Shamelessly stolen from Owen Taylor
|
||||
|
||||
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_SDL],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries from the sdl-config script
|
||||
dnl
|
||||
AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)],
|
||||
sdl_prefix="$withval", sdl_prefix="")
|
||||
AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
|
||||
sdl_exec_prefix="$withval", sdl_exec_prefix="")
|
||||
AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program],
|
||||
, enable_sdltest=yes)
|
||||
|
||||
if test x$sdl_exec_prefix != x ; then
|
||||
sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix"
|
||||
if test x${SDL_CONFIG+set} != xset ; then
|
||||
SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config
|
||||
fi
|
||||
fi
|
||||
if test x$sdl_prefix != x ; then
|
||||
sdl_args="$sdl_args --prefix=$sdl_prefix"
|
||||
if test x${SDL_CONFIG+set} != xset ; then
|
||||
SDL_CONFIG=$sdl_prefix/bin/sdl-config
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_REQUIRE([AC_CANONICAL_TARGET])
|
||||
PATH="$prefix/bin:$prefix/usr/bin:$PATH"
|
||||
AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH])
|
||||
min_sdl_version=ifelse([$1], ,0.11.0,$1)
|
||||
AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
|
||||
no_sdl=""
|
||||
if test "$SDL_CONFIG" = "no" ; then
|
||||
no_sdl=yes
|
||||
else
|
||||
SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags`
|
||||
SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs`
|
||||
|
||||
sdl_major_version=`$SDL_CONFIG $sdl_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
if test "x$enable_sdltest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
|
||||
LIBS="$LIBS $SDL_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed SDL is sufficiently new. (Also sanity
|
||||
dnl checks the results of sdl-config to some extent
|
||||
dnl
|
||||
rm -f conf.sdltest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "SDL.h"
|
||||
|
||||
char*
|
||||
my_strdup (char *str)
|
||||
{
|
||||
char *new_str;
|
||||
|
||||
if (str)
|
||||
{
|
||||
new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
|
||||
strcpy (new_str, str);
|
||||
}
|
||||
else
|
||||
new_str = NULL;
|
||||
|
||||
return new_str;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int major, minor, micro;
|
||||
char *tmp_version;
|
||||
|
||||
/* This hangs on some systems (?)
|
||||
system ("touch conf.sdltest");
|
||||
*/
|
||||
{ FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); }
|
||||
|
||||
/* HP/UX 9 (%@#!) writes to sscanf strings */
|
||||
tmp_version = my_strdup("$min_sdl_version");
|
||||
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
|
||||
printf("%s, bad version string\n", "$min_sdl_version");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (($sdl_major_version > major) ||
|
||||
(($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
|
||||
(($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
|
||||
printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro);
|
||||
printf("*** best to upgrade to the required version.\n");
|
||||
printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n");
|
||||
printf("*** to point to the correct copy of sdl-config, and remove the file\n");
|
||||
printf("*** config.cache before re-running configure\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
if test "x$no_sdl" = x ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test "$SDL_CONFIG" = "no" ; then
|
||||
echo "*** The sdl-config script installed by SDL could not be found"
|
||||
echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
|
||||
echo "*** your path, or set the SDL_CONFIG environment variable to the"
|
||||
echo "*** full path to sdl-config."
|
||||
else
|
||||
if test -f conf.sdltest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run SDL test program, checking why..."
|
||||
CFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
|
||||
LIBS="$LIBS $SDL_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include "SDL.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{ return 0; }
|
||||
#undef main
|
||||
#define main K_and_R_C_main
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding SDL or finding the wrong"
|
||||
echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means SDL was incorrectly installed"
|
||||
echo "*** or that you have moved SDL since it was installed. In the latter case, you"
|
||||
echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
SDL_CFLAGS=""
|
||||
SDL_LIBS=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
AC_SUBST(SDL_CFLAGS)
|
||||
AC_SUBST(SDL_LIBS)
|
||||
rm -f conf.sdltest
|
||||
])
|
||||
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Macros for wxWindows detection. Typically used in configure.in as:
|
||||
dnl
|
||||
dnl AC_ARG_ENABLE(...)
|
||||
dnl AC_ARG_WITH(...)
|
||||
dnl ...
|
||||
dnl AM_OPTIONS_WXCONFIG
|
||||
dnl ...
|
||||
dnl ...
|
||||
dnl AM_PATH_WXCONFIG(2.3.4, wxWin=1)
|
||||
dnl if test "$wxWin" != 1; then
|
||||
dnl AC_MSG_ERROR([
|
||||
dnl wxWindows must be installed on your system
|
||||
dnl but wx-config script couldn't be found.
|
||||
dnl
|
||||
dnl Please check that wx-config is in path, the directory
|
||||
dnl where wxWindows libraries are installed (returned by
|
||||
dnl 'wx-config --libs' command) is in LD_LIBRARY_PATH or
|
||||
dnl equivalent variable and wxWindows version is 2.3.4 or above.
|
||||
dnl ])
|
||||
dnl fi
|
||||
dnl CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS"
|
||||
dnl CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY"
|
||||
dnl CFLAGS="$CFLAGS $WX_CFLAGS_ONLY"
|
||||
dnl
|
||||
dnl LDFLAGS="$LDFLAGS $WX_LIBS"
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl AM_OPTIONS_WXCONFIG
|
||||
dnl
|
||||
dnl adds support for --wx-prefix, --wx-exec-prefix and --wx-config
|
||||
dnl command line options
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
AC_DEFUN([AM_OPTIONS_WXCONFIG],
|
||||
[
|
||||
AC_ARG_WITH(wx-prefix, [ --with-wx-prefix=PREFIX Prefix where wxWindows is installed (optional)],
|
||||
wx_config_prefix="$withval", wx_config_prefix="")
|
||||
AC_ARG_WITH(wx-exec-prefix,[ --with-wx-exec-prefix=PREFIX Exec prefix where wxWindows is installed (optional)],
|
||||
wx_config_exec_prefix="$withval", wx_config_exec_prefix="")
|
||||
AC_ARG_WITH(wx-config,[ --with-wx-config=CONFIG wx-config script to use (optional)],
|
||||
wx_config_name="$withval", wx_config_name="")
|
||||
])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl AM_PATH_WXCONFIG(VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl
|
||||
dnl Test for wxWindows, and define WX_C*FLAGS, WX_LIBS and WX_LIBS_STATIC
|
||||
dnl (the latter is for static linking against wxWindows). Set WX_CONFIG_NAME
|
||||
dnl environment variable to override the default name of the wx-config script
|
||||
dnl to use. Set WX_CONFIG_PATH to specify the full path to wx-config - in this
|
||||
dnl case the macro won't even waste time on tests for its existence.
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
dnl
|
||||
dnl Get the cflags and libraries from the wx-config script
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_WXCONFIG],
|
||||
[
|
||||
dnl do we have wx-config name: it can be wx-config or wxd-config or ...
|
||||
if test x${WX_CONFIG_NAME+set} != xset ; then
|
||||
WX_CONFIG_NAME=wx-config
|
||||
fi
|
||||
if test "x$wx_config_name" != x ; then
|
||||
WX_CONFIG_NAME="$wx_config_name"
|
||||
fi
|
||||
|
||||
dnl deal with optional prefixes
|
||||
if test x$wx_config_exec_prefix != x ; then
|
||||
wx_config_args="$wx_config_args --exec-prefix=$wx_config_exec_prefix"
|
||||
WX_LOOKUP_PATH="$wx_config_exec_prefix/bin"
|
||||
fi
|
||||
if test x$wx_config_prefix != x ; then
|
||||
wx_config_args="$wx_config_args --prefix=$wx_config_prefix"
|
||||
WX_LOOKUP_PATH="$WX_LOOKUP_PATH:$wx_config_prefix/bin"
|
||||
fi
|
||||
|
||||
dnl don't search the PATH if WX_CONFIG_NAME is absolute filename
|
||||
if test -x "$WX_CONFIG_NAME" ; then
|
||||
AC_MSG_CHECKING(for wx-config)
|
||||
WX_CONFIG_PATH="$WX_CONFIG_NAME"
|
||||
AC_MSG_RESULT($WX_CONFIG_PATH)
|
||||
else
|
||||
AC_PATH_PROG(WX_CONFIG_PATH, $WX_CONFIG_NAME, no, "$WX_LOOKUP_PATH:$PATH")
|
||||
fi
|
||||
|
||||
if test "$WX_CONFIG_PATH" != "no" ; then
|
||||
WX_VERSION=""
|
||||
no_wx=""
|
||||
|
||||
min_wx_version=ifelse([$1], ,2.2.1,$1)
|
||||
AC_MSG_CHECKING(for wxWindows version >= $min_wx_version)
|
||||
|
||||
WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args"
|
||||
|
||||
WX_VERSION=`$WX_CONFIG_WITH_ARGS --version`
|
||||
wx_config_major_version=`echo $WX_VERSION | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
wx_config_minor_version=`echo $WX_VERSION | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
wx_config_micro_version=`echo $WX_VERSION | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
|
||||
wx_requested_major_version=`echo $min_wx_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
wx_requested_minor_version=`echo $min_wx_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
wx_requested_micro_version=`echo $min_wx_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
|
||||
wx_ver_ok=""
|
||||
if test $wx_config_major_version -gt $wx_requested_major_version; then
|
||||
wx_ver_ok=yes
|
||||
else
|
||||
if test $wx_config_major_version -eq $wx_requested_major_version; then
|
||||
if test $wx_config_minor_version -gt $wx_requested_minor_version; then
|
||||
wx_ver_ok=yes
|
||||
else
|
||||
if test $wx_config_minor_version -eq $wx_requested_minor_version; then
|
||||
if test $wx_config_micro_version -ge $wx_requested_micro_version; then
|
||||
wx_ver_ok=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$wx_ver_ok" = x ; then
|
||||
no_wx=yes
|
||||
else
|
||||
WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs`
|
||||
WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs`
|
||||
|
||||
dnl starting with version 2.2.6 wx-config has --cppflags argument
|
||||
wx_has_cppflags=""
|
||||
if test $wx_config_major_version -gt 2; then
|
||||
wx_has_cppflags=yes
|
||||
else
|
||||
if test $wx_config_major_version -eq 2; then
|
||||
if test $wx_config_minor_version -gt 2; then
|
||||
wx_has_cppflags=yes
|
||||
else
|
||||
if test $wx_config_minor_version -eq 2; then
|
||||
if test $wx_config_micro_version -ge 6; then
|
||||
wx_has_cppflags=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$wx_has_cppflags" = x ; then
|
||||
dnl no choice but to define all flags like CFLAGS
|
||||
WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags`
|
||||
WX_CPPFLAGS=$WX_CFLAGS
|
||||
WX_CXXFLAGS=$WX_CFLAGS
|
||||
|
||||
WX_CFLAGS_ONLY=$WX_CFLAGS
|
||||
WX_CXXFLAGS_ONLY=$WX_CFLAGS
|
||||
else
|
||||
dnl we have CPPFLAGS included in CFLAGS included in CXXFLAGS
|
||||
WX_CPPFLAGS=`$WX_CONFIG_WITH_ARGS --cppflags`
|
||||
WX_CXXFLAGS=`$WX_CONFIG_WITH_ARGS --cxxflags`
|
||||
WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags`
|
||||
|
||||
WX_CFLAGS_ONLY=`echo $WX_CFLAGS | sed "s@^$WX_CPPFLAGS *@@"`
|
||||
WX_CXXFLAGS_ONLY=`echo $WX_CXXFLAGS | sed "s@^$WX_CFLAGS *@@"`
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$no_wx" = x ; then
|
||||
AC_MSG_RESULT(yes (version $WX_VERSION))
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
if test "x$WX_VERSION" = x; then
|
||||
dnl no wx-config at all
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(no (version $WX_VERSION is not new enough))
|
||||
fi
|
||||
|
||||
WX_CFLAGS=""
|
||||
WX_CPPFLAGS=""
|
||||
WX_CXXFLAGS=""
|
||||
WX_LIBS=""
|
||||
WX_LIBS_STATIC=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(WX_CPPFLAGS)
|
||||
AC_SUBST(WX_CFLAGS)
|
||||
AC_SUBST(WX_CXXFLAGS)
|
||||
AC_SUBST(WX_CFLAGS_ONLY)
|
||||
AC_SUBST(WX_CXXFLAGS_ONLY)
|
||||
AC_SUBST(WX_LIBS)
|
||||
AC_SUBST(WX_LIBS_STATIC)
|
||||
AC_SUBST(WX_VERSION)
|
||||
])
|
||||
|
||||
# Configure paths for libogg
|
||||
# Jack Moffitt <[email protected]> 10-21-2000
|
||||
# Shamelessly stolen from Owen Taylor and Manish Singh
|
||||
|
||||
dnl XIPH_PATH_OGG([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libogg, and define OGG_CFLAGS and OGG_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_OGG],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(ogg,[ --with-ogg=PFX Prefix where libogg is installed (optional)], ogg_prefix="$withval", ogg_prefix="")
|
||||
AC_ARG_WITH(ogg-libraries,[ --with-ogg-libraries=DIR Directory where libogg library is installed (optional)], ogg_libraries="$withval", ogg_libraries="")
|
||||
AC_ARG_WITH(ogg-includes,[ --with-ogg-includes=DIR Directory where libogg header files are installed (optional)], ogg_includes="$withval", ogg_includes="")
|
||||
AC_ARG_ENABLE(oggtest, [ --disable-oggtest Do not try to compile and run a test Ogg program],, enable_oggtest=yes)
|
||||
|
||||
if test "x$ogg_libraries" != "x" ; then
|
||||
OGG_LIBS="-L$ogg_libraries"
|
||||
elif test "x$ogg_prefix" != "x" ; then
|
||||
OGG_LIBS="-L$ogg_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE" ; then
|
||||
OGG_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
OGG_LIBS="$OGG_LIBS -logg"
|
||||
|
||||
if test "x$ogg_includes" != "x" ; then
|
||||
OGG_CFLAGS="-I$ogg_includes"
|
||||
elif test "x$ogg_prefix" != "x" ; then
|
||||
OGG_CFLAGS="-I$ogg_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OGG_CFLAGS=""
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for Ogg)
|
||||
no_ogg=""
|
||||
|
||||
|
||||
if test "x$enable_oggtest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Ogg is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.oggtest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
system("touch conf.oggtest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_ogg=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_ogg" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.oggtest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Ogg test program, checking why..."
|
||||
CFLAGS="$CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <ogg/ogg.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Ogg or finding the wrong"
|
||||
echo "*** version of Ogg. If it is not finding Ogg, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Ogg was incorrectly installed"
|
||||
echo "*** or that you have moved Ogg since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
OGG_CFLAGS=""
|
||||
OGG_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(OGG_CFLAGS)
|
||||
AC_SUBST(OGG_LIBS)
|
||||
rm -f conf.oggtest
|
||||
])
|
||||
|
||||
# Configure paths for libvorbis
|
||||
# Jack Moffitt <[email protected]> 10-21-2000
|
||||
# Shamelessly stolen from Owen Taylor and Manish Singh
|
||||
# thomasvs added check for vorbis_bitrate_addblock which is new in rc3
|
||||
|
||||
dnl XIPH_PATH_VORBIS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libvorbis, and define VORBIS_CFLAGS and VORBIS_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_VORBIS],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(vorbis,[ --with-vorbis=PFX Prefix where libvorbis is installed (optional)], vorbis_prefix="$withval", vorbis_prefix="")
|
||||
AC_ARG_WITH(vorbis-libraries,[ --with-vorbis-libraries=DIR Directory where libvorbis library is installed (optional)], vorbis_libraries="$withval", vorbis_libraries="")
|
||||
AC_ARG_WITH(vorbis-includes,[ --with-vorbis-includes=DIR Directory where libvorbis header files are installed (optional)], vorbis_includes="$withval", vorbis_includes="")
|
||||
AC_ARG_ENABLE(vorbistest, [ --disable-vorbistest Do not try to compile and run a test Vorbis program],, enable_vorbistest=yes)
|
||||
|
||||
if test "x$vorbis_libraries" != "x" ; then
|
||||
VORBIS_LIBS="-L$vorbis_libraries"
|
||||
elif test "x$vorbis_prefix" != "x" ; then
|
||||
VORBIS_LIBS="-L$vorbis_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
VORBIS_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
VORBIS_LIBS="$VORBIS_LIBS -lvorbis -lm"
|
||||
VORBISFILE_LIBS="-lvorbisfile"
|
||||
VORBISENC_LIBS="-lvorbisenc"
|
||||
|
||||
if test "x$vorbis_includes" != "x" ; then
|
||||
VORBIS_CFLAGS="-I$vorbis_includes"
|
||||
elif test "x$vorbis_prefix" != "x" ; then
|
||||
VORBIS_CFLAGS="-I$vorbis_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
VORBIS_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for Vorbis)
|
||||
no_vorbis=""
|
||||
|
||||
|
||||
if test "x$enable_vorbistest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $VORBIS_CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $VORBIS_LIBS $VORBISENC_LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Vorbis is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.vorbistest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisenc.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
vorbis_block vb;
|
||||
vorbis_dsp_state vd;
|
||||
vorbis_info vi;
|
||||
|
||||
vorbis_info_init (&vi);
|
||||
vorbis_encode_init (&vi, 2, 44100, -1, 128000, -1);
|
||||
vorbis_analysis_init (&vd, &vi);
|
||||
vorbis_block_init (&vd, &vb);
|
||||
/* this function was added in 1.0rc3, so this is what we're testing for */
|
||||
vorbis_bitrate_addblock (&vb);
|
||||
|
||||
system("touch conf.vorbistest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_vorbis=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_vorbis" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.vorbistest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Vorbis test program, checking why..."
|
||||
CFLAGS="$CFLAGS $VORBIS_CFLAGS"
|
||||
LIBS="$LIBS $VORBIS_LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <vorbis/codec.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Vorbis or finding the wrong"
|
||||
echo "*** version of Vorbis. If it is not finding Vorbis, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Vorbis was incorrectly installed"
|
||||
echo "*** or that you have moved Vorbis since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
VORBIS_CFLAGS=""
|
||||
VORBIS_LIBS=""
|
||||
VORBISFILE_LIBS=""
|
||||
VORBISENC_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(VORBIS_CFLAGS)
|
||||
AC_SUBST(VORBIS_LIBS)
|
||||
AC_SUBST(VORBISFILE_LIBS)
|
||||
AC_SUBST(VORBISENC_LIBS)
|
||||
rm -f conf.vorbistest
|
||||
])
|
||||
|
||||
dnl XIPH_PATH_THEORA([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for libtheora, and define THEORA_CFLAGS and THEORA_LIBS
|
||||
dnl
|
||||
AC_DEFUN([XIPH_PATH_THEORA],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(theora,[ --with-theora=PFX Prefix where libtheora is installed (optional)], theora_prefix="$withval", theora_prefix="")
|
||||
AC_ARG_WITH(theora-libraries,[ --with-theora-libraries=DIR Directory where libtheora library is installed (optional)], theora_libraries="$withval", theora_libraries="")
|
||||
AC_ARG_WITH(theora-includes,[ --with-theora-includes=DIR Directory where libtheora header files are installed (optional)], theora_includes="$withval", theora_includes="")
|
||||
AC_ARG_ENABLE(theoratest, [ --disable-theoratest Do not try to compile and run a test Theora program],, enable_theoratest=yes)
|
||||
|
||||
if test "x$theora_libraries" != "x" ; then
|
||||
THEORA_LIBS="-L$theora_libraries"
|
||||
elif test "x$theora_prefix" != "x" ; then
|
||||
THEORA_LIBS="-L$theora_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
THEORA_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
THEORA_LIBS="$THEORA_LIBS -ltheora"
|
||||
|
||||
if test "x$theora_includes" != "x" ; then
|
||||
THEORA_CFLAGS="-I$theora_includes"
|
||||
elif test "x$theora_prefix" != "x" ; then
|
||||
THEORA_CFLAGS="-I$theora_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
THEORA_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for Theora)
|
||||
no_theora=""
|
||||
|
||||
|
||||
if test "x$enable_theoratest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $THEORA_CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $THEORA_LIBS $OGG_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed Theora is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.theoratest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <theora/theora.h>
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
theora_info ti;
|
||||
theora_state ts;
|
||||
|
||||
theora_info_init(&ti);
|
||||
|
||||
system("touch conf.theoratest");
|
||||
return 0;
|
||||
}
|
||||
|
||||
],, no_theora=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_theora" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.theoratest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run Theora test program, checking why..."
|
||||
CFLAGS="$CFLAGS $THEORA_CFLAGS"
|
||||
LIBS="$LIBS $THEORA_LIBS $OGG_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <vorbis/codec.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding Theora or finding the wrong"
|
||||
echo "*** version of Theora. If it is not finding Theora, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means Theora was incorrectly installed"
|
||||
echo "*** or that you have moved Theora since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
THEORA_CFLAGS=""
|
||||
THEORA_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(THEORA_CFLAGS)
|
||||
AC_SUBST(THEORA_LIBS)
|
||||
rm -f conf.theoratest
|
||||
])
|
||||
|
||||
|
||||
dnl AM_PATH_OPENAL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for OpenAL, and define OPENAL_CFLAGS and OPENAL_LIBS
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_OPENAL],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(openal,[ --with-openal=PFX Prefix where OpenAL is installed (optional)], openal_prefix="$withval", openal_prefix="")
|
||||
AC_ARG_WITH(openal-libraries,[ --with-openal-libraries=DIR Directory where OpenAL library is installed (optional)], openal_libraries="$withval", openal_libraries="")
|
||||
AC_ARG_WITH(openal-includes,[ --with-openal-includes=DIR Directory where OpenAL header files are installed (optional)], openal_includes="$withval", openal_includes="")
|
||||
AC_ARG_ENABLE(openaltest, [ --disable-openaltest Do not try to compile and run a test OpenAL program],, enable_openaltest=yes)
|
||||
|
||||
if test "x$openal_libraries" != "x" ; then
|
||||
OPENAL_LIBS="-L$openal_libraries"
|
||||
elif test "x$openal_prefix" != "x" ; then
|
||||
OPENAL_LIBS="-L$openal_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OPENAL_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
OPENAL_LIBS="$OPENAL_LIBS -lopenal"
|
||||
|
||||
if test "x$openal_includes" != "x" ; then
|
||||
OPENAL_CFLAGS="-I$openal_includes"
|
||||
elif test "x$openal_prefix" != "x" ; then
|
||||
OPENAL_CFLAGS="-I$openal_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OPENAL_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for OpenAL)
|
||||
no_openal=""
|
||||
|
||||
|
||||
if test "x$enable_openaltest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $OPENAL_CFLAGS"
|
||||
LIBS="$LIBS $OPENAL_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed OpenAL is sufficiently new.
|
||||
dnl
|
||||
rm -f conf.openaltest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
#ifdef AL_VERSION_1_1
|
||||
alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT");
|
||||
|
||||
system("touch conf.openaltest");
|
||||
return 0;
|
||||
#else
|
||||
printf("\n*** OpenAL version 1.1 or greater is required.\n");
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
],, no_openal=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_openal" = "x" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test -f conf.openaltest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run OpenAL test program, checking why..."
|
||||
CFLAGS="$CFLAGS $OPENAL_CFLAGS"
|
||||
LIBS="$LIBS $OPENAL_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <AL/al.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding OpenAL or finding the wrong"
|
||||
echo "*** version of OpenAL. If it is not finding OpenAL, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means OpenAL was incorrectly installed"
|
||||
echo "*** or that you have moved OpenAL since it was installed." ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
OPENAL_CFLAGS=""
|
||||
OPENAL_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(OPENAL_CFLAGS)
|
||||
AC_SUBST(OPENAL_LIBS)
|
||||
rm -f conf.openaltest
|
||||
])
|
||||
|
||||
dnl AM_PATH_OPENGL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for OpenGL, and define OPENGL_CFLAGS and OPENGL_LIBS
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_OPENGL],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries
|
||||
dnl
|
||||
AC_ARG_WITH(opengl,[ --with-opengl=PFX Prefix where OpenGL is installed (optional)], opengl_prefix="$withval", opengl_prefix="")
|
||||
AC_ARG_WITH(opengl-libraries,[ --with-opengl-libraries=DIR Directory where OpenGL library is installed (optional)], opengl_libraries="$withval", opengl_libraries="")
|
||||
AC_ARG_WITH(opengl-includes,[ --with-opengl-includes=DIR Directory where OpenGL header files are installed (optional)], opengl_includes="$withval", opengl_includes="")
|
||||
AC_ARG_ENABLE(opengltest, [ --disable-opengltest Do not try to compile and run a test OpenGL program],, enable_opengltest=yes)
|
||||
|
||||
if test "x$opengl_libraries" != "x" ; then
|
||||
OPENGL_LIBS="-L$opengl_libraries"
|
||||
elif test "x$opengl_prefix" != "x" ; then
|
||||
OPENGL_LIBS="-L$opengl_prefix/lib"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OPENGL_LIBS="-L$libdir"
|
||||
fi
|
||||
|
||||
OPENGL_LIBS="$OPENGL_LIBS -lGL -lGLU"
|
||||
|
||||
if test "x$opengl_includes" != "x" ; then
|
||||
OPENGL_CFLAGS="-I$opengl_includes"
|
||||
elif test "x$opengl_prefix" != "x" ; then
|
||||
OPENGL_CFLAGS="-I$opengl_prefix/include"
|
||||
elif test "x$prefix" != "xNONE"; then
|
||||
OPENGL_CFLAGS=""
|
||||
fi
|
||||
|
||||
|
||||
no_opengl=""
|
||||
|
||||
|
||||
if test "x$enable_opengltest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $OPENGL_CFLAGS"
|
||||
LIBS="$LIBS $OPENGL_LIBS"
|
||||
|
||||
AC_CHECK_LIB(GL, glPushMatrix,
|
||||
[AC_CHECK_HEADER(GL/gl.h,
|
||||
[AC_CHECK_LIB(GLU, gluPerspective,
|
||||
[AC_CHECK_HEADER(GL/glu.h, ,
|
||||
dnl NOTE: this is a failure
|
||||
no_opengl=yes
|
||||
)]
|
||||
)]
|
||||
)]
|
||||
)
|
||||
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_opengl" = "x" ; then
|
||||
ifelse([$1], , :, [$1])
|
||||
else
|
||||
OPENGL_CFLAGS=""
|
||||
OPENGL_LIBS=""
|
||||
ifelse([$2], , :, [$2])
|
||||
fi
|
||||
AC_SUBST(OPENGL_CFLAGS)
|
||||
AC_SUBST(OPENGL_LIBS)
|
||||
])
|
||||
@@ -1,40 +0,0 @@
|
||||
version: 1.0.0.{build}
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
clone_depth: 10
|
||||
environment:
|
||||
matrix:
|
||||
- VS_VERSION: 12
|
||||
CMAKE_GENERATOR: Visual Studio 12 2013
|
||||
PlatformToolset: v120_xp
|
||||
- VS_VERSION: 14
|
||||
CMAKE_GENERATOR: Visual Studio 14 2015
|
||||
PlatformToolset: v140_xp
|
||||
before_build:
|
||||
- git submodule update --init --recursive
|
||||
- ps: . $Env:APPVEYOR_BUILD_FOLDER/ci/appveyor/check_release.ps1
|
||||
- ps: . $Env:APPVEYOR_BUILD_FOLDER/ci/appveyor/before_build.ps1
|
||||
build_script:
|
||||
- ps: . $Env:APPVEYOR_BUILD_FOLDER/ci/appveyor/build.ps1
|
||||
|
||||
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
auth_token:
|
||||
secure: 3kV4efHXwRnfXzmJPRAOs8D7+MhwXUXYeayI/P5y114L09kJa6b6L70beXdW7yYr
|
||||
on:
|
||||
ReleaseBuild: true # deploy on release push only
|
||||
|
||||
- provider: BinTray
|
||||
username: sirknightly
|
||||
api_key:
|
||||
secure: pYWqfiZhIWvFYdjVWPXNaHobmnkXIWa4+LwoiyMTEiu4Z0CiCAW0ZrMfTKVkORKz
|
||||
subject: scp-fs2open
|
||||
repo: FSO
|
||||
package: nightly
|
||||
version: $(VersionName)
|
||||
publish: true
|
||||
override: true
|
||||
on:
|
||||
NightlyBuild: true # deploy on nightly push only
|
||||
Executable
+139
@@ -0,0 +1,139 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
PKG_NAME="fs2_open"
|
||||
|
||||
# check the version of a package
|
||||
check_version() {
|
||||
COMMAND=$1
|
||||
MAJOR=$2
|
||||
MINOR=$3
|
||||
MICRO=$4
|
||||
|
||||
($COMMAND --version) </dev/null >/dev/null 2>&1 || return 1
|
||||
|
||||
ver=`$COMMAND --version|head -n 1|sed 's/^.*) //'|sed 's/ (.*)//'`
|
||||
major=`echo $ver | cut -d. -f1 | sed s/[a-zA-Z\-].*//g`
|
||||
minor=`echo $ver | cut -d. -f2 | sed s/[a-zA-Z\-].*//g`
|
||||
micro=`echo $ver | cut -d. -f3 | sed s/[a-zA-Z\-].*//g`
|
||||
test -z "$major" && major=0
|
||||
test -z "$minor" && minor=0
|
||||
test -z "$micro" && micro=0
|
||||
|
||||
fail=0
|
||||
if [ ! "$major" -gt "$MAJOR" ]; then
|
||||
if [ "$major" -lt "$MAJOR" ]; then
|
||||
fail=1
|
||||
elif [ ! "$minor" -gt "$MINOR" ]; then
|
||||
if [ "$minor" -lt "$MINOR" ]; then
|
||||
fail=1
|
||||
elif [ "$micro" -lt "$MICRO" ]; then
|
||||
fail=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
return "$fail"
|
||||
}
|
||||
|
||||
AUTOMAKE=
|
||||
ACLOCAL=
|
||||
DIE=0
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`autoconf' installed to."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
for AM in automake-1.11 automake-1.10 automake-1.9 automake-1.8 automake-1.7 automake-1.6 automake; do
|
||||
(check_version "$AM" 1 6 1) && {
|
||||
AUTOMAKE="$AM"
|
||||
break
|
||||
}
|
||||
done
|
||||
|
||||
if [ -z "$AUTOMAKE" ]; then
|
||||
echo
|
||||
echo "**Error**: You must have \`automake' version 1.6.1 or greater"
|
||||
echo "installed to compile $PKG_NAME. Download the appropriate package"
|
||||
echo "for your distribution, or get the source tarball at"
|
||||
echo "ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
fi
|
||||
|
||||
# if no automake, don't bother testing for aclocal
|
||||
test -z "$AUTOMAKE" || {
|
||||
for ACL in aclocal-1.11 aclocal-1.10 aclocal-1.9 aclocal-1.8 aclocal-1.7 aclocal-1.6 aclocal; do
|
||||
(check_version "$ACL" 1 6 1) && {
|
||||
ACLOCAL="$ACL"
|
||||
break
|
||||
}
|
||||
done
|
||||
|
||||
if [ -z "$ACLOCAL" ]; then
|
||||
echo
|
||||
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
|
||||
echo "installed seems to be outdated. Get a recent package from"
|
||||
echo "ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
fi
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$*"; then
|
||||
echo "**Warning**: I am going to run \`configure' with no arguments."
|
||||
echo "If you wish to pass any to it, please specify them on the"
|
||||
echo \`$0\'" command line."
|
||||
echo
|
||||
fi
|
||||
|
||||
case $CC in
|
||||
xlc )
|
||||
am_opt=--include-deps;;
|
||||
esac
|
||||
|
||||
for coin in `find $srcdir -name configure.ac -print`
|
||||
do
|
||||
dr=`dirname $coin`
|
||||
if test -f $dr/NO-AUTO-GEN; then
|
||||
echo skipping $dr -- flagged as no auto-gen
|
||||
else
|
||||
echo processing $dr
|
||||
macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
|
||||
( cd $dr
|
||||
aclocalinclude="$ACLOCAL_FLAGS"
|
||||
for k in $macrodirs; do
|
||||
if test -d $k; then
|
||||
aclocalinclude="$aclocalinclude -I $k"
|
||||
##else
|
||||
## echo "**Warning**: No such directory \`$k'. Ignored."
|
||||
fi
|
||||
done
|
||||
echo "Running $ACLOCAL $aclocalinclude ..."
|
||||
"$ACLOCAL" $aclocalinclude
|
||||
echo "Running $AUTOMAKE --add-missing --copy --foreign $am_opt ..."
|
||||
"$AUTOMAKE" --add-missing --copy --foreign $am_opt
|
||||
echo "Running autoconf..."
|
||||
autoconf
|
||||
)
|
||||
fi
|
||||
done
|
||||
|
||||
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
|
||||
|
||||
# to not run configure, call autogen.sh as,
|
||||
# NOCONFIGURE=1 ./autogen.sh
|
||||
if test x$NOCONFIGURE = x; then
|
||||
echo Running $srcdir/configure $conf_flags "$@" ...
|
||||
$srcdir/configure $conf_flags "$@" \
|
||||
&& echo Now type \`make\' to compile $PKG_NAME.
|
||||
else
|
||||
echo Skipping configure process.
|
||||
fi
|
||||
@@ -1,5 +0,0 @@
|
||||
New-Item build -type directory
|
||||
Set-Location -Path build
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$env:APPVEYOR_BUILD_FOLDER/../install" -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" `
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS=SSE2 -G "$Env:CMAKE_GENERATOR" -T "$Env:PlatformToolset" ..
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
write "$env:DeployBuild"
|
||||
write "$env:DeployConfig"
|
||||
|
||||
if ([System.Convert]::ToBoolean($env:DeployBuild)) {
|
||||
# Release build
|
||||
if (![System.Convert]::ToBoolean($env:DeployConfig)) {
|
||||
exit 0 # End the build
|
||||
}
|
||||
|
||||
$Configs = @("Release", "FastDebug")
|
||||
foreach ($config in $Configs) {
|
||||
cmake --build . --config "$config" --target INSTALL -- /verbosity:minimal
|
||||
if (! ($?)) {
|
||||
Add-AppveyorMessage "A release build failed!"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
7z a "$($env:PackageName)-builds-Win32.zip" "$env:APPVEYOR_BUILD_FOLDER/../install/*"
|
||||
Push-AppveyorArtifact "$($env:PackageName)-builds-Win32.zip"
|
||||
} else {
|
||||
cmake --build . --config "$Env:CONFIGURATION" -- /verbosity:minimal
|
||||
|
||||
if (! ($?)) {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
# Default values
|
||||
Set-AppveyorBuildVariable 'ReleaseBuild' 'false'
|
||||
Set-AppveyorBuildVariable 'NightlyBuild' 'false'
|
||||
Set-AppveyorBuildVariable 'DeployBuild' 'false'
|
||||
Set-AppveyorBuildVariable 'PackagePrefix' ''
|
||||
Set-AppveyorBuildVariable 'VersionName' ''
|
||||
|
||||
if ([System.Convert]::ToBoolean($env:APPVEYOR_REPO_TAG) -And ("$env:APPVEYOR_REPO_TAG_NAME" -match "^release_(.*)")) {
|
||||
# Tag matches
|
||||
Set-AppveyorBuildVariable 'ReleaseBuild' 'true'
|
||||
Set-AppveyorBuildVariable 'PackageName' "fs2_open_$($matches[1])"
|
||||
}
|
||||
|
||||
if ([System.Convert]::ToBoolean($env:APPVEYOR_REPO_TAG) -And ("$env:APPVEYOR_REPO_TAG_NAME" -match "^nightly_(.*)")) {
|
||||
# Tag matches
|
||||
Set-AppveyorBuildVariable 'NightlyBuild' 'true'
|
||||
Set-AppveyorBuildVariable 'PackageName' "nightly_$($matches[1])"
|
||||
Set-AppveyorBuildVariable 'VersionName' "$($matches[1])"
|
||||
}
|
||||
|
||||
if (($Env:Configuration -eq "Release") -And ($Env:VS_VERSION -eq "14")) {
|
||||
Set-AppveyorBuildVariable 'DeployConfig' 'true'
|
||||
} else {
|
||||
Set-AppveyorBuildVariable 'DeployConfig' 'false'
|
||||
}
|
||||
|
||||
if ([System.Convert]::ToBoolean($env:ReleaseBuild) -Or [System.Convert]::ToBoolean($env:NightlyBuild)) {
|
||||
Set-AppveyorBuildVariable 'DeployBuild' 'true'
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"package": {
|
||||
"subject": "scp-fs2open",
|
||||
"repo": "FSO",
|
||||
"name": "nightly"
|
||||
},
|
||||
|
||||
"version": {
|
||||
"name": "$VERSION_NAME"
|
||||
},
|
||||
|
||||
"files": [
|
||||
{
|
||||
"includePattern": "/tmp/builds/(.*)",
|
||||
"uploadPattern": "$1"
|
||||
}
|
||||
],
|
||||
"publish": true
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
|
||||
if [ "$NIGHTLY_BUILD" = true ]; then
|
||||
echo "Generating bintray config..."
|
||||
sed -e "s/\$VERSION_NAME/$VERSION_NAME/" ci/bintray.template.json > ci/bintray.json
|
||||
fi
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
fi
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
export CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON"
|
||||
if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
mkdir -p $config
|
||||
cd $config
|
||||
eval $CMAKE -DFSO_INSTALL_DEBUG_FILES=ON -DCMAKE_BUILD_TYPE=$config -DCMAKE_INSTALL_PREFIX="/tmp/release" \
|
||||
-DFSO_BUILD_APPIMAGE=ON -DAPPIMAGE_ASSISTANT="$HOME/AppImageAssistant" \
|
||||
-DFSO_BUILD_INCLUDED_LIBS=ON ../..
|
||||
cd ..
|
||||
done
|
||||
else
|
||||
eval $CMAKE -DCMAKE_BUILD_TYPE=$CONFIGURATION -DFSO_BUILD_TESTS=ON ..
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
cmake -G "Xcode" -DFSO_FATAL_WARNINGS=ON -DFSO_INSTALL_DEBUG_FILES=ON -DCMAKE_INSTALL_PREFIX="/tmp/release" ..
|
||||
else
|
||||
cmake -G "Xcode" ..
|
||||
fi
|
||||
fi
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
RELEASE_BUILD=false
|
||||
NIGHTLY_BUILD=false
|
||||
BUILD_DEPLOYMENT=false
|
||||
BUILD_CONFIGS="Release FastDebug"
|
||||
VERSION_NAME=""
|
||||
PACKAGE_NAME=""
|
||||
|
||||
RELEASE_PATTERN="^release_(.*)$"
|
||||
NIGHTLY_PATTERN="^nightly_(.*)$"
|
||||
|
||||
if [[ "$TRAVIS_TAG" =~ $RELEASE_PATTERN ]]; then
|
||||
echo "This is a release tag!";
|
||||
RELEASE_BUILD=true;
|
||||
PACKAGE_NAME="fs2_open_${BASH_REMATCH[1]}";
|
||||
fi
|
||||
if [[ "$TRAVIS_TAG" =~ $NIGHTLY_PATTERN ]]; then
|
||||
echo "This is a nightly tag!";
|
||||
NIGHTLY_BUILD=true;
|
||||
VERSION_NAME="${BASH_REMATCH[1]}"
|
||||
PACKAGE_NAME="nightly_${BASH_REMATCH[1]}";
|
||||
fi
|
||||
|
||||
if ([ "$RELEASE_BUILD" = true ] || [ "$NIGHTLY_BUILD" = true ]); then
|
||||
BUILD_DEPLOYMENT=true;
|
||||
fi
|
||||
|
||||
if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
if ([ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CC" = "clang" ]); then
|
||||
echo "Skipping non-release compiler";
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
if ([[ "$CONFIGURATION" == "Debug" ]]); then
|
||||
echo "Skipping non-release configuration";
|
||||
exit 0;
|
||||
fi
|
||||
fi
|
||||
|
||||
export RELEASE_BUILD
|
||||
export NIGHTLY_BUILD
|
||||
export BUILD_DEPLOYMENT
|
||||
export BUILD_CONFIGS
|
||||
export VERSION_NAME
|
||||
export PACKAGE_NAME
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
|
||||
FILENAME=
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
if [ ! -d "$HOME/cmake/bin" ]; then
|
||||
# If the cache does not currently contain CMake then download and install it
|
||||
FILENAME=cmake-3.4.3-Linux-x86_64
|
||||
|
||||
mkdir -p $HOME/cmake/
|
||||
|
||||
wget -O /tmp/cmake.tar.gz --no-check-certificate https://www.cmake.org/files/v3.4/$FILENAME.tar.gz
|
||||
tar -xzf /tmp/cmake.tar.gz -C $HOME/cmake/ --strip-components=1
|
||||
fi
|
||||
export PATH=$HOME/cmake/bin:$PATH
|
||||
|
||||
cd $HOME
|
||||
|
||||
if [ "${BUILD_DEPLOYMENT}" = true ]; then
|
||||
wget -c "https://github.com/probonopd/AppImageKit/releases/download/5/AppImageAssistant" # (64-bit)
|
||||
chmod a+x ./AppImageAssistant
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
gem install xcpretty xcpretty-travis-formatter thefox-pastebin
|
||||
|
||||
brew update
|
||||
brew outdated cmake || brew upgrade cmake
|
||||
fi
|
||||
|
||||
cmake --version
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
mkdir -p /tmp/builds
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
cd build
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
cd "$config"
|
||||
ninja install appimage
|
||||
cd ..
|
||||
done
|
||||
|
||||
ls -al /tmp/release
|
||||
(cd /tmp/release && tar -cvzf /tmp/builds/$PACKAGE_NAME-builds-Linux.tar.gz *.AppImage)
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
cd build
|
||||
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
cmake --build . --config "$config" --target install | tee build.log \
|
||||
| xcpretty -f `xcpretty-travis-formatter`
|
||||
XCODE_RET=${PIPESTATUS[0]}
|
||||
if [ "$XCODE_RET" -ne "0" ]; then
|
||||
tar -cvzf build.log.tar.gz build.log
|
||||
curl --upload-file build.log.tar.gz "https://transfer.sh/build.log.tar.gz"
|
||||
exit $XCODE_RET
|
||||
fi
|
||||
done
|
||||
|
||||
ls -al /tmp/release
|
||||
|
||||
(cd /tmp/release && tar -cvzf /tmp/builds/$PACKAGE_NAME-builds-MacOSX.tar.gz *)
|
||||
fi
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
cd build
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
ninja all
|
||||
|
||||
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
|
||||
--suppressions="$TRAVIS_BUILD_DIR/ci/travis/valgrind.supp" ./bin/unittests
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
cmake --build . --config "$CONFIGURATION" | tee build.log | xcpretty -f `xcpretty-travis-formatter`
|
||||
XCODE_RET=${PIPESTATUS[0]}
|
||||
if [ "$XCODE_RET" -ne "0" ]; then
|
||||
tar -cvzf build.log.tar.gz build.log
|
||||
curl --upload-file build.log.tar.gz "https://transfer.sh/build.log.tar.gz"
|
||||
exit $XCODE_RET
|
||||
fi
|
||||
fi
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
liblsan Invalid read
|
||||
Memcheck:Addr8
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
}
|
||||
{
|
||||
Travis memleak
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:_dl_signal_error
|
||||
fun:_dl_open
|
||||
fun:dlopen_doit
|
||||
fun:_dl_catch_error
|
||||
fun:_dlerror_run
|
||||
fun:dlopen@@GLIBC_2.2.5
|
||||
obj:/usr/lib/x86_64-linux-gnu/libmirclient.so.7
|
||||
fun:call_init.part.0
|
||||
fun:call_init
|
||||
fun:_dl_init
|
||||
fun:dl_open_worker
|
||||
fun:_dl_catch_error
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=FreeSpace Open
|
||||
Exec=$<TARGET_FILE_NAME:Freespace2>
|
||||
Icon=app_icon.png
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
HERE=$(dirname $(readlink -f "${0}"))
|
||||
export LD_LIBRARY_PATH="${HERE}"/lib:$PATH
|
||||
"${HERE}"/bin/$<TARGET_FILE_NAME:Freespace2> $@
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
set(REQUIRED_CXX_FEATURES cxx_rvalue_references cxx_nullptr)
|
||||
|
||||
get_property(CMAKE_CXX_KNOWN_FEATURES GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${GENERATED_SOURCE_DIR}/scp_compiler_detection.h"
|
||||
PREFIX SCP
|
||||
COMPILERS AppleClang Clang GNU MSVC
|
||||
FEATURES ${CMAKE_CXX_KNOWN_FEATURES}
|
||||
VERSION 3.2
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
SET(BINARY_DESTINATION "bin")
|
||||
SET(LIBRAY_DESTINATION "lib")
|
||||
|
||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/AppRun.in" "${CMAKE_CURRENT_BINARY_DIR}/AppRun.gen" @ONLY)
|
||||
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>"
|
||||
INPUT "${CMAKE_CURRENT_BINARY_DIR}/AppRun.gen")
|
||||
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>" DESTINATION "." RENAME "AppRun")
|
||||
|
||||
|
||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/AppImage.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/AppImage.desktop.gen" @ONLY)
|
||||
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop"
|
||||
INPUT "${CMAKE_CURRENT_BINARY_DIR}/AppImage.desktop.gen")
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop" DESTINATION "." RENAME "fso.desktop")
|
||||
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/freespace2/resources/app_icon.png" DESTINATION ".")
|
||||
|
||||
add_custom_target(appimage
|
||||
COMMAND "${APPIMAGE_ASSISTANT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/fs2_open_${FSO_BINARY_SUFFIX}.AppImage")
|
||||
|
||||
add_dependencies(appimage install)
|
||||
@@ -1,52 +0,0 @@
|
||||
// Code snippet from http://stackoverflow.com/a/7495023
|
||||
#ifdef _WIN32
|
||||
#include <intrin.h>
|
||||
// Windows
|
||||
#define cpuid __cpuid
|
||||
|
||||
#else
|
||||
|
||||
// GCC Inline Assembly
|
||||
void cpuid(int CPUInfo[4],int InfoType){
|
||||
__asm__ __volatile__ (
|
||||
"cpuid":
|
||||
"=a" (CPUInfo[0]),
|
||||
"=b" (CPUInfo[1]),
|
||||
"=c" (CPUInfo[2]),
|
||||
"=d" (CPUInfo[3]) :
|
||||
"a" (InfoType)
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int SSE = false;
|
||||
int SSE2 = false;
|
||||
int AVX = false;
|
||||
|
||||
int info[4];
|
||||
cpuid(info, 0);
|
||||
int nIds = info[0];
|
||||
|
||||
// Detect Instruction Set
|
||||
if (nIds >= 1){
|
||||
cpuid(info,0x00000001);
|
||||
SSE = (info[3] & ((int)1 << 25)) != 0;
|
||||
SSE2 = (info[3] & ((int)1 << 26)) != 0;
|
||||
|
||||
AVX = (info[2] & ((int)1 << 28)) != 0;
|
||||
}
|
||||
|
||||
if(AVX)
|
||||
std::cout << "AVX";
|
||||
else if(SSE2)
|
||||
std::cout << "SSE2";
|
||||
else if(SSE)
|
||||
std::cout << "SSE";
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
# ------------------------- Begin Generic CMake Variable Logging ------------------
|
||||
|
||||
# /* C++ comment style not allowed */
|
||||
|
||||
|
||||
# if you are building in-source, this is the same as CMAKE_SOURCE_DIR, otherwise
|
||||
# this is the top level directory of your build tree
|
||||
MESSAGE( STATUS "CMAKE_BINARY_DIR: " ${CMAKE_BINARY_DIR} )
|
||||
|
||||
# if you are building in-source, this is the same as CMAKE_CURRENT_SOURCE_DIR, otherwise this
|
||||
# is the directory where the compiled or generated files from the current CMakeLists.txt will go to
|
||||
MESSAGE( STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
|
||||
# this is the directory, from which cmake was started, i.e. the top level source directory
|
||||
MESSAGE( STATUS "CMAKE_SOURCE_DIR: " ${CMAKE_SOURCE_DIR} )
|
||||
|
||||
# this is the directory where the currently processed CMakeLists.txt is located in
|
||||
MESSAGE( STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
|
||||
# contains the full path to the top level directory of your build tree
|
||||
MESSAGE( STATUS "PROJECT_BINARY_DIR: " ${PROJECT_BINARY_DIR} )
|
||||
|
||||
MESSAGE( STATUS "CMAKE_CXX_COMPILER_ID: " ${CMAKE_CXX_COMPILER_ID} )
|
||||
|
||||
# contains the full path to the root of your project source directory,
|
||||
# i.e. to the nearest directory where CMakeLists.txt contains the PROJECT() command
|
||||
MESSAGE( STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR} )
|
||||
|
||||
# set this variable to specify a common place where CMake should put all executable files
|
||||
# (instead of CMAKE_CURRENT_BINARY_DIR)
|
||||
MESSAGE( STATUS "EXECUTABLE_OUTPUT_PATH: " ${EXECUTABLE_OUTPUT_PATH} )
|
||||
|
||||
# set this variable to specify a common place where CMake should put all libraries
|
||||
# (instead of CMAKE_CURRENT_BINARY_DIR)
|
||||
MESSAGE( STATUS "LIBRARY_OUTPUT_PATH: " ${LIBRARY_OUTPUT_PATH} )
|
||||
|
||||
# tell CMake to search first in directories listed in CMAKE_MODULE_PATH
|
||||
# when you use FIND_PACKAGE() or INCLUDE()
|
||||
MESSAGE( STATUS "CMAKE_MODULE_PATH: " ${CMAKE_MODULE_PATH} )
|
||||
|
||||
# this is the complete path of the cmake which runs currently (e.g. /usr/local/bin/cmake)
|
||||
MESSAGE( STATUS "CMAKE_COMMAND: " ${CMAKE_COMMAND} )
|
||||
|
||||
# this is the CMake installation directory
|
||||
MESSAGE( STATUS "CMAKE_ROOT: " ${CMAKE_ROOT} )
|
||||
|
||||
# this is the filename including the complete path of the file where this variable is used.
|
||||
MESSAGE( STATUS "CMAKE_CURRENT_LIST_FILE: " ${CMAKE_CURRENT_LIST_FILE} )
|
||||
|
||||
# this is linenumber where the variable is used
|
||||
MESSAGE( STATUS "CMAKE_CURRENT_LIST_LINE: " ${CMAKE_CURRENT_LIST_LINE} )
|
||||
|
||||
# this is used when searching for include files e.g. using the FIND_PATH() command.
|
||||
MESSAGE( STATUS "CMAKE_INCLUDE_PATH: " ${CMAKE_INCLUDE_PATH} )
|
||||
|
||||
# this is used when searching for libraries e.g. using the FIND_LIBRARY() command.
|
||||
MESSAGE( STATUS "CMAKE_LIBRARY_PATH: " ${CMAKE_LIBRARY_PATH} )
|
||||
|
||||
# the complete system name, e.g. "Linux-2.4.22", "FreeBSD-5.4-RELEASE" or "Windows 5.1"
|
||||
MESSAGE( STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM} )
|
||||
|
||||
# the short system name, e.g. "Linux", "FreeBSD" or "Windows"
|
||||
MESSAGE( STATUS "CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME} )
|
||||
|
||||
# only the version part of CMAKE_SYSTEM
|
||||
MESSAGE( STATUS "CMAKE_SYSTEM_VERSION: " ${CMAKE_SYSTEM_VERSION} )
|
||||
|
||||
# the processor name (e.g. "Intel(R) Pentium(R) M processor 2.00GHz")
|
||||
MESSAGE( STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR} )
|
||||
|
||||
# is TRUE on all UNIX-like OS's, including Apple OS X and CygWin
|
||||
MESSAGE( STATUS "UNIX: " ${UNIX} )
|
||||
|
||||
# is TRUE on Windows, including CygWin
|
||||
MESSAGE( STATUS "WIN32: " ${WIN32} )
|
||||
|
||||
# is TRUE on Apple OS X
|
||||
MESSAGE( STATUS "APPLE: " ${APPLE} )
|
||||
|
||||
# is TRUE when using the MinGW compiler in Windows
|
||||
MESSAGE( STATUS "MINGW: " ${MINGW} )
|
||||
|
||||
# is TRUE on Windows when using the CygWin version of cmake
|
||||
MESSAGE( STATUS "CYGWIN: " ${CYGWIN} )
|
||||
|
||||
# is TRUE on Windows when using a Borland compiler
|
||||
MESSAGE( STATUS "BORLAND: " ${BORLAND} )
|
||||
|
||||
# Microsoft compiler
|
||||
MESSAGE( STATUS "MSVC: " ${MSVC} )
|
||||
MESSAGE( STATUS "MSVC_IDE: " ${MSVC_IDE} )
|
||||
MESSAGE( STATUS "MSVC60: " ${MSVC60} )
|
||||
MESSAGE( STATUS "MSVC70: " ${MSVC70} )
|
||||
MESSAGE( STATUS "MSVC71: " ${MSVC71} )
|
||||
MESSAGE( STATUS "MSVC80: " ${MSVC80} )
|
||||
MESSAGE( STATUS "CMAKE_COMPILER_2005: " ${CMAKE_COMPILER_2005} )
|
||||
|
||||
|
||||
# set this to true if you don't want to rebuild the object files if the rules have changed,
|
||||
# but not the actual source files or headers (e.g. if you changed the some compiler switches)
|
||||
MESSAGE( STATUS "CMAKE_SKIP_RULE_DEPENDENCY: " ${CMAKE_SKIP_RULE_DEPENDENCY} )
|
||||
|
||||
# since CMake 2.1 the install rule depends on all, i.e. everything will be built before installing.
|
||||
# If you don't like this, set this one to true.
|
||||
MESSAGE( STATUS "CMAKE_SKIP_INSTALL_ALL_DEPENDENCY: " ${CMAKE_SKIP_INSTALL_ALL_DEPENDENCY} )
|
||||
|
||||
# If set, runtime paths are not added when using shared libraries. Default it is set to OFF
|
||||
MESSAGE( STATUS "CMAKE_SKIP_RPATH: " ${CMAKE_SKIP_RPATH} )
|
||||
|
||||
# set this to true if you are using makefiles and want to see the full compile and link
|
||||
# commands instead of only the shortened ones
|
||||
MESSAGE( STATUS "CMAKE_VERBOSE_MAKEFILE: " ${CMAKE_VERBOSE_MAKEFILE} )
|
||||
|
||||
# this will cause CMake to not put in the rules that re-run CMake. This might be useful if
|
||||
# you want to use the generated build files on another machine.
|
||||
MESSAGE( STATUS "CMAKE_SUPPRESS_REGENERATION: " ${CMAKE_SUPPRESS_REGENERATION} )
|
||||
|
||||
|
||||
# A simple way to get switches to the compiler is to use ADD_DEFINITIONS().
|
||||
# But there are also two variables exactly for this purpose:
|
||||
|
||||
# the compiler flags for compiling C sources
|
||||
MESSAGE( STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS} )
|
||||
|
||||
# the compiler flags for compiling C++ sources
|
||||
MESSAGE( STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS} )
|
||||
|
||||
|
||||
# Choose the type of build. Example: SET(CMAKE_BUILD_TYPE Debug)
|
||||
MESSAGE( STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} )
|
||||
|
||||
# if this is set to ON, then all libraries are built as shared libraries by default.
|
||||
MESSAGE( STATUS "BUILD_SHARED_LIBS: " ${BUILD_SHARED_LIBS} )
|
||||
|
||||
# the compiler used for C files
|
||||
MESSAGE( STATUS "CMAKE_C_COMPILER: " ${CMAKE_C_COMPILER} )
|
||||
|
||||
# the compiler used for C++ files
|
||||
MESSAGE( STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER} )
|
||||
|
||||
# if the compiler is a variant of gcc, this should be set to 1
|
||||
MESSAGE( STATUS "CMAKE_COMPILER_IS_GNUCC: " ${CMAKE_COMPILER_IS_GNUCC} )
|
||||
|
||||
# if the compiler is a variant of g++, this should be set to 1
|
||||
MESSAGE( STATUS "CMAKE_COMPILER_IS_GNUCXX : " ${CMAKE_COMPILER_IS_GNUCXX} )
|
||||
|
||||
# the tools for creating libraries
|
||||
MESSAGE( STATUS "CMAKE_AR: " ${CMAKE_AR} )
|
||||
MESSAGE( STATUS "CMAKE_RANLIB: " ${CMAKE_RANLIB} )
|
||||
|
||||
#
|
||||
#MESSAGE( STATUS ": " ${} )
|
||||
|
||||
# ------------------------- End of Generic CMake Variable Logging ------------------
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
# add a target to generate API documentation with Doxygen
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
SET(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/documentation/doxygen")
|
||||
FILE(MAKE_DIRECTORY "${OUTPUT_DIR}")
|
||||
|
||||
FILE(TO_NATIVE_PATH ${OUTPUT_DIR} OUTPUT_DIR)
|
||||
SET(OUTPUT_DIR \"${OUTPUT_DIR}\")
|
||||
|
||||
SET(INPUTS "${CMAKE_CURRENT_SOURCE_DIR}/code" "${CMAKE_CURRENT_SOURCE_DIR}/freespace2" "${CMAKE_CURRENT_SOURCE_DIR}/fred2" "${CMAKE_CURRENT_SOURCE_DIR}/wxfred2")
|
||||
|
||||
SET(INPUT_DIRS)
|
||||
FOREACH(DIR IN LISTS INPUTS)
|
||||
FILE(TO_NATIVE_PATH ${DIR} native_dir)
|
||||
|
||||
LIST(APPEND INPUT_DIRS \"${native_dir}\")
|
||||
ENDFOREACH(DIR)
|
||||
STRING(REPLACE ";" " " INPUT_DIRS "${INPUT_DIRS}")
|
||||
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/fs2open.Doxyfile.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/fs2open.Doxyfile
|
||||
@ONLY)
|
||||
|
||||
add_custom_target(doxygen
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/fs2open.Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen" VERBATIM
|
||||
)
|
||||
|
||||
set_target_properties(doxygen
|
||||
PROPERTIES
|
||||
FOLDER "Documentation"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
EXCLUDE_FROM_DEFAULT_BUILD ON
|
||||
)
|
||||
endif(DOXYGEN_FOUND)
|
||||
Vendored
-1
Submodule cmake/external/cotire deleted from 40a46bf2fb.
Vendored
-1
Submodule cmake/external/rpavlik-cmake-modules deleted from 7cef9577d6.
@@ -1,33 +0,0 @@
|
||||
|
||||
add_library(speech INTERFACE)
|
||||
|
||||
if (WIN32)
|
||||
find_package(WindowsSDK REQUIRED)
|
||||
|
||||
foreach(dir ${WINDOWSSDK_DIRS})
|
||||
get_windowssdk_library_dirs("${dir}" LIB_DIRS)
|
||||
|
||||
find_library(SPEECH_LIBRARY
|
||||
NAMES sapi
|
||||
PATHS ${LIB_DIRS}
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
if (SPEECH_LIBRARY)
|
||||
set(SDK_DIR "${dir}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (NOT SPEECH_LIBRARY)
|
||||
message(SEND_ERROR "Text to speech library could not be found! Either install it or disable the speech option.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_windowssdk_include_dirs("${SDK_DIR}" INCLUDE_DIRS)
|
||||
|
||||
target_include_directories(speech INTERFACE ${INCLUDE_DIRS})
|
||||
else()
|
||||
message(SEND_ERROR "Text to Speech is not supported on this platform!")
|
||||
endif()
|
||||
|
||||
target_compile_definitions(speech INTERFACE -DFS2_SPEECH)
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
include(platformChecks)
|
||||
include(Cxx11)
|
||||
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_LIST_DIR}/project.h.in ${GENERATED_SOURCE_DIR}/project.h)
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
SET(BINARY_DESTINATION ".")
|
||||
SET(LIBRAY_DESTINATION "${BINARY_DESTINATION}")
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(IS_64BIT TRUE)
|
||||
else()
|
||||
set(IS_64BIT FALSE)
|
||||
endif()
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
SET(CODE_HEADERS ${CMAKE_SOURCE_DIR}/code)
|
||||
|
||||
SET(FREESPACE_HEADERS ${CMAKE_SOURCE_DIR}/freespace2)
|
||||
|
||||
SET(FRED_HEADERS ${CMAKE_SOURCE_DIR}/fred2)
|
||||
|
||||
SET(WXFRED_HEADERS ${CMAKE_SOURCE_DIR}/wxfred2)
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${FSO_VERSION_MAJOR})
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR ${FSO_VERSION_MINOR})
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH ${FSO_VERSION_BUILD})
|
||||
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${FSO_PROJECT_DESCRIPTION})
|
||||
|
||||
IF(WIN32)
|
||||
SET(CPACK_NSIS_MUI_ICON ${FSO_INSTALLER_ICON})
|
||||
|
||||
set(CPACK_NSIS_MENU_LINKS "http://www.hard-light.net/" "FreeSpace Community")
|
||||
ENDIF(WIN32)
|
||||
|
||||
include(CPack)
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
MESSAGE(STATUS "Doing Mac OSX specific things...")
|
||||
SET(EXE_GUI_TYPE MACOSX_BUNDLE)
|
||||
|
||||
FIND_LIBRARY(COCOA_LIBRARY Cocoa)
|
||||
|
||||
if (NOT COCOA_LIBRARY)
|
||||
message(FATAL_ERROR "Couldn't find Cocoa!")
|
||||
endif()
|
||||
|
||||
target_link_libraries(platform INTERFACE ${COCOA_LIBRARY})
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
target_compile_definitions(platform INTERFACE SCP_BSD)
|
||||
|
||||
find_library(EXECINFO_LIB execinfo)
|
||||
|
||||
if (NOT EXECINFO_LIB)
|
||||
message(FATAL_ERROR "Couldn't find libexecinfo! Please install it and rerun the configuration.")
|
||||
else()
|
||||
target_link_libraries(platform INTERFACE "${EXECINFO_LIB}")
|
||||
endif()
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
target_compile_definitions(platform INTERFACE SCP_SOLARIS)
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
INCLUDE(util)
|
||||
|
||||
MESSAGE(STATUS "Configuring UNIX specific things and stuff...")
|
||||
|
||||
target_compile_definitions(platform INTERFACE SCP_UNIX USE_OPENAL)
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
MESSAGE(STATUS "Configuring Windows specific things and stuff...")
|
||||
|
||||
target_link_libraries(platform INTERFACE
|
||||
comctl32.lib
|
||||
msacm32.lib
|
||||
odbc32.lib
|
||||
odbccp32.lib
|
||||
vfw32.lib
|
||||
winmm.lib
|
||||
wsock32.lib
|
||||
Psapi.lib
|
||||
)
|
||||
|
||||
target_compile_definitions(platform INTERFACE WIN32 USE_OPENAL _WINDOWS)
|
||||
|
||||
# Specify minimum Windows version for the headers (currently this is XP)
|
||||
target_compile_definitions(platform INTERFACE NTDDI_VERSION=0x05010000 _WIN32_WINNT=0x0501)
|
||||
|
||||
SET(EXE_GUI_TYPE WIN32)
|
||||
@@ -1,26 +0,0 @@
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckIncludeFileCXX)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckPrototypeDefinition)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckTypeSize)
|
||||
|
||||
CHECK_INCLUDE_FILE("execinfo.h" HAVE_EXECINFO_H)
|
||||
CHECK_INCLUDE_FILE_CXX("cxxabi.h" HAVE_CXXAPI_H)
|
||||
|
||||
# Check if we have glu.h
|
||||
FIND_PACKAGE(OpenGL REQUIRED)
|
||||
if (APPLE)
|
||||
set(GL_INCLUDE_DIR "${OPENGL_INCLUDE_DIR}/Headers")
|
||||
else()
|
||||
set(GL_INCLUDE_DIR "${OPENGL_INCLUDE_DIR}/GL")
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES "${GL_INCLUDE_DIR}")
|
||||
CHECK_INCLUDE_FILE("glu.h" HAVE_GLU_H)
|
||||
|
||||
set(PLATFORM_CHECK_HEADER "${GENERATED_SOURCE_DIR}/platformChecks.h")
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_LIST_DIR}/platformChecks.h.in "${PLATFORM_CHECK_HEADER}")
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
#ifndef __PLATFORM_CHECKS_H__
|
||||
#define __PLATFORM_CHECKS_H__
|
||||
#pragma once
|
||||
|
||||
#cmakedefine HAVE_EXECINFO_H
|
||||
#cmakedefine HAVE_CXXAPI_H
|
||||
#cmakedefine HAVE_GLU_H
|
||||
|
||||
#cmakedefine01 IS_64BIT
|
||||
|
||||
#endif // __PLATFORM_CHECKS_H__
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
add_library(platform INTERFACE)
|
||||
|
||||
IF(FSO_CMAKE_DEBUG)
|
||||
INCLUDE(debug-vars)
|
||||
ENDIF(FSO_CMAKE_DEBUG)
|
||||
|
||||
IF(WIN32)
|
||||
INCLUDE(platform-win32)
|
||||
ELSEIF(UNIX)
|
||||
INCLUDE(platform-unix)
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
INCLUDE(platform-freebsd)
|
||||
ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
INCLUDE(platform-solaris)
|
||||
ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
include(platform-darwin)
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
ELSE(WIN32)
|
||||
MESSAGE(STATUS "This platform is not supported, good luck!")
|
||||
ENDIF(WIN32)
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
|
||||
#ifndef __PROJECT_H
|
||||
#define __PROJECT_H
|
||||
|
||||
#define FS_VERSION_MAJOR @FSO_VERSION_MAJOR@
|
||||
#define FS_VERSION_MINOR @FSO_VERSION_MINOR@
|
||||
#define FS_VERSION_BUILD @FSO_VERSION_BUILD@
|
||||
#define FS_VERSION_REVIS @FSO_VERSION_REVISION@
|
||||
#define FS_VERSION_REVIS_STR "@FSO_VERSION_REVISION_STR@"
|
||||
|
||||
#define FS_VERSION_HAS_REVIS @FSO_VERSION_HAS_REVISION@
|
||||
|
||||
#define FS_VERSION_FULL "@FSO_FULL_VERSION_STRING@"
|
||||
#define FS_PRODUCT_VERSION "@FSO_PRODUCT_VERSION_STRING@"
|
||||
|
||||
#endif // __PROJECT_H
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
MESSAGE(STATUS "Doing configuration specific to Apple Clang...")
|
||||
|
||||
# TODO: Actually add Mac specific flags here...
|
||||
|
||||
# Suppress specific warning
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -funroll-loops -fsigned-char -Wno-unknown-pragmas")
|
||||
|
||||
# Omit "conversion from string literal to 'char *' is deprecated" warnings.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-write-strings")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wno-char-subscripts")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Wno-unused-variable")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wextra -Wshadow -Wno-unused-parameter")
|
||||
@@ -1,65 +0,0 @@
|
||||
# Clang
|
||||
include(EnableExtraCompilerWarnings)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
MESSAGE(STATUS "Doing configuration specific to clang...")
|
||||
|
||||
unset(COMPILER_FLAGS)
|
||||
if(DEFINED ENV{CXXFLAGS})
|
||||
set(COMPILER_FLAGS $ENV{CXXFLAGS})
|
||||
endif()
|
||||
|
||||
if(NOT COMPILER_FLAGS)
|
||||
set(COMPILER_FLAGS "-march=native -pipe")
|
||||
endif()
|
||||
|
||||
globally_enable_extra_compiler_warnings()
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -funroll-loops -fsigned-char -Wno-unknown-pragmas")
|
||||
|
||||
# Omit "argument unused during compilation" when clang is used with ccache.
|
||||
if(${CMAKE_CXX_COMPILER} MATCHES "ccache")
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Qunused-arguments")
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Ninja")
|
||||
# Force color diagnostics for Ninja generator
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fdiagnostics-color")
|
||||
endif()
|
||||
|
||||
# Omit "deprecated conversion from string constant to 'char*'" warnings.
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-write-strings")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-function")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-deprecated -Wno-char-subscripts")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-parameter")
|
||||
|
||||
check_cxx_compiler_flag(-Wshift-negative-value SUPPORTS_SHIFT_NEGATIVE_VALUE)
|
||||
if(SUPPORTS_SHIFT_NEGATIVE_VALUE)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-shift-negative-value")
|
||||
endif()
|
||||
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable")
|
||||
|
||||
set(COMPILER_FLAGS_DEBUG "-O0 -g -Wshadow")
|
||||
|
||||
if (FSO_FATAL_WARNINGS)
|
||||
# Make warnings fatal if the right variable is set
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Werror")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS ${COMPILER_FLAGS})
|
||||
set(CMAKE_C_FLAGS ${COMPILER_FLAGS})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g -rdynamic")
|
||||
@@ -1,100 +0,0 @@
|
||||
|
||||
include(EnableExtraCompilerWarnings)
|
||||
include(CheckCCompilerFlag)
|
||||
include(util)
|
||||
|
||||
MESSAGE(STATUS "Doing configuration specific to gcc...")
|
||||
|
||||
option(GCC_ENABLE_LEAK_CHECK "Enable -fsanitize=leak" OFF)
|
||||
option(GCC_ENABLE_ADDRESS_SANITIZER "Enable -fsanitize=address" OFF)
|
||||
|
||||
unset(COMPILER_FLAGS)
|
||||
if(DEFINED ENV{CXXFLAGS})
|
||||
set(COMPILER_FLAGS $ENV{CXXFLAGS})
|
||||
endif()
|
||||
|
||||
if(NOT COMPILER_FLAGS)
|
||||
set(COMPILER_FLAGS "-march=native -pipe")
|
||||
endif()
|
||||
|
||||
globally_enable_extra_compiler_warnings()
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -funroll-loops -fsigned-char -Wno-unknown-pragmas")
|
||||
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Ninja")
|
||||
# Force color diagnostics for Ninja generator
|
||||
CHECK_C_COMPILER_FLAG(-fdiagnostics-color SUPPORTS_DIAGNOSTIC_COLOR)
|
||||
|
||||
if(SUPPORTS_DIAGNOSTIC_COLOR)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fdiagnostics-color")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Start with an empty list
|
||||
set(SANITIZE_FLAGS)
|
||||
|
||||
if(GCC_ENABLE_ADDRESS_SANITIZER)
|
||||
set(CMAKE_REQUIRED_FLAGS "-fsanitize=address")
|
||||
CHECK_C_COMPILER_FLAG("-fsanitize=address" SUPPORTS_SANITIZE_ADDRESS)
|
||||
|
||||
if (SUPPORTS_SANITIZE_ADDRESS)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fsanitize=address")
|
||||
endif()
|
||||
|
||||
set(SANITIZE_FLAGS ${SANITIZE_FLAGS} "address")
|
||||
endif()
|
||||
if (GCC_ENABLE_LEAK_CHECK)
|
||||
check_linker_flag("-fsanitize=leak" SUPPORTS_FSANITIZE_LEAK)
|
||||
|
||||
if (SUPPORTS_FSANITIZE_LEAK)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=leak")
|
||||
endif()
|
||||
|
||||
set(SANITIZE_FLAGS ${SANITIZE_FLAGS} "leak")
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" "," SANITIZE_FLAGS "${SANITIZE_FLAGS}")
|
||||
if (NOT "${SANITIZE_FLAGS}" STREQUAL "")
|
||||
set(SANITIZE_FLAGS "-fsanitize=${SANITIZE_FLAGS}")
|
||||
endif()
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
|
||||
# Omit "deprecated conversion from string constant to 'char*'" warnings.
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-write-strings")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-function")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-deprecated -Wno-char-subscripts")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-parameter")
|
||||
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered")
|
||||
|
||||
set(COMPILER_FLAGS_DEBUG "-O0 -g -Wshadow")
|
||||
|
||||
if (FSO_FATAL_WARNINGS)
|
||||
# Make warnings fatal if the right variable is set
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Werror")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS ${COMPILER_FLAGS})
|
||||
set(CMAKE_C_FLAGS ${COMPILER_FLAGS})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||
|
||||
if (SANITIZE_FLAGS)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
endif()
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g -rdynamic")
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-zignore")
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
@@ -1,142 +0,0 @@
|
||||
|
||||
include(EnableExtraCompilerWarnings)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(util)
|
||||
|
||||
MESSAGE(STATUS "Doing configuration specific to visual studio...")
|
||||
|
||||
set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS Debug)
|
||||
|
||||
option(MSVC_USE_RUNTIME_DLL "Use the dynamically linked version of the runtime" OFF)
|
||||
option(MSVC_RELEASE_DEBUGGING "Set options that allow to debug release builds" OFF)
|
||||
|
||||
MARK_AS_ADVANCED(FORCE MSVC_USE_RUNTIME_DLL)
|
||||
MARK_AS_ADVANCED(FORCE MSVC_RELEASE_DEBUGGING)
|
||||
|
||||
# These are the warnings we disable
|
||||
set(WARNING_FLAGS
|
||||
/wd4100 # unreferenced formal parameters
|
||||
/wd4127 # constant conditional (assert)
|
||||
/wd4201 # nonstandard extension used: nameless struct/union (happens a lot in Windows include headers)
|
||||
/wd4290 # C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
/wd4390 # empty control statement (triggered by nprintf and mprintf's inside of one-line if's, etc)
|
||||
/wd4410 # illegal size for operand... ie... fxch st(1)
|
||||
/wd4511 # copy constructor could not be generated (happens a lot in Windows include headers)
|
||||
/wd4512 # assignment operator could not be generated (happens a lot in Windows include headers)
|
||||
/wd4514 # unreferenced inline function removed
|
||||
/wd4611 # _setjmp warning. Since we use setjmp alot, and we don't really use constructors or destructors, this warning doesn't really apply to us.
|
||||
/wd4663 # C++ language change (template specification)
|
||||
/wd4710 # is inline function not expanded (who cares?)
|
||||
/wd4711 # tells us an inline function was expanded (who cares?)
|
||||
/wd4786 # is identifier truncated to 255 characters (happens all the time in Microsoft #includes) -- Goober5000"
|
||||
/wd4996 # deprecated strcpy, strcat, sprintf, etc. (from MSVC 2005) - taylor
|
||||
/wd4311 # Disables warnings about casting pointer types to ints. The funny thing is these warnings can't be resolved, just disabled... - m!m
|
||||
/wd4302 # Same as above - m!m
|
||||
/wd4366 # The result of the unary '&' operator may be unaligned - m!m
|
||||
$<$<CONFIG:Release>:/wd4101> # In release mode there are unreferenced variables because debug needs them
|
||||
)
|
||||
|
||||
target_compile_options(compiler INTERFACE ${WARNING_FLAGS})
|
||||
|
||||
# Base
|
||||
set(CMAKE_C_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo")
|
||||
set(CMAKE_CXX_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "/MANIFEST /DYNAMICBASE:NO /SAFESEH:NO /ERRORREPORT:PROMPT /NOLOGO")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "")
|
||||
|
||||
# Release
|
||||
set(CMAKE_C_FLAGS_RELEASE "/GL /W2 /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/GL /W2 /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/OPT:REF /LTCG /INCREMENTAL:NO")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/LTCG")
|
||||
|
||||
globally_enable_extra_compiler_warnings()
|
||||
|
||||
if (MSVC_RELEASE_DEBUGGING)
|
||||
CHECK_CXX_COMPILER_FLAG("/Zo" MSVC_COMPILER_SUPPORTS_ARCH_ZO)
|
||||
|
||||
if (MSVC_COMPILER_SUPPORTS_ARCH_ZO)
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zo")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zo")
|
||||
endif()
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG")
|
||||
endif()
|
||||
|
||||
IF(MSVC_USE_RUNTIME_DLL)
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
|
||||
ELSE(MSVC_USE_RUNTIME_DLL)
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
|
||||
ENDIF(MSVC_USE_RUNTIME_DLL)
|
||||
|
||||
# Debug
|
||||
set(CMAKE_C_FLAGS_DEBUG "/W4 /Gy /Zi /Od /RTC1 /Gd /Oy-")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "/W4 /Gy /Zi /Od /RTC1 /Gd /Oy-")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /INCREMENTAL:NO /MAPINFO:EXPORTS /NODEFAULTLIB:libcmt.lib")
|
||||
|
||||
IF(MSVC_USE_RUNTIME_DLL)
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
|
||||
ELSE(MSVC_USE_RUNTIME_DLL)
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
|
||||
ENDIF(MSVC_USE_RUNTIME_DLL)
|
||||
|
||||
INCLUDE(MSVCMultipleProcessCompile)
|
||||
|
||||
# Visual Studio supports compiling for multiple vector instruction sets
|
||||
SET(POSSIBLE_INSTUCTION_SETS "" SSE SSE2 AVX)
|
||||
|
||||
if (NOT DEFINED MSVC_SIMD_INSTRUCTIONS)
|
||||
detect_simd_instructions(MSVC_DETECTED_SIMD_INSTRUCTIONS)
|
||||
|
||||
SET(MSVC_SIMD_INSTRUCTIONS "${MSVC_DETECTED_SIMD_INSTRUCTIONS}" CACHE FILEPATH "The SIMD instructions which will be used, possible values are ${POSSIBLE_INSTUCTION_SETS}")
|
||||
MARK_AS_ADVANCED(FORCE MSVC_SIMD_INSTRUCTIONS)
|
||||
endif()
|
||||
set(FSO_INSTRUCTION_SET ${MSVC_SIMD_INSTRUCTIONS})
|
||||
|
||||
LIST(FIND POSSIBLE_INSTUCTION_SETS "${MSVC_SIMD_INSTRUCTIONS}" SET_INDEX)
|
||||
|
||||
if (SET_INDEX LESS 0)
|
||||
MESSAGE(STATUS "An invalid instruction set was specified, defaulting to no special compiler options.")
|
||||
else()
|
||||
IF (NOT SET_INDEX EQUAL 0)
|
||||
SET(FOUND)
|
||||
|
||||
FOREACH(list_index RANGE ${SET_INDEX} 1)
|
||||
list(GET POSSIBLE_INSTUCTION_SETS ${list_index} _simd_set)
|
||||
CHECK_CXX_COMPILER_FLAG("/arch:${_simd_set}" COMPILER_SUPPORTS_ARCH_${_simd_set})
|
||||
|
||||
IF(COMPILER_SUPPORTS_ARCH_${_simd_set})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:${_simd_set}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:${_simd_set}")
|
||||
|
||||
SET(FOUND TRUE)
|
||||
BREAK()
|
||||
ENDIF()
|
||||
ENDFOREACH(list_index)
|
||||
|
||||
IF(NOT FOUND)
|
||||
# Don't set anything, it will likely not work
|
||||
MESSAGE(STATUS "Your compiler does not support any optimization flags, defaulting to none")
|
||||
ENDIF(NOT FOUND)
|
||||
ELSE()
|
||||
CHECK_CXX_COMPILER_FLAG("/arch:IA32" COMPILER_SUPPORTS_ARCH_IA32)
|
||||
|
||||
IF(COMPILER_SUPPORTS_ARCH_IA32)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:IA32")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:IA32")
|
||||
ENDIF(COMPILER_SUPPORTS_ARCH_IA32)
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(compiler INTERFACE _CRT_SECURE_NO_DEPRECATE
|
||||
_CRT_SECURE_NO_WARNINGS _SECURE_SCL=0 NOMINMAX)
|
||||
|
||||
if (FSO_FATAL_WARNINGS)
|
||||
# Make warnings fatal if the right variable is set
|
||||
target_compile_options(compiler INTERFACE "/WX")
|
||||
endif()
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
# File to execute compiler specific commands
|
||||
|
||||
add_library(compiler INTERFACE)
|
||||
|
||||
target_compile_definitions(compiler INTERFACE "$<$<CONFIG:Release>:NDEBUG>;$<$<CONFIG:Debug>:_DEBUG>;$<$<CONFIG:FastDebug>:_DEBUG>")
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
include(toolchain-gcc)
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
include(toolchain-msvc)
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
include(toolchain-clang)
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
||||
include(toolchain-apple-clang)
|
||||
ELSE("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
MESSAGE(STATUS "No special handling for this compiler present, good luck!")
|
||||
ENDIF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
|
||||
# Copy release settings to FastDebug
|
||||
set(CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_FASTDEBUG "${CMAKE_EXE_LINKER_RELEASE}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_FASTDEBUG "${CMAKE_STATIC_LINKER_FLAGS_RELEASE}")
|
||||
|
||||
if (MSVC)
|
||||
# Adjust runtime library
|
||||
string(REPLACE "/MD" "/MDd" CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_FASTDEBUG}")
|
||||
string(REPLACE "/MT" "/MTd" CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_FASTDEBUG}")
|
||||
|
||||
string(REPLACE "/MD" "/MDd" CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_FASTDEBUG}")
|
||||
string(REPLACE "/MT" "/MTd" CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_FASTDEBUG}")
|
||||
endif()
|
||||
@@ -1,164 +0,0 @@
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
FUNCTION(MAKE_CACHE_INTERNAL VARIABLE)
|
||||
SET(${VARIABLE} ${${VARIABLE}} CACHE INTERNAL "Internal cache variable")
|
||||
ENDFUNCTION(MAKE_CACHE_INTERNAL)
|
||||
|
||||
FUNCTION(ADD_IMPORTED_LIB NAME INCLUDES LIBS)
|
||||
ADD_LIBRARY(${NAME} INTERFACE)
|
||||
|
||||
target_link_libraries(${NAME} INTERFACE "${LIBS}")
|
||||
|
||||
target_include_directories(${NAME} INTERFACE "${INCLUDES}")
|
||||
ENDFUNCTION(ADD_IMPORTED_LIB)
|
||||
|
||||
MACRO(PKG_CONFIG_LIB_RESOLVE NAME OUTVAR)
|
||||
SET(${OUTVAR} "")
|
||||
foreach(lib ${${NAME}_LIBRARIES})
|
||||
find_library(${lib}_LIBRARY
|
||||
NAMES ${lib}
|
||||
HINTS ${${NAME}_LIBDIR} ${${NAME}_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if (NOT ${${lib}_LIBRARY} MATCHES ".*NOTFOUND.*")
|
||||
SET(${OUTVAR} ${${OUTVAR}} ${${lib}_LIBRARY})
|
||||
endif (NOT ${${lib}_LIBRARY} MATCHES ".*NOTFOUND.*")
|
||||
endforeach(lib)
|
||||
ENDMACRO(PKG_CONFIG_LIB_RESOLVE)
|
||||
|
||||
# Copy from http://cmake.3232098.n2.nabble.com/RFC-cmake-analog-to-AC-SEARCH-LIBS-td7585423.html
|
||||
INCLUDE (CheckFunctionExists)
|
||||
INCLUDE (CheckLibraryExists)
|
||||
|
||||
MACRO (CMAKE_SEARCH_LIBS v_func v_lib func)
|
||||
CHECK_FUNCTION_EXISTS (${func} ${v_func})
|
||||
IF (NOT ${v_func})
|
||||
FOREACH (lib ${ARGN})
|
||||
CHECK_LIBRARY_EXISTS (${lib} ${func} "" "HAVE_${func}_IN_${lib}")
|
||||
IF (${HAVE_${func}_IN_${lib}})
|
||||
SET (${v_func} TRUE)
|
||||
SET (${v_lib} "${lib}" CACHE INTERNAL "Library providing ${func}")
|
||||
BREAK()
|
||||
ENDIF (${HAVE_${func}_IN_${lib}})
|
||||
ENDFOREACH (lib)
|
||||
ENDIF (NOT ${v_func})
|
||||
ENDMACRO (CMAKE_SEARCH_LIBS)
|
||||
# End copy
|
||||
|
||||
FUNCTION(EP_CHECK_FILE_EXISTS FILE OUTVAR TARGET NAME COMMAND WORKING_DIR)
|
||||
string (REPLACE ";" " " COMMAND_STR "${COMMAND}")
|
||||
IF(WIN32)
|
||||
# Do something special for windows...
|
||||
SET(COMMAND "cmd /C \"${COMMAND_STR}\"")
|
||||
ELSE(WIN32)
|
||||
SET(COMMAND "${COMMAND_STR}")
|
||||
ENDIF(WIN32)
|
||||
|
||||
FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${NAME}" "
|
||||
IF(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}\")
|
||||
MESSAGE(\"'${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}' already exists, nothing to be done.\")
|
||||
ELSE(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}\")
|
||||
execute_process(COMMAND ${COMMAND} WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${WORKING_DIR}\")
|
||||
ENDIF(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}\")
|
||||
")
|
||||
|
||||
SET(${OUTVAR} "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${NAME} PARENT_SCOPE)
|
||||
ENDFUNCTION(EP_CHECK_FILE_EXISTS)
|
||||
|
||||
MACRO(COPY_FILES_TO_TARGET _target)
|
||||
FOREACH(file IN LISTS TARGET_COPY_FILES)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${file}" "$<TARGET_FILE_DIR:${_target}>"
|
||||
COMMENT "copying '${file}'..."
|
||||
)
|
||||
ENDFOREACH(file)
|
||||
ENDMACRO(COPY_FILES_TO_TARGET)
|
||||
|
||||
macro(_clear_old_libraries_state)
|
||||
set(is_debug FALSE)
|
||||
set(is_optimized FALSE)
|
||||
endmacro(_clear_old_libraries_state)
|
||||
|
||||
function(CONVERT_OLD_LIBRARIES)
|
||||
_clear_old_libraries_state()
|
||||
set(out_list)
|
||||
foreach(lib ${ARGV})
|
||||
if ("${lib}" STREQUAL "debug")
|
||||
_clear_old_libraries_state()
|
||||
set(is_debug TRUE)
|
||||
elseif("${lib}" STREQUAL "optimized")
|
||||
_clear_old_libraries_state()
|
||||
set(is_optimized TRUE)
|
||||
elseif("${lib}" STREQUAL "general")
|
||||
_clear_old_libraries_state()
|
||||
else("${lib}" STREQUAL "debug")
|
||||
# Expecting normal library
|
||||
if(is_debug)
|
||||
list(APPEND out_list "$<$<CONFIG:Debug>:${lib}>")
|
||||
elseif(is_optimized)
|
||||
list(APPEND out_list "$<$<CONFIG:Release>:${lib}>")
|
||||
else(is_debug)
|
||||
list(APPEND out_list "${lib}")
|
||||
endif(is_debug)
|
||||
endif("${lib}" STREQUAL "debug")
|
||||
endforeach(lib)
|
||||
|
||||
set(CONVERTED_LIBRARIES ${out_list} PARENT_SCOPE)
|
||||
endfunction(CONVERT_OLD_LIBRARIES)
|
||||
|
||||
macro(set_policy policy value)
|
||||
if (POLICY ${policy})
|
||||
cmake_policy(SET ${policy} ${value})
|
||||
endif ()
|
||||
endmacro(set_policy)
|
||||
|
||||
macro(set_if_not_defined VAR VALUE)
|
||||
if (NOT DEFINED ${VAR})
|
||||
set(${VAR} ${VALUE})
|
||||
endif()
|
||||
endmacro(set_if_not_defined)
|
||||
|
||||
macro(configure_cotire target)
|
||||
IF(COTIRE_ENABLE)
|
||||
# Disable unity build as it doesn't work well for us
|
||||
set_target_properties(${target} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
|
||||
|
||||
# add ignored paths for the precompiled header here
|
||||
set_target_properties(code PROPERTIES COTIRE_PREFIX_HEADER_IGNORE_PATH
|
||||
"${CMAKE_SOURCE_DIR};${CMAKE_BINARY_DIR}")
|
||||
cotire(${target})
|
||||
ENDIF(COTIRE_ENABLE)
|
||||
endmacro(configure_cotire)
|
||||
|
||||
macro(add_target_copy_files)
|
||||
INSTALL(FILES ${ARGN}
|
||||
DESTINATION ${BINARY_DESTINATION}
|
||||
)
|
||||
|
||||
SET(TARGET_COPY_FILES ${TARGET_COPY_FILES} ${ARGN} CACHE INTERNAL "" FORCE)
|
||||
endmacro(add_target_copy_files)
|
||||
|
||||
function(detect_simd_instructions _out_var)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(${_out_var} "" PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Detecting SIMD features of current CPU...")
|
||||
TRY_RUN(RUN_RESULT COMPILE_RESULT "${CMAKE_BINARY_DIR}/temp" "${CMAKE_SOURCE_DIR}/cmake/cpufeatures.cpp"
|
||||
RUN_OUTPUT_VARIABLE FEATURE_OUTPUT)
|
||||
|
||||
IF(COMPILE_RESULT)
|
||||
MESSAGE(STATUS "Detected compatibility for the ${FEATURE_OUTPUT} feature set.")
|
||||
SET(${_out_var} ${FEATURE_OUTPUT} PARENT_SCOPE)
|
||||
ELSE(COMPILE_RESULT)
|
||||
MESSAGE("Compilation of CPU feature detector failed, please set the instruction set manually.")
|
||||
set(${_out_var} "" PARENT_SCOPE)
|
||||
ENDIF(COMPILE_RESULT)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function (check_linker_flag _flag _out_var)
|
||||
SET(CMAKE_REQUIRED_FLAGS "${_flag}")
|
||||
CHECK_C_COMPILER_FLAG("" ${_out_var})
|
||||
endfunction(check_linker_flag)
|
||||
@@ -1,52 +0,0 @@
|
||||
|
||||
include(util)
|
||||
|
||||
if (EXISTS "${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
# This allows to override the values by using a special file
|
||||
include("${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
endif()
|
||||
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 3)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 7)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 5)
|
||||
|
||||
# A numeric revision e.g. the CI build number
|
||||
set_if_not_defined(FSO_VERSION_REVISION 0)
|
||||
|
||||
# A generic revision string, can be anything
|
||||
set_if_not_defined(FSO_VERSION_REVISION_STR "${FSO_VERSION_REVISION}")
|
||||
|
||||
if("${FSO_VERSION_REVISION}" STREQUAL "0" AND "${FSO_VERSION_REVISION_STR}" STREQUAL "${FSO_VERSION_REVISION}")
|
||||
set(FSO_VERSION_HAS_REVISION 0)
|
||||
else()
|
||||
set(FSO_VERSION_HAS_REVISION 1)
|
||||
endif()
|
||||
|
||||
set(FSO_FULL_VERSION_STRING "${FSO_VERSION_MAJOR}.${FSO_VERSION_MINOR}.${FSO_VERSION_BUILD}")
|
||||
set(FSO_PRODUCT_VERSION_STRING "${FSO_FULL_VERSION_STRING}")
|
||||
|
||||
if (FSO_VERSION_HAS_REVISION)
|
||||
set(FSO_FULL_VERSION_STRING "${FSO_FULL_VERSION_STRING}.${FSO_VERSION_REVISION_STR}")
|
||||
endif()
|
||||
|
||||
IF(NOT FSO_VERSION_HAS_REVISION)
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_VERSION_MAJOR}_${FSO_VERSION_MINOR}_${FSO_VERSION_BUILD}")
|
||||
ELSE()
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_VERSION_MAJOR}_${FSO_VERSION_MINOR}_${FSO_VERSION_BUILD}_${FSO_VERSION_REVISION_STR}")
|
||||
ENDIF()
|
||||
|
||||
IF(IS_64BIT)
|
||||
# This is a 64-bit builds
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_x64")
|
||||
ENDIF()
|
||||
|
||||
IF (NOT "${FSO_INSTRUCTION_SET}" STREQUAL "")
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_${FSO_INSTRUCTION_SET}")
|
||||
ENDIF()
|
||||
|
||||
IF (NOT "${FSO_BUILD_POSTFIX}" STREQUAL "")
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_${FSO_BUILD_POSTFIX}")
|
||||
ENDIF()
|
||||
|
||||
set(CONFIG_POSTFIX "$<$<CONFIG:Release>:>$<$<CONFIG:Debug>:-DEBUG>$<$<CONFIG:FastDebug>:-FASTDBG>")
|
||||
set(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}${CONFIG_POSTFIX}")
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
INCLUDE(source_groups.cmake)
|
||||
|
||||
INCLUDE(voice_rec.cmake)
|
||||
|
||||
ADD_LIBRARY(code STATIC ${file_root} ${VOICE_REC_FILES})
|
||||
|
||||
target_compile_features(code PUBLIC ${REQUIRED_CXX_FEATURES})
|
||||
|
||||
INCLUDE(default_files.cmake)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_definitions(code PUBLIC "PDB_DEBUGGING=1")
|
||||
endif(MSVC)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(code PUBLIC ${CODE_HEADERS})
|
||||
TARGET_INCLUDE_DIRECTORIES(code PUBLIC ${FREESPACE_HEADERS})
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(code PUBLIC ${GENERATED_SOURCE_DIR})
|
||||
TARGET_INCLUDE_DIRECTORIES(code PUBLIC ${GENERATED_SOURCE_DIR}/code)
|
||||
|
||||
target_link_libraries(code PUBLIC gl_12)
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${OPENAL_LIBS})
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${LUA_LIBS})
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${PNG_LIBS})
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${JPEG_LIBS})
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC oggvorbis)
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${SDL_LIBS})
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC platform)
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC compiler)
|
||||
|
||||
IF (FSO_USE_SPEECH)
|
||||
find_package(Speech REQUIRED)
|
||||
target_link_libraries(code PUBLIC speech)
|
||||
ENDIF(FSO_USE_SPEECH)
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC jansson)
|
||||
|
||||
# Headers for standalone "gui" on UNIX
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${MONGOOSE_LIBS})
|
||||
ENDIF(UNIX)
|
||||
|
||||
IF(FSO_BUILD_TOOLS)
|
||||
ADD_SUBDIRECTORY(cfilearchiver)
|
||||
|
||||
ADD_SUBDIRECTORY(cfileextractor)
|
||||
ENDIF(FSO_BUILD_TOOLS)
|
||||
|
||||
include(util)
|
||||
configure_cotire(code)
|
||||
|
||||
include(../cmake/Cxx11.cmake)
|
||||
@@ -0,0 +1,849 @@
|
||||
## code/Makefile.am for fs2_open
|
||||
##
|
||||
## $Id: Makefile.am,v 1.31.2.10 2007-11-22 04:52:12 taylor Exp $
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
freespace2/app_icon.ico \
|
||||
freespace2/freespace.rc \
|
||||
freespace2/freespaceresource.h \
|
||||
freespace2/goal_com.bmp \
|
||||
freespace2/goal_fail.bmp \
|
||||
freespace2/goal_inc.bmp \
|
||||
freespace2/goal_none.bmp \
|
||||
freespace2/goal_ord.bmp \
|
||||
fred2/addvariabledlg.cpp \
|
||||
fred2/addvariabledlg.h \
|
||||
fred2/adjustgriddlg.cpp \
|
||||
fred2/adjustgriddlg.h \
|
||||
fred2/asteroideditordlg.cpp \
|
||||
fred2/asteroideditordlg.h \
|
||||
fred2/bgbitmapdlg.cpp \
|
||||
fred2/bgbitmapdlg.h \
|
||||
fred2/briefingeditordlg.cpp \
|
||||
fred2/briefingeditordlg.h \
|
||||
fred2/campaigneditordlg.cpp \
|
||||
fred2/campaigneditordlg.h \
|
||||
fred2/campaignfilelistbox.cpp \
|
||||
fred2/campaignfilelistbox.h \
|
||||
fred2/campaigntreeview.cpp \
|
||||
fred2/campaigntreeview.h \
|
||||
fred2/campaigntreewnd.cpp \
|
||||
fred2/campaigntreewnd.h \
|
||||
fred2/cmdbrief.cpp \
|
||||
fred2/cmdbrief.h \
|
||||
fred2/createwingdlg.cpp \
|
||||
fred2/createwingdlg.h \
|
||||
fred2/customwingnames.cpp \
|
||||
fred2/customwingnames.h \
|
||||
fred2/debriefingeditordlg.cpp \
|
||||
fred2/debriefingeditordlg.h \
|
||||
fred2/dialog1.cpp \
|
||||
fred2/dialog1.h \
|
||||
fred2/dumpstats.cpp \
|
||||
fred2/dumpstats.h \
|
||||
fred2/editor.h \
|
||||
fred2/eventeditor.cpp \
|
||||
fred2/eventeditor.h \
|
||||
fred2/folderdlg.cpp \
|
||||
fred2/folderdlg.h \
|
||||
fred2/fred.cpp \
|
||||
fred2/fred.h \
|
||||
fred2/fred.rc \
|
||||
fred2/freddoc.cpp \
|
||||
fred2/freddoc.h \
|
||||
fred2/fredrender.cpp \
|
||||
fred2/fredrender.h \
|
||||
fred2/fredstubs.cpp \
|
||||
fred2/fredview.cpp \
|
||||
fred2/fredview.h \
|
||||
fred2/grid.cpp \
|
||||
fred2/grid.h \
|
||||
fred2/ignoreordersdlg.cpp \
|
||||
fred2/ignoreordersdlg.h \
|
||||
fred2/initialships.cpp \
|
||||
fred2/initialships.h \
|
||||
fred2/initialstatus.cpp \
|
||||
fred2/initialstatus.h \
|
||||
fred2/mainfrm.cpp \
|
||||
fred2/mainfrm.h \
|
||||
fred2/makehelp.bat \
|
||||
fred2/management.cpp \
|
||||
fred2/management.h \
|
||||
fred2/messageeditordlg.cpp \
|
||||
fred2/messageeditordlg.h \
|
||||
fred2/missiongoalsdlg.cpp \
|
||||
fred2/missiongoalsdlg.h \
|
||||
fred2/missionnotesdlg.cpp \
|
||||
fred2/missionnotesdlg.h \
|
||||
fred2/missionsave.cpp \
|
||||
fred2/missionsave.h \
|
||||
fred2/modifyvariabledlg.cpp \
|
||||
fred2/modifyvariabledlg.h \
|
||||
fred2/operatorargtypeselect.cpp \
|
||||
fred2/operatorargtypeselect.h \
|
||||
fred2/orienteditor.cpp \
|
||||
fred2/orienteditor.h \
|
||||
fred2/playerstarteditor.cpp \
|
||||
fred2/playerstarteditor.h \
|
||||
fred2/prefsdlg.cpp \
|
||||
fred2/prefsdlg.h \
|
||||
fred2/reinforcementeditordlg.cpp \
|
||||
fred2/reinforcementeditordlg.h \
|
||||
fred2/resource.h \
|
||||
fred2/resource.hm \
|
||||
fred2/setglobalshipflags.cpp \
|
||||
fred2/setglobalshipflags.h \
|
||||
fred2/sexp_tree.cpp \
|
||||
fred2/sexp_tree.h \
|
||||
fred2/shieldsysdlg.cpp \
|
||||
fred2/shieldsysdlg.h \
|
||||
fred2/ship_select.cpp \
|
||||
fred2/ship_select.h \
|
||||
fred2/shipchecklistbox.cpp \
|
||||
fred2/shipchecklistbox.h \
|
||||
fred2/shipclasseditordlg.cpp \
|
||||
fred2/shipclasseditordlg.h \
|
||||
fred2/shipeditordlg.cpp \
|
||||
fred2/shipeditordlg.h \
|
||||
fred2/shipflagsdlg.cpp \
|
||||
fred2/shipflagsdlg.h \
|
||||
fred2/shipgoalsdlg.cpp \
|
||||
fred2/shipgoalsdlg.h \
|
||||
fred2/shipspecialdamage.cpp \
|
||||
fred2/shipspecialdamage.h \
|
||||
fred2/shipspecialhitpoints.cpp \
|
||||
fred2/shipspecialhitpoints.h \
|
||||
fred2/shiptexturesdlg.cpp \
|
||||
fred2/shiptexturesdlg.h \
|
||||
fred2/starfieldeditor.cpp \
|
||||
fred2/starfieldeditor.h \
|
||||
fred2/stdafx.cpp \
|
||||
fred2/stdafx.h \
|
||||
fred2/textviewdlg.cpp \
|
||||
fred2/textviewdlg.h \
|
||||
fred2/voiceactingmanager.cpp \
|
||||
fred2/voiceactingmanager.h \
|
||||
fred2/waypointpathdlg.cpp \
|
||||
fred2/waypointpathdlg.h \
|
||||
fred2/weaponeditordlg.cpp \
|
||||
fred2/weaponeditordlg.h \
|
||||
fred2/wing.cpp \
|
||||
fred2/wing.h \
|
||||
fred2/wing_editor.cpp \
|
||||
fred2/wing_editor.h \
|
||||
fred2/hlp/afxcore.rtf \
|
||||
fred2/hlp/afxhelp.hm \
|
||||
fred2/hlp/afxprint.rtf \
|
||||
fred2/hlp/appexit.bmp \
|
||||
fred2/hlp/bullet.bmp \
|
||||
fred2/hlp/curarw2.bmp \
|
||||
fred2/hlp/curarw4.bmp \
|
||||
fred2/hlp/curhelp.bmp \
|
||||
fred2/hlp/editcopy.bmp \
|
||||
fred2/hlp/editcut.bmp \
|
||||
fred2/hlp/editpast.bmp \
|
||||
fred2/hlp/editundo.bmp \
|
||||
fred2/hlp/filenew.bmp \
|
||||
fred2/hlp/fileopen.bmp \
|
||||
fred2/hlp/fileprnt.bmp \
|
||||
fred2/hlp/filesave.bmp \
|
||||
fred2/hlp/fred.hm \
|
||||
fred2/hlp/fred.hpj \
|
||||
fred2/hlp/help.log \
|
||||
fred2/hlp/hlpsbar.bmp \
|
||||
fred2/hlp/hlptbar.bmp \
|
||||
fred2/hlp/recfirst.bmp \
|
||||
fred2/hlp/reclast.bmp \
|
||||
fred2/hlp/recnext.bmp \
|
||||
fred2/hlp/recprev.bmp \
|
||||
fred2/hlp/scmax.bmp \
|
||||
fred2/hlp/scmenu.bmp \
|
||||
fred2/hlp/scmin.bmp \
|
||||
fred2/res/bitmap1.bmp \
|
||||
fred2/res/black_do.bmp \
|
||||
fred2/res/bmp00001.bmp \
|
||||
fred2/res/chained.bmp \
|
||||
fred2/res/chained_directive.bmp \
|
||||
fred2/res/cursor1.cur \
|
||||
fred2/res/cursor2.cur \
|
||||
fred2/res/data.bmp \
|
||||
fred2/res/fred.ico \
|
||||
fred2/res/fred.rc2 \
|
||||
fred2/res/freddoc.ico \
|
||||
fred2/res/green_do.bmp \
|
||||
fred2/res/root.bmp \
|
||||
fred2/res/root_directive.bmp \
|
||||
fred2/res/toolbar.bmp \
|
||||
fred2/res/toolbar1.bmp \
|
||||
fred2/res/variable.bmp \
|
||||
sound/phrases.xml \
|
||||
sound/gc.exe \
|
||||
wxfred2/res/fred.ico \
|
||||
wxfred2/wxfred.xrc
|
||||
|
||||
|
||||
# D_ variants are defaults and should always be used
|
||||
# FS2_ variants are for game building and wxFRED
|
||||
AM_CXXFLAGS = @D_CFLAGS@ @FS2_CXXFLAGS@
|
||||
AM_LDFLAGS = @D_LDFLAGS@ @FS2_LDFLAGS@
|
||||
|
||||
noinst_LIBRARIES = libcode.a
|
||||
noinst_PROGRAMS = @FS2_BINARY@
|
||||
|
||||
EXTRA_PROGRAMS = fs2_open_r fs2_open_d wxFRED2_r wxFRED2_d fs2_open_INF_r fs2_open_INF_d wxFRED2_INF_r wxFRED2_INF_d
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin CORE library
|
||||
##
|
||||
|
||||
FS2_SOURCES = \
|
||||
ai/ai.cpp \
|
||||
ai/ai.h \
|
||||
ai/aibig.cpp \
|
||||
ai/aibig.h \
|
||||
ai/aicode.cpp \
|
||||
ai/aigoals.cpp \
|
||||
ai/aigoals.h \
|
||||
ai/aiinternal.h \
|
||||
ai/ailocal.h \
|
||||
ai/aiturret.cpp \
|
||||
ai/ai_profiles.cpp \
|
||||
ai/ai_profiles.h \
|
||||
anim/animplay.cpp \
|
||||
anim/animplay.h \
|
||||
anim/packunpack.cpp \
|
||||
anim/packunpack.h \
|
||||
asteroid/asteroid.cpp \
|
||||
asteroid/asteroid.h \
|
||||
autopilot/autopilot.cpp \
|
||||
autopilot/autopilot.h \
|
||||
bmpman/bm_internal.h \
|
||||
bmpman/bmpman.cpp \
|
||||
bmpman/bmpman.h \
|
||||
camera/camera.cpp \
|
||||
camera/camera.h \
|
||||
cfile/cfile.cpp \
|
||||
cfile/cfile.h \
|
||||
cfile/cfilearchive.cpp \
|
||||
cfile/cfilearchive.h \
|
||||
cfile/cfilelist.cpp \
|
||||
cfile/cfilesystem.cpp \
|
||||
cfile/cfilesystem.h \
|
||||
cmdline/cmdline.cpp \
|
||||
cmdline/cmdline.h \
|
||||
cmeasure/cmeasure.cpp \
|
||||
cmeasure/cmeasure.h \
|
||||
controlconfig/controlsconfig.cpp \
|
||||
controlconfig/controlsconfig.h \
|
||||
controlconfig/controlsconfigcommon.cpp \
|
||||
cutscene/cutscenes.cpp \
|
||||
cutscene/cutscenes.h \
|
||||
cutscene/decoder16.cpp \
|
||||
cutscene/decoder8.cpp \
|
||||
cutscene/movie.cpp \
|
||||
cutscene/movie.h \
|
||||
cutscene/mve_audio.cpp \
|
||||
cutscene/mvelib.cpp \
|
||||
cutscene/mvelib.h \
|
||||
cutscene/mveplayer.cpp \
|
||||
cutscene/oggplayer.cpp \
|
||||
cutscene/oggplayer.h \
|
||||
ddsutils/ddsutils.cpp \
|
||||
ddsutils/ddsutils.h \
|
||||
debris/debris.cpp \
|
||||
debris/debris.h \
|
||||
debugconsole/console.cpp \
|
||||
debugconsole/dbugfile.h \
|
||||
debugconsole/timerbar.cpp \
|
||||
debugconsole/timerbar.h \
|
||||
exceptionhandler/exceptionhandler.cpp \
|
||||
exceptionhandler/exceptionhandler.h \
|
||||
external_dll/externalcode.h \
|
||||
external_dll/trackirglobal.cpp \
|
||||
external_dll/trackirglobal.h \
|
||||
fireball/fireballs.cpp \
|
||||
fireball/fireballs.h \
|
||||
fireball/warpineffect.cpp \
|
||||
fs2netd/fs2netd_client.cpp \
|
||||
fs2netd/fs2netd_client.h \
|
||||
fs2netd/tcp_client.cpp \
|
||||
fs2netd/tcp_client.h \
|
||||
fs2netd/tcp_socket.cpp \
|
||||
fs2netd/tcp_socket.h \
|
||||
fs2netd/protocol.h \
|
||||
gamehelp/contexthelp.cpp \
|
||||
gamehelp/contexthelp.h \
|
||||
gamehelp/gameplayhelp.cpp \
|
||||
gamehelp/gameplayhelp.h \
|
||||
gamesequence/gamesequence.cpp \
|
||||
gamesequence/gamesequence.h \
|
||||
gamesnd/eventmusic.cpp \
|
||||
gamesnd/eventmusic.h \
|
||||
gamesnd/gamesnd.cpp \
|
||||
gamesnd/gamesnd.h \
|
||||
globalincs/alphacolors.cpp \
|
||||
globalincs/alphacolors.h \
|
||||
globalincs/def_files.cpp \
|
||||
globalincs/def_files.h \
|
||||
globalincs/fsmemory.cpp \
|
||||
globalincs/fsmemory.h \
|
||||
globalincs/globals.h \
|
||||
globalincs/linklist.h \
|
||||
globalincs/pstypes.h \
|
||||
globalincs/safe_strings.cpp \
|
||||
globalincs/safe_strings.h \
|
||||
globalincs/safe_strings_test.cpp \
|
||||
globalincs/systemvars.cpp \
|
||||
globalincs/systemvars.h \
|
||||
globalincs/version.cpp \
|
||||
globalincs/version.h \
|
||||
graphics/2d.cpp \
|
||||
graphics/2d.h \
|
||||
graphics/font.cpp \
|
||||
graphics/font.h \
|
||||
graphics/generic.cpp \
|
||||
graphics/generic.h \
|
||||
graphics/grbatch.cpp \
|
||||
graphics/grbatch.h \
|
||||
graphics/grinternal.h \
|
||||
graphics/gropengl.cpp \
|
||||
graphics/gropengl.h \
|
||||
graphics/gropenglbmpman.cpp \
|
||||
graphics/gropenglbmpman.h \
|
||||
graphics/gropengldraw.cpp \
|
||||
graphics/gropengldraw.h \
|
||||
graphics/gropenglextension.cpp \
|
||||
graphics/gropenglextension.h \
|
||||
graphics/gropengllight.cpp \
|
||||
graphics/gropengllight.h \
|
||||
graphics/gropenglpostprocessing.cpp \
|
||||
graphics/gropenglpostprocessing.h \
|
||||
graphics/gropenglshader.cpp \
|
||||
graphics/gropenglshader.h \
|
||||
graphics/gropenglstate.cpp \
|
||||
graphics/gropenglstate.h \
|
||||
graphics/gropengltexture.cpp \
|
||||
graphics/gropengltexture.h \
|
||||
graphics/gropengltnl.cpp \
|
||||
graphics/gropengltnl.h \
|
||||
graphics/grstub.cpp \
|
||||
graphics/grstub.h \
|
||||
graphics/line.h \
|
||||
graphics/tmapper.h \
|
||||
hud/hud.cpp \
|
||||
hud/hud.h \
|
||||
hud/hudartillery.cpp \
|
||||
hud/hudartillery.h \
|
||||
hud/hudbrackets.cpp \
|
||||
hud/hudbrackets.h \
|
||||
hud/hudconfig.cpp \
|
||||
hud/hudconfig.h \
|
||||
hud/hudescort.cpp \
|
||||
hud/hudescort.h \
|
||||
hud/hudets.cpp \
|
||||
hud/hudets.h \
|
||||
hud/hudgauges.h \
|
||||
hud/hudlock.cpp \
|
||||
hud/hudlock.h \
|
||||
hud/hudmessage.cpp \
|
||||
hud/hudmessage.h \
|
||||
hud/hudnavigation.cpp \
|
||||
hud/hudnavigation.h \
|
||||
hud/hudobserver.cpp \
|
||||
hud/hudobserver.h \
|
||||
hud/hudparse.cpp \
|
||||
hud/hudparse.h \
|
||||
hud/hudreticle.cpp \
|
||||
hud/hudreticle.h \
|
||||
hud/hudshield.cpp \
|
||||
hud/hudshield.h \
|
||||
hud/hudsquadmsg.cpp \
|
||||
hud/hudsquadmsg.h \
|
||||
hud/hudtarget.cpp \
|
||||
hud/hudtarget.h \
|
||||
hud/hudtargetbox.cpp \
|
||||
hud/hudtargetbox.h \
|
||||
hud/hudwingmanstatus.cpp \
|
||||
hud/hudwingmanstatus.h \
|
||||
iff_defs/iff_defs.cpp \
|
||||
iff_defs/iff_defs.h \
|
||||
inetfile/cftp.cpp \
|
||||
inetfile/cftp.h \
|
||||
inetfile/chttpget.cpp \
|
||||
inetfile/chttpget.h \
|
||||
inetfile/inetgetfile.cpp \
|
||||
inetfile/inetgetfile.h \
|
||||
io/key.cpp \
|
||||
io/key.h \
|
||||
io/keycontrol.cpp \
|
||||
io/keycontrol.h \
|
||||
io/mouse.cpp \
|
||||
io/mouse.h \
|
||||
io/timer.cpp \
|
||||
io/timer.h \
|
||||
jpgutils/jpgutils.cpp \
|
||||
jpgutils/jpgutils.h \
|
||||
jumpnode/jumpnode.cpp \
|
||||
jumpnode/jumpnode.h \
|
||||
lab/lab.cpp \
|
||||
lab/lab.h \
|
||||
lab/wmcgui.cpp \
|
||||
lab/wmcgui.h \
|
||||
lighting/lighting.cpp \
|
||||
lighting/lighting.h \
|
||||
localization/fhash.cpp \
|
||||
localization/fhash.h \
|
||||
localization/localize.cpp \
|
||||
localization/localize.h \
|
||||
math/fix.cpp \
|
||||
math/fix.h \
|
||||
math/floating.cpp \
|
||||
math/floating.h \
|
||||
math/fvi.cpp \
|
||||
math/fvi.h \
|
||||
math/spline.cpp \
|
||||
math/spline.h \
|
||||
math/staticrand.cpp \
|
||||
math/staticrand.h \
|
||||
math/vecmat.cpp \
|
||||
math/vecmat.h \
|
||||
menuui/barracks.cpp \
|
||||
menuui/barracks.h \
|
||||
menuui/credits.cpp \
|
||||
menuui/credits.h \
|
||||
menuui/fishtank.cpp \
|
||||
menuui/fishtank.h \
|
||||
menuui/mainhallmenu.cpp \
|
||||
menuui/mainhallmenu.h \
|
||||
menuui/mainhalltemp.cpp \
|
||||
menuui/mainhalltemp.h \
|
||||
menuui/optionsmenu.cpp \
|
||||
menuui/optionsmenu.h \
|
||||
menuui/optionsmenumulti.cpp \
|
||||
menuui/optionsmenumulti.h \
|
||||
menuui/playermenu.cpp \
|
||||
menuui/playermenu.h \
|
||||
menuui/readyroom.cpp \
|
||||
menuui/readyroom.h \
|
||||
menuui/snazzyui.cpp \
|
||||
menuui/snazzyui.h \
|
||||
menuui/techmenu.cpp \
|
||||
menuui/techmenu.h \
|
||||
menuui/trainingmenu.cpp \
|
||||
menuui/trainingmenu.h \
|
||||
mission/missionbriefcommon.cpp \
|
||||
mission/missionbriefcommon.h \
|
||||
mission/missioncampaign.cpp \
|
||||
mission/missioncampaign.h \
|
||||
mission/missiongoals.cpp \
|
||||
mission/missiongoals.h \
|
||||
mission/missiongrid.cpp \
|
||||
mission/missiongrid.h \
|
||||
mission/missionhotkey.cpp \
|
||||
mission/missionhotkey.h \
|
||||
mission/missionload.cpp \
|
||||
mission/missionload.h \
|
||||
mission/missionlog.cpp \
|
||||
mission/missionlog.h \
|
||||
mission/missionmessage.cpp \
|
||||
mission/missionmessage.h \
|
||||
mission/missionparse.cpp \
|
||||
mission/missionparse.h \
|
||||
mission/missiontraining.cpp \
|
||||
mission/missiontraining.h \
|
||||
missionui/chatbox.cpp \
|
||||
missionui/chatbox.h \
|
||||
missionui/fictionviewer.cpp \
|
||||
missionui/fictionviewer.h \
|
||||
missionui/missionbrief.cpp \
|
||||
missionui/missionbrief.h \
|
||||
missionui/missioncmdbrief.cpp \
|
||||
missionui/missioncmdbrief.h \
|
||||
missionui/missiondebrief.cpp \
|
||||
missionui/missiondebrief.h \
|
||||
missionui/missionloopbrief.cpp \
|
||||
missionui/missionloopbrief.h \
|
||||
missionui/missionpause.cpp \
|
||||
missionui/missionpause.h \
|
||||
missionui/missionrecommend.cpp \
|
||||
missionui/missionrecommend.h \
|
||||
missionui/missionscreencommon.cpp \
|
||||
missionui/missionscreencommon.h \
|
||||
missionui/missionshipchoice.cpp \
|
||||
missionui/missionshipchoice.h \
|
||||
missionui/missionstats.cpp \
|
||||
missionui/missionstats.h \
|
||||
missionui/missionweaponchoice.cpp \
|
||||
missionui/missionweaponchoice.h \
|
||||
missionui/redalert.cpp \
|
||||
missionui/redalert.h \
|
||||
model/model.h \
|
||||
model/modelanim.cpp \
|
||||
model/modelanim.h \
|
||||
model/modelcollide.cpp \
|
||||
model/modelinterp.cpp \
|
||||
model/modelsinc.h \
|
||||
model/modeloctant.cpp \
|
||||
model/modelread.cpp \
|
||||
nebula/neb.cpp \
|
||||
nebula/neb.h \
|
||||
nebula/neblightning.cpp \
|
||||
nebula/neblightning.h \
|
||||
network/chat_api.cpp \
|
||||
network/chat_api.h \
|
||||
network/multi.cpp \
|
||||
network/multi.h \
|
||||
network/multilag.cpp \
|
||||
network/multilag.h \
|
||||
network/multimsgs.cpp \
|
||||
network/multimsgs.h \
|
||||
network/multiteamselect.cpp \
|
||||
network/multiteamselect.h \
|
||||
network/multiui.cpp \
|
||||
network/multiui.h \
|
||||
network/multiutil.cpp \
|
||||
network/multiutil.h \
|
||||
network/multi_campaign.cpp \
|
||||
network/multi_campaign.h \
|
||||
network/multi_data.cpp \
|
||||
network/multi_data.h \
|
||||
network/multi_dogfight.cpp \
|
||||
network/multi_dogfight.h \
|
||||
network/multi_endgame.cpp \
|
||||
network/multi_endgame.h \
|
||||
network/multi_ingame.cpp \
|
||||
network/multi_ingame.h \
|
||||
network/multi_kick.cpp \
|
||||
network/multi_kick.h \
|
||||
network/multi_log.cpp \
|
||||
network/multi_log.h \
|
||||
network/multi_obj.cpp \
|
||||
network/multi_obj.h \
|
||||
network/multi_observer.cpp \
|
||||
network/multi_observer.h \
|
||||
network/multi_options.cpp \
|
||||
network/multi_options.h \
|
||||
network/multi_pause.cpp \
|
||||
network/multi_pause.h \
|
||||
network/multi_pinfo.cpp \
|
||||
network/multi_pinfo.h \
|
||||
network/multi_ping.cpp \
|
||||
network/multi_ping.h \
|
||||
network/multi_pmsg.cpp \
|
||||
network/multi_pmsg.h \
|
||||
network/multi_pxo.cpp \
|
||||
network/multi_pxo.h \
|
||||
network/multi_rate.cpp \
|
||||
network/multi_rate.h \
|
||||
network/multi_respawn.cpp \
|
||||
network/multi_respawn.h \
|
||||
network/multi_sexp.cpp \
|
||||
network/multi_sexp.h \
|
||||
network/multi_team.cpp \
|
||||
network/multi_team.h \
|
||||
network/multi_update.h \
|
||||
network/multi_voice.cpp \
|
||||
network/multi_voice.h \
|
||||
network/multi_xfer.cpp \
|
||||
network/multi_xfer.h \
|
||||
network/psnet2.cpp \
|
||||
network/psnet2.h \
|
||||
network/stand_gui.cpp \
|
||||
network/stand_gui-unix.cpp \
|
||||
network/stand_gui.h \
|
||||
object/collidedebrisship.cpp \
|
||||
object/collidedebrisweapon.cpp \
|
||||
object/collideshipship.cpp \
|
||||
object/collideshipweapon.cpp \
|
||||
object/collideweaponweapon.cpp \
|
||||
object/deadobjectdock.cpp \
|
||||
object/deadobjectdock.h \
|
||||
object/objcollide.cpp \
|
||||
object/objcollide.h \
|
||||
object/objectdock.cpp \
|
||||
object/objectdock.h \
|
||||
object/object.cpp \
|
||||
object/object.h \
|
||||
object/objectshield.cpp \
|
||||
object/objectshield.h \
|
||||
object/objectsnd.cpp \
|
||||
object/objectsnd.h \
|
||||
object/objectsort.cpp \
|
||||
object/parseobjectdock.cpp \
|
||||
object/parseobjectdock.h \
|
||||
object/waypoint.cpp \
|
||||
object/waypoint.h \
|
||||
observer/observer.cpp \
|
||||
observer/observer.h \
|
||||
palman/palman.cpp \
|
||||
palman/palman.h \
|
||||
parse/encrypt.cpp \
|
||||
parse/encrypt.h \
|
||||
parse/lua.cpp \
|
||||
parse/lua.h \
|
||||
parse/parselo.cpp \
|
||||
parse/parselo.h \
|
||||
parse/scripting.cpp \
|
||||
parse/scripting.h \
|
||||
parse/sexp.cpp \
|
||||
parse/sexp.h \
|
||||
particle/particle.cpp \
|
||||
particle/particle.h \
|
||||
pcxutils/pcxutils.cpp \
|
||||
pcxutils/pcxutils.h \
|
||||
pngutils/pngutils.cpp \
|
||||
pngutils/pngutils.h \
|
||||
physics/physics.cpp \
|
||||
physics/physics.h \
|
||||
playerman/managepilot.cpp \
|
||||
playerman/managepilot.h \
|
||||
playerman/player.h \
|
||||
playerman/playercontrol.cpp \
|
||||
popup/popup.cpp \
|
||||
popup/popup.h \
|
||||
popup/popupdead.cpp \
|
||||
popup/popupdead.h \
|
||||
radar/radar.cpp \
|
||||
radar/radar.h \
|
||||
radar/radardradis.cpp \
|
||||
radar/radardradis.h \
|
||||
radar/radarorb.cpp \
|
||||
radar/radarorb.h \
|
||||
radar/radarsetup.cpp \
|
||||
radar/radarsetup.h \
|
||||
render/3d.h \
|
||||
render/3dclipper.cpp \
|
||||
render/3ddraw.cpp \
|
||||
render/3dinternal.h \
|
||||
render/3dlaser.cpp \
|
||||
render/3dmath.cpp \
|
||||
render/3dsetup.cpp \
|
||||
ship/afterburner.cpp \
|
||||
ship/afterburner.h \
|
||||
ship/awacs.cpp \
|
||||
ship/awacs.h \
|
||||
ship/shield.cpp \
|
||||
ship/ship.cpp \
|
||||
ship/ship.h \
|
||||
ship/shipcontrails.cpp \
|
||||
ship/shipcontrails.h \
|
||||
ship/shipfx.cpp \
|
||||
ship/shipfx.h \
|
||||
ship/shiphit.cpp \
|
||||
ship/shiphit.h \
|
||||
ship/subsysdamage.h \
|
||||
sound/audiostr.cpp \
|
||||
sound/audiostr.h \
|
||||
sound/acm.cpp \
|
||||
sound/acm.h \
|
||||
sound/ds.cpp \
|
||||
sound/ds.h \
|
||||
sound/ds3d.cpp \
|
||||
sound/ds3d.h \
|
||||
sound/dscap.cpp \
|
||||
sound/dscap.h \
|
||||
sound/fsspeech.cpp \
|
||||
sound/fsspeech.h \
|
||||
sound/openal.cpp \
|
||||
sound/openal.h \
|
||||
sound/rtvoice.cpp \
|
||||
sound/rtvoice.h \
|
||||
sound/sound.cpp \
|
||||
sound/sound.h \
|
||||
sound/speech.cpp \
|
||||
sound/speech.h \
|
||||
sound/voicerec.cpp \
|
||||
sound/voicerec.h \
|
||||
sound/ogg/ogg.cpp \
|
||||
sound/ogg/ogg.h \
|
||||
species_defs/species_defs.cpp \
|
||||
species_defs/species_defs.h \
|
||||
starfield/nebula.cpp \
|
||||
starfield/nebula.h \
|
||||
starfield/starfield.cpp \
|
||||
starfield/starfield.h \
|
||||
starfield/supernova.cpp \
|
||||
starfield/supernova.h \
|
||||
stats/medals.cpp \
|
||||
stats/medals.h \
|
||||
stats/scoring.cpp \
|
||||
stats/scoring.h \
|
||||
stats/stats.cpp \
|
||||
stats/stats.h \
|
||||
tgautils/tgautils.cpp \
|
||||
tgautils/tgautils.h \
|
||||
ui/button.cpp \
|
||||
ui/checkbox.cpp \
|
||||
ui/gadget.cpp \
|
||||
ui/icon.cpp \
|
||||
ui/inputbox.cpp \
|
||||
ui/keytrap.cpp \
|
||||
ui/listbox.cpp \
|
||||
ui/radio.cpp \
|
||||
ui/scroll.cpp \
|
||||
ui/slider.cpp \
|
||||
ui/slider2.cpp \
|
||||
ui/ui.h \
|
||||
ui/uidefs.h \
|
||||
ui/uidraw.cpp \
|
||||
ui/uimouse.cpp \
|
||||
ui/window.cpp \
|
||||
weapon/beam.cpp \
|
||||
weapon/beam.h \
|
||||
weapon/corkscrew.cpp \
|
||||
weapon/corkscrew.h \
|
||||
weapon/emp.cpp \
|
||||
weapon/emp.h \
|
||||
weapon/flak.cpp \
|
||||
weapon/flak.h \
|
||||
weapon/muzzleflash.cpp \
|
||||
weapon/muzzleflash.h \
|
||||
weapon/shockwave.cpp \
|
||||
weapon/shockwave.h \
|
||||
weapon/swarm.cpp \
|
||||
weapon/swarm.h \
|
||||
weapon/trails.cpp \
|
||||
weapon/trails.h \
|
||||
weapon/weapons.cpp \
|
||||
weapon/weapon.h
|
||||
|
||||
## conditional includes follow:
|
||||
|
||||
## joystic support sources
|
||||
if FS2_OS_WIN32
|
||||
JOY_SOURCES = \
|
||||
io/joy.cpp \
|
||||
io/joy.h \
|
||||
io/joy_ff.cpp \
|
||||
io/joy_ff.h \
|
||||
io/sw_error.hpp \
|
||||
io/sw_force.h \
|
||||
io/sw_guid.hpp \
|
||||
io/swff_lib.cpp
|
||||
endif
|
||||
|
||||
if FS2_OS_UNIX
|
||||
JOY_SOURCES = \
|
||||
io/joy.h \
|
||||
io/joy_ff.h \
|
||||
io/joy-unix.cpp
|
||||
endif
|
||||
|
||||
## Win32-specific sources
|
||||
if FS2_OS_WIN32
|
||||
WIN32_SOURCES = \
|
||||
directx/vasync.h \
|
||||
directx/vd3dtypes.h \
|
||||
directx/vddraw.h \
|
||||
directx/vdinput.h \
|
||||
directx/vdplay.h \
|
||||
directx/vdplobby.h \
|
||||
directx/vdsetup.h \
|
||||
directx/vdvp.h \
|
||||
globalincs/windebug.cpp \
|
||||
graphics/gl/GLAUX.H \
|
||||
graphics/gl/GLU.H \
|
||||
graphics/gl/Gl.h \
|
||||
graphics/gl/Glext.h \
|
||||
graphics/gl/wglext.h \
|
||||
osapi/monopub.h \
|
||||
osapi/osapi.cpp \
|
||||
osapi/osapi.h \
|
||||
osapi/osregistry.cpp \
|
||||
osapi/osregistry.h \
|
||||
osapi/outwnd.cpp \
|
||||
osapi/outwnd.h
|
||||
endif
|
||||
|
||||
## Unix-specific sources
|
||||
if FS2_OS_UNIX
|
||||
UNIX_SOURCES = \
|
||||
osapi/osapi_unix.cpp \
|
||||
osapi/osapi.h \
|
||||
osapi/osregistry_unix.cpp \
|
||||
osapi/osregistry.h \
|
||||
osapi/outwnd_unix.cpp \
|
||||
osapi/outwnd.h \
|
||||
windows_stub/stubs.cpp \
|
||||
windows_stub/config.h
|
||||
endif
|
||||
|
||||
|
||||
## libcode.a
|
||||
libcode_a_SOURCES = ${FS2_SOURCES} ${JOY_SOURCES} ${WIN32_SOURCES} \
|
||||
${UNIX_SOURCES}
|
||||
|
||||
##
|
||||
## End CODE library
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin MAIN fs2 binary
|
||||
##
|
||||
|
||||
FS2OPEN_SOURCES = \
|
||||
freespace2/freespace.cpp \
|
||||
freespace2/freespace.h \
|
||||
freespace2/levelpaging.cpp \
|
||||
freespace2/levelpaging.h
|
||||
|
||||
fs2_open_d_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_r_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_INF_d_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_INF_r_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_d_LDADD = libcode.a
|
||||
fs2_open_r_LDADD = libcode.a
|
||||
fs2_open_INF_d_LDADD = libcode.a
|
||||
fs2_open_INF_r_LDADD = libcode.a
|
||||
|
||||
##
|
||||
## End MAIN binary
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin wxFRED2 binary
|
||||
##
|
||||
|
||||
wxFRED_SOURCES = \
|
||||
wxfred2/wxfred2.cpp \
|
||||
wxfred2/wxfred2.h \
|
||||
wxfred2/fredframe.cpp \
|
||||
wxfred2/fredframe.h \
|
||||
wxfred2/wxfred_xrc.cpp \
|
||||
wxfred2/wxfred_xrc.h
|
||||
|
||||
wxFRED2_d_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_r_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_INF_d_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_INF_r_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_d_LDADD = libcode.a
|
||||
wxFRED2_r_LDADD = libcode.a
|
||||
wxFRED2_INF_d_LDADD = libcode.a
|
||||
wxFRED2_INF_r_LDADD = libcode.a
|
||||
|
||||
##
|
||||
## End wxFRED2 binary
|
||||
##
|
||||
###############################################################################
|
||||
+1
-1
@@ -82,7 +82,7 @@ void set_wingnum(int objnum, int wingnum)
|
||||
Ai_info[ai_index].wing = wingnum;
|
||||
}
|
||||
|
||||
char *ai_get_goal_target_name(const char *name, int *index)
|
||||
char *ai_get_goal_target_name(char *name, int *index)
|
||||
{
|
||||
Assert(name != NULL);
|
||||
Assert(index != NULL);
|
||||
|
||||
+54
-27
@@ -12,28 +12,51 @@
|
||||
#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 "ship/ship_flags.h"
|
||||
#include "object/waypoint.h"
|
||||
|
||||
class ship_weapon;
|
||||
class ship_subsys;
|
||||
class object;
|
||||
class ship_info;
|
||||
struct ship_weapon;
|
||||
struct ship_subsys;
|
||||
struct object;
|
||||
struct ship_info;
|
||||
|
||||
#define AI_DEFAULT_CLASS 3 // default AI class for new ships (Fred)
|
||||
|
||||
typedef struct ai_flag_name {
|
||||
AI::AI_Flags flag;
|
||||
char flag_name[TOKEN_LENGTH];
|
||||
} ai_flag_name;
|
||||
#define AIF_FORMATION_WING (1 << 0) // Fly in formation as part of wing.
|
||||
#define AIF_AWAITING_REPAIR (1 << 1) // Awaiting a repair ship.
|
||||
#define AIF_BEING_REPAIRED (1 << 2) // Currently docked with repair ship.
|
||||
#define AIF_REPAIRING (1 << 3) // Repairing a ship (or going to repair a ship)
|
||||
#define AIF_SEEK_LOCK (1 << 4) // set if should focus on gaining aspect lock, not hitting with lasers
|
||||
#define AIF_FORMATION_OBJECT (1 << 5) // Fly in formation off a specific object.
|
||||
#define AIF_TEMPORARY_IGNORE (1 << 6) // Means current ignore_objnum is only temporary, not an order from the player.
|
||||
#define AIF_USE_EXIT_PATH (1 << 7) // Used by path code, to flag path as an exit path
|
||||
#define AIF_USE_STATIC_PATH (1 << 8) // Used by path code, use fixed path, don't try to recreate
|
||||
#define AIF_TARGET_COLLISION (1 << 9) // Collided with aip->target_objnum last frame. Avoid that ship for half a second or so.
|
||||
#define AIF_UNLOAD_SECONDARIES (1 << 10) // Fire secondaries as fast as possible!
|
||||
#define AIF_ON_SUBSYS_PATH (1 << 11) // Current path leads to a subsystem
|
||||
#define AIF_AVOID_SHOCKWAVE_SHIP (1 << 12) // Avoid an existing shockwave from a ship.
|
||||
#define AIF_AVOID_SHOCKWAVE_WEAPON (1 << 13) // Avoid an expected shockwave from a weapon. shockwave_object field contains object index.
|
||||
#define AIF_AVOID_SHOCKWAVE_STARTED (1 << 14) // Already started avoiding shockwave, don't keep deciding whether to avoid.
|
||||
#define AIF_ATTACK_SLOWLY (1 << 15) // Move slowly while attacking.
|
||||
#define AIF_REPAIR_OBSTRUCTED (1 << 16) // Ship wants to be repaired, but path is obstructed.
|
||||
#define AIF_KAMIKAZE (1 << 17) // Crash into target
|
||||
#define AIF_NO_DYNAMIC (1 << 18) // Not allowed to get dynamic goals
|
||||
#define AIF_AVOIDING_SMALL_SHIP (1 << 19) // Avoiding a player ship.
|
||||
#define AIF_AVOIDING_BIG_SHIP (1 << 20) // Avoiding a large ship.
|
||||
#define AIF_BIG_SHIP_COLLIDE_RECOVER_1 (1 << 21) // Collided into a big ship. Recovering by flying away.
|
||||
#define AIF_BIG_SHIP_COLLIDE_RECOVER_2 (1 << 22) // Collided into a big ship. Fly towards big ship sphere perimeter.
|
||||
#define AIF_STEALTH_PURSUIT (1 << 23) // AI is trying to fight stealth ship
|
||||
|
||||
#define MAX_AI_FLAG_NAMES 2
|
||||
extern ai_flag_name Ai_flag_names[];
|
||||
// Goober5000
|
||||
#define AIF_UNLOAD_PRIMARIES (1 << 24) // Fire primaries as fast as possible!
|
||||
#define AIF_TRYING_UNSUCCESSFULLY_TO_WARP (1 << 25) // Trying to warp, but can't warp at the moment
|
||||
|
||||
#define AIF_AVOID_SHOCKWAVE (AIF_AVOID_SHOCKWAVE_SHIP | AIF_AVOID_SHOCKWAVE_WEAPON)
|
||||
#define AIF_FORMATION (AIF_FORMATION_WING | AIF_FORMATION_OBJECT)
|
||||
|
||||
// dock_orient_and_approach() modes.
|
||||
#define DOA_APPROACH 1 // Approach the current point on the path (aip->path_cur)
|
||||
@@ -75,7 +98,6 @@ extern ai_flag_name Ai_flag_names[];
|
||||
#define AIGF_PURGE (1<<5) // purge this goal next time we process
|
||||
#define AIGF_GOALS_PURGED (1<<6) // this goal has already caused other goals to get purged
|
||||
#define AIGF_DEPART_SOUND_PLAYED (1<<7) // Goober5000 - replacement for AL's hack ;)
|
||||
#define AIGF_TARGET_OWN_TEAM (1<<8) // Goober5000 - removes standard precautions against AI ships taking traitorous actions
|
||||
|
||||
#define AIGF_DOCK_INDEXES_VALID (AIGF_DOCKER_INDEX_VALID|AIGF_DOCKEE_INDEX_VALID)
|
||||
|
||||
@@ -193,8 +215,10 @@ typedef struct ai_class {
|
||||
int ai_chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
|
||||
float ai_max_aim_update_delay[NUM_SKILL_LEVELS];
|
||||
float ai_turret_max_aim_update_delay[NUM_SKILL_LEVELS];
|
||||
flagset<AI::Profile_Flags> ai_profile_flags; //Holds the state of flags that are set
|
||||
flagset<AI::Profile_Flags> ai_profile_flags_set; //Holds which flags are set and which are just left alone
|
||||
int ai_profile_flags; //Holds the state of flags that are set
|
||||
int ai_profile_flags_set; //Holds which flags are set and which are just left alone
|
||||
int ai_profile_flags2;
|
||||
int ai_profile_flags2_set;
|
||||
|
||||
//SUSHI: These are optional overrides to an AI class to prevent the automatic scaling based on AI class index
|
||||
int ai_aburn_use_factor[NUM_SKILL_LEVELS];
|
||||
@@ -291,7 +315,7 @@ extern pnode *Ppfp; // Free pointer in path points.
|
||||
#define MAX_IGNORE_NEW_OBJECTS 7
|
||||
|
||||
typedef struct ai_info {
|
||||
flagset<AI::AI_Flags> ai_flags; // Special flags for AI behavior.
|
||||
int ai_flags; // Special flags for AI behavior.
|
||||
int shipnum; // Ship using this slot, -1 means none.
|
||||
int type; //
|
||||
int wing; // Member of what wing? -1 means none.
|
||||
@@ -333,10 +357,10 @@ typedef struct ai_info {
|
||||
int ai_class; // Class. Might be override of default.
|
||||
|
||||
// Probably become obsolete, to be replaced by path_start, path_cur, etc.
|
||||
waypoint_list *wp_list; // waypoint list being followed
|
||||
size_t wp_index; // waypoint index in list
|
||||
waypoint_list *wp_list; // waypoint list being followed
|
||||
SCP_list<waypoint>::iterator wp_index; // waypoint index in list
|
||||
int wp_flags; // waypoint flags, see WPF_xxxx
|
||||
int waypoint_speed_cap; // -1 no cap, otherwise cap - changed to int by Goober5000
|
||||
int waypoint_speed_cap; // -1 no cap, otherwise cap - changed to int by Goober5000
|
||||
|
||||
// Path following information
|
||||
int path_start; // Index into global array, start of path.
|
||||
@@ -424,7 +448,8 @@ typedef struct ai_info {
|
||||
int ai_chance_to_use_missiles_on_plr;
|
||||
float ai_max_aim_update_delay;
|
||||
float ai_turret_max_aim_update_delay;
|
||||
flagset<AI::Profile_Flags> ai_profile_flags; //Holds AI_Profiles flags (possibly overriden by AI class) that actually apply to AI
|
||||
int ai_profile_flags; //Holds AI_Profiles flags (possibly overriden by AI class) that actually apply to AI
|
||||
int ai_profile_flags2;
|
||||
|
||||
|
||||
union {
|
||||
@@ -553,7 +578,7 @@ extern char** Ai_class_names;
|
||||
extern int Num_ai_classes;
|
||||
extern int Ai_firing_enabled;
|
||||
|
||||
extern const char *Skill_level_names(int skill_level, int translate = 1);
|
||||
extern char *Skill_level_names(int skill_level, int translate = 1);
|
||||
extern int Ai_goal_signature;
|
||||
|
||||
// need access to following data in AiBig.cpp
|
||||
@@ -579,19 +604,20 @@ void ai_process( object * obj, int ai_index, float frametime );
|
||||
int get_wingnum(int objnum);
|
||||
|
||||
void set_wingnum(int objnum, int wingnum);
|
||||
char *ai_get_goal_target_name(const char *name, int *index);
|
||||
char *ai_get_goal_target_name(char *name, int *index);
|
||||
|
||||
extern void init_ai_system(void);
|
||||
extern void ai_attack_object(object *attacker, object *attacked, ship_subsys *ssp);
|
||||
extern void ai_evade_object(object *evader, object *evaded);
|
||||
extern void ai_ignore_object(object *ignorer, object *ignored, int ignore_new);
|
||||
extern void ai_ignore_wing(object *ignorer, int wingnum);
|
||||
extern void ai_ignore_wing(object *ignorer, int wingnum, int priority);
|
||||
extern void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type);
|
||||
extern void ai_stay_still(object *still_objp, vec3d *view_pos);
|
||||
extern void ai_set_default_behavior(object *obj, int classnum);
|
||||
extern void ai_do_default_behavior(object *obj);
|
||||
extern void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags);
|
||||
extern void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal);
|
||||
extern void ai_ship_destroy(int shipnum, Ship::Exit_Flags method);
|
||||
extern void ai_ship_destroy(int shipnum, int method);
|
||||
extern void ai_turn_towards_vector(vec3d *dest, object *objp, float frametime, float turn_time, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec = NULL, int sexp_flags = 0);
|
||||
extern void init_ai_object(int objnum);
|
||||
extern void ai_init(void); // Call this one to parse ai.tbl.
|
||||
@@ -689,7 +715,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);
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
#ifndef AI_FLAGS_H
|
||||
#define AI_FLAGS_H
|
||||
|
||||
#include "globalincs/flagset.h"
|
||||
|
||||
namespace AI {
|
||||
FLAG_LIST(AI_Flags) {
|
||||
Formation_wing, // Fly in formation as part of wing.
|
||||
Awaiting_repair, // Awaiting a repair ship.
|
||||
Being_repaired, // Currently docked with repair ship.
|
||||
Repairing, // Repairing a ship (or going to repair a ship)
|
||||
Seek_lock, // set if should focus on gaining aspect lock, not hitting with lasers
|
||||
Formation_object, // Fly in formation off a specific object.
|
||||
Temporary_ignore, // Means current ignore_objnum is only temporary, not an order from the player.
|
||||
Use_exit_path, // Used by path code, to flag path as an exit path
|
||||
Use_static_path, // Used by path code, use fixed path, don't try to recreate
|
||||
Target_collision, // Collided with aip->target_objnum last frame. Avoid that ship for half a second or so.
|
||||
Unload_secondaries, // Fire secondaries as fast as possible!
|
||||
On_subsys_path, // Current path leads to a subsystem
|
||||
Avoid_shockwave_ship, // Avoid an existing shockwave from a ship.
|
||||
Avoid_shockwave_weapon, // Avoid an expected shockwave from a weapon. shockwave_object field contains object index.
|
||||
Avoid_shockwave_started, // Already started avoiding shockwave, don't keep deciding whether to avoid.
|
||||
Attack_slowly, // Move slowly while attacking.
|
||||
Repair_obstructed, // Ship wants to be repaired, but path is obstructed.
|
||||
Kamikaze, // Crash into target
|
||||
No_dynamic, // Not allowed to get dynamic goals
|
||||
Avoiding_small_ship, // Avoiding a player ship.
|
||||
Avoiding_big_ship, // Avoiding a large ship.
|
||||
Big_ship_collide_recover_1, // Collided into a big ship. Recovering by flying away.
|
||||
Big_ship_collide_recover_2, // Collided into a big ship. Fly towards big ship sphere perimeter.
|
||||
Stealth_pursuit, // AI is trying to fight stealth ship
|
||||
Unload_primaries, // Fire primaries as fast as possible!
|
||||
Trying_unsuccessfully_to_warp, // Trying to warp, but can't warp at the moment
|
||||
Free_afterburner_use, // Use afterburners while following waypoints or flying towards objects
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
|
||||
FLAG_LIST(Goal_Flags) {
|
||||
Docker_index_valid, // when set, index field for docker is valid
|
||||
Dockee_index_valid, // when set, index field for dockee is valid
|
||||
Goal_on_hold, // when set, this goal cannot currently be satisfied, although it could be in the future
|
||||
Subsys_needs_fixup, // when set, the subsystem index (for a destroy subsystem goal) is invalid and must be gotten from the subsys name stored in docker.name field!!
|
||||
Goal_override, // paired with AIG_TYPE_DYNAMIC to mean this goal overrides any other goal
|
||||
Purge, // purge this goal next time we process
|
||||
Goals_purged, // this goal has already caused other goals to get purged
|
||||
Depart_sound_played,// Goober5000 - replacement for AL's hack ;)
|
||||
Target_own_team,
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
|
||||
FLAG_LIST(Override_Flags) {
|
||||
Full, // Full sexp control
|
||||
Roll, // Sexp forced roll maneuver
|
||||
Pitch, // Sexp forced pitch change
|
||||
Heading, // Sexp forced heading change
|
||||
Full_lat, // full control over up/side/forward movement
|
||||
Up, // vertical movement
|
||||
Sideways, // horizontal movement
|
||||
Forward, // forward movement
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
|
||||
FLAG_LIST(Profile_Flags) {
|
||||
Advanced_turret_fov_edge_checks,
|
||||
Ai_aims_from_ship_center,
|
||||
Ai_can_slow_down_attacking_big_ships,
|
||||
Ai_guards_specific_ship_in_wing,
|
||||
All_ships_manage_shields,
|
||||
Allow_multi_event_scoring,
|
||||
Allow_primary_link_at_start,
|
||||
Allow_rapid_secondary_dumbfire,
|
||||
Allow_turrets_target_weapons_freely,
|
||||
Allow_vertical_dodge,
|
||||
Aspect_invulnerability_fix,
|
||||
Aspect_lock_countermeasure,
|
||||
Assist_scoring_scales_with_damage,
|
||||
Beams_damage_weapons,
|
||||
Big_ships_can_attack_beam_turrets_on_untargeted_ships,
|
||||
Disable_linked_fire_penalty,
|
||||
Disable_weapon_damage_scaling,
|
||||
Dont_insert_random_turret_fire_delay,
|
||||
Fix_ai_class_bug,
|
||||
Fix_ai_path_order_bug,
|
||||
Fix_heat_seeker_stealth_bug,
|
||||
Fix_linked_primary_bug,
|
||||
Force_beam_turret_fov,
|
||||
Glide_decay_requires_thrust,
|
||||
Hack_improve_non_homing_swarm_turret_fire_accuracy,
|
||||
Huge_turret_weapons_ignore_bombs,
|
||||
Include_beams_in_stat_calcs,
|
||||
Kill_scoring_scales_with_damage,
|
||||
Multi_allow_empty_primaries,
|
||||
Multi_allow_empty_secondaries,
|
||||
Navigation_subsys_governs_warp,
|
||||
No_min_dock_speed_cap,
|
||||
No_special_player_avoid,
|
||||
No_warp_camera,
|
||||
Perform_fewer_scream_checks,
|
||||
Player_weapon_scale_fix,
|
||||
Prevent_targeting_bombs_beyond_range,
|
||||
Require_turret_to_have_target_in_fov,
|
||||
Shockwaves_damage_small_ship_subsystems,
|
||||
Smart_afterburner_management,
|
||||
Smart_primary_weapon_selection,
|
||||
Smart_secondary_weapon_selection,
|
||||
Smart_shield_management,
|
||||
Smart_subsystem_targeting_for_turrets,
|
||||
Strict_turred_tagged_only_targeting,
|
||||
Turrets_ignore_target_radius,
|
||||
Use_additive_weapon_velocity,
|
||||
Use_newtonian_dampening,
|
||||
Use_only_single_fov_for_turrets,
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+444
-517
File diff suppressed because it is too large.
Load diff
+8
-22
@@ -9,10 +9,9 @@
|
||||
#ifndef _AI_PROFILES_H_
|
||||
#define _AI_PROFILES_H_
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "ai/ai_flags.h"
|
||||
|
||||
// flag int defines
|
||||
#define AIP_FLAG 1
|
||||
@@ -54,22 +53,15 @@
|
||||
// flags2
|
||||
#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0)
|
||||
#define AIPF2_NO_SPECIAL_PLAYER_AVOID (1 << 1)
|
||||
#define AIPF2_PERFORM_FEWER_SCREAM_CHECKS (1 << 2)
|
||||
#define AIPF2_PERFORM_LESS_SCREAM_CHECKS (1 << 2)
|
||||
#define AIPF2_ALL_SHIPS_MANAGE_SHIELDS (1 << 3)
|
||||
#define AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS (1 << 4)
|
||||
#define AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV (1 << 5)
|
||||
#define AIPF2_AI_AIMS_FROM_SHIP_CENTER (1 << 6)
|
||||
#define AIPF2_ALLOW_PRIMARY_LINK_AT_START (1 << 7)
|
||||
#define AIPF2_ALLOW_PRIMARY_LINK_DELAY (1 << 7)
|
||||
#define AIPF2_BEAMS_DAMAGE_WEAPONS (1 << 8)
|
||||
#define AIPF2_PLAYER_WEAPON_SCALE_FIX (1 << 9)
|
||||
#define AIPF2_NO_WARP_CAMERA (1 << 10)
|
||||
#define AIPF2_ASPECT_LOCK_COUNTERMEASURE (1 << 11)
|
||||
#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)
|
||||
#define AIPF2_AI_CAN_SLOW_DOWN_ATTACKING_BIG_SHIPS (1 << 17)
|
||||
|
||||
// AI Path types
|
||||
#define AI_PATH_MODE_NORMAL 0
|
||||
@@ -77,11 +69,12 @@
|
||||
|
||||
#define MAX_AI_PROFILES 5
|
||||
|
||||
class ai_profile_t {
|
||||
public:
|
||||
typedef struct ai_profile_t {
|
||||
|
||||
char profile_name[NAME_LENGTH];
|
||||
|
||||
flagset<AI::Profile_Flags> flags;
|
||||
int flags;
|
||||
int flags2;
|
||||
|
||||
// difficulty-related values
|
||||
int max_incoming_asteroids[NUM_SKILL_LEVELS]; // max number of asteroids thrown at friendlies
|
||||
@@ -154,20 +147,13 @@ public:
|
||||
|
||||
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;
|
||||
|
||||
void reset();
|
||||
};
|
||||
} ai_profile_t;
|
||||
|
||||
|
||||
extern int Num_ai_profiles;
|
||||
extern int Default_ai_profile;
|
||||
extern ai_profile_t Ai_profiles[MAX_AI_PROFILES];
|
||||
|
||||
#define AI_PROFILES_INDEX(ai_p) ((int)((ai_p) - Ai_profiles))
|
||||
|
||||
void ai_profiles_init();
|
||||
|
||||
|
||||
+144
-189
@@ -10,23 +10,21 @@
|
||||
|
||||
|
||||
#include "ai/aibig.h"
|
||||
#include "ai/aigoals.h"
|
||||
#include "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"
|
||||
|
||||
|
||||
|
||||
#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
|
||||
@@ -118,6 +116,8 @@ void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec,
|
||||
if (num_tries > octp->nverts)
|
||||
num_tries = octp->nverts;
|
||||
|
||||
int best_index = -1;
|
||||
|
||||
for (i=0; i<num_tries; i++) {
|
||||
int index;
|
||||
float dist, dot;
|
||||
@@ -142,6 +142,7 @@ void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec,
|
||||
|
||||
if (in_fov) {
|
||||
if (dist < nearest_dist) {
|
||||
best_index = index;
|
||||
nearest_dist = dist;
|
||||
best_point = result_point;
|
||||
*local_attack_point = rel_point;
|
||||
@@ -172,8 +173,6 @@ done_1:
|
||||
}
|
||||
|
||||
mc_info mc;
|
||||
mc_info_init(&mc);
|
||||
|
||||
mc.model_instance_num = Ships[objp->instance].model_instance_num;
|
||||
mc.model_num = sip->model_num;
|
||||
mc.orient = &objp->orient;
|
||||
@@ -350,8 +349,8 @@ void ai_big_avoid_ship()
|
||||
// reset path following information
|
||||
void ai_big_subsys_path_cleanup(ai_info *aip)
|
||||
{
|
||||
if ( aip->ai_flags[AI::AI_Flags::On_subsys_path] ) {
|
||||
aip->ai_flags.remove(AI::AI_Flags::On_subsys_path);
|
||||
if ( aip->ai_flags & AIF_ON_SUBSYS_PATH ) {
|
||||
aip->ai_flags &= ~AIF_ON_SUBSYS_PATH;
|
||||
aip->path_goal_dist = -1;
|
||||
aip->path_start = -1;
|
||||
aip->path_cur = -1;
|
||||
@@ -370,25 +369,20 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
object *target_objp;
|
||||
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
|
||||
if ( aip->target_objnum < 0 )
|
||||
return 0;
|
||||
|
||||
target_objp = &Objects[aip->target_objnum];
|
||||
|
||||
if ( (aip->targeted_subsys != NULL) && (aip->targeted_subsys->system_info->path_num >= 0) ) {
|
||||
if ( (aip->targeted_subsys != NULL) && (aip->target_objnum >= 0) && (aip->targeted_subsys->system_info->path_num >= 0) ) {
|
||||
polymodel *pm;
|
||||
int subsys_path_num, subsys_in_sight, checked_sight;
|
||||
float dist;
|
||||
|
||||
// Get models of both source and target
|
||||
polymodel *pm = model_get( Ship_info[Ships[Pl_objp->instance].ship_info_index].model_num );
|
||||
polymodel *pm_t = model_get( Ship_info[Ships[target_objp->instance].ship_info_index].model_num );
|
||||
|
||||
// Necessary sanity check
|
||||
Assertion(aip->targeted_subsys->system_info->path_num < pm_t->n_paths, "Invalid Path number %d for subsystem %s on ship %s (Model: %s)\n", aip->targeted_subsys->system_info->path_num, aip->targeted_subsys->system_info->name, Ship_info[Ships[target_objp->instance].ship_info_index].name, pm_t->filename );
|
||||
if (aip->targeted_subsys->system_info->path_num >= pm_t->n_paths)
|
||||
pm = model_get( Ship_info[Ships[Pl_objp->instance].ship_info_index].model_num );
|
||||
//Necessary sanity check
|
||||
polymodel *pm_t;
|
||||
pm_t = model_get(Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].model_num);
|
||||
Assertion(aip->targeted_subsys->system_info->path_num <= pm_t->n_paths, "Invalid Path number %d for subsystem %s on ship %s (Model: %s)\n", aip->targeted_subsys->system_info->path_num, aip->targeted_subsys->system_info->name, Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].name, pm_t->filename );
|
||||
if (aip->targeted_subsys->system_info->path_num > pm_t->n_paths)
|
||||
return 0;
|
||||
|
||||
// If attacking a subsystem, ensure that we have an unobstructed line of sight... if not, then move
|
||||
// towards path linked to subsystem
|
||||
subsys_in_sight = 0; // assume Pl_objp doesn't have line of sight to subys
|
||||
@@ -432,13 +426,13 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
|
||||
aip->path_goal_dist = 5;
|
||||
subsys_path_num = aip->targeted_subsys->system_info->path_num;
|
||||
if ( ((aip->path_start) == -1 || (aip->mp_index != subsys_path_num)) && subsys_path_num < pm_t->n_paths ) {
|
||||
if ( ((aip->path_start) == -1 || (aip->mp_index != subsys_path_num)) && subsys_path_num <= pm->n_paths ) {
|
||||
// maybe create a new path
|
||||
if ( subsys_path_num >= 0 ) {
|
||||
Assert(aip->target_objnum >= 0);
|
||||
ai_find_path(Pl_objp, aip->target_objnum, subsys_path_num, 0, 1);
|
||||
if ( aip->path_start >= 0 ) {
|
||||
aip->ai_flags.set(AI::AI_Flags::On_subsys_path);
|
||||
aip->ai_flags |= AIF_ON_SUBSYS_PATH;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -510,7 +504,7 @@ int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
{
|
||||
// if moving slowly (or stopped), and SIF_SMALL_SHIP, then enter STRAFE mode if enemy fighter/bombers
|
||||
// are near
|
||||
if ( sip->is_small_ship() ) {
|
||||
if ( sip->flags & SIF_SMALL_SHIP ) {
|
||||
if ( timestamp_elapsed(aip->scan_for_enemy_timestamp) ) {
|
||||
ship_obj *so;
|
||||
object *test_objp;
|
||||
@@ -525,7 +519,7 @@ int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
test_sp = &Ships[test_objp->instance];
|
||||
|
||||
if ( iff_x_attacks_y(Ships[Pl_objp->instance].team, test_sp->team) ) {
|
||||
if ( Ship_info[test_sp->ship_info_index].is_small_ship() ) {
|
||||
if ( Ship_info[test_sp->ship_info_index].flags & SIF_SMALL_SHIP ) {
|
||||
dist_squared = vm_vec_dist_squared(&Pl_objp->pos, &test_objp->pos);
|
||||
if ( dist_squared < ENTER_STRAFE_THREAT_DIST_SQUARED ) {
|
||||
return 1;
|
||||
@@ -593,7 +587,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
} // end if ( Pl_objp->phys_info.speed < 3.0f )
|
||||
|
||||
//Maybe enter glide strafe (check every 8 seconds, on a different schedule for each ship)
|
||||
if ((sip->can_glide == true) && !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && static_randf((Missiontime + static_rand(aip->shipnum)) >> 19) < aip->ai_glide_strafe_percent) {
|
||||
if ((sip->can_glide == true) && !(aip->ai_flags & AIF_KAMIKAZE) && static_randf((Missiontime + static_rand(aip->shipnum)) >> 19) < aip->ai_glide_strafe_percent) {
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_STRAFE;
|
||||
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
|
||||
@@ -604,15 +598,11 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
|
||||
// see if Pl_objp needs to reposition to get a good shot at subsystem which is being attacked
|
||||
if ( ai_big_maybe_follow_subsys_path() ) {
|
||||
if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze])) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vec3d *rel_pos;
|
||||
vec3d vec_to_enemy;
|
||||
float weapon_travel_dist;
|
||||
vec3d *rel_pos, vec_to_enemy;
|
||||
float weapon_travel_dist;
|
||||
|
||||
start_bank = Ships[aip->shipnum].weapons.current_primary_bank;
|
||||
|
||||
@@ -637,25 +627,11 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
weapon_travel_dist = ai_get_weapon_dist(&Ships[Pl_objp->instance].weapons);
|
||||
|
||||
if ( aip->targeted_subsys != NULL ) {
|
||||
if (dist_to_enemy > (weapon_travel_dist-20)) {
|
||||
if (dist_to_enemy > (weapon_travel_dist-20))
|
||||
accelerate_ship(aip, 1.0f);
|
||||
|
||||
ship *shipp = &Ships[Pl_objp->instance];
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (dot_to_enemy > 0.75f)) {
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
aip->afterburner_stop_time = Missiontime + 3*F1_0;
|
||||
}
|
||||
} else if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze])) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
} else {
|
||||
else {
|
||||
// AL 12-31-97: Move at least as quickly as your target is moving...
|
||||
accelerate_ship(aip, MAX(1.0f - dot_to_enemy, Objects[aip->target_objnum].phys_info.fspeed/sip->max_speed));
|
||||
|
||||
if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze])) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -676,22 +652,10 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
if (dist_to_enemy < ATTACK_STOP_DISTANCE) {
|
||||
// accelerate_ship(aip, accel * 0.5f);
|
||||
accelerate_ship(aip, -1.0f);
|
||||
if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze])) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
} else {
|
||||
accelerate_ship(aip, accel);
|
||||
|
||||
ship *shipp = &Ships[Pl_objp->instance];
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel > 0.95f)) {
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
aip->afterburner_stop_time = Missiontime + 3*F1_0;
|
||||
}
|
||||
} else if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze])) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -748,77 +712,84 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
|
||||
}
|
||||
|
||||
if (tswp->num_secondary_banks > 0) {
|
||||
if (!(En_objp->flags[Object::Object_Flags::Protected]) || (aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP))) {
|
||||
|
||||
int priority1, priority2;
|
||||
|
||||
priority1 = -1;
|
||||
priority2 = -1;
|
||||
|
||||
// Maybe favor selecting a bomb.
|
||||
// Note, if you're firing a bomb, if it's aspect seeking, the firing conditions can be looser.
|
||||
if (Ship_info[Ships[En_objp->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))
|
||||
if (En_objp->phys_info.speed * dist_to_enemy < 5000.0f) // Don't select a bomb if enemy moving fast relative to distance
|
||||
priority1 = WIF_BOMB;
|
||||
|
||||
if (!(En_objp->flags & OF_PROTECTED)) {
|
||||
//ai_select_secondary_weapon(Pl_objp, tswp, priority1, priority2); // Note, need to select to get weapon speed and lifetime
|
||||
|
||||
ai_choose_secondary_weapon(Pl_objp, aip, En_objp);
|
||||
int current_bank = tswp->current_secondary_bank;
|
||||
if (current_bank > -1) {
|
||||
weapon_info *swip = &Weapon_info[tswp->secondary_bank_weapons[current_bank]];
|
||||
weapon_info *swip = &Weapon_info[tswp->secondary_bank_weapons[current_bank]];
|
||||
|
||||
if(!(En_objp->flags[Object::Object_Flags::Protected]) || ((aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP)) && swip->wi_flags[Weapon::Info_Flags::Puncture] )) { //override lockdown on protected ships when using anti subsystem weapons - Valathil
|
||||
// If ship is protected and very low on hits, don't fire missiles.
|
||||
if (!(En_objp->flags[Object::Object_Flags::Protected]) || (En_objp->hull_strength > 10*swip->damage)) {
|
||||
if (aip->ai_flags[AI::AI_Flags::Unload_secondaries]) {
|
||||
if (timestamp_until(swp->next_secondary_fire_stamp[current_bank]) > swip->fire_wait*1000.0f) {
|
||||
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (swip->fire_wait*1000.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank])) {
|
||||
float firing_range;
|
||||
if (swip->wi_flags[Weapon::Info_Flags::Local_ssm])
|
||||
firing_range=swip->lssm_lock_range;
|
||||
else
|
||||
firing_range = MIN((swip->max_speed * swip->lifetime), swip->weapon_range);
|
||||
// reduce firing range of secondaries in nebula
|
||||
extern int Nebula_sec_range;
|
||||
if ((The_mission.flags[Mission::Mission_Flags::Fullneb]) && Nebula_sec_range) {
|
||||
firing_range *= 0.8f;
|
||||
}
|
||||
|
||||
float t = 0.25f; // default delay in seconds until next fire.
|
||||
|
||||
if (dist_to_enemy < firing_range*1.0f) {
|
||||
|
||||
|
||||
//vm_vec_scale_add(&future_enemy_pos, enemy_pos, enemy_vel, dist_to_enemy/swip->max_speed);
|
||||
//if (vm_vec_dist_quick(&future_enemy_pos, firing_pos) < firing_range * 0.8f) {
|
||||
if (ai_fire_secondary_weapon(Pl_objp)) {
|
||||
|
||||
int current_bank_adjusted = MAX_SHIP_PRIMARY_BANKS + current_bank;
|
||||
|
||||
if ((aip->ai_flags[AI::AI_Flags::Unload_secondaries]) || (swip->burst_flags[Weapon::Burst_Flags::Fast_firing])) {
|
||||
if (swip->burst_shots > swp->burst_counter[current_bank_adjusted]) {
|
||||
t = swip->burst_delay;
|
||||
swp->burst_counter[current_bank_adjusted]++;
|
||||
} else {
|
||||
t = swip->fire_wait;
|
||||
if ((swip->burst_shots > 0) && (swip->burst_flags[Weapon::Burst_Flags::Random_length])) {
|
||||
swp->burst_counter[current_bank_adjusted] = myrand() % swip->burst_shots;
|
||||
} else {
|
||||
swp->burst_counter[current_bank_adjusted] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (swip->burst_shots > swp->burst_counter[current_bank_adjusted]) {
|
||||
t = set_secondary_fire_delay(aip, temp_shipp, swip, true);
|
||||
swp->burst_counter[current_bank_adjusted]++;
|
||||
} else {
|
||||
t = set_secondary_fire_delay(aip, temp_shipp, swip, false);
|
||||
if ((swip->burst_shots > 0) && (swip->burst_flags[Weapon::Burst_Flags::Random_length])) {
|
||||
swp->burst_counter[current_bank_adjusted] = myrand() % swip->burst_shots;
|
||||
} else {
|
||||
swp->burst_counter[current_bank_adjusted] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (t*1000.0f));
|
||||
}
|
||||
//}
|
||||
}
|
||||
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (t*1000.0f));
|
||||
}
|
||||
// If ship is protected and very low on hits, don't fire missiles.
|
||||
if ((current_bank > -1) && (!(En_objp->flags & OF_PROTECTED) || (En_objp->hull_strength > 10*swip->damage))) {
|
||||
if (aip->ai_flags & AIF_UNLOAD_SECONDARIES) {
|
||||
if (timestamp_until(swp->next_secondary_fire_stamp[current_bank]) > swip->fire_wait*1000.0f) {
|
||||
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (swip->fire_wait*1000.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank])) {
|
||||
float firing_range;
|
||||
if (swip->wi_flags2 & WIF2_LOCAL_SSM)
|
||||
firing_range=swip->lssm_lock_range;
|
||||
else
|
||||
firing_range = MIN((swip->max_speed * swip->lifetime), swip->weapon_range);
|
||||
// reduce firing range of secondaries in nebula
|
||||
extern int Nebula_sec_range;
|
||||
if ((The_mission.flags & MISSION_FLAG_FULLNEB) && Nebula_sec_range) {
|
||||
firing_range *= 0.8f;
|
||||
}
|
||||
|
||||
float t = 0.25f; // default delay in seconds until next fire.
|
||||
|
||||
if (dist_to_enemy < firing_range*1.0f) {
|
||||
|
||||
|
||||
//vm_vec_scale_add(&future_enemy_pos, enemy_pos, enemy_vel, dist_to_enemy/swip->max_speed);
|
||||
//if (vm_vec_dist_quick(&future_enemy_pos, firing_pos) < firing_range * 0.8f) {
|
||||
if (ai_fire_secondary_weapon(Pl_objp)) {
|
||||
if ((aip->ai_flags & AIF_UNLOAD_SECONDARIES) || (swip->burst_flags & WBF_FAST_FIRING)) {
|
||||
if (swip->burst_shots > swp->burst_counter[current_bank]) {
|
||||
t = swip->burst_delay;
|
||||
swp->burst_counter[current_bank]++;
|
||||
} else {
|
||||
t = swip->fire_wait;
|
||||
if ((swip->burst_shots > 0) && (swip->burst_flags & WBF_RANDOM_LENGTH)) {
|
||||
swp->burst_counter[current_bank] = myrand() % swip->burst_shots;
|
||||
} else {
|
||||
swp->burst_counter[current_bank] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (swip->burst_shots > swp->burst_counter[current_bank]) {
|
||||
t = set_secondary_fire_delay(aip, temp_shipp, swip, true);
|
||||
swp->burst_counter[current_bank]++;
|
||||
} else {
|
||||
t = set_secondary_fire_delay(aip, temp_shipp, swip, false);
|
||||
if ((swip->burst_shots > 0) && (swip->burst_flags & WBF_RANDOM_LENGTH)) {
|
||||
swp->burst_counter[current_bank] = myrand() % swip->burst_shots;
|
||||
} else {
|
||||
swp->burst_counter[current_bank] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (t*1000.0f));
|
||||
}
|
||||
//}
|
||||
}
|
||||
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (t*1000.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -881,20 +852,17 @@ void ai_big_chase()
|
||||
dist_to_enemy = vm_vec_normalized_dir(&vec_to_enemy, &enemy_pos, &player_pos); // - En_objp->radius;
|
||||
dot_to_enemy = vm_vec_dot(&vec_to_enemy, &Pl_objp->orient.vec.fvec);
|
||||
|
||||
if (aip->ai_flags[AI::AI_Flags::Target_collision]) {
|
||||
if (aip->ai_flags & AIF_TARGET_COLLISION) {
|
||||
if ( ai_big_strafe_maybe_retreat(dist_to_enemy, &enemy_pos) ) {
|
||||
aip->mode = AIM_STRAFE;
|
||||
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
|
||||
aip->submode = AIS_STRAFE_AVOID;
|
||||
aip->submode_start_time = Missiontime;
|
||||
if (Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aip->ai_flags[AI::AI_Flags::Kamikaze]) {
|
||||
if (aip->ai_flags & AIF_KAMIKAZE) {
|
||||
//nprintf(("AI", "Kamikaze: %7.3f %7.3f\n", dot_to_enemy, dist_to_enemy));
|
||||
accelerate_ship(aip, 1.0f);
|
||||
if ((dist_to_enemy < 400.0f) && ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
@@ -904,7 +872,7 @@ void ai_big_chase()
|
||||
}
|
||||
|
||||
// If just acquired target, or target is not in reasonable cone, don't refine believed enemy position.
|
||||
if ((dot_to_enemy < 0.25f) || (aip->target_time < 1.0f) || (aip->ai_flags[AI::AI_Flags::Seek_lock])) {
|
||||
if ((dot_to_enemy < 0.25f) || (aip->target_time < 1.0f) || (aip->ai_flags & AIF_SEEK_LOCK)) {
|
||||
update_aspect_lock_information(aip, &vec_to_enemy, dist_to_enemy - En_objp->radius, En_objp->radius);
|
||||
} else if (aip->targeted_subsys != NULL) {
|
||||
Assert(aip->targeted_subsys != NULL);
|
||||
@@ -914,10 +882,10 @@ void ai_big_chase()
|
||||
dist_to_enemy = vm_vec_normalized_dir(&vec_to_enemy, &enemy_pos, &player_pos); // - En_objp->radius;
|
||||
dot_to_enemy = vm_vec_dot(&vec_to_enemy, &Pl_objp->orient.vec.fvec);
|
||||
update_aspect_lock_information(aip, &vec_to_enemy, dist_to_enemy, En_objp->radius);
|
||||
} else if (En_objp->flags[Object::Object_Flags::Protected]) { // If protected and we're not attacking a subsystem, stop attacking!
|
||||
} else if (En_objp->flags & OF_PROTECTED) { // If protected and we're not attacking a subsystem, stop attacking!
|
||||
update_aspect_lock_information(aip, &vec_to_enemy, dist_to_enemy - En_objp->radius, En_objp->radius);
|
||||
aip->target_objnum = -1;
|
||||
if (find_enemy(OBJ_INDEX(Pl_objp), MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level]) == -1) {
|
||||
if (find_enemy(Pl_objp-Objects, MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level]) == -1) {
|
||||
ai_do_default_behavior(Pl_objp);
|
||||
return;
|
||||
}
|
||||
@@ -930,12 +898,8 @@ void ai_big_chase()
|
||||
case SM_ATTACK:
|
||||
case SM_SUPER_ATTACK:
|
||||
if (vm_vec_dist_quick(&Pl_objp->pos, &predicted_enemy_pos) > 100.0f + En_objp->radius * 2.0f) {
|
||||
if (maybe_avoid_big_ship(Pl_objp, En_objp, aip, &predicted_enemy_pos, 10.0f)) {
|
||||
if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze])) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
if (maybe_avoid_big_ship(Pl_objp, En_objp, aip, &predicted_enemy_pos, 10.0f))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aip->target_time < 2.0f)
|
||||
@@ -951,13 +915,6 @@ void ai_big_chase()
|
||||
//
|
||||
// Set turn and acceleration based on submode.
|
||||
//
|
||||
|
||||
if (((aip->submode != SM_ATTACK) && (aip->submode != SM_SUPER_ATTACK) && (aip->submode != SM_ATTACK_FOREVER) && (aip->submode != SM_EVADE_WEAPON)) || (aip->mode == AIM_STRAFE)){
|
||||
if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze])) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
}
|
||||
|
||||
switch (aip->submode) {
|
||||
case SM_CONTINUOUS_TURN:
|
||||
ai_big_chase_ct();
|
||||
@@ -1174,7 +1131,7 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
|
||||
Assert(aip->mode == AIM_STRAFE);
|
||||
|
||||
// ensure that Pl_objp is still targeting a big ship
|
||||
if ( !(esip->is_big_or_huge()) ) {
|
||||
if ( !(esip->flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) ) {
|
||||
ai_big_switch_to_chase_mode(aip);
|
||||
return;
|
||||
}
|
||||
@@ -1198,7 +1155,7 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
|
||||
// If just acquired target, or target is not in reasonable cone, don't refine believed enemy position.
|
||||
vm_vec_normalized_dir(&vec_to_enemy, enemy_pos, &player_pos);
|
||||
*dot_to_enemy=vm_vec_dot(&vec_to_enemy, &Pl_objp->orient.vec.fvec);
|
||||
if ((*dot_to_enemy < 0.25f) || (aip->target_time < 1.0f) || (aip->ai_flags[AI::AI_Flags::Seek_lock])) {
|
||||
if ((*dot_to_enemy < 0.25f) || (aip->target_time < 1.0f) || (aip->ai_flags & AIF_SEEK_LOCK)) {
|
||||
predicted_enemy_pos=*enemy_pos;
|
||||
} else {
|
||||
vec3d gun_pos, pnt;
|
||||
@@ -1206,7 +1163,7 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
|
||||
float weapon_speed;
|
||||
|
||||
// Compute position of gun in absolute space and use that as fire position.
|
||||
if (po->n_guns > 0 && !(The_mission.ai_profile->flags[AI::Profile_Flags::Ai_aims_from_ship_center])) {
|
||||
if (po->n_guns > 0 && !(The_mission.ai_profile->flags2 & AIPF2_AI_AIMS_FROM_SHIP_CENTER)) {
|
||||
pnt = po->gun_banks[0].pnt[0];
|
||||
vm_vec_unrotate(&gun_pos, &pnt, &Pl_objp->orient);
|
||||
vm_vec_add2(&gun_pos, &Pl_objp->pos);
|
||||
@@ -1239,7 +1196,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);
|
||||
}
|
||||
@@ -1254,19 +1211,20 @@ int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
|
||||
|
||||
// Inside 2 sec retreat, setting goal point to box point + 300m
|
||||
// If collision, use std collision resolution.
|
||||
if ( !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && ((aip->ai_flags[AI::AI_Flags::Target_collision]) || (time_to_target < STRAFE_RETREAT_COLLIDE_TIME) || (dist_normal_to_target < STRAFE_RETREAT_COLLIDE_DIST + speed_to_dist_penalty)) ) {
|
||||
if (aip->ai_flags[AI::AI_Flags::Target_collision]) {
|
||||
if ( !(aip->ai_flags & AIF_KAMIKAZE) && ((aip->ai_flags & AIF_TARGET_COLLISION) || (time_to_target < STRAFE_RETREAT_COLLIDE_TIME) || (dist_normal_to_target < STRAFE_RETREAT_COLLIDE_DIST + speed_to_dist_penalty)) ) {
|
||||
if (aip->ai_flags & AIF_TARGET_COLLISION) {
|
||||
// use standard collision resolution
|
||||
aip->ai_flags.remove(AI::AI_Flags::Target_collision);
|
||||
aip->ai_flags &= ~AIF_TARGET_COLLISION;
|
||||
big_ship_collide_recover_start(Pl_objp, En_objp, &Pl_objp->pos, NULL);
|
||||
} else {
|
||||
// too close for comfort so fly to box point + 300
|
||||
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;
|
||||
@@ -1301,7 +1259,7 @@ void ai_big_strafe_attack()
|
||||
if ( ai_big_strafe_maybe_retreat(target_dist, &target_pos) )
|
||||
return;
|
||||
|
||||
if (aip->ai_flags[AI::AI_Flags::Kamikaze]) {
|
||||
if (aip->ai_flags & AIF_KAMIKAZE) {
|
||||
if (target_dist < 1200.0f) {
|
||||
ai_turn_towards_vector(&target_pos, Pl_objp, flFrametime, Ship_info[Ships[Pl_objp->instance].ship_info_index].srotation_time, NULL, NULL, 0.0f, 0);
|
||||
accelerate_ship(aip, 1.0f);
|
||||
@@ -1313,7 +1271,7 @@ void ai_big_strafe_attack()
|
||||
}
|
||||
}
|
||||
|
||||
if (!(aip->ai_flags[AI::AI_Flags::Seek_lock]) || (aip->aspect_locked_time < 2.0f)) {
|
||||
if (!(aip->ai_flags & AIF_SEEK_LOCK) || (aip->aspect_locked_time < 2.0f)) {
|
||||
t = ai_endangered_by_weapon(aip);
|
||||
if ( t > 0.0f && t < 1.5f ) {
|
||||
// set up goal_point for avoid path to turn towards
|
||||
@@ -1350,30 +1308,27 @@ void ai_big_strafe_attack()
|
||||
ai_big_maybe_fire_weapons(target_dist, target_dot, &Pl_objp->pos, &En_objp->pos, &En_objp->phys_info.vel);
|
||||
turn_towards_point(Pl_objp, &target_pos, NULL, 0.0f);
|
||||
|
||||
// Slow down if we've not been hit for a while
|
||||
fix last_hit = Missiontime - aip->last_hit_time;
|
||||
if ( aip->ai_profile_flags[AI::Profile_Flags::Ai_can_slow_down_attacking_big_ships] ) {
|
||||
// Slow down if we've not been hit for a while
|
||||
if ( target_dist > 1200 || last_hit < F1_0*6) {
|
||||
accel = 1.0f;
|
||||
} else {
|
||||
float attack_time;
|
||||
attack_time = f2fl(Missiontime - aip->submode_start_time);
|
||||
if ( attack_time > 15 ) {
|
||||
accel = 0.2f;
|
||||
} else if ( attack_time > 10 ) {
|
||||
accel = 0.4f;
|
||||
} else if ( attack_time > 8 ) {
|
||||
accel = 0.6f;
|
||||
} else if ( attack_time > 5 ) {
|
||||
accel = 0.8f;
|
||||
} else {
|
||||
accel = 1.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( target_dist > 1200 || last_hit < F1_0*6) {
|
||||
accel = 1.0f;
|
||||
} else {
|
||||
float attack_time;
|
||||
attack_time = f2fl(Missiontime - aip->submode_start_time);
|
||||
if ( attack_time > 15 ) {
|
||||
accel = 0.2f;
|
||||
} else if ( attack_time > 10 ) {
|
||||
accel = 0.4f;
|
||||
} else if ( attack_time > 8 ) {
|
||||
accel = 0.6f;
|
||||
} else if ( attack_time > 5 ) {
|
||||
accel = 0.8f;
|
||||
} else {
|
||||
accel = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
accel = 1.0f;
|
||||
accelerate_ship(aip, accel);
|
||||
|
||||
// if haven't been hit in quite a while, leave strafe mode
|
||||
@@ -1622,7 +1577,7 @@ void ai_big_strafe_position()
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
|
||||
//Maybe use AIS_STRAFE_GLIDE_ATTACK
|
||||
if ((sip->can_glide == true) && !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && (frand() < aip->ai_glide_strafe_percent)) {
|
||||
if ((sip->can_glide == true) && !(aip->ai_flags & AIF_KAMIKAZE) && (frand() < aip->ai_glide_strafe_percent)) {
|
||||
aip->submode = AIS_STRAFE_GLIDE_ATTACK;
|
||||
aip->submode_parm1 = 0;
|
||||
} else {
|
||||
@@ -1654,7 +1609,7 @@ void ai_big_strafe()
|
||||
}
|
||||
*/
|
||||
// check if target is still a big ship... if not enter chase mode
|
||||
if ( !(Ship_info[Ships[En_objp->instance].ship_info_index].is_big_or_huge()) ) {
|
||||
if ( !(Ship_info[Ships[En_objp->instance].ship_info_index].flags & (SIF_BIG_SHIP|SIF_HUGE_SHIP)) ) {
|
||||
ai_big_switch_to_chase_mode(aip);
|
||||
return;
|
||||
}
|
||||
@@ -1727,12 +1682,12 @@ int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consi
|
||||
|
||||
// if Pl_objp's target is not a big/capital ship, then cannot enter strafe mode
|
||||
// AL 12-31-97: Even though transports are considered big ships, don't enter strafe mode on them
|
||||
if ( !(sip->is_big_or_huge()) || (sip->flags[Ship::Info_Flags::Transport]) ) {
|
||||
if ( !(sip->flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) || (sip->flags & SIF_TRANSPORT) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If Pl_objp not a fighter or bomber, don't enter strafe mode. -- MK, 11/11/97.
|
||||
if ( !(Ship_info[Ships[pl_objp->instance].ship_info_index].is_fighter_bomber()) ) {
|
||||
if ( !(Ship_info[Ships[pl_objp->instance].ship_info_index].flags & (SIF_FIGHTER | SIF_BOMBER)) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1754,7 +1709,7 @@ int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consi
|
||||
//JAS IMPOSSIBLE } else {
|
||||
// switch targets
|
||||
sip = &Ship_info[Ships[parent_objp->instance].ship_info_index];
|
||||
if ( !(sip->is_big_or_huge()) || (sip->flags[Ship::Info_Flags::Transport]) ) {
|
||||
if ( !(sip->flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) || (sip->flags & SIF_TRANSPORT) ) {
|
||||
return 0;
|
||||
}
|
||||
set_target_objnum(aip, OBJ_INDEX(parent_objp));
|
||||
@@ -1809,8 +1764,8 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
|
||||
// the ai will not always go after different ships firing beams at them.
|
||||
// Approx 1/4 chance we'll go after the other ship's beam.
|
||||
|
||||
bool attack_turret_on_different_ship = (aip->ai_profile_flags[AI::Profile_Flags::Big_ships_can_attack_beam_turrets_on_untargeted_ships])
|
||||
&& (Weapon_info[Weapons[weapon_objp->instance].weapon_info_index].wi_flags[Weapon::Info_Flags::Beam]) && (frand()*100 < 25.0f);
|
||||
bool attack_turret_on_different_ship = (aip->ai_profile_flags & AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS)
|
||||
&& (Weapon_info[Weapons[weapon_objp->instance].weapon_info_index].wi_flags & WIF_BEAM) && (frand()*100 < 25.0f);
|
||||
|
||||
// unless we're making an exception, we should only attack a turret if it sits on the current target
|
||||
if ( !attack_turret_on_different_ship )
|
||||
|
||||
+2
-2
@@ -12,10 +12,10 @@
|
||||
#ifndef __AIBIG_H__
|
||||
#define __AIBIG_H__
|
||||
|
||||
class object;
|
||||
struct object;
|
||||
struct ai_info;
|
||||
struct vec3d;
|
||||
class ship_subsys;
|
||||
struct ship_subsys;
|
||||
|
||||
void ai_big_ship(object *objp);
|
||||
void ai_big_chase();
|
||||
|
||||
+1068
-1378
File diff suppressed because it is too large.
Load diff
+84
-88
@@ -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
|
||||
@@ -93,7 +93,7 @@ int Num_ai_goals = sizeof(Ai_goal_names) / sizeof(ai_goal_list);
|
||||
// HUD what a ship's current orders are. If the AI goal doesn't correspond to something that
|
||||
// ought to be printable, then NULL is used.
|
||||
// JAS: Converted to a function in order to externalize the strings
|
||||
const char *Ai_goal_text(int goal)
|
||||
char *Ai_goal_text(int goal)
|
||||
{
|
||||
switch(goal) {
|
||||
case 1:
|
||||
@@ -131,9 +131,18 @@ const char *Ai_goal_text(int goal)
|
||||
}
|
||||
|
||||
// function to maybe add the form on my wing goal for a player's starting wing. Called when a player wing arrives.
|
||||
// Goober5000 - made more generic
|
||||
void ai_maybe_add_form_goal( wing *wingp )
|
||||
{
|
||||
int j;
|
||||
char *wing_leader;
|
||||
|
||||
// if the wing leader isn't available (ie, dead/departed) then go ahead and bail now
|
||||
if (wingp->ship_index[wingp->special_ship] < 0)
|
||||
return;
|
||||
|
||||
// Goober5000 - the wing leader is now not necessarily the player
|
||||
wing_leader = Ships[wingp->ship_index[wingp->special_ship]].ship_name;
|
||||
|
||||
// iterate through the ship_index list of this wing and check for orders. We will do
|
||||
// this for all ships in the wing instead of on a wing only basis in case some ships
|
||||
@@ -143,15 +152,20 @@ void ai_maybe_add_form_goal( wing *wingp )
|
||||
|
||||
Assert( wingp->ship_index[j] != -1 ); // get Allender
|
||||
|
||||
// don't process wing leader
|
||||
if (j == wingp->special_ship)
|
||||
continue;
|
||||
|
||||
aip = &Ai_info[Ships[wingp->ship_index[j]].ai_index];
|
||||
|
||||
// don't process Player_ship
|
||||
if ( aip == Player_ai )
|
||||
continue;
|
||||
|
||||
// it is sufficient enough to check the first goal entry to see if it has a valid goal
|
||||
if ( aip->goals[0].ai_mode == AI_GOAL_NONE ) {
|
||||
// need to add a form on my wing goal here. Ships are always forming on the player's wing.
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, Player_ship->ship_name, aip );
|
||||
// need to add a form on my wing goal here
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, wing_leader, aip );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,28 +173,38 @@ void ai_maybe_add_form_goal( wing *wingp )
|
||||
void ai_post_process_mission()
|
||||
{
|
||||
object *objp;
|
||||
int i;
|
||||
|
||||
/*
|
||||
// Goober5000 - considering that this is also done in parse_wing_create_ships,
|
||||
// it's redundant (and possibly premature for some wings) here
|
||||
|
||||
// Check ships in player starting wings. Those ships should follow these rules:
|
||||
// (1) if they have no orders, they should get a form on my wing order
|
||||
// (2) if they have an order, they are free to act on it.
|
||||
//
|
||||
// So basically, we are checking for (1)
|
||||
if ( !Fred_running ) {
|
||||
// MK, 5/9/98: Used to iterate through MAX_STARTING_WINGS, but this was too many ships forming on player.
|
||||
// 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) {
|
||||
wing *wingp;
|
||||
if ( !Fred_running )
|
||||
{
|
||||
int i;
|
||||
|
||||
wingp = &Wings[Starting_wings[i]];
|
||||
|
||||
ai_maybe_add_form_goal( wingp );
|
||||
|
||||
}
|
||||
// Goober5000 - make all wings form on their respective leaders
|
||||
for ( i = 0; i < Num_wings; i++ )
|
||||
{
|
||||
ai_maybe_add_form_goal( &Wings[i] );
|
||||
}
|
||||
|
||||
// for ( i = 0; i < 1; i++ ) { // MK, 5/9/98: Used to iterate through MAX_STARTING_WINGS, but this was too many ships forming on player.
|
||||
// if ( Starting_wings[i] != -1 ) {
|
||||
// wing *wingp;
|
||||
//
|
||||
// wingp = &Wings[Starting_wings[i]];
|
||||
//
|
||||
// ai_maybe_add_form_goal( wingp );
|
||||
//
|
||||
// }
|
||||
// }
|
||||
}
|
||||
*/
|
||||
|
||||
// for every valid ship object, call process_mission_orders to be sure that ships start the
|
||||
// mission following the orders in the mission file right away instead of waiting N seconds
|
||||
@@ -199,17 +223,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 +238,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;
|
||||
}
|
||||
}
|
||||
@@ -526,14 +545,14 @@ int ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
|
||||
// insanity?
|
||||
if (loop_count >= 100)
|
||||
Warning(LOCATION, "Too many iterations while looking for a dockpoint on %s.\n", shipp->ship_name);
|
||||
Warning(LOCATION, "Too many iterations while looking for a dockpoint on %s. Either there was a bug or this is an übership.\n", shipp->ship_name);
|
||||
|
||||
// if we're here, just return the first dockpoint
|
||||
return model_find_dock_index(Ship_info[shipp->ship_info_index].model_num, 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 +561,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;
|
||||
|
||||
@@ -584,10 +602,10 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
|
||||
// look for docking points of the appriopriate type. Use cargo docks for cargo ships.
|
||||
/*
|
||||
if (Ship_info[Ships[shipnum].ship_info_index].flags[Ship::Info_Flags::Cargo]) {
|
||||
if (Ship_info[Ships[shipnum].ship_info_index].flags & SIF_CARGO) {
|
||||
docker_index = ai_goal_find_dockpoint(aip->shipnum, DOCK_TYPE_CARGO);
|
||||
dockee_index = ai_goal_find_dockpoint(shipnum, DOCK_TYPE_CARGO);
|
||||
} else if (Ship_info[Ships[aip->shipnum].ship_info_index].flags[Ship::Info_Flags::Support]) {
|
||||
} else if (Ship_info[Ships[aip->shipnum].ship_info_index].flags & SIF_SUPPORT) {
|
||||
docker_index = ai_goal_find_dockpoint(aip->shipnum, DOCK_TYPE_REARM);
|
||||
dockee_index = ai_goal_find_dockpoint(shipnum, DOCK_TYPE_REARM);
|
||||
}
|
||||
@@ -985,16 +1003,6 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
aigp->priority = MAX_GOAL_PRIORITY;
|
||||
}
|
||||
|
||||
// Goober5000 - we now have an extra optional chase argument to allow chasing our own team
|
||||
if ( op == OP_AI_CHASE || op == OP_AI_CHASE_WING || op == OP_AI_DISABLE_SHIP || op == OP_AI_DISARM_SHIP ) {
|
||||
if ((CDDDR(node) != -1) && is_sexp_true(CDDDR(node)))
|
||||
aigp->flags |= AIGF_TARGET_OWN_TEAM;
|
||||
}
|
||||
if ( op == OP_AI_DESTROY_SUBSYS ) {
|
||||
if ((CDDDDR(node) != -1) && is_sexp_true(CDDDDR(node)))
|
||||
aigp->flags |= AIGF_TARGET_OWN_TEAM;
|
||||
}
|
||||
|
||||
// Goober5000 - since none of the goals act on the actor,
|
||||
// don't assign the goal if the actor's goal target is itself
|
||||
if (aigp->target_name != NULL && !strcmp(aigp->target_name, actor_name))
|
||||
@@ -1387,20 +1395,16 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
ship *shipp = &Ships[objp->instance];
|
||||
|
||||
// always valid if has subspace drive
|
||||
if (!(shipp->flags[Ship::Ship_Flags::No_subspace_drive]))
|
||||
if (!(shipp->flags2 & SF2_NO_SUBSPACE_DRIVE))
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
|
||||
// if no subspace drive, only valid if our mothership is present
|
||||
// if no subspace drive, only valid if there's somewhere to depart to
|
||||
|
||||
// check that we have a mothership and that we can depart to it
|
||||
if (shipp->departure_location == DEPART_AT_DOCK_BAY)
|
||||
{
|
||||
int anchor_shipnum = ship_name_lookup(Parse_names[shipp->departure_anchor]);
|
||||
if (anchor_shipnum >= 0 && ship_useful_for_departure(anchor_shipnum, shipp->departure_path_mask))
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
}
|
||||
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
// locate a capital ship on the same team:
|
||||
if (ship_get_ship_with_dock_bay(shipp->team) >= 0)
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
else
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
}
|
||||
|
||||
|
||||
@@ -1466,13 +1470,8 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// for this goal to be valid).
|
||||
Assert ( aigp->ai_submode >= 0 );
|
||||
ssp = ship_get_indexed_subsys( &Ships[sindex], aigp->ai_submode );
|
||||
if (ssp != NULL) {
|
||||
status = mission_log_get_time( LOG_SHIP_SUBSYS_DESTROYED, aigp->target_name, ssp->system_info->subobj_name, NULL );
|
||||
} else {
|
||||
// not supposed to ever happen, but could if there is a mismatch between the table and model subsystems
|
||||
nprintf(("AI", "Couldn't find subsystem %d for ship %s\n", aigp->ai_submode, Ships[sindex].ship_name));
|
||||
status = 0;
|
||||
}
|
||||
status = mission_log_get_time( LOG_SHIP_SUBSYS_DESTROYED, aigp->target_name, ssp->system_info->subobj_name, NULL );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1499,17 +1498,13 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// checking departure and destroyed. In multiplayer, since ships can respawn,
|
||||
// they get log entries for being destroyed even though they have respawned.
|
||||
sindex = ship_name_lookup( aigp->target_name );
|
||||
if ( sindex < 0 ) {
|
||||
if ( sindex == -1 ) {
|
||||
status = mission_log_get_time( LOG_SHIP_DEPARTED, aigp->target_name, NULL, NULL);
|
||||
if ( !status ) {
|
||||
status = mission_log_get_time( LOG_SHIP_DESTROYED, aigp->target_name, NULL, NULL);
|
||||
if ( !status ) {
|
||||
status = mission_log_get_time( LOG_SELF_DESTRUCTED, aigp->target_name, NULL, NULL);
|
||||
}
|
||||
if ( status )
|
||||
return_val = AI_GOAL_NOT_ACHIEVABLE;
|
||||
}
|
||||
|
||||
if ( status )
|
||||
return_val = AI_GOAL_NOT_ACHIEVABLE;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
@@ -1573,7 +1568,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
wing *wingp = &Wings[sindex];
|
||||
|
||||
if ( wingp->flags[Ship::Wing_Flags::Gone] )
|
||||
if ( wingp->flags & WF_WING_GONE )
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
else if ( wingp->total_arrived_count == 0 )
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
@@ -1661,7 +1656,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
}
|
||||
|
||||
// if ship is disabled, don't know if it can dock or not
|
||||
if ( Ships[objp->instance].flags[Ship::Ship_Flags::Disabled] )
|
||||
if ( Ships[objp->instance].flags & SF_DISABLED )
|
||||
return AI_GOAL_NOT_KNOWN;
|
||||
|
||||
// we must also determine if we're prevented from docking for any reason
|
||||
@@ -1802,20 +1797,20 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
}
|
||||
|
||||
// if desitnation currently being repaired, then goal is stil active
|
||||
if ( Ai_info[Ships[sindex].ai_index].ai_flags[AI::AI_Flags::Being_repaired] )
|
||||
if ( Ai_info[Ships[sindex].ai_index].ai_flags & AIF_BEING_REPAIRED )
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
|
||||
// if the destination ship is dying or departing (but not completed yet), the mark goal as
|
||||
// not achievable.
|
||||
if ( Ships[sindex].is_dying_or_departing())
|
||||
if ( Ships[sindex].flags & (SF_DYING | SF_DEPARTING) )
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
|
||||
// if the destination object is no longer awaiting repair, then remove the item
|
||||
if ( !(Ai_info[Ships[sindex].ai_index].ai_flags[AI::AI_Flags::Awaiting_repair]) )
|
||||
if ( !(Ai_info[Ships[sindex].ai_index].ai_flags & AIF_AWAITING_REPAIR) )
|
||||
return AI_GOAL_NOT_ACHIEVABLE;
|
||||
|
||||
// not repairing anything means that he can do this goal!!!
|
||||
if ( !(aip->ai_flags[AI::AI_Flags::Repairing]) )
|
||||
if ( !(aip->ai_flags & AIF_REPAIRING) )
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
|
||||
// test code!!!
|
||||
@@ -1888,8 +1883,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 +2001,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) {
|
||||
@@ -2038,11 +2034,11 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
// if this object was flying in formation off of another object, remove the flag that tells him
|
||||
// to do this. The form-on-my-wing command is removed from the goal list as soon as it is called, so
|
||||
// we are safe removing this bit here.
|
||||
aip->ai_flags.remove(AI::AI_Flags::Formation_object);
|
||||
aip->ai_flags &= ~AIF_FORMATION_OBJECT;
|
||||
|
||||
// Goober5000 - we may want to use AI for the player
|
||||
// AL 3-7-98: If this is a player ship, and the goal is not a formation goal, then do a quick out
|
||||
if ( !(Player_use_ai) && (objp->flags[Object::Object_Flags::Player_ship]) && (current_goal->ai_mode != AI_GOAL_FORM_ON_WING) )
|
||||
if ( !(Player_use_ai) && (objp->flags & OF_PLAYER_SHIP) && (current_goal->ai_mode != AI_GOAL_FORM_ON_WING) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -2198,12 +2194,12 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
if (current_goal->ai_mode != AI_GOAL_DESTROY_SUBSYSTEM) {
|
||||
if (aip->target_objnum != -1) {
|
||||
// Only protect if _not_ a capital ship. We don't want the Lucifer accidentally getting protected.
|
||||
if (Ship_types[Ship_info[Ships[shipnum].ship_info_index].class_type].flags[Ship::Type_Info_Flags::AI_protected_on_cripple])
|
||||
Objects[aip->target_objnum].flags.set(Object::Object_Flags::Protected);
|
||||
if (Ship_types[Ship_info[Ships[shipnum].ship_info_index].class_type].ai_bools & STI_AI_PROTECTED_ON_CRIPPLE)
|
||||
Objects[aip->target_objnum].flags |= OF_PROTECTED;
|
||||
}
|
||||
} else // Just in case this ship had been protected, unprotect it.
|
||||
if (aip->target_objnum != -1)
|
||||
Objects[aip->target_objnum].flags.remove(Object::Object_Flags::Protected);
|
||||
Objects[aip->target_objnum].flags &= ~OF_PROTECTED;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2219,7 +2215,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
break;
|
||||
|
||||
case AI_GOAL_WARP: {
|
||||
mission_do_departure( objp, true );
|
||||
mission_do_departure( objp );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2292,7 +2288,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
|
||||
}
|
||||
|
||||
void ai_update_goal_references(ai_goal *goals, int type, const char *old_name, const char *new_name)
|
||||
void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
|
||||
{
|
||||
int i, mode, flag, dummy;
|
||||
|
||||
@@ -2359,7 +2355,7 @@ void ai_update_goal_references(ai_goal *goals, int type, const char *old_name, c
|
||||
}
|
||||
}
|
||||
|
||||
int query_referenced_in_ai_goals(ai_goal *goals, int type, const char *name)
|
||||
int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
|
||||
{
|
||||
int i, mode, flag;
|
||||
|
||||
@@ -2424,7 +2420,7 @@ int query_referenced_in_ai_goals(ai_goal *goals, int type, const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *ai_add_dock_name(const char *str)
|
||||
char *ai_add_dock_name(char *str)
|
||||
{
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
+5
-5
@@ -86,7 +86,7 @@ extern int Num_ai_goals;
|
||||
extern int Num_ai_dock_names;
|
||||
extern char Ai_dock_names[MAX_AI_DOCK_NAMES][NAME_LENGTH];
|
||||
|
||||
extern const char *Ai_goal_text(int goal);
|
||||
extern char *Ai_goal_text(int goal);
|
||||
|
||||
// extern function definitions
|
||||
extern void ai_post_process_mission();
|
||||
@@ -117,11 +117,11 @@ extern void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip );
|
||||
extern void ai_mission_goal_complete( ai_info *aip );
|
||||
extern void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp );
|
||||
|
||||
extern void ai_update_goal_references(ai_goal *goals, int type, const char *old_name, const char *new_name);
|
||||
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 void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name);
|
||||
extern int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name);
|
||||
extern char *ai_add_dock_name(char *str);
|
||||
|
||||
extern int ai_query_goal_valid( int ship, int ai_goal_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 );
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
+311
-621
File diff suppressed because it is too large.
Load diff
+21
-27
@@ -10,16 +10,17 @@
|
||||
|
||||
|
||||
#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"
|
||||
#include "graphics/material.h"
|
||||
|
||||
|
||||
|
||||
static color Color_xparent;
|
||||
|
||||
@@ -195,8 +196,8 @@ anim_instance *anim_play(anim_play_struct *aps)
|
||||
}
|
||||
|
||||
if(aps->base_w < 0 || aps->base_h < 0) {
|
||||
instance->base_w = gr_screen.max_w_unscaled_zoomed;
|
||||
instance->base_h = gr_screen.max_h_unscaled_zoomed;
|
||||
instance->base_w = gr_screen.max_w_unscaled;
|
||||
instance->base_h = gr_screen.max_h_unscaled;
|
||||
} else {
|
||||
instance->base_w = aps->base_w;
|
||||
instance->base_h = aps->base_h;
|
||||
@@ -253,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;
|
||||
@@ -460,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 ) {
|
||||
@@ -469,7 +472,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
if ( instance->last_bitmap != -1 ){
|
||||
bm_release(instance->last_bitmap);
|
||||
}
|
||||
bitmap_id = bm_create(bpp, instance->parent->width, instance->parent->height, instance->frame, bitmap_flags);
|
||||
bitmap_id = bm_create(16, instance->parent->width, instance->parent->height, instance->frame, bitmap_flags);
|
||||
}
|
||||
|
||||
if ( bitmap_id == -1 ) {
|
||||
@@ -485,35 +488,29 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
|
||||
// determine x,y to display the bitmap at
|
||||
if ( instance->world_pos == NULL ) {
|
||||
int old_max_w_unscaled = gr_screen.max_w_unscaled;
|
||||
int old_max_h_unscaled = gr_screen.max_h_unscaled;
|
||||
int old_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed;
|
||||
int old_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed;
|
||||
gr_set_screen_scale(instance->base_w, instance->base_h);
|
||||
gr_set_clip(0, 0, instance->base_w, instance->base_h, GR_RESIZE_MENU);
|
||||
gr_set_clip(0, 0, instance->base_w, instance->base_h, false);
|
||||
if ( instance->aa_color == NULL ) {
|
||||
gr_bitmap(instance->x, instance->y, GR_RESIZE_MENU_NO_OFFSET);
|
||||
gr_bitmap(instance->x, instance->y);
|
||||
}
|
||||
else {
|
||||
gr_set_color_fast( (color*)instance->aa_color );
|
||||
gr_aabitmap(instance->x, instance->y, GR_RESIZE_MENU_NO_OFFSET);
|
||||
gr_aabitmap(instance->x, instance->y);
|
||||
}
|
||||
gr_set_screen_scale(old_max_w_unscaled, old_max_h_unscaled, old_max_w_unscaled_zoomed, old_max_h_unscaled_zoomed);
|
||||
gr_reset_screen_scale();
|
||||
gr_reset_clip();
|
||||
}
|
||||
else {
|
||||
g3_rotate_vertex(&image_vertex,instance->world_pos);
|
||||
Assert(instance->radius != 0.0f);
|
||||
//g3_draw_bitmap(&image_vertex, 0, instance->radius*1.5f, TMAP_FLAG_TEXTURED | TMAP_HTL_2D);
|
||||
material mat_params;
|
||||
material_set_unlit(&mat_params, bitmap_id, 1.0f, false, false);
|
||||
g3_render_rect_screen_aligned_2d(&mat_params, &image_vertex, 0, instance->radius*1.5f);
|
||||
g3_draw_bitmap(&image_vertex, 0, instance->radius*1.5f, TMAP_FLAG_TEXTURED | TMAP_HTL_2D);
|
||||
}
|
||||
|
||||
instance->last_bitmap = bitmap_id;
|
||||
}
|
||||
|
||||
t2 = timer_get_fixed_seconds();
|
||||
render_time = f2fl(t2-t1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -971,9 +968,6 @@ void anim_display_info(char *real_filename)
|
||||
// read the keyframe frame nums and offsets
|
||||
key_frame_nums = (int*)vm_malloc(sizeof(int)*A.num_keys);
|
||||
Assert(key_frame_nums != NULL);
|
||||
if (key_frame_nums == NULL)
|
||||
return;
|
||||
|
||||
for ( i = 0; i < A.num_keys; i++ ) {
|
||||
key_frame_nums[i] = 0;
|
||||
cfread(&key_frame_nums[i], 2, 1, fp);
|
||||
@@ -1006,7 +1000,7 @@ void anim_display_info(char *real_filename)
|
||||
printf("FPS: %d\n", A.fps);
|
||||
|
||||
#ifndef NDEBUG
|
||||
printf("Transparent RGB: (%u,%u,%u)\n", A.xparent_r, A.xparent_g, A.xparent_b);
|
||||
printf("Transparent RGB: (%d,%d,%d)\n", A.xparent_r, A.xparent_g, A.xparent_b);
|
||||
#endif
|
||||
|
||||
printf("ac version: %d\n", A.version);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -301,6 +301,7 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
|
||||
|
||||
Assert(packed_size == (save-dest_start) );
|
||||
return packed_size;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -466,6 +467,7 @@ int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, in
|
||||
|
||||
Assert(packed_size == (save-dest_start) );
|
||||
return packed_size;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
+236
-330
@@ -10,38 +10,37 @@
|
||||
|
||||
|
||||
#include "asteroid/asteroid.h"
|
||||
#include "debugconsole/console.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 "freespace.h"
|
||||
#include "gamesnd/gamesnd.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 <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
|
||||
@@ -65,9 +64,6 @@ asteroid_field Asteroid_field;
|
||||
|
||||
static int Asteroid_impact_explosion_ani;
|
||||
static float Asteroid_impact_explosion_radius;
|
||||
char Asteroid_icon_closeup_model[NAME_LENGTH];
|
||||
vec3d Asteroid_icon_closeup_position;
|
||||
float Asteroid_icon_closeup_zoom;
|
||||
|
||||
#define ASTEROID_CHECK_WRAP_TIMESTAMP 2000 // how often an asteroid gets checked for wrapping
|
||||
#define ASTEROID_UPDATE_COLLIDE_TIMESTAMP 2000 // how often asteroid is checked for impending collisions with escort ships
|
||||
@@ -106,7 +102,7 @@ int asteroid_obj_list_add(int objnum)
|
||||
int index;
|
||||
|
||||
asteroid *cur_asteroid = &Asteroids[Objects[objnum].instance];
|
||||
index = (int)(cur_asteroid - Asteroids);
|
||||
index = cur_asteroid - Asteroids;
|
||||
|
||||
Assert(index >= 0 && index < MAX_ASTEROID_OBJS);
|
||||
Assert(!(Asteroid_objs[index].flags & ASTEROID_OBJ_USED));
|
||||
@@ -319,12 +315,8 @@ object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int asteroi
|
||||
}
|
||||
|
||||
vm_angles_2_matrix(&orient, &angs);
|
||||
flagset<Object::Object_Flags> asteroid_default_flagset;
|
||||
asteroid_default_flagset += Object::Object_Flags::Renders;
|
||||
asteroid_default_flagset += Object::Object_Flags::Physics;
|
||||
asteroid_default_flagset += Object::Object_Flags::Collides;
|
||||
|
||||
objnum = obj_create(OBJ_ASTEROID, -1, n, &orient, &pos, radius, asteroid_default_flagset);
|
||||
|
||||
objnum = obj_create( OBJ_ASTEROID, -1, n, &orient, &pos, radius, OF_RENDERS | OF_PHYSICS | OF_COLLIDES);
|
||||
|
||||
if ( (objnum == -1) || (objnum >= MAX_OBJECTS) ) {
|
||||
mprintf(("Couldn't create asteroid -- out of object slots\n"));
|
||||
@@ -332,11 +324,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);
|
||||
@@ -448,7 +435,6 @@ void asteroid_sub_create(object *parent_objp, int asteroid_type, vec3d *relvec)
|
||||
*/
|
||||
void asteroid_load(int asteroid_info_index, int asteroid_subtype)
|
||||
{
|
||||
int i;
|
||||
asteroid_info *asip;
|
||||
|
||||
Assert( asteroid_info_index < (int)Asteroid_info.size() );
|
||||
@@ -465,25 +451,13 @@ void asteroid_load(int asteroid_info_index, int asteroid_subtype)
|
||||
|
||||
asip->model_num[asteroid_subtype] = model_load( asip->pof_files[asteroid_subtype], 0, NULL );
|
||||
|
||||
if (asip->model_num[asteroid_subtype] >= 0)
|
||||
{
|
||||
polymodel *pm = asip->modelp[asteroid_subtype] = model_get(asip->model_num[asteroid_subtype]);
|
||||
if (asip->model_num[asteroid_subtype] > -1) {
|
||||
asip->modelp[asteroid_subtype] = model_get(asip->model_num[asteroid_subtype]);
|
||||
|
||||
if ( asip->num_detail_levels != pm->n_detail_levels )
|
||||
{
|
||||
if ( !Is_standalone )
|
||||
{
|
||||
// just log to file for standalone servers
|
||||
Warning(LOCATION, "For asteroid '%s', detail level\nmismatch (POF needs %d)", asip->name, pm->n_detail_levels );
|
||||
}
|
||||
else
|
||||
{
|
||||
nprintf(("Warning", "For asteroid '%s', detail level mismatch (POF needs %d)", asip->name, pm->n_detail_levels));
|
||||
}
|
||||
}
|
||||
// Stuff detail level distances.
|
||||
for ( i=0; i<pm->n_detail_levels; i++ )
|
||||
pm->detail_depth[i] = (i < asip->num_detail_levels) ? i2fl(asip->detail_distance[i]) : 0.0f;
|
||||
for (int i = 0; i < asip->num_detail_levels; i++) {
|
||||
asip->modelp[asteroid_subtype]->detail_depth[i] = i2fl(asip->detail_distance[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,7 +781,7 @@ void maybe_throw_asteroid(int count)
|
||||
|
||||
// if asteroid is inside inner bound, kill it
|
||||
if (asteroid_in_inner_bound(&Asteroid_field, &objp->pos, 0.0f)) {
|
||||
objp->flags.set(Object::Object_Flags::Should_be_dead);
|
||||
objp->flags |= OF_SHOULD_BE_DEAD;
|
||||
} else {
|
||||
Asteroids[objp->instance].target_objnum = so->objnum;
|
||||
|
||||
@@ -836,12 +810,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 );
|
||||
}
|
||||
@@ -871,19 +843,20 @@ void asteroid_maybe_reposition(object *objp, asteroid_field *asfieldp)
|
||||
dist = vm_vec_normalized_dir(&vec_to_asteroid, &objp->pos, &Eye_position);
|
||||
dot = vm_vec_dot(&Eye_matrix.vec.fvec, &vec_to_asteroid);
|
||||
|
||||
if ( (dot < 0.7f) || (dist > asfieldp->bound_rad) ) {
|
||||
if ((dot < 0.7f) || (dist > 3000.0f)) {
|
||||
if (Num_asteroids > MAX_ASTEROIDS-10) {
|
||||
objp->flags.set(Object::Object_Flags::Should_be_dead);
|
||||
objp->flags |= OF_SHOULD_BE_DEAD;
|
||||
} else {
|
||||
// check to ensure player won't see asteroid appear either
|
||||
asteroid_wrap_pos(objp, asfieldp);
|
||||
Asteroids[objp->instance].target_objnum = -1;
|
||||
|
||||
dist = vm_vec_normalized_dir(&vec_to_asteroid, &objp->pos, &Eye_position);
|
||||
vm_vec_normalized_dir(&vec_to_asteroid, &objp->pos, &Eye_position);
|
||||
dot = vm_vec_dot(&Eye_matrix.vec.fvec, &vec_to_asteroid);
|
||||
dist = vm_vec_dist_quick(&objp->pos, &Eye_position);
|
||||
|
||||
if ( (dot > 0.7f) && (dist < (asfieldp->bound_rad * 1.3f)) ) {
|
||||
// player would see asteroid pop out other side, so reverse velocity instead of wrapping
|
||||
if (( dot > 0.7f) && (dist < 3000.0f)) {
|
||||
// player would see asteroid pop out other side, so reverse velocity instead of wrapping
|
||||
objp->pos = old_asteroid_pos;
|
||||
vm_vec_copy_scale(&objp->phys_info.vel, &old_vel, -1.0f);
|
||||
objp->phys_info.desired_vel = objp->phys_info.vel;
|
||||
@@ -908,7 +881,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
|
||||
@@ -918,14 +891,13 @@ void asteroid_process_pre( object *objp )
|
||||
}
|
||||
}
|
||||
|
||||
int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos, collision_info_struct *asteroid_hit_info, vec3d* hitnormal)
|
||||
int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos, collision_info_struct *asteroid_hit_info)
|
||||
{
|
||||
if (!Asteroids_enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mc_info mc;
|
||||
mc_info_init(&mc);
|
||||
int num, asteroid_subtype;
|
||||
|
||||
Assert( pasteroid->type == OBJ_ASTEROID );
|
||||
@@ -940,7 +912,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
|
||||
@@ -950,34 +922,24 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
|
||||
mc.flags = (MC_CHECK_MODEL);
|
||||
|
||||
if (model_collide(&mc))
|
||||
{
|
||||
*hitpos = mc.hit_point_world;
|
||||
|
||||
if (hitnormal)
|
||||
{
|
||||
vec3d normal;
|
||||
model_find_world_dir(&normal, &mc.hit_normal, mc.model_num, mc.hit_submodel, mc.orient);
|
||||
|
||||
*hitnormal = normal;
|
||||
}
|
||||
}
|
||||
|
||||
return mc.num_hits;
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -999,19 +961,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);
|
||||
|
||||
@@ -1025,6 +987,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)) {
|
||||
@@ -1038,7 +1001,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++) {
|
||||
@@ -1059,10 +1023,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;
|
||||
@@ -1079,14 +1043,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
|
||||
@@ -1111,7 +1075,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
|
||||
@@ -1125,11 +1089,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);
|
||||
@@ -1180,12 +1144,14 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
|
||||
}
|
||||
}
|
||||
|
||||
void asteroid_render(object * obj, draw_list *scene)
|
||||
void asteroid_render(object * obj)
|
||||
{
|
||||
if (Asteroids_enabled) {
|
||||
int num;
|
||||
polymodel *pm;
|
||||
asteroid *asp;
|
||||
|
||||
|
||||
pm = NULL;
|
||||
num = obj->instance;
|
||||
|
||||
Assert((num >= 0) && (num < MAX_ASTEROIDS));
|
||||
@@ -1194,13 +1160,7 @@ void asteroid_render(object * obj, draw_list *scene)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1339,7 +1299,7 @@ void asteroid_do_area_effect(object *asteroid_objp)
|
||||
ship_objp = &Objects[so->objnum];
|
||||
|
||||
// don't blast navbuoys
|
||||
if ( ship_get_SIF(ship_objp->instance)[Ship::Info_Flags::Navbuoy] ) {
|
||||
if ( ship_get_SIF(ship_objp->instance) & SIF_NAVBUOY ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1354,42 +1314,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[Object::Object_Flags::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);
|
||||
@@ -1401,14 +1361,14 @@ void asteroid_hit( object * pasteroid_obj, object * other_obj, vec3d * hitpos, f
|
||||
weapon_info *wip;
|
||||
wip = &Weapon_info[Weapons[other_obj->instance].weapon_info_index];
|
||||
// If the weapon didn't play any impact animation, play custom asteroid impact animation
|
||||
if ( wip->impact_weapon_expl_effect < 0 ) {
|
||||
particle::create( hitpos, &vmd_zero_vector, 0.0f, Asteroid_impact_explosion_radius, particle::PARTICLE_BITMAP, Asteroid_impact_explosion_ani );
|
||||
if ( wip->impact_weapon_expl_index < 0 ) {
|
||||
particle_create( hitpos, &vmd_zero_vector, 0.0f, Asteroid_impact_explosion_radius, PARTICLE_BITMAP, Asteroid_impact_explosion_ani );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// evaluate any relevant player scoring implications
|
||||
scoring_eval_hit(pasteroid_obj,other_obj);
|
||||
scoring_eval_hit(asteroid_obj,other_obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1422,15 +1382,30 @@ void asteroid_level_close()
|
||||
if (Asteroids[i].flags & AF_USED) {
|
||||
Asteroids[i].flags &= ~AF_USED;
|
||||
Assert(Asteroids[i].objnum >=0 && Asteroids[i].objnum < MAX_OBJECTS);
|
||||
Objects[Asteroids[i].objnum].flags.set(Object::Object_Flags::Should_be_dead);
|
||||
Objects[Asteroids[i].objnum].flags |= OF_SHOULD_BE_DEAD;
|
||||
}
|
||||
}
|
||||
|
||||
Asteroid_field.num_initial_asteroids=0;
|
||||
}
|
||||
|
||||
DCF_BOOL2(asteroids, Asteroids_enabled, "enables or disables asteroids", "Usage: asteroids [bool]\nTurns asteroid system on/off. If nothing passed, then toggles it.\n");
|
||||
|
||||
DCF(asteroids,"Turns asteroids on/off")
|
||||
{
|
||||
if ( Dc_command ) {
|
||||
dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);
|
||||
if ( Dc_arg_type & ARG_TRUE )
|
||||
Asteroids_enabled = 1;
|
||||
else if ( Dc_arg_type & ARG_FALSE )
|
||||
Asteroids_enabled = 0;
|
||||
else if ( Dc_arg_type & ARG_NONE )
|
||||
Asteroids_enabled ^= 1;
|
||||
}
|
||||
if ( Dc_help )
|
||||
dc_printf( "Usage: asteroids [bool]\nTurns asteroid system on/off. If nothing passed, then toggles it.\n" );
|
||||
|
||||
if ( Dc_status )
|
||||
dc_printf( "asteroids are %s\n", (Asteroids_enabled?"ON":"OFF") );
|
||||
}
|
||||
|
||||
void hud_target_asteroid()
|
||||
{
|
||||
@@ -1473,21 +1448,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.set(Object::Object_Flags::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
|
||||
@@ -1498,29 +1473,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;
|
||||
|
||||
@@ -1544,8 +1519,8 @@ void asteroid_maybe_break_up(object *pasteroid_obj)
|
||||
|
||||
random_shuffle(roids_to_create.begin(), roids_to_create.end());
|
||||
|
||||
size_t total_roids = roids_to_create.size();
|
||||
for (size_t i = 0; i < total_roids; i++) {
|
||||
int total_roids = roids_to_create.size();
|
||||
for (int i = 0; i < total_roids; i++) {
|
||||
vec3d dir_vec,final_vec;
|
||||
vec3d parent_vel,hit_rel_vec;
|
||||
|
||||
@@ -1560,8 +1535,8 @@ void asteroid_maybe_break_up(object *pasteroid_obj)
|
||||
float r = sqrt(1.0f - y*y);
|
||||
float phi = i * inc;
|
||||
|
||||
dir_vec.xyz.x = cosf(phi)*r;
|
||||
dir_vec.xyz.y = sinf(phi)*r;
|
||||
dir_vec.xyz.x = cos(phi)*r;
|
||||
dir_vec.xyz.y = sin(phi)*r;
|
||||
dir_vec.xyz.z = y;
|
||||
|
||||
// Randomize the direction a bit
|
||||
@@ -1569,24 +1544,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");
|
||||
}
|
||||
}
|
||||
@@ -1610,36 +1585,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);
|
||||
|
||||
@@ -1647,17 +1622,13 @@ 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;
|
||||
@@ -1672,11 +1643,11 @@ int asteroid_will_collide(object *pasteroid_obj, object *escort_objp)
|
||||
*/
|
||||
int asteroid_valid_ship_to_warn_collide(ship *shipp)
|
||||
{
|
||||
if ( !(Ship_info[shipp->ship_info_index].is_big_or_huge()) ) {
|
||||
if ( !(Ship_info[shipp->ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( shipp->flags[Ship::Ship_Flags::Dying] || shipp->flags[Ship::Ship_Flags::Depart_warp] ) {
|
||||
if ( shipp->flags & (SF_DYING|SF_DEPART_WARP) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1741,7 +1712,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;
|
||||
@@ -1786,7 +1757,6 @@ float asteroid_time_to_impact(object *asteroid_objp)
|
||||
float time=-1.0f, total_dist, speed;
|
||||
asteroid *asp;
|
||||
mc_info mc;
|
||||
mc_info_init(&mc);
|
||||
|
||||
asp = &Asteroids[asteroid_objp->instance];
|
||||
|
||||
@@ -1822,11 +1792,13 @@ void asteroid_parse_section(asteroid_info *asip)
|
||||
required_string( "$POF file2:" );
|
||||
stuff_string(asip->pof_files[1], F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if ( (stristr(asip->name, "Asteroid") != NULL) ) {
|
||||
if ( (stristr(asip->name,"Asteroid") != NULL) ) {
|
||||
required_string( "$POF file3:" );
|
||||
stuff_string(asip->pof_files[2], F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
|
||||
asip->num_detail_levels = 0;
|
||||
|
||||
required_string("$Detail distance:");
|
||||
asip->num_detail_levels = stuff_int_list(asip->detail_distance, MAX_ASTEROID_DETAIL_LEVELS, RAW_INTEGER_TYPE);
|
||||
|
||||
@@ -1892,171 +1864,105 @@ void asteroid_parse_section(asteroid_info *asip)
|
||||
}
|
||||
|
||||
/**
|
||||
Read in data from asteroid.tbl into Asteroid_info[] array.
|
||||
|
||||
After this function is completes, the Asteroid_info[] array will
|
||||
contain exactly three asteroids per species plus exactly three
|
||||
generic asteroids. These three asteroids are a set
|
||||
of small, medium, and large asteroids in that exact order.
|
||||
|
||||
If asteroid.tbl contains too many or too few asteroids as per
|
||||
the rules above this function will abort the engine with an
|
||||
error message stating the number expected and it will write
|
||||
to the debug.log how everything was parsed.
|
||||
|
||||
Note that by saying "asteroid" this code is talking about
|
||||
the asteroids and the debris that make up asteroid fields
|
||||
and debris fields. Which means that these debris have nothing
|
||||
to do with the debris of ships that explode, however these
|
||||
are the same debris and asteroids that get flung at a ship
|
||||
that is being protected.
|
||||
*/
|
||||
* Read in data from asteroid.tbl into Asteroid_info[] array
|
||||
*/
|
||||
void asteroid_parse_tbl()
|
||||
{
|
||||
char impact_ani_file[MAX_FILENAME_LEN];
|
||||
int *asteroid_tally = NULL;
|
||||
int i, 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();
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
required_string("#Asteroid Types");
|
||||
|
||||
size_t tally = 0;
|
||||
size_t 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);
|
||||
|
||||
size_t 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: " SIZE_T_ARG "\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 " SIZE_T_ARG " asteroids/debris when " SIZE_T_ARG " expected\n\n"
|
||||
"<Number expected> = <Number of species> * %d + %d generic asteroids\n"
|
||||
SIZE_T_ARG " = " 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, nullptr, nullptr, nullptr, true);
|
||||
}
|
||||
|
||||
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));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("asteroid.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Asteroid Types");
|
||||
|
||||
asteroid_tally = new int[Species_info.size() + 1];
|
||||
|
||||
memset(asteroid_tally, 0, sizeof(int) * (Species_info.size()+1));
|
||||
|
||||
while (required_string_either("#End","$Name:"))
|
||||
{
|
||||
asteroid_info new_asteroid;
|
||||
|
||||
for (i = 0; i < NUM_DEBRIS_POFS; i++)
|
||||
new_asteroid.model_num[i] = -1;
|
||||
|
||||
asteroid_parse_section( &new_asteroid );
|
||||
|
||||
Assert( Species_info.size() );
|
||||
// sanity check for debris type sizes
|
||||
for (i = (int)Species_info.size(); i >= 0; i--) {
|
||||
// must remain in proper order
|
||||
// 0 - generic debris types
|
||||
// > 0 - species specific debris types
|
||||
if ( (i == 0) || stristr(new_asteroid.name, Species_info[i-1].species_name) ) {
|
||||
Assert( asteroid_tally[i] < NUM_DEBRIS_SIZES );
|
||||
|
||||
if ( asteroid_tally[i] >= NUM_DEBRIS_SIZES ) {
|
||||
// too many sizes specified, don't increment Num_debris_types and we'll overwrite
|
||||
// the current entry with the next
|
||||
break;
|
||||
}
|
||||
|
||||
// we're safe to continue
|
||||
asteroid_tally[i]++;
|
||||
Asteroid_info.push_back( new_asteroid );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
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);
|
||||
|
||||
// close localization
|
||||
lcl_ext_close();
|
||||
|
||||
// check for any missing info
|
||||
char *errormsg = new char[75 + (Species_info.size() * (NAME_LENGTH))];
|
||||
bool species_missing = false;
|
||||
strcpy(errormsg, "The following species are missing debris types in asteroids.tbl:\n");
|
||||
for (i = 0; i < (int)Species_info.size(); i++)
|
||||
{
|
||||
int idx = (i+1); // offset from generic asteroids at 0..NUM_DEBRIS_SIZES
|
||||
|
||||
if (asteroid_tally[idx] < NUM_DEBRIS_SIZES)
|
||||
{
|
||||
strcat(errormsg, Species_info[i].species_name);
|
||||
strcat(errormsg, "\n");
|
||||
species_missing = true;
|
||||
}
|
||||
}
|
||||
strcat(errormsg, "\0");
|
||||
|
||||
if (species_missing)
|
||||
{
|
||||
Error(LOCATION, errormsg);
|
||||
}
|
||||
|
||||
delete[] asteroid_tally;
|
||||
delete[] errormsg;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2098,7 +2004,7 @@ int set_asteroid_throw_objnum()
|
||||
ship_objp = &Objects[so->objnum];
|
||||
float radius = ship_objp->radius*2.0f;
|
||||
|
||||
if (Ship_info[Ships[ship_objp->instance].ship_info_index].is_big_or_huge()) {
|
||||
if (Ship_info[Ships[ship_objp->instance].ship_info_index].flags & (SIF_HUGE_SHIP | SIF_BIG_SHIP)) {
|
||||
if (ship_objp->pos.xyz.x + radius > Asteroid_field.min_bound.xyz.x)
|
||||
if (ship_objp->pos.xyz.y + radius > Asteroid_field.min_bound.xyz.y)
|
||||
if (ship_objp->pos.xyz.z + radius > Asteroid_field.min_bound.xyz.z)
|
||||
|
||||
+14
-26
@@ -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 object;
|
||||
struct polymodel;
|
||||
struct collision_info_struct;
|
||||
class draw_list;
|
||||
|
||||
#define MAX_ASTEROIDS 512
|
||||
|
||||
@@ -53,9 +52,7 @@ typedef struct asteroid_split_info {
|
||||
int max;
|
||||
} asteroid_split_info;
|
||||
|
||||
class asteroid_info
|
||||
{
|
||||
public:
|
||||
typedef struct asteroid_info {
|
||||
char name[NAME_LENGTH]; // name for the asteroid
|
||||
char pof_files[NUM_DEBRIS_POFS][MAX_FILENAME_LEN]; // POF files to load/associate with ship
|
||||
int num_detail_levels; // number of detail levels for this ship
|
||||
@@ -80,17 +77,13 @@ public:
|
||||
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
|
||||
fireball_radius_multiplier( -1 )
|
||||
{
|
||||
name[ 0 ] = 0;
|
||||
name[ 0 ] = NULL;
|
||||
memset( pof_files, 0, sizeof( pof_files ) );
|
||||
memset( detail_distance, 0, sizeof( detail_distance ) );
|
||||
|
||||
for (int i = 0; i < NUM_DEBRIS_POFS; i++)
|
||||
{
|
||||
modelp[i] = NULL;
|
||||
model_num[i] = -1;
|
||||
pof_files[i][0] = 0;
|
||||
}
|
||||
memset( modelp, 0, sizeof( modelp ) );
|
||||
memset( model_num, 0, sizeof( model_num ) );
|
||||
}
|
||||
};
|
||||
} asteroid_info;
|
||||
|
||||
|
||||
#define AF_USED (1<<0) // Set means used.
|
||||
@@ -98,7 +91,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
|
||||
@@ -126,7 +118,6 @@ typedef enum {
|
||||
typedef struct asteroid_field {
|
||||
vec3d min_bound; // Minimum range of field.
|
||||
vec3d max_bound; // Maximum range of field.
|
||||
float bound_rad;
|
||||
int has_inner_bound;
|
||||
vec3d inner_min_bound;
|
||||
vec3d inner_max_bound;
|
||||
@@ -144,20 +135,17 @@ extern asteroid_field Asteroid_field;
|
||||
|
||||
extern int Num_asteroids;
|
||||
extern int Asteroids_enabled;
|
||||
extern char Asteroid_icon_closeup_model[NAME_LENGTH]; // model for asteroid field briefing icon rendering
|
||||
extern vec3d Asteroid_icon_closeup_position; // closeup position for asteroid field briefing icon rendering
|
||||
extern float Asteroid_icon_closeup_zoom; // zoom position for asteroid field briefing icon rendering
|
||||
|
||||
void asteroid_init();
|
||||
void asteroid_level_init();
|
||||
void asteroid_level_close();
|
||||
void asteroid_create_all();
|
||||
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);
|
||||
int asteroid_check_collision( object *asteroid_objp, object * other_obj, vec3d * hitpos, collision_info_struct *asteroid_hit_info=NULL, vec3d* hitnormal=NULL );
|
||||
void asteroid_hit( object *pasteroid_objp, object *other_objp, vec3d *hitpos, float damage );
|
||||
void asteroid_process_pre( object *asteroid_objp, float frame_time);
|
||||
void asteroid_process_post( object *asteroid_objp, float frame_time);
|
||||
int asteroid_check_collision( object *asteroid_objp, object * other_obj, vec3d * hitpos, collision_info_struct *asteroid_hit_info=NULL );
|
||||
void asteroid_hit( object *asteroid_objp, object *other_objp, vec3d *hitpos, float damage );
|
||||
int asteroid_count();
|
||||
int asteroid_collide_objnum(object *asteroid_objp);
|
||||
float asteroid_time_to_impact(object *asteroid_objp);
|
||||
|
||||
+170
-192
@@ -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 "freespace.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
#include "def_files/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
|
||||
@@ -178,7 +178,7 @@ bool CanAutopilot(vec3d targetPos, bool send_msg)
|
||||
object *other_objp = &Objects[so->objnum];
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags[Ship::Info_Flags::Cargo])) // ignore cargo
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
|
||||
{
|
||||
// Cannot autopilot if enemy within AutopilotMinEnemyDistance meters
|
||||
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < AutopilotMinEnemyDistance) {
|
||||
@@ -209,7 +209,7 @@ bool CanAutopilot(vec3d targetPos, bool send_msg)
|
||||
|
||||
// check for support ships
|
||||
// cannot autopilot if support ship present
|
||||
if ( ship_find_repair_ship(Player_obj) != 0 ) {
|
||||
if ( ship_find_repair_ship(Player_obj) != NULL ) {
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_PRESENT);
|
||||
return false;
|
||||
@@ -225,49 +225,38 @@ extern object* Autopilot_flight_leader;
|
||||
// * Control switched from player to AI
|
||||
// * Time compression to 32x
|
||||
// * Lock time compression -WMC
|
||||
// * Tell AI to fly to targeted Nav Point (for all nav-status wings/ships)
|
||||
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
bool StartAutopilot()
|
||||
{
|
||||
// Check for support ship and dismiss it if it is not doing anything.
|
||||
// If the support ship is doing something then tell the user such.
|
||||
for ( object *objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) )
|
||||
{
|
||||
if ((objp->type == OBJ_SHIP) && !(objp->flags[Object::Object_Flags::Should_be_dead]))
|
||||
{
|
||||
Assertion((objp->instance >= 0) && (objp->instance < MAX_SHIPS),
|
||||
"objp does not have a valid pointer to a ship. Pointer is %d, which is smaller than 0 or bigger than %d",
|
||||
objp->instance, MAX_SHIPS);
|
||||
ship *shipp = &Ships[objp->instance];
|
||||
|
||||
if (shipp->team != Player_ship->team)
|
||||
continue;
|
||||
|
||||
Assertion((shipp->ship_info_index >= 0) && (shipp->ship_info_index < static_cast<int>(Ship_info.size())),
|
||||
"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()));
|
||||
ship_info *sip = &Ship_info[shipp->ship_info_index];
|
||||
|
||||
if ( !(sip->flags[Ship::Info_Flags::Support]) )
|
||||
continue;
|
||||
|
||||
// don't deal with dying or departing support ships
|
||||
if ( shipp->is_dying_or_departing() )
|
||||
continue;
|
||||
|
||||
Assert(shipp->ai_index != -1);
|
||||
ai_info* support_ship_aip = &(Ai_info[Ships[objp->instance].ai_index]);
|
||||
|
||||
// is support ship trying to rearm-repair
|
||||
if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
|
||||
// no, so tell it to depart
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
|
||||
} else {
|
||||
// yes
|
||||
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
|
||||
return false;
|
||||
}
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
object* support_ship_op = ship_find_repair_ship(Player_obj);
|
||||
if ( support_ship_op == NULL ) {
|
||||
// no more
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Assert( support_ship_op->type == OBJ_SHIP );
|
||||
Assert( support_ship_op->instance >= 0 );
|
||||
Assert( support_ship_op->instance < MAX_SHIPS );
|
||||
Assert( Ships[support_ship_op->instance].ai_index != -1 );
|
||||
|
||||
ai_info* support_ship_aip = &(Ai_info[Ships[support_ship_op->instance].ai_index]);
|
||||
|
||||
// is support ship trying to rearm-repair
|
||||
if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
|
||||
// no, so tell it to depart
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
|
||||
} else {
|
||||
// yes
|
||||
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
if (!CanAutopilot())
|
||||
return false;
|
||||
@@ -286,7 +275,7 @@ bool StartAutopilot()
|
||||
Autopilot_flight_leader = Player_obj;
|
||||
}
|
||||
|
||||
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
LockAPConv = timestamp(); // lock convergence instantly
|
||||
else
|
||||
LockAPConv = timestamp(3000); // 3 seconds before we lock convergence
|
||||
@@ -325,7 +314,7 @@ bool StartAutopilot()
|
||||
|
||||
|
||||
// instantly turn player toward tpos
|
||||
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{
|
||||
vm_vec_sub(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
|
||||
vm_vector_2_matrix(&Player_obj->orient, &norm1, NULL, NULL);
|
||||
@@ -334,8 +323,8 @@ bool StartAutopilot()
|
||||
for (i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1 &&
|
||||
(Ships[i].flags[Ship::Ship_Flags::Navpoint_carry] ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags[Ship::Wing_Flags::Nav_carry])
|
||||
(Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
|
||||
)
|
||||
)
|
||||
{
|
||||
@@ -345,7 +334,7 @@ bool StartAutopilot()
|
||||
}
|
||||
|
||||
// damp speed_cap to 90% of actual -- to make sure ships stay in formation
|
||||
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
speed_cap = 0.90f * speed_cap;
|
||||
|
||||
if ( speed_cap < 1.0f ) {
|
||||
@@ -367,27 +356,28 @@ bool StartAutopilot()
|
||||
for (i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1 &&
|
||||
(Ships[i].flags[Ship::Ship_Flags::Navpoint_carry] ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags[Ship::Wing_Flags::Nav_carry])
|
||||
(Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
|
||||
)
|
||||
)
|
||||
{
|
||||
// do we have capital ships in the area?
|
||||
if (Ship_info[Ships[i].ship_info_index].is_big_ship() || Ship_info[Ships[i].ship_info_index].flags[Ship::Info_Flags::Capital] || Ship_info[Ships[i].ship_info_index].flags[Ship::Info_Flags::Supercap])
|
||||
if (Ship_info[Ships[i].ship_info_index].flags
|
||||
& ( SIF_CRUISER | SIF_CAPITAL | SIF_SUPERCAP | SIF_CORVETTE | SIF_AWACS | SIF_GAS_MINER | SIF_FREIGHTER | SIF_TRANSPORT))
|
||||
{
|
||||
capshipPresent = true;
|
||||
|
||||
capIndexes.push_back(i);
|
||||
// ok.. what size class
|
||||
|
||||
if (Ship_info[Ships[i].ship_info_index].flags[Ship::Info_Flags::Capital] || Ship_info[Ships[i].ship_info_index].flags[Ship::Info_Flags::Supercap])
|
||||
{
|
||||
capship_counts[0]++;
|
||||
if (capship_spreads[0] < Objects[Ships[i].objnum].radius)
|
||||
capship_spreads[0] = Objects[Ships[i].objnum].radius;
|
||||
}
|
||||
else if (Ship_info[Ships[i].ship_info_index].flags[Ship::Info_Flags::Corvette])
|
||||
{
|
||||
if (Ship_info[Ships[i].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
|
||||
{
|
||||
capship_counts[0]++;
|
||||
if (capship_spreads[0] < Objects[Ships[i].objnum].radius)
|
||||
capship_spreads[0] = Objects[Ships[i].objnum].radius;
|
||||
}
|
||||
else if (Ship_info[Ships[i].ship_info_index].flags & (SIF_CORVETTE))
|
||||
{
|
||||
capship_counts[1]++;
|
||||
if (capship_spreads[1] < Objects[Ships[i].objnum].radius)
|
||||
capship_spreads[1] = Objects[Ships[i].objnum].radius;
|
||||
@@ -415,15 +405,15 @@ bool StartAutopilot()
|
||||
radius = Objects[Ships[i].objnum].radius;
|
||||
}
|
||||
|
||||
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{// instantly turn the ship to match the direction player is looking
|
||||
//vm_vec_sub(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
|
||||
vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
|
||||
}
|
||||
|
||||
// snap wings into formation
|
||||
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics] && // only if using cinematics
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags[Ship::Wing_Flags::Nav_carry]) // only if in a wing
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS && // only if using cinematics
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY) // only if in a wing
|
||||
&& Autopilot_flight_leader != &Objects[Ships[i].objnum]) //only if not flight leader's object
|
||||
{
|
||||
ai_info *aip = &Ai_info[Ships[i].ai_index];
|
||||
@@ -434,7 +424,7 @@ bool StartAutopilot()
|
||||
if (leader_objp != &Objects[Ships[i].objnum])
|
||||
{
|
||||
// not leader.. get our position relative to leader
|
||||
get_absolute_wing_pos_autopilot(&goal_point, leader_objp, wing_index, aip->ai_flags[AI::AI_Flags::Formation_object]);
|
||||
get_absolute_wing_pos_autopilot(&goal_point, leader_objp, wing_index, aip->ai_flags & AIF_FORMATION_OBJECT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -469,10 +459,8 @@ bool StartAutopilot()
|
||||
}
|
||||
}
|
||||
// lock primary and secondary weapons
|
||||
if (LockWeaponsDuringAutopilot) {
|
||||
Ships[i].flags.set(Ship::Ship_Flags::Primaries_locked);
|
||||
Ships[i].flags.set(Ship::Ship_Flags::Secondaries_locked);
|
||||
}
|
||||
if ( LockWeaponsDuringAutopilot )
|
||||
Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
|
||||
// clear the ship goals and cap the waypoint speed
|
||||
ai_clear_ship_goals(&Ai_info[Ships[i].ai_index]);
|
||||
@@ -480,7 +468,7 @@ bool StartAutopilot()
|
||||
|
||||
|
||||
// if they're not part of a wing set their goal
|
||||
if (Ships[i].wingnum == -1 || The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
|
||||
if (Ships[i].wingnum == -1 || The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{
|
||||
if (Navs[CurrentNav].flags & NP_WAYPOINT)
|
||||
{
|
||||
@@ -497,11 +485,11 @@ bool StartAutopilot()
|
||||
}
|
||||
|
||||
// assign wing goals
|
||||
if (!(The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics]))
|
||||
if (!(The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS))
|
||||
{
|
||||
for (i = 0; i < MAX_WINGS; i++)
|
||||
{
|
||||
if (Wings[i].flags[Ship::Wing_Flags::Nav_carry] )
|
||||
if (Wings[i].flags & WF_NAV_CARRY )
|
||||
{
|
||||
//ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip );
|
||||
|
||||
@@ -539,8 +527,8 @@ bool StartAutopilot()
|
||||
{
|
||||
if (Ships[i].objnum != -1)
|
||||
{
|
||||
if (Ships[i].flags[Ship::Ship_Flags::Navpoint_carry] ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags[Ship::Wing_Flags::Nav_carry]))
|
||||
if (Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY))
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
{
|
||||
if (Ai_info[Ships[i].ai_index].goals[j].ai_mode == AI_GOAL_WAYPOINTS_ONCE ||
|
||||
@@ -558,7 +546,7 @@ bool StartAutopilot()
|
||||
start_dist = DistanceTo(CurrentNav);
|
||||
|
||||
// ----------------------------- setup cinematic -----------------------------
|
||||
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{
|
||||
if (capshipPresent)
|
||||
{
|
||||
@@ -571,7 +559,7 @@ bool StartAutopilot()
|
||||
vm_vec_add(&front, &Autopilot_flight_leader->orient.vec.fvec, &zero);
|
||||
vm_vec_add(&up, &Autopilot_flight_leader->orient.vec.uvec, &zero);
|
||||
vm_vec_add(&offset, &zero, &zero);
|
||||
if (Ship_info[Ships[*idx].ship_info_index].flags[Ship::Info_Flags::Capital] || Ship_info[Ships[*idx].ship_info_index].flags[Ship::Info_Flags::Supercap])
|
||||
if (Ship_info[Ships[*idx].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
|
||||
{
|
||||
//0 - below - three lines of position
|
||||
|
||||
@@ -605,7 +593,7 @@ bool StartAutopilot()
|
||||
|
||||
capship_placed[0]++;
|
||||
}
|
||||
else if (Ship_info[Ships[*idx].ship_info_index].flags[Ship::Info_Flags::Corvette])
|
||||
else if (Ship_info[Ships[*idx].ship_info_index].flags & SIF_CORVETTE)
|
||||
{
|
||||
//1 above - 3 lines of position
|
||||
// front/back to zero
|
||||
@@ -716,9 +704,9 @@ bool StartAutopilot()
|
||||
|
||||
vm_vec_add(&Objects[Ships[*idx].objnum].pos, &Autopilot_flight_leader->pos, &offset);
|
||||
|
||||
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[*idx].objnum].pos) > distance)
|
||||
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
{
|
||||
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[*idx].objnum].pos);
|
||||
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -914,16 +902,14 @@ void EndAutoPilot()
|
||||
{
|
||||
if (Ships[i].objnum != -1 &&
|
||||
(
|
||||
Ships[i].flags[Ship::Ship_Flags::Navpoint_carry] ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags[Ship::Wing_Flags::Nav_carry] )
|
||||
Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY )
|
||||
)
|
||||
)
|
||||
{
|
||||
//unlock their weaponry
|
||||
if (LockWeaponsDuringAutopilot) {
|
||||
Ships[i].flags.remove(Ship::Ship_Flags::Primaries_locked);
|
||||
Ships[i].flags.remove(Ship::Ship_Flags::Secondaries_locked);
|
||||
}
|
||||
if ( LockWeaponsDuringAutopilot )
|
||||
Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
Ai_info[Ships[i].ai_index].waypoint_speed_cap = -1; // uncap their speed
|
||||
Ai_info[Ships[i].ai_index].mode = AIM_NONE; // make AI re-evaluate current ship mode
|
||||
|
||||
@@ -958,11 +944,11 @@ void EndAutoPilot()
|
||||
}
|
||||
|
||||
// un-assign wing goals
|
||||
if ( !(The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics]) )
|
||||
if ( !(The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS) )
|
||||
{
|
||||
for (i = 0; i < MAX_WINGS; i++)
|
||||
{
|
||||
if (Wings[i].flags[Ship::Wing_Flags::Nav_carry] )
|
||||
if (Wings[i].flags & WF_NAV_CARRY )
|
||||
{
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
{
|
||||
@@ -998,7 +984,6 @@ camera* nav_get_set_camera()
|
||||
return nav_camera.getCamera();
|
||||
}
|
||||
|
||||
extern int Cmdline_old_collision_sys;
|
||||
void nav_warp(bool prewarp=false)
|
||||
{
|
||||
/* ok... find our end distance - norm1 is still a unit vector in the
|
||||
@@ -1044,8 +1029,8 @@ void nav_warp(bool prewarp=false)
|
||||
for (int i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1
|
||||
&& (Ships[i].flags[Ship::Ship_Flags::Navpoint_carry]
|
||||
|| (Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags[Ship::Wing_Flags::Nav_carry])))
|
||||
&& (Ships[i].flags2 & SF2_NAVPOINT_CARRY
|
||||
|| (Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)))
|
||||
{
|
||||
vm_vec_add(&Objects[Ships[i].objnum].pos, &Objects[Ships[i].objnum].pos, &targetPos);
|
||||
Objects[Ships[i].objnum].phys_info.vel = velocity;
|
||||
@@ -1053,11 +1038,8 @@ void nav_warp(bool prewarp=false)
|
||||
}
|
||||
|
||||
// retime all collision pairs
|
||||
if ( Cmdline_old_collision_sys ) {
|
||||
obj_all_collisions_retime();
|
||||
} else {
|
||||
obj_collide_retime_cached_pairs();
|
||||
}
|
||||
obj_all_collisions_retime();
|
||||
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
@@ -1072,7 +1054,7 @@ void NavSystem_Do()
|
||||
{
|
||||
if (AutoPilotEngaged)
|
||||
{
|
||||
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
{
|
||||
camera *cam = nav_get_set_camera();
|
||||
if (CinematicStarted)
|
||||
@@ -1151,7 +1133,7 @@ void NavSystem_Do()
|
||||
}
|
||||
|
||||
// ramp time compression - only if not using cinematics
|
||||
if (AutoPilotEngaged && !(The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics]))
|
||||
if (AutoPilotEngaged && !(The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS))
|
||||
{
|
||||
int dstfrm_start = start_dist - DistanceTo(CurrentNav);
|
||||
|
||||
@@ -1196,14 +1178,14 @@ void NavSystem_Do()
|
||||
*/
|
||||
for (int i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1 && Ships[i].flags[Ship::Ship_Flags::Navpoint_needslink])
|
||||
if (Ships[i].objnum != -1 && Ships[i].flags2 & SF2_NAVPOINT_NEEDSLINK)
|
||||
{
|
||||
object *other_objp = &Objects[Ships[i].objnum];
|
||||
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < (NavLinkDistance + other_objp->radius))
|
||||
{
|
||||
Ships[i].flags.remove(Ship::Ship_Flags::Navpoint_needslink);
|
||||
Ships[i].flags.set(Ship::Ship_Flags::Navpoint_carry);
|
||||
Ships[i].flags2 &= ~SF2_NAVPOINT_NEEDSLINK;
|
||||
Ships[i].flags2 |= SF2_NAVPOINT_CARRY;
|
||||
|
||||
send_autopilot_msgID(NP_MSG_MISC_LINKED);
|
||||
}
|
||||
@@ -1215,7 +1197,7 @@ void NavSystem_Do()
|
||||
|
||||
void send_autopilot_msgID(int msgid)
|
||||
{
|
||||
if (msgid < 0 || msgid >= NP_NUM_MESSAGES)
|
||||
if (msgid < 0 || msgid > NP_NUM_MESSAGES)
|
||||
return;
|
||||
|
||||
send_autopilot_msg(NavMsgs[msgid].message, NavMsgs[msgid].filename);
|
||||
@@ -1254,9 +1236,7 @@ void send_autopilot_msg(char *msg, char *snd)
|
||||
// Inits the Nav System
|
||||
void NavSystem_Init()
|
||||
{
|
||||
for (int i = 0; i < MAX_NAVPOINTS; i++)
|
||||
Navs[i].clear();
|
||||
|
||||
memset((char *)&Navs, 0, sizeof(Navs));
|
||||
AutoPilotEngaged = false;
|
||||
CurrentNav = -1;
|
||||
audio_handle = -1;
|
||||
@@ -1274,69 +1254,75 @@ void NavSystem_Init()
|
||||
|
||||
void parse_autopilot_table(char *filename)
|
||||
{
|
||||
int rval;
|
||||
SCP_vector<SCP_string> lines;
|
||||
|
||||
try
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
{
|
||||
if (filename == NULL)
|
||||
read_file_text_from_default(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));
|
||||
lcl_ext_close();
|
||||
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");
|
||||
|
||||
// close localization
|
||||
lcl_ext_close();
|
||||
}
|
||||
|
||||
|
||||
@@ -1346,13 +1332,20 @@ int FindNav(char *Nav)
|
||||
{
|
||||
for (int i = 0; i < MAX_NAVPOINTS; i++)
|
||||
{
|
||||
if (!stricmp(Navs[i].m_NavName, Nav))
|
||||
if (!stricmp(Navs[i].NavName, Nav))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Set A Nav point to "ZERO"
|
||||
void ZeroNav(int i)
|
||||
{
|
||||
memset((char *)&Navs[i], 0, sizeof(NavPoint));
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Removes a Nav
|
||||
bool DelNavPoint(char *Nav)
|
||||
@@ -1363,6 +1356,7 @@ bool DelNavPoint(char *Nav)
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool DelNavPoint(int nav)
|
||||
{
|
||||
if (nav != -1)
|
||||
@@ -1375,7 +1369,7 @@ bool DelNavPoint(int nav)
|
||||
}
|
||||
|
||||
}
|
||||
Navs[MAX_NAVPOINTS-1].clear();
|
||||
ZeroNav(MAX_NAVPOINTS-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1403,7 +1397,7 @@ bool AddNav_Ship(char *Nav, char *TargetName, int flags)
|
||||
// Create the NavPoint struct
|
||||
NavPoint tnav;
|
||||
|
||||
strcpy_s(tnav.m_NavName, Nav);
|
||||
strncpy(tnav.NavName, Nav, 32);
|
||||
tnav.flags = NP_SHIP | flags;
|
||||
|
||||
Assert(!(tnav.flags & NP_WAYPOINT));
|
||||
@@ -1449,7 +1443,7 @@ bool AddNav_Waypoint(char *Nav, char *WP_Path, int node, int flags)
|
||||
// Create the NavPoint struct
|
||||
NavPoint tnav;
|
||||
|
||||
strcpy_s(tnav.m_NavName, Nav);
|
||||
strncpy(tnav.NavName, Nav, 32);
|
||||
tnav.flags = NP_WAYPOINT | flags;
|
||||
|
||||
Assert(!(tnav.flags & NP_SHIP));
|
||||
@@ -1572,23 +1566,7 @@ bool Nav_UnSet_Visited(char *Nav)
|
||||
return Nav_UnSet_Flag(Nav, NP_VISITED);
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Selects a navpoint by name.
|
||||
void SelectNav(char *Nav)
|
||||
{
|
||||
for (int i = 0; i < MAX_NAVPOINTS; i++)
|
||||
{
|
||||
if (!stricmp(Navs[i].m_NavName, Nav))
|
||||
if (!(Nav_Get_Flags(Nav) & NP_HIDDEN || Nav_Get_Flags(Nav) & NP_NOACCESS)) CurrentNav = i;
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Deselects any navpoint selected.
|
||||
void DeselectNav()
|
||||
{
|
||||
CurrentNav = 0;
|
||||
}
|
||||
|
||||
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "object/object.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
// milliseconds between updates
|
||||
@@ -26,10 +25,9 @@
|
||||
#define NP_NOSELECT ( NP_HIDDEN | NP_NOACCESS )
|
||||
#define NP_VALIDTYPE ( NP_WAYPOINT | NP_SHIP )
|
||||
|
||||
class NavPoint
|
||||
struct NavPoint
|
||||
{
|
||||
public:
|
||||
char m_NavName[32];
|
||||
char NavName[32];
|
||||
int flags;
|
||||
|
||||
void *target_obj;
|
||||
@@ -37,15 +35,6 @@ public:
|
||||
|
||||
vec3d *GetPosition();
|
||||
char* GetInternalName();
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_NavName[0] = 0;
|
||||
flags = 0;
|
||||
|
||||
target_obj = NULL;
|
||||
waypoint_num = -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -94,7 +83,7 @@ inline bool CanAutopilot(bool send_msg=false) { return CanAutopilot(Player_obj->
|
||||
// * Checks if Autopilot is allowed. See CanAutopilot() for conditions.
|
||||
// * Control switched from player to AI
|
||||
// * Time compression to 32x
|
||||
// * Tell AI to fly to targeted Nav Point (for all nav-status wings/ships)
|
||||
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
// Returns false if autopilot cannot be started. True otherwise.
|
||||
bool StartAutopilot();
|
||||
@@ -123,12 +112,6 @@ void parse_autopilot_table(char *filename);
|
||||
// Finds a Nav point by name
|
||||
int FindNav(char *Nav);
|
||||
|
||||
// Selects a Nav point by name
|
||||
void SelectNav(char *Nav);
|
||||
|
||||
// Deselects any navpoint selected.
|
||||
void DeselectNav();
|
||||
|
||||
// Set A Nav point to "ZERO"
|
||||
void ZeroNav(int i);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
+92
-66
@@ -1,105 +1,131 @@
|
||||
#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
|
||||
float total_time; //!< used for animations -- total animation time (not always derived from num_frames/fps)
|
||||
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;
|
||||
struct {
|
||||
bool is_apng; //!< Is this animation an APNG?
|
||||
float frame_delay; //!< cumulative frame delay
|
||||
} apng;
|
||||
} 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
|
||||
size_t 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, int bpp, ubyte flags );
|
||||
void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_apng( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_pcx( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
|
||||
// image specific lock functions
|
||||
void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_pcx( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags );
|
||||
|
||||
|
||||
#endif // BMPMAN_INTERNAL
|
||||
|
||||
#endif // __BM_INTERNAL_H__
|
||||
+2515
-2925
File diff suppressed because it is too large.
Load diff
+200
-618
@@ -1,701 +1,283 @@
|
||||
#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
|
||||
|
||||
// special types
|
||||
BM_TYPE_RENDER_TARGET_STATIC, //!< 24/32 bit setup internally as a static render target
|
||||
BM_TYPE_RENDER_TARGET_DYNAMIC, //!< 24/32 bit setup internally as a dynamic render target
|
||||
|
||||
// Compressed types (bitmap.c_type)
|
||||
BM_TYPE_DXT1, //!< 24 bit with switchable alpha
|
||||
BM_TYPE_DXT3, //!< 32 bit with 4 bit alpha
|
||||
BM_TYPE_DXT5, //!< 32 bit with 8 bit alpha
|
||||
BM_TYPE_CUBEMAP_DDS, //!< generic DDS cubemap (uncompressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT1, //!< 24-bit cubemap (compressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT3, //!< 32-bit cubemap (compressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT5 //!< 32-bit cubemap (compressed cubemap surface)
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
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
|
||||
int bpp; //!< Requested bitdepth of each pixel. ( 7, 8, 15, 16, 24, 32)
|
||||
int 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 size_t 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);
|
||||
|
||||
/**
|
||||
* @brief Gets the next available bitmap slot.
|
||||
*/
|
||||
int bm_get_next_handle();
|
||||
// any texture type
|
||||
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP )
|
||||
|
||||
#define BMP_FLAG_RENDER_TARGET_STATIC (1<<0)
|
||||
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1)
|
||||
#define BMP_FLAG_CUBEMAP (1<<2)
|
||||
#define BMP_FLAG_RENDER_TARGET_MIPMAP (1<<3)
|
||||
|
||||
/**
|
||||
* @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, size_t size);
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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, size_t size);
|
||||
|
||||
class bitmap_lookup {
|
||||
ubyte *Bitmap_data;
|
||||
extern int Bm_paging;
|
||||
|
||||
int Width;
|
||||
int Height;
|
||||
int Num_channels;
|
||||
void bm_init();
|
||||
|
||||
float map_texture_address(float address);
|
||||
public:
|
||||
bitmap_lookup(int bitmap_num);
|
||||
~bitmap_lookup();
|
||||
void bm_close();
|
||||
|
||||
bool valid();
|
||||
int bm_get_cache_slot( int bitmap_id, int separate_ani_frames );
|
||||
|
||||
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);
|
||||
};
|
||||
int bm_get_next_handle();
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
int bm_load(const char* filename);
|
||||
void *bm_malloc(int n, int size);
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
void bm_update_memory_used(int n, int size);
|
||||
|
||||
// how many bytes of textures are used.
|
||||
extern int bm_texture_ram;
|
||||
|
||||
// This loads a bitmap so we can draw with it later.
|
||||
// It returns a negative number if it couldn't load
|
||||
// the bitmap. On success, it returns the bitmap
|
||||
// number.
|
||||
int bm_load(char * filename);
|
||||
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
|
||||
*/
|
||||
int bm_load_duplicate(const char *filename);
|
||||
// special load function. basically allows you to load a bitmap which already exists (by filename).
|
||||
// this is useful because in some cases we need to have a bitmap which is locked in screen format
|
||||
// _and_ texture format, such as pilot pics and squad logos
|
||||
int bm_load_duplicate(char *filename);
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
|
||||
* @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( 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 = nullptr, int *fps = nullptr, int *keyframe = nullptr, float *total_time = nullptr, bool can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
|
||||
//Loads either animation (bm_load_animation) or still image (bm_load)
|
||||
extern int bm_load_either(char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
|
||||
|
||||
/**
|
||||
* @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, bool can_drop_frames = false, 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 );
|
||||
|
||||
/**
|
||||
* @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, int 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.
|
||||
*/
|
||||
int bm_reload(int bitmap_handle, const char* filename);
|
||||
/*
|
||||
* Example on using bm_create
|
||||
*
|
||||
{
|
||||
static int test_inited = 0;
|
||||
static int test_bmp;
|
||||
static uint test_bmp_data[128*64];
|
||||
|
||||
if ( !test_inited ) {
|
||||
test_inited = 1;
|
||||
// Create the new bitmap and fill in its data.
|
||||
// When you're done with it completely, call
|
||||
// bm_release to free up the bitmap handle
|
||||
test_bmp = bm_create( 32, 128, 64, test_bmp_data );
|
||||
int i,j;
|
||||
for (i=0; i<64; i++ ) {
|
||||
for (j=0; j<64; j++ ) {
|
||||
uint r=i*4;
|
||||
test_bmp_data[j+i*128] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bm_unload(test_bmp); // this pages out the data, so that the
|
||||
// next bm_lock will convert the new data to the
|
||||
// correct bpp
|
||||
|
||||
// put in new data
|
||||
int x,y;
|
||||
gr_reset_clip();
|
||||
for (y=0; y<64; y++)
|
||||
for (x=0; x<128; x++ )
|
||||
test_bmp_data[y*128+x] = 15;
|
||||
|
||||
// Draw the bitmap to upper left corner
|
||||
gr_set_bitmap(test_bmp);
|
||||
gr_bitmap( 0,0 );
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//============================================================================
|
||||
// Paging stuff
|
||||
//============================================================================
|
||||
|
||||
/**
|
||||
* @brief Tells bmpman to start keeping track of what bitmaps are used where
|
||||
*/
|
||||
void bm_page_in_start();
|
||||
|
||||
/**
|
||||
* @brief Tells bmpman to stop paging (?)
|
||||
*/
|
||||
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 );
|
||||
|
||||
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);
|
||||
|
||||
extern int UNLITMAP; //this holds a reference to a map that is optional used instead of the base map for unlit rendering
|
||||
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 SPECGLOSSMAP; //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 AMBIENTMAP; // ambient occluion map. red channel affects ambient lighting, green channel affects diffuse and specular
|
||||
extern int MISCMAP; // Utility map, to be utilized for various things shader authors can come up with
|
||||
|
||||
/**
|
||||
* @brief Returns the compression type of the bitmap indexed by handle
|
||||
*/
|
||||
int bm_is_compressed(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 correct TCACHE_TYPE for compressed graphics (uncompressed are assumed TCACHE_TYPE_NORMAL)
|
||||
*/
|
||||
int bm_get_tcache_type(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);
|
||||
|
||||
/**
|
||||
* @brief Calculates & returns the current frame of an animation
|
||||
*
|
||||
* @param[in] frame1_handle Handle of the animation
|
||||
* @param[in] elapsed_time Time in seconds since the animation started playing
|
||||
* @param[in] loop (optional) specifies if the animation should loop, default is false which causes animation to hold on the last frame
|
||||
* @param[in] divisor (optional) if greater than zero, elapsed time will be divided by this value i.e. allows "percentage complete" to be used to determine the frame instead of the animations total time derived from fps * frames
|
||||
*
|
||||
* @returns current frame of the animation (range is zero to the number of frames minus one)
|
||||
*/
|
||||
int bm_get_anim_frame(const int frame1_handle, float elapsed_time, const float divisor = 0.0f, const bool loop = false);
|
||||
int bm_make_render_target( int width, int height, int flags );
|
||||
int bm_is_render_target(int bitmap_id);
|
||||
int bm_set_render_target(int handle, int face = -1);
|
||||
|
||||
#endif
|
||||
+53
-171
@@ -1,15 +1,15 @@
|
||||
#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"
|
||||
|
||||
//*************************IMPORTANT GLOBALS*************************
|
||||
float VIEWER_ZOOM_DEFAULT = 0.75f; // Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
|
||||
@@ -80,7 +80,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);
|
||||
}
|
||||
|
||||
@@ -109,27 +109,6 @@ void camera::set_object_host(object *objp, int n_object_host_submodel)
|
||||
|
||||
object_host = object_h(objp);
|
||||
object_host_submodel = n_object_host_submodel;
|
||||
set_custom_position_function(NULL);
|
||||
set_custom_orientation_function(NULL);
|
||||
if(n_object_host_submodel > 0)
|
||||
{
|
||||
if(objp->type == OBJ_SHIP)
|
||||
{
|
||||
ship_subsys* ssp = GET_FIRST(&Ships[objp->instance].subsys_list);
|
||||
while ( ssp != END_OF_LIST( &Ships[objp->instance].subsys_list ) )
|
||||
{
|
||||
if(ssp->system_info->subobj_num == n_object_host_submodel)
|
||||
{
|
||||
if(ssp->system_info->type == SUBSYSTEM_TURRET)
|
||||
{
|
||||
set_custom_position_function(get_turret_cam_pos);
|
||||
set_custom_orientation_function(get_turret_cam_orient);
|
||||
}
|
||||
}
|
||||
ssp = GET_NEXT( ssp );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void camera::set_object_target(object *objp, int n_object_target_submodel)
|
||||
@@ -161,7 +140,7 @@ void camera::set_custom_orientation_function(void (*n_func_custom_orientation)(c
|
||||
|
||||
void camera::set_position(vec3d *in_position, float in_translation_time, float in_translation_acceleration_time, float in_translation_deceleration_time, float in_end_velocity)
|
||||
{
|
||||
if(in_position != NULL && in_translation_time == 0.0f && in_translation_acceleration_time == 0.0f && in_translation_deceleration_time == 0.0f)
|
||||
if(in_translation_time == 0.0f && in_translation_acceleration_time == 0.0f && in_translation_deceleration_time == 0.0f)
|
||||
{
|
||||
c_pos = *in_position;
|
||||
pos_x.set(c_pos.xyz.x);
|
||||
@@ -194,7 +173,7 @@ void camera::set_translation_velocity(vec3d *in_velocity, float in_acceleration_
|
||||
|
||||
void camera::set_rotation(matrix *in_orientation, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
|
||||
{
|
||||
if(in_orientation != NULL && in_rotation_time == 0.0f && in_rotation_acceleration_time == 0.0f && in_rotation_deceleration_time == 0.0f)
|
||||
if(in_rotation_time == 0.0f && in_rotation_acceleration_time == 0.0f && in_rotation_deceleration_time == 0.0f)
|
||||
{
|
||||
c_ori = *in_orientation;
|
||||
for(int i = 0; i < 9; i++)
|
||||
@@ -291,14 +270,11 @@ float camera::get_fov()
|
||||
return c_fov;
|
||||
}
|
||||
|
||||
eye* get_submodel_eye(polymodel *pm, int submodel_num);
|
||||
void camera::get_info(vec3d *position, matrix *orientation)
|
||||
{
|
||||
if(position == NULL && orientation == NULL)
|
||||
return;
|
||||
|
||||
eye* eyep = NULL;
|
||||
vec3d host_normal;
|
||||
|
||||
//POSITION
|
||||
if(!(flags & CAM_STATIONARY_POS) || object_host.IsValid())
|
||||
{
|
||||
@@ -327,20 +303,7 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
vm_vec_unrotate(&c_pos, &c_pos_in, &objp->orient);
|
||||
vm_vec_add2(&c_pos, &objp->pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
model_find_world_point( &c_pos, &pt, pm->id, object_host_submodel, &objp->orient, &objp->pos );
|
||||
}
|
||||
model_find_world_point( &c_pos, &pt, pm->id, object_host_submodel, &objp->orient, &objp->pos );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -349,7 +312,7 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
}
|
||||
|
||||
//Do custom position stuff, if needed
|
||||
if(func_custom_position != NULL && !eyep)
|
||||
if(func_custom_position != NULL)
|
||||
{
|
||||
func_custom_position(this, &c_pos);
|
||||
}
|
||||
@@ -361,7 +324,6 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
//ORIENTATION
|
||||
if(orientation != NULL)
|
||||
{
|
||||
bool target_set = false;
|
||||
if(!(flags & CAM_STATIONARY_ORI) || object_target.IsValid() || object_host.IsValid())
|
||||
{
|
||||
if(object_target.IsValid())
|
||||
@@ -391,19 +353,10 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
vec3d targetvec;
|
||||
vm_vec_normalized_dir(&targetvec, &target_pos, &c_pos);
|
||||
vm_vector_2_matrix(&c_ori, &targetvec, NULL, NULL);
|
||||
target_set = true;
|
||||
}
|
||||
else if(object_host.IsValid())
|
||||
{
|
||||
if(eyep)
|
||||
{
|
||||
vm_vector_2_matrix(&c_ori, &host_normal, vm_vec_same(&host_normal, &object_host.objp->orient.vec.uvec)?NULL:&object_host.objp->orient.vec.uvec, NULL);
|
||||
target_set = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_ori = object_host.objp->orient;
|
||||
}
|
||||
c_ori = object_host.objp->orient;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -423,7 +376,7 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
vm_orthogonalize_matrix(&c_ori);
|
||||
}
|
||||
//Do custom orientation stuff, if needed
|
||||
if(func_custom_orientation != NULL && !target_set)
|
||||
if(func_custom_orientation != NULL)
|
||||
{
|
||||
func_custom_orientation(this, &c_ori);
|
||||
}
|
||||
@@ -515,8 +468,8 @@ void warp_camera::do_frame(float in_frametime)
|
||||
|
||||
float tmp_angle = frand()*PI2;
|
||||
|
||||
tmp.xyz.x = 22.0f * sinf(tmp_angle);
|
||||
tmp.xyz.y = -22.0f * cosf(tmp_angle);
|
||||
tmp.xyz.x = 22.0f * (float)sin(tmp_angle);
|
||||
tmp.xyz.y = -22.0f * (float)cos(tmp_angle);
|
||||
|
||||
this->set_velocity( &tmp, 0 );
|
||||
}
|
||||
@@ -540,17 +493,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, char* in_text, char* in_imageanim, float in_display_time, float in_fade_time, 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
|
||||
memset( imageanim, 0, sizeof(imageanim) );
|
||||
memset( &text_pos, 0, 2*sizeof(int) );
|
||||
@@ -560,16 +504,17 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char*
|
||||
if ( ((in_text != NULL) && (strlen(in_text) <= 0)) && ((in_imageanim != NULL) && (strlen(in_imageanim) <= 0)) )
|
||||
return;
|
||||
|
||||
char text_buf[256];
|
||||
if (in_text != NULL && in_text[0] != '\0')
|
||||
{
|
||||
text_buf = in_text;
|
||||
sexp_replace_variable_names_with_values(text_buf);
|
||||
in_text = text_buf.c_str();
|
||||
strcpy_s(text_buf, in_text);
|
||||
sexp_replace_variable_names_with_values(text_buf, 256);
|
||||
in_text = text_buf;
|
||||
}
|
||||
|
||||
|
||||
int num_text_lines = 0;
|
||||
const char *text_line_ptrs[MAX_SUBTITLE_LINES];
|
||||
char *text_line_ptrs[MAX_SUBTITLE_LINES];
|
||||
int text_line_lens[MAX_SUBTITLE_LINES];
|
||||
|
||||
//Setup text
|
||||
@@ -577,10 +522,11 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char*
|
||||
int split_width = (in_width > 0) ? in_width : 200;
|
||||
|
||||
num_text_lines = split_str(in_text, split_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
|
||||
SCP_string temp_str;
|
||||
for(int i = 0; i < num_text_lines; i++)
|
||||
{
|
||||
text_buf.assign(text_line_ptrs[i], text_line_lens[i]);
|
||||
text_lines.push_back(text_buf);
|
||||
temp_str.assign(text_line_ptrs[i], text_line_lens[i]);
|
||||
text_lines.push_back(temp_str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,8 +558,8 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char*
|
||||
int old_fontnum;
|
||||
if (text_fontnum >= 0)
|
||||
{
|
||||
old_fontnum = font::get_current_fontnum();
|
||||
font::set_font(text_fontnum);
|
||||
old_fontnum = gr_get_current_fontnum();
|
||||
gr_set_font(text_fontnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -634,7 +580,7 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char*
|
||||
// restore old font
|
||||
if (old_fontnum >= 0)
|
||||
{
|
||||
font::set_font(old_fontnum);
|
||||
gr_set_font(old_fontnum);
|
||||
}
|
||||
|
||||
//Get image size
|
||||
@@ -653,20 +599,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;
|
||||
@@ -710,8 +656,8 @@ void subtitle::do_frame(float frametime)
|
||||
int old_fontnum;
|
||||
if (text_fontnum >= 0)
|
||||
{
|
||||
old_fontnum = font::get_current_fontnum();
|
||||
font::set_font(text_fontnum);
|
||||
old_fontnum = gr_get_current_fontnum();
|
||||
gr_set_font(text_fontnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -725,14 +671,14 @@ void subtitle::do_frame(float frametime)
|
||||
|
||||
for(SCP_vector<SCP_string>::iterator line = text_lines.begin(); line != text_lines.end(); ++line)
|
||||
{
|
||||
gr_string(x, y, (char*)line->c_str(), GR_RESIZE_NONE);
|
||||
gr_string(x, y, (char*)line->c_str(), false);
|
||||
y += font_height;
|
||||
}
|
||||
|
||||
// restore old font
|
||||
if (old_fontnum >= 0)
|
||||
{
|
||||
font::set_font(old_fontnum);
|
||||
gr_set_font(old_fontnum);
|
||||
}
|
||||
|
||||
if(image_id >= 0)
|
||||
@@ -746,18 +692,18 @@ void subtitle::do_frame(float frametime)
|
||||
vec3d scale;
|
||||
|
||||
bm_get_info(image_id, &orig_w, &orig_h);
|
||||
scale.xyz.x = (image_pos.w > 0) ? (image_pos.w / (float) orig_w) : 1.0f;
|
||||
scale.xyz.y = (image_pos.h > 0) ? (image_pos.h / (float) orig_h) : 1.0f;
|
||||
scale.xyz.x = image_pos.w / (float) orig_w;
|
||||
scale.xyz.y = image_pos.h / (float) orig_h;
|
||||
scale.xyz.z = 1.0f;
|
||||
|
||||
gr_push_scale_matrix(&scale);
|
||||
gr_bitmap(fl2i(image_pos.x / scale.xyz.x), fl2i(image_pos.y / scale.xyz.y), GR_RESIZE_NONE);
|
||||
gr_bitmap(image_pos.x, image_pos.y, false);
|
||||
gr_pop_scale_matrix();
|
||||
}
|
||||
// no scaling
|
||||
else
|
||||
{
|
||||
gr_bitmap(image_pos.x, image_pos.y, GR_RESIZE_NONE);
|
||||
gr_bitmap(image_pos.x, image_pos.y, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,7 +770,7 @@ camid::camid()
|
||||
sig = -1;
|
||||
}
|
||||
|
||||
camid::camid(size_t n_idx, int n_sig)
|
||||
camid::camid(int n_idx, int n_sig)
|
||||
{
|
||||
idx = n_idx;
|
||||
sig = n_sig;
|
||||
@@ -838,7 +784,7 @@ camera* camid::getCamera()
|
||||
return Cameras[idx];
|
||||
}
|
||||
|
||||
size_t camid::getIndex()
|
||||
uint camid::getIndex()
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
@@ -873,9 +819,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();
|
||||
}
|
||||
|
||||
@@ -954,7 +897,7 @@ camid cam_get_current()
|
||||
return Current_camera;
|
||||
}
|
||||
|
||||
size_t cam_get_num()
|
||||
uint cam_get_num()
|
||||
{
|
||||
return Cameras.size();
|
||||
}
|
||||
@@ -987,15 +930,12 @@ bool cam_set_camera(camid cid)
|
||||
Viewer_mode |= VM_FREECAMERA;
|
||||
Current_camera = cid;
|
||||
|
||||
if (!Cutscene_camera_displays_hud)
|
||||
if(!Camera_hud_draw_saved)
|
||||
{
|
||||
if(!Camera_hud_draw_saved)
|
||||
{
|
||||
Camera_hud_draw_value = hud_get_draw();
|
||||
Camera_hud_draw_saved = true;
|
||||
}
|
||||
hud_set_draw(0);
|
||||
Camera_hud_draw_value = hud_get_draw();
|
||||
Camera_hud_draw_saved = true;
|
||||
}
|
||||
hud_set_draw(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1003,11 +943,8 @@ void cam_reset_camera()
|
||||
{
|
||||
Viewer_mode &= ~VM_FREECAMERA;
|
||||
|
||||
if (!Cutscene_camera_displays_hud)
|
||||
{
|
||||
hud_set_draw(Camera_hud_draw_value);
|
||||
Camera_hud_draw_saved = false;
|
||||
}
|
||||
hud_set_draw(Camera_hud_draw_value);
|
||||
Camera_hud_draw_saved = false;
|
||||
}
|
||||
|
||||
void subtitles_close()
|
||||
@@ -1033,59 +970,4 @@ void subtitles_do_frame_post_shaded(float frametime)
|
||||
if ( sub->is_post_shaded( ) )
|
||||
sub->do_frame(frametime);
|
||||
}
|
||||
}
|
||||
|
||||
vec3d normal_cache;
|
||||
|
||||
void get_turret_cam_pos(camera *cam, vec3d *pos)
|
||||
{
|
||||
object_h obj(cam->get_object_host());
|
||||
if(!obj.IsValid())
|
||||
return;
|
||||
ship* shipp = &Ships[cam->get_object_host()->instance];
|
||||
ship_subsys* ssp = GET_FIRST(&shipp->subsys_list);
|
||||
while ( ssp != END_OF_LIST( &shipp->subsys_list ) )
|
||||
{
|
||||
if(ssp->system_info->subobj_num == cam->get_object_host_submodel())
|
||||
{
|
||||
ship_get_global_turret_gun_info(cam->get_object_host(), ssp, pos, &normal_cache, 1, NULL);
|
||||
vec3d offset = vmd_zero_vector;
|
||||
offset.xyz.x = 0.0001f;
|
||||
vm_vec_add2(pos, &offset); // prevent beam turrets from crashing with a nullvec
|
||||
break;
|
||||
}
|
||||
ssp = GET_NEXT( ssp );
|
||||
}
|
||||
}
|
||||
|
||||
void get_turret_cam_orient(camera *cam, matrix *ori)
|
||||
{
|
||||
object_h obj(cam->get_object_host());
|
||||
if(!obj.IsValid())
|
||||
return;
|
||||
vm_vector_2_matrix(ori, &normal_cache, vm_vec_same(&normal_cache, &cam->get_object_host()->orient.vec.uvec)?NULL:&cam->get_object_host()->orient.vec.uvec, NULL);
|
||||
}
|
||||
|
||||
eye* get_submodel_eye(polymodel *pm, int submodel_num)
|
||||
{
|
||||
if(pm->n_view_positions > 0)
|
||||
{
|
||||
for(int i = 0; i < pm->n_view_positions; ++i)
|
||||
{
|
||||
if(pm->view_positions[i].parent == submodel_num)
|
||||
{
|
||||
return &pm->view_positions[i];
|
||||
}
|
||||
int sm = pm->submodel[submodel_num].first_child;
|
||||
while(sm > 0) //look for eyepoints attached to children, important for turret arms
|
||||
{
|
||||
if(pm->view_positions[i].parent == sm)
|
||||
{
|
||||
return &pm->view_positions[i];
|
||||
}
|
||||
sm = pm->submodel[sm].next_sibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -137,8 +137,8 @@ private:
|
||||
|
||||
bool post_shaded;
|
||||
public:
|
||||
subtitle(int in_x_pos, int in_y_pos, const char* in_text = NULL, const char* in_imageanim = NULL,
|
||||
float in_display_time = 0, float in_fade_time = 0.0f, const color *in_text_color = NULL, int in_text_fontnum = -1,
|
||||
subtitle(int in_x_pos, int in_y_pos, char* in_text = NULL, char* in_imageanim = NULL,
|
||||
float in_display_time = 0, float in_fade_time = 0.0f, color *in_text_color = NULL, int in_text_fontnum = -1,
|
||||
bool center_x = false, bool center_y = false, int in_width = 0, int in_height = 0, bool post_shaded=false);
|
||||
~subtitle();
|
||||
|
||||
@@ -166,10 +166,7 @@ void cam_reset_camera();
|
||||
camid cam_lookup(char *name);
|
||||
camid cam_get_camera(uint index);
|
||||
camid cam_get_current();
|
||||
size_t cam_get_num();
|
||||
|
||||
void get_turret_cam_pos(camera *cam, vec3d *pos);
|
||||
void get_turret_cam_orient(camera *cam, matrix *ori);
|
||||
uint cam_get_num();
|
||||
|
||||
void subtitles_close();
|
||||
void subtitles_do_frame(float frametime);
|
||||
|
||||
+251
-300
@@ -29,17 +29,16 @@
|
||||
#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"
|
||||
|
||||
|
||||
#include <limits>
|
||||
|
||||
char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
|
||||
char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
|
||||
#ifdef SCP_UNIX
|
||||
char Cfile_user_dir_legacy[CFILE_ROOT_DIRECTORY_LEN] = "";
|
||||
char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
|
||||
#endif
|
||||
|
||||
// During cfile_init, verify that Pathtypes[n].index == n for each item
|
||||
@@ -87,160 +86,142 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_CBANIMS, "data" DIR_SEPARATOR_STR "cbanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
|
||||
};
|
||||
|
||||
|
||||
#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;
|
||||
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, size_t offset, size_t 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();
|
||||
|
||||
static void dump_opened_files()
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
void cf_chksum_long_init();
|
||||
|
||||
void cfile_close()
|
||||
{
|
||||
mprintf(("Still opened files:\n"));
|
||||
dump_opened_files();
|
||||
|
||||
cf_free_secondary_filelist();
|
||||
|
||||
cfile_inited = 0;
|
||||
}
|
||||
|
||||
#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(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
|
||||
*/
|
||||
int cfile_init(const char *exe_dir, const char *cdrom_dir)
|
||||
// cfile_init() initializes the cfile system. Called once at application start.
|
||||
//
|
||||
// returns: success ==> 0
|
||||
// error ==> non-zero
|
||||
//
|
||||
int cfile_init(char *exe_dir, char *cdrom_dir)
|
||||
{
|
||||
int i;
|
||||
|
||||
// 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';
|
||||
size_t i = strlen(buf);
|
||||
memset(buf, 0, CFILE_ROOT_DIRECTORY_LEN);
|
||||
strncpy(buf, exe_dir, CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
i = strlen(buf);
|
||||
|
||||
// are we in a root directory?
|
||||
if(cfile_in_root_dir(buf)){
|
||||
os::dialogs::Message(os::dialogs::MESSAGEBOX_ERROR, "FreeSpace2/Fred2 cannot be run from a drive root directory!");
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
while (i--) {
|
||||
if (buf[i] == DIR_SEPARATOR_CHAR){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *p;
|
||||
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;
|
||||
}
|
||||
|
||||
p = strrchr(buf, DIR_SEPARATOR_CHAR);
|
||||
*p = '\0';
|
||||
|
||||
cfile_chdir(buf);
|
||||
|
||||
// set root directory
|
||||
strncpy(Cfile_root_dir, buf, CFILE_ROOT_DIRECTORY_LEN-1);
|
||||
strncpy(Cfile_user_dir, os_get_config_path().c_str(), CFILE_ROOT_DIRECTORY_LEN-1);
|
||||
|
||||
// set root directory
|
||||
strncpy(Cfile_root_dir, buf, CFILE_ROOT_DIRECTORY_LEN-1);
|
||||
#ifdef SCP_UNIX
|
||||
// Initialize path of old pilot files
|
||||
extern const char* Osreg_user_dir_legacy;
|
||||
snprintf(Cfile_user_dir_legacy, CFILE_ROOT_DIRECTORY_LEN-1, "%s/%s/", getenv("HOME"), Osreg_user_dir_legacy);
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -254,13 +235,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;
|
||||
@@ -276,108 +257,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)
|
||||
|
||||
int cfile_chdir(char *dir)
|
||||
{
|
||||
char dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
int e;
|
||||
char OriginalDirectory[CFILE_ROOT_DIRECTORY_LEN];
|
||||
char *Path = NULL;
|
||||
char NoDir[] = "\\.";
|
||||
|
||||
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN-1);
|
||||
|
||||
Assert(Cfile_stack_pos < CFILE_STACK_MAX);
|
||||
#ifdef _WIN32
|
||||
char *colon_pos = strchr(dir, ':');
|
||||
if (colon_pos) {
|
||||
if (!cfile_chdrive( tolower(*(colon_pos - 1)) - 'a' + 1, 1))
|
||||
return 1;
|
||||
|
||||
if (Cfile_stack_pos >= CFILE_STACK_MAX) {
|
||||
return -1;
|
||||
Path = colon_pos+1;
|
||||
} else
|
||||
#endif // _WIN32
|
||||
{
|
||||
Path = dir;
|
||||
}
|
||||
|
||||
strncpy(Cfile_stack[Cfile_stack_pos++], OriginalDirectory,
|
||||
CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
if (!(*Path)) {
|
||||
Path = NoDir;
|
||||
}
|
||||
|
||||
cf_create_default_path_string(dir, sizeof(dir) - 1, type, NULL);
|
||||
// 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 _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)
|
||||
{
|
||||
char OriginalDirectory[CFILE_ROOT_DIRECTORY_LEN];
|
||||
|
||||
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
|
||||
return _cfile_chdir(dir, OriginalDirectory);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cfile_pop_dir()
|
||||
@@ -407,7 +379,7 @@ int cfile_flush_dir(int dir_type)
|
||||
// proceed to delete the files
|
||||
del_count = 0;
|
||||
#if defined _WIN32
|
||||
intptr_t find_handle;
|
||||
int find_handle;
|
||||
_finddata_t find;
|
||||
find_handle = _findfirst( "*", &find );
|
||||
if (find_handle != -1) {
|
||||
@@ -430,7 +402,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
|
||||
@@ -457,12 +429,13 @@ int cfile_flush_dir(int dir_type)
|
||||
// filename = name of filename or filepath to process
|
||||
// ext = extension to add. Must start with the period
|
||||
// Returns: new filename or filepath with extension.
|
||||
char *cf_add_ext(const char *filename, const char *ext)
|
||||
char *cf_add_ext(char *filename, char *ext)
|
||||
{
|
||||
int flen, elen;
|
||||
static char path[MAX_PATH_LEN];
|
||||
|
||||
size_t flen = strlen(filename);
|
||||
size_t elen = strlen(ext);
|
||||
flen = strlen(filename);
|
||||
elen = strlen(ext);
|
||||
Assert(flen < MAX_PATH_LEN);
|
||||
strcpy_s(path, filename);
|
||||
if ((flen < 4) || stricmp(path + flen - elen, ext)) {
|
||||
@@ -473,29 +446,39 @@ 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(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Same as _access function to read a file's access bits
|
||||
int cf_access(const char *filename, int dir_type, int mode)
|
||||
int cf_access(char *filename, int dir_type, int mode)
|
||||
{
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
@@ -509,23 +492,29 @@ int cf_access(const char *filename, int dir_type, int mode)
|
||||
|
||||
// Returns 1 if the file exists, 0 if not.
|
||||
// Checks only the file system.
|
||||
// cf_find_file_location checks the filesystem before VPs
|
||||
// If offset is 0, it was found in the filesystem, so offset is boolean false
|
||||
// If offset equates to boolean true, it was found in a VP and the logic will negate the function return
|
||||
int cf_exists(const char *filename, int dir_type)
|
||||
int cf_exists(char *filename, int dir_type)
|
||||
{
|
||||
size_t offset = 1;
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
if ( (filename == NULL) || !strlen(filename) )
|
||||
return 0;
|
||||
Assert(CF_TYPE_SPECIFIED(dir_type));
|
||||
|
||||
return (cf_find_file_location(filename, dir_type, 0, NULL, NULL, &offset) && !offset);
|
||||
cf_create_default_path_string(longname, sizeof(longname) - 1, dir_type, filename);
|
||||
|
||||
FILE *fp = fopen(longname, "rb");
|
||||
if (fp)
|
||||
{
|
||||
// Goober5000 - these were switched, causing the fclose to be unreachable
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
// Returns !0 if the file exists, 0 if not.
|
||||
// Checks both the file system and the VPs.
|
||||
int cf_exists_full(const char *filename, int dir_type)
|
||||
int cf_exists_full(char *filename, int dir_type)
|
||||
{
|
||||
if ( (filename == NULL) || !strlen(filename) )
|
||||
return 0;
|
||||
@@ -534,7 +523,7 @@ int cf_exists_full(const char *filename, int dir_type)
|
||||
}
|
||||
|
||||
// same as the above, but with extension check
|
||||
int cf_exists_full_ext(const char *filename, int dir_type, const int num_ext, const char **ext_list)
|
||||
int cf_exists_full_ext(char *filename, int dir_type, const int num_ext, const char **ext_list)
|
||||
{
|
||||
if ( (filename == NULL) || !strlen(filename) )
|
||||
return 0;
|
||||
@@ -546,7 +535,7 @@ int cf_exists_full_ext(const char *filename, int dir_type, const int num_ext, co
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void cf_attrib(const char *filename, int set, int clear, int dir_type)
|
||||
void cf_attrib(char *filename, int set, int clear, int dir_type)
|
||||
{
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
@@ -565,7 +554,7 @@ void cf_attrib(const char *filename, int set, int clear, int dir_type)
|
||||
}
|
||||
#endif
|
||||
|
||||
int cf_rename(const char *old_name, const char *name, int dir_type)
|
||||
int cf_rename(char *old_name, char *name, int dir_type)
|
||||
{
|
||||
Assert( CF_TYPE_SPECIFIED(dir_type) );
|
||||
|
||||
@@ -592,28 +581,6 @@ int cf_rename(const char *old_name, const char *name, int dir_type)
|
||||
|
||||
}
|
||||
|
||||
|
||||
// This takes a path (e.g. "C:\Games\FreeSpace2\Lots\More\Directories") and creates it in its entirety.
|
||||
// Do note that this requires the path to have normalized directory separators as defined by DIR_SEPARATOR_CHAR
|
||||
static void mkdir_recursive(const char *path) {
|
||||
size_t pre = 0, pos;
|
||||
SCP_string tmp(path);
|
||||
SCP_string dir;
|
||||
|
||||
if (tmp[tmp.size() - 1] != DIR_SEPARATOR_CHAR) {
|
||||
// force trailing / so we can handle everything in loop
|
||||
tmp += DIR_SEPARATOR_CHAR;
|
||||
}
|
||||
|
||||
while ((pos = tmp.find_first_of(DIR_SEPARATOR_CHAR, pre)) != std::string::npos) {
|
||||
dir = tmp.substr(0, pos++);
|
||||
pre = pos;
|
||||
if (dir.size() == 0) continue; // if leading / first time is 0 length
|
||||
|
||||
_mkdir(dir.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the directory path if it doesn't exist. Even creates all its
|
||||
// parent paths.
|
||||
void cf_create_directory( int dir_type )
|
||||
@@ -622,7 +589,7 @@ void cf_create_directory( int dir_type )
|
||||
int dir_tree[CF_MAX_PATH_TYPES];
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
Assertion( CF_TYPE_SPECIFIED(dir_type), "Invalid dir_type passed to cf_create_directory." );
|
||||
Assert( CF_TYPE_SPECIFIED(dir_type) );
|
||||
|
||||
int current_dir = dir_type;
|
||||
|
||||
@@ -639,9 +606,13 @@ void cf_create_directory( int dir_type )
|
||||
|
||||
for (i=num_dirs-1; i>=0; i-- ) {
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, dir_tree[i], NULL );
|
||||
mprintf(( "CFILE: Creating new directory '%s'\n", longname ));
|
||||
mkdir_recursive(longname);
|
||||
|
||||
if ( _mkdir(longname)==0 ) {
|
||||
mprintf(( "CFILE: Created new directory '%s'\n", longname ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -663,7 +634,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(char *file_path, 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 )
|
||||
@@ -748,7 +719,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;
|
||||
}
|
||||
@@ -757,7 +728,7 @@ CFILE *_cfopen(const char* source, int line, const char *file_path, const char *
|
||||
//================================================
|
||||
// Search for file on disk, on cdrom, or in a packfile
|
||||
|
||||
size_t offset, size;
|
||||
int offset, size;
|
||||
char copy_file_path[MAX_PATH_LEN]; // FIX change in memory from cf_find_file_location
|
||||
strcpy_s(copy_file_path, file_path);
|
||||
|
||||
@@ -765,7 +736,6 @@ CFILE *_cfopen(const char* source, int line, const char *file_path, const char *
|
||||
if ( cf_find_file_location( copy_file_path, dir_type, sizeof(longname) - 1, longname, &size, &offset, localize ) ) {
|
||||
|
||||
// Fount it, now create a cfile out of it
|
||||
nprintf(("CFileDebug", "Requested file %s found at: %s\n", file_path, longname));
|
||||
|
||||
if ( type & CFILE_MEMORY_MAPPED ) {
|
||||
|
||||
@@ -777,12 +747,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
|
||||
}
|
||||
@@ -794,10 +764,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -818,7 +788,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 size_t size, const size_t offset, int dir_type)
|
||||
CFILE *cfopen_special(char *file_path, char *mode, const int size, const int offset, int dir_type)
|
||||
{
|
||||
if ( !cfile_inited) {
|
||||
Int3();
|
||||
@@ -827,6 +797,7 @@ CFILE *_cfopen_special(const char* source, int line, const char *file_path, cons
|
||||
|
||||
Assert( file_path && strlen(file_path) );
|
||||
Assert( mode != NULL );
|
||||
Assert( offset >= 0 );
|
||||
|
||||
// cfopen_special() only supports reading files, not creating them
|
||||
if ( strchr(mode, 'w') ) {
|
||||
@@ -842,10 +813,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -864,7 +835,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;
|
||||
}
|
||||
@@ -877,7 +848,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;
|
||||
@@ -894,13 +865,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;
|
||||
}
|
||||
|
||||
@@ -978,7 +943,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;
|
||||
|
||||
@@ -997,9 +962,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)
|
||||
@@ -1017,7 +979,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, size_t offset, size_t size)
|
||||
CFILE *cf_open_packed_cfblock(FILE *fp, int type, int offset, int size)
|
||||
{
|
||||
// Found it in a pack file
|
||||
int cfile_block_index;
|
||||
@@ -1039,9 +1001,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;
|
||||
@@ -1057,9 +1016,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;
|
||||
@@ -1086,9 +1045,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);
|
||||
@@ -1381,12 +1337,12 @@ int cfwrite_char(char b, CFILE *file)
|
||||
return cfwrite( &b, sizeof(b), 1, file);
|
||||
}
|
||||
|
||||
int cfwrite_string(const char *buf, CFILE *file)
|
||||
int cfwrite_string(char *buf, CFILE *file)
|
||||
{
|
||||
if ( (!buf) || (buf && !buf[0]) ) {
|
||||
return cfwrite_char(0, file);
|
||||
}
|
||||
int len = (int)strlen(buf);
|
||||
int len = strlen(buf);
|
||||
if(!cfwrite(buf, len, 1, file)){
|
||||
return 0;
|
||||
}
|
||||
@@ -1395,7 +1351,7 @@ int cfwrite_string(const char *buf, CFILE *file)
|
||||
|
||||
int cfwrite_string_len(const char *buf, CFILE *file)
|
||||
{
|
||||
int len = (int)strlen(buf);
|
||||
int len = strlen(buf);
|
||||
|
||||
if(!cfwrite_int(len, file)){
|
||||
return 0;
|
||||
@@ -1421,11 +1377,7 @@ int cfilelength( CFILE * cfile )
|
||||
Assert(cb->fp != NULL);
|
||||
|
||||
// cb->size gets set at cfopen
|
||||
|
||||
// The rest of the code still uses ints, do an overflow check to detect cases where this fails
|
||||
Assertion(cb->size <= static_cast<size_t>(std::numeric_limits<int>::max()),
|
||||
"Integer overflow in cfilelength! A file is too large (but I don't know which...).");
|
||||
return (int) cb->size;
|
||||
return cb->size;
|
||||
}
|
||||
|
||||
// cfwrite() writes to the file
|
||||
@@ -1470,7 +1422,7 @@ int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
Assert( cb->size == filelength(fileno(cb->fp)) );
|
||||
#endif
|
||||
|
||||
return (int)(bytes_written / elsize);
|
||||
return ((int)bytes_written / elsize);
|
||||
}
|
||||
|
||||
|
||||
@@ -1523,7 +1475,7 @@ int cfputc(int c, CFILE *cfile)
|
||||
// returns: success ==> non-negative value
|
||||
// error ==> EOF
|
||||
//
|
||||
int cfputs(const char *str, CFILE *cfile)
|
||||
int cfputs(char *str, CFILE *cfile)
|
||||
{
|
||||
if(!cf_is_valid(cfile))
|
||||
return EOF;
|
||||
@@ -1628,7 +1580,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
|
||||
|
||||
@@ -1651,7 +1603,7 @@ ushort cf_add_chksum_short(ushort seed, ubyte *buffer, int size)
|
||||
}
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
uint cf_add_chksum_long(uint seed, ubyte *buffer, size_t size)
|
||||
uint cf_add_chksum_long(uint seed, ubyte *buffer, int size)
|
||||
{
|
||||
uint crc;
|
||||
ubyte *p;
|
||||
@@ -1665,7 +1617,7 @@ uint cf_add_chksum_long(uint seed, ubyte *buffer, size_t size)
|
||||
return crc;
|
||||
}
|
||||
|
||||
static void cf_chksum_long_init()
|
||||
void cf_chksum_long_init()
|
||||
{
|
||||
int i, j;
|
||||
uint crc;
|
||||
@@ -1686,7 +1638,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;
|
||||
@@ -1741,14 +1693,16 @@ static int cf_chksum_do(CFILE *cfile, ushort *chk_short, uint *chk_long, int max
|
||||
}
|
||||
|
||||
// get the chksum of a pack file (VP)
|
||||
int cf_chksum_pack(const char *filename, uint *chk_long, bool full)
|
||||
int cf_chksum_pack(char *filename, uint *chk_long, bool full)
|
||||
{
|
||||
const size_t safe_size = 2097152; // 2 Meg
|
||||
const int safe_size = 2097152; // 2 Meg
|
||||
const int header_offset = 32; // skip 32bytes for header (header is currently smaller than this though)
|
||||
|
||||
ubyte cf_buffer[CF_CHKSUM_SAMPLE_SIZE];
|
||||
size_t read_size;
|
||||
size_t max_size;
|
||||
int cf_len = 0;
|
||||
int cf_total;
|
||||
int read_size;
|
||||
int max_size;
|
||||
|
||||
if (chk_long == NULL) {
|
||||
Int3();
|
||||
@@ -1766,7 +1720,7 @@ int cf_chksum_pack(const char *filename, uint *chk_long, bool full)
|
||||
|
||||
// get the max size
|
||||
fseek(fp, 0, SEEK_END);
|
||||
max_size = (size_t)ftell(fp);
|
||||
max_size = ftell(fp);
|
||||
|
||||
// maybe do a chksum of the entire file
|
||||
if (full) {
|
||||
@@ -1774,19 +1728,16 @@ int cf_chksum_pack(const char *filename, uint *chk_long, bool full)
|
||||
}
|
||||
// othewise it's only a partial check
|
||||
else {
|
||||
if (max_size > safe_size) {
|
||||
max_size = safe_size;
|
||||
}
|
||||
CLAMP(max_size, 0, safe_size);
|
||||
|
||||
Assertion(max_size > header_offset,
|
||||
"max_size (" SIZE_T_ARG ") > header_offset in packfile %s", max_size, filename);
|
||||
Assert( max_size > header_offset );
|
||||
max_size -= header_offset;
|
||||
|
||||
fseek(fp, -((long)max_size), SEEK_END);
|
||||
fseek(fp, -(max_size), SEEK_END);
|
||||
}
|
||||
|
||||
size_t cf_total = 0;
|
||||
size_t cf_len = 0;
|
||||
cf_total = 0;
|
||||
|
||||
do {
|
||||
// determine how much we want to read
|
||||
if ( (max_size - cf_total) >= CF_CHKSUM_SAMPLE_SIZE )
|
||||
@@ -1810,7 +1761,7 @@ int cf_chksum_pack(const char *filename, uint *chk_long, bool full)
|
||||
return 1;
|
||||
}
|
||||
// get the 2 byte checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_short(const char *filename, ushort *chksum, int max_size, int cf_type)
|
||||
int cf_chksum_short(char *filename, ushort *chksum, int max_size, int cf_type)
|
||||
{
|
||||
int ret_val;
|
||||
CFILE *cfile = NULL;
|
||||
@@ -1860,7 +1811,7 @@ int cf_chksum_short(CFILE *file, ushort *chksum, int max_size)
|
||||
}
|
||||
|
||||
// get the 32 bit CRC checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_long(const char *filename, uint *chksum, int max_size, int cf_type)
|
||||
int cf_chksum_long(char *filename, uint *chksum, int max_size, int cf_type)
|
||||
{
|
||||
int ret_val;
|
||||
CFILE *cfile = NULL;
|
||||
|
||||
+28
-34
@@ -99,7 +99,7 @@ typedef struct {
|
||||
|
||||
// callback function used for get_file_list() to filter files to be added to list. Return 1
|
||||
// to add file to list, or 0 to not add it.
|
||||
extern int (*Get_file_list_filter)(const char *filename);
|
||||
extern int (*Get_file_list_filter)(char *filename);
|
||||
|
||||
// extra check for child directory under CF_TYPE_*
|
||||
// NOTE: if specified cf_get_file_list() will not search pack files!
|
||||
@@ -109,14 +109,13 @@ extern const char *Get_file_list_child;
|
||||
// cfile directory. valid after cfile_init() returns successfully
|
||||
#define CFILE_ROOT_DIRECTORY_LEN 256
|
||||
extern char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
extern char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
#ifdef SCP_UNIX
|
||||
extern char Cfile_user_dir_legacy[CFILE_ROOT_DIRECTORY_LEN];
|
||||
extern char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
#endif
|
||||
|
||||
//================= LOW-LEVEL FUNCTIONS ==================
|
||||
int cfile_init(const char *exe_dir, const char *cdrom_dir=NULL);
|
||||
void cfile_close();
|
||||
// Call this once at the beginning of the program
|
||||
int cfile_init(char *exe_dir,char *cdrom_dir=NULL);
|
||||
|
||||
// Call this if pack files got added or removed or the
|
||||
// cdrom changed. This will refresh the list of filenames
|
||||
@@ -124,23 +123,18 @@ void cfile_close();
|
||||
void cfile_refresh();
|
||||
|
||||
// add an extension to a filename if it doesn't already have it
|
||||
char *cf_add_ext(const char *filename, const char *ext);
|
||||
char *cf_add_ext(char *filename, char *ext);
|
||||
|
||||
// return CF_TYPE (directory location type) of a CFILE you called cfopen() successfully on.
|
||||
int cf_get_dir_type(CFILE *cfile);
|
||||
|
||||
|
||||
// Opens the file. If no path is given, use the extension to look into the
|
||||
// default path. If mode is NULL, delete the file.
|
||||
CFILE *_cfopen(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(char *filename, char *mode, int type = CFILE_NORMAL, int dir_type = CF_TYPE_ANY, bool localize = false);
|
||||
|
||||
// like cfopen(), but it accepts a fully qualified path only (ie, the result of a cf_find_file_location() call)
|
||||
// NOTE: only supports reading files!!
|
||||
CFILE *_cfopen_special(const char* source_file, int line, const char *file_path, const char *mode,
|
||||
const size_t size, const size_t offset, int dir_type = CF_TYPE_ANY);
|
||||
#define cfopen_special(...) _cfopen_special(LOCATION, __VA_ARGS__) // Pass source location to the function
|
||||
CFILE *cfopen_special(char *file_path, char *mode, const int size, const int offset, int dir_type = CF_TYPE_ANY);
|
||||
|
||||
// Flush the open file buffer
|
||||
int cflush(CFILE *cfile);
|
||||
@@ -155,21 +149,21 @@ void cf_set_version( CFILE * cfile, int version );
|
||||
void cf_set_max_read_len(CFILE *cfile, size_t len);
|
||||
|
||||
// Deletes a file. Returns 0 on error, 1 if successful
|
||||
int cf_delete(const char *filename, int dir_type);
|
||||
int cf_delete(char *filename, int dir_type);
|
||||
|
||||
// Same as _access function to read a file's access bits
|
||||
int cf_access(const char *filename, int dir_type, int mode);
|
||||
int cf_access(char *filename, int dir_type, int mode);
|
||||
|
||||
// Returns 1 if the file exists, 0 if not.
|
||||
// Checks only the file system.
|
||||
int cf_exists(const char *filename, int dir_type);
|
||||
int cf_exists(char *filename, int dir_type);
|
||||
|
||||
// Goober5000
|
||||
// Returns 1 if the file exists, 0 if not.
|
||||
// Checks both the file system and the VPs.
|
||||
int cf_exists_full(const char *filename, int dir_type);
|
||||
int cf_exists_full(char *filename, int dir_type);
|
||||
// check num_ext worth of ext_list extensions
|
||||
int cf_exists_full_ext(const char *filename, int dir_type, const int num_ext, const char **ext_list);
|
||||
int cf_exists_full_ext(char *filename, int dir_type, const int num_ext, const char **ext_list);
|
||||
|
||||
// ctmpfile() opens a temporary file stream. File is deleted automatically when closed
|
||||
CFILE *ctmpfile();
|
||||
@@ -203,7 +197,7 @@ int cftell(CFILE *fp);
|
||||
int cfputc(int c, CFILE *cfile);
|
||||
|
||||
// cfputs() writes a string to a file
|
||||
int cfputs(const char *str, CFILE *cfile);
|
||||
int cfputs(char *str, CFILE *cfile);
|
||||
|
||||
// cfgetc() reads a character to a file
|
||||
int cfgetc(CFILE *cfile);
|
||||
@@ -218,20 +212,20 @@ int cfeof(CFILE *cfile);
|
||||
void *cf_returndata(CFILE *cfile);
|
||||
|
||||
// get the 2 byte checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_short(const char *filename, ushort *chksum, int max_size = -1, int cf_type = CF_TYPE_ANY );
|
||||
int cf_chksum_short(char *filename, ushort *chksum, int max_size = -1, int cf_type = CF_TYPE_ANY );
|
||||
|
||||
// get the 2 byte checksum of the passed file - return 0 if operation failed, 1 if succeeded
|
||||
// NOTE : preserves current file position
|
||||
int cf_chksum_short(CFILE *file, ushort *chksum, int max_size = -1);
|
||||
|
||||
// get the 32 bit CRC checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_long(const char *filename, uint *chksum, int max_size = -1, int cf_type = CF_TYPE_ANY );
|
||||
int cf_chksum_long(char *filename, uint *chksum, int max_size = -1, int cf_type = CF_TYPE_ANY );
|
||||
|
||||
// get the 32 bit CRC checksum of the passed file - return 0 if operation failed, 1 if succeeded
|
||||
// NOTE : preserves current file position
|
||||
int cf_chksum_long(CFILE *file, uint *chksum, int max_size = -1);
|
||||
|
||||
int cf_chksum_pack(const char *filename, uint *chk_long, bool full = false);
|
||||
int cf_chksum_pack(char *filename, uint *chk_long, bool full = false);
|
||||
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
@@ -239,21 +233,21 @@ int cf_chksum_pack(const char *filename, uint *chk_long, bool full = false);
|
||||
ushort cf_add_chksum_short(ushort seed, ubyte *buffer, int size);
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
uint cf_add_chksum_long(uint seed, ubyte *buffer, size_t size);
|
||||
uint cf_add_chksum_long(uint seed, ubyte *buffer, int size);
|
||||
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
//================= HIGH LEVEL FUNCTIONS ==================
|
||||
int cfexist(const char *filename); // Returns true if file exists on disk (1) or in hog (2).
|
||||
int cfexist(char *filename); // Returns true if file exists on disk (1) or in hog (2).
|
||||
|
||||
// rename a file, utilizing the extension to determine where file is.
|
||||
#define CF_RENAME_SUCCESS 0 // successfully renamed the file
|
||||
#define CF_RENAME_FAIL_ACCESS 1 // new name could not be created
|
||||
#define CF_RENAME_FAIL_EXIST 2 // old name does not exist
|
||||
int cf_rename(const char *old_name, const char *name, int type = CF_TYPE_ANY );
|
||||
int cf_rename(char *old_name, char *name, int type = CF_TYPE_ANY );
|
||||
|
||||
// changes the attributes of a file
|
||||
void cf_attrib(const char *name, int set, int clear, int type);
|
||||
void cf_attrib(char *name, int set, int clear, int type);
|
||||
|
||||
// flush (delete all files in) the passed directory (by type), return the # of files deleted
|
||||
// NOTE : WILL NOT DELETE READ-ONLY FILES
|
||||
@@ -300,7 +294,7 @@ int cfwrite_vector(vec3d *vec, CFILE *file);
|
||||
int cfwrite_angles(angles *ang, CFILE *file);
|
||||
|
||||
// writes variable length, null-termined string.
|
||||
int cfwrite_string(const char *buf, CFILE *file);
|
||||
int cfwrite_string(char *buf, CFILE *file);
|
||||
|
||||
/**
|
||||
* @brief Write a fixed length string (not including its null terminator), with the length stored in file
|
||||
@@ -310,9 +304,9 @@ int cfwrite_string(const char *buf, CFILE *file);
|
||||
*/
|
||||
int cfwrite_string_len(const char *buf, CFILE *file);
|
||||
|
||||
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *filter, int sort = CF_SORT_NONE, SCP_vector<file_list_info> *info = NULL );
|
||||
int cf_get_file_list( int max, char **list, int type, const char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int type, const char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, char *filter, int sort = CF_SORT_NONE, SCP_vector<file_list_info> *info = NULL );
|
||||
int cf_get_file_list( int max, char **list, int type, char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int type, char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
void cf_sort_filenames( int n, char **list, int sort, file_list_info *info = NULL );
|
||||
void cf_sort_filenames( SCP_vector<SCP_string> &list, int sort, SCP_vector<file_list_info> *info = NULL );
|
||||
|
||||
@@ -325,7 +319,7 @@ void cf_sort_filenames( SCP_vector<SCP_string> &list, int sort, SCP_vector<file_
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns 0.
|
||||
int cf_find_file_location( const char *filespec, int pathtype, int max_out, char *pack_filename, size_t *size, size_t *offset, bool localize = false);
|
||||
int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize = false);
|
||||
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files. Searches all locations in order for first filename using ext filter list.
|
||||
@@ -339,10 +333,10 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns -1, else returns offset into ext_list.
|
||||
// (NOTE: This function is exponentially slow, so don't use it unless truely needed!!)
|
||||
int cf_find_file_location_ext(const char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out = 0, char *pack_filename = NULL, size_t *size = NULL, size_t *offset = NULL, bool localize = false);
|
||||
int cf_find_file_location_ext(char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out = 0, char *pack_filename = NULL, int *size = NULL, int *offset = NULL, bool localize = false);
|
||||
|
||||
// Functions to change directories
|
||||
int cfile_chdir(const char *dir);
|
||||
int cfile_chdir(char *dir);
|
||||
|
||||
#ifdef _WIN32
|
||||
int cfile_chdrive(int DriveNum, int flag);
|
||||
@@ -393,6 +387,6 @@ namespace cfile
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* __CFILE_H__ */
|
||||
+27
-25
@@ -27,14 +27,13 @@
|
||||
#include "luaconf.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
|
||||
|
||||
#define CHECK_POSITION
|
||||
|
||||
// Called once to setup the low-level reading code.
|
||||
|
||||
void cf_init_lowlevel_read_code( CFILE * cfile, size_t lib_offset, size_t size, size_t pos )
|
||||
void cf_init_lowlevel_read_code( CFILE * cfile, int lib_offset, int size, int pos )
|
||||
{
|
||||
Assert(cfile != NULL);
|
||||
|
||||
@@ -48,12 +47,13 @@ void cf_init_lowlevel_read_code( CFILE * cfile, size_t lib_offset, size_t size,
|
||||
|
||||
if ( cb->fp ) {
|
||||
if ( cb->lib_offset ) {
|
||||
fseek( cb->fp, (long)cb->lib_offset, SEEK_SET );
|
||||
fseek( cb->fp, cb->lib_offset, SEEK_SET );
|
||||
}
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
auto raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
int raw_position;
|
||||
raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -84,8 +84,9 @@ int cfeof(CFILE *cfile)
|
||||
Assert(cb->fp != NULL);
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
auto raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
int raw_position;
|
||||
raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
#endif
|
||||
|
||||
if (cb->raw_position >= cb->size ) {
|
||||
@@ -115,14 +116,12 @@ int cftell( CFILE * cfile )
|
||||
Assert(cb->fp != NULL);
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
auto raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
int raw_position;
|
||||
raw_position = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(raw_position == cb->raw_position);
|
||||
#endif
|
||||
|
||||
// The rest of the code still uses ints, do an overflow check to detect cases where this fails
|
||||
Assertion(cb->raw_position <= static_cast<size_t>(std::numeric_limits<int>::max()),
|
||||
"Integer overflow in cftell, a file is probably too large (but I don't know which one).");
|
||||
return (int) cb->raw_position;
|
||||
return cb->raw_position;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +143,7 @@ int cfseek( CFILE *cfile, int offset, int where )
|
||||
Assert( !cb->data );
|
||||
Assert( cb->fp != NULL );
|
||||
|
||||
size_t goal_position;
|
||||
int goal_position;
|
||||
|
||||
switch( where ) {
|
||||
case CF_SEEK_SET:
|
||||
@@ -163,12 +162,13 @@ int cfseek( CFILE *cfile, int offset, int where )
|
||||
return 1;
|
||||
}
|
||||
|
||||
int result = fseek(cb->fp, (long)goal_position, SEEK_SET );
|
||||
int result = fseek(cb->fp, goal_position, SEEK_SET );
|
||||
cb->raw_position = goal_position - cb->lib_offset;
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
int tmp_offset;
|
||||
tmp_offset = (int)ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
@@ -185,7 +185,7 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
if(!cf_is_valid(cfile))
|
||||
return 0;
|
||||
|
||||
size_t size = elsize*nelem;
|
||||
int size = elsize*nelem;
|
||||
|
||||
if(buf == NULL || size <= 0)
|
||||
return 0;
|
||||
@@ -208,7 +208,7 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
}
|
||||
|
||||
if (cb->max_read_len) {
|
||||
if ( cb->raw_position+size > cb->max_read_len ) {
|
||||
if ( (size_t)(cb->raw_position+size) > cb->max_read_len ) {
|
||||
std::ostringstream s_buf;
|
||||
s_buf << "Attempted to read " << size << "-byte(s) beyond length limit";
|
||||
|
||||
@@ -216,17 +216,18 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
}
|
||||
}
|
||||
|
||||
size_t bytes_read = fread( buf, 1, size, cb->fp );
|
||||
int bytes_read = fread( buf, 1, size, cb->fp );
|
||||
if ( bytes_read > 0 ) {
|
||||
cb->raw_position += bytes_read;
|
||||
}
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
int tmp_offset;
|
||||
tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
#endif
|
||||
|
||||
return (int)(bytes_read / elsize);
|
||||
return bytes_read / elsize;
|
||||
|
||||
}
|
||||
|
||||
@@ -252,8 +253,9 @@ int cfread_lua_number(double *buf, CFILE *cfile)
|
||||
cb->raw_position += ftell(cb->fp)-orig_pos;
|
||||
|
||||
#if defined(CHECK_POSITION) && !defined(NDEBUG)
|
||||
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
int tmp_offset;
|
||||
tmp_offset = ftell(cb->fp) - cb->lib_offset;
|
||||
Assert(tmp_offset==cb->raw_position);
|
||||
#endif
|
||||
|
||||
return items_read;
|
||||
|
||||
@@ -34,20 +34,18 @@ typedef struct Cfile_block {
|
||||
// int fd; // file descriptor
|
||||
size_t data_length; // length of data for mmap
|
||||
#endif
|
||||
size_t lib_offset;
|
||||
size_t raw_position;
|
||||
size_t size; // for packed files
|
||||
int lib_offset;
|
||||
int raw_position;
|
||||
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, size_t lib_offset, size_t size, size_t pos );
|
||||
void cf_init_lowlevel_read_code( CFILE * cfile, int lib_offset, int size, int pos );
|
||||
|
||||
#endif
|
||||
@@ -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 )
|
||||
@@ -420,7 +420,7 @@ int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
}
|
||||
}
|
||||
|
||||
return (int)((out - (char *)buf)/elsize);
|
||||
return (out - (char *)buf)/elsize;
|
||||
}
|
||||
|
||||
int cfwrite_compressed(void *param_buf, int param_elsize, int param_nelem, CFILE *cfile)
|
||||
|
||||
+204
-207
@@ -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,18 +33,18 @@
|
||||
#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"
|
||||
#include "osapi/osapi.h"
|
||||
|
||||
|
||||
|
||||
#define CF_ROOTTYPE_PATH 0
|
||||
#define CF_ROOTTYPE_PACK 1
|
||||
|
||||
// for a defined and specifically set location to get/send pilot/campaign files
|
||||
SCP_string Pilot_file_path;
|
||||
char *Pilot_file_path = NULL;
|
||||
|
||||
// Created by:
|
||||
// specifying hard drive tree
|
||||
@@ -95,6 +96,7 @@ typedef struct cf_file_block {
|
||||
static uint Num_files = 0;
|
||||
static cf_file_block *File_blocks[CF_MAX_FILE_BLOCKS];
|
||||
|
||||
|
||||
// Return a pointer to to file 'index'.
|
||||
cf_file *cf_get_file(int index)
|
||||
{
|
||||
@@ -178,7 +180,7 @@ int cf_get_packfile_count(cf_root *root)
|
||||
#if defined _WIN32
|
||||
filespec += "*.vp";
|
||||
|
||||
intptr_t find_handle;
|
||||
int find_handle;
|
||||
_finddata_t find;
|
||||
|
||||
find_handle = _findfirst( filespec.c_str( ), &find );
|
||||
@@ -218,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
|
||||
@@ -266,7 +272,7 @@ void cf_build_pack_list( cf_root *root )
|
||||
#if defined _WIN32
|
||||
strcat_s( filespec, "*.vp" );
|
||||
|
||||
intptr_t find_handle;
|
||||
int find_handle;
|
||||
_finddata_t find;
|
||||
|
||||
find_handle = _findfirst( filespec, &find );
|
||||
@@ -335,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;
|
||||
@@ -359,123 +365,109 @@ void cf_build_pack_list( cf_root *root )
|
||||
vm_free(temp_roots_sort);
|
||||
}
|
||||
|
||||
static char normalize_directory_separator(char in)
|
||||
{
|
||||
if (in == '/')
|
||||
{
|
||||
return DIR_SEPARATOR_CHAR;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
static void cf_add_mod_roots(const char* rootDirectory)
|
||||
void cf_build_root_list(char *cdrom_dir)
|
||||
{
|
||||
if (Cmdline_mod)
|
||||
{
|
||||
for (const char* cur_pos=Cmdline_mod; strlen(cur_pos) != 0; cur_pos+= (strlen(cur_pos)+1))
|
||||
Num_roots = 0;
|
||||
Num_path_roots = 0;
|
||||
|
||||
cf_root *root;
|
||||
char str_temp[CF_MAX_PATHNAME_LENGTH], *cur_pos;
|
||||
int path_len;
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
// =========================================================================
|
||||
// now look for mods under the users HOME directory to use before system ones
|
||||
if (Cmdline_mod) {
|
||||
for (cur_pos=Cmdline_mod; strlen(cur_pos) != 0; cur_pos+= (strlen(cur_pos)+1))
|
||||
{
|
||||
SCP_stringstream ss;
|
||||
ss << rootDirectory;
|
||||
memset(str_temp, 0, CF_MAX_PATHNAME_LENGTH);
|
||||
strncpy(str_temp, cur_pos, CF_MAX_PATHNAME_LENGTH-1);
|
||||
|
||||
if (rootDirectory[strlen(rootDirectory) - 1] != DIR_SEPARATOR_CHAR)
|
||||
{
|
||||
ss << DIR_SEPARATOR_CHAR;
|
||||
strncat(str_temp, DIR_SEPARATOR_STR, (CF_MAX_PATHNAME_LENGTH - strlen(str_temp) - 1));
|
||||
|
||||
// truncated string check
|
||||
if ( (strlen(Cfile_user_dir) + strlen(str_temp) + 1) >= CF_MAX_PATHNAME_LENGTH ) {
|
||||
Int3();
|
||||
}
|
||||
|
||||
ss << cur_pos << DIR_SEPARATOR_STR;
|
||||
root = cf_create_root();
|
||||
|
||||
SCP_string rootPath = ss.str();
|
||||
if (rootPath.size() + 1 >= CF_MAX_PATHNAME_LENGTH) {
|
||||
Error(LOCATION, "The length of mod directory path '%s' exceeds the maximum of %d!\n", rootPath.c_str(), CF_MAX_PATHNAME_LENGTH);
|
||||
strncpy( root->path, Cfile_user_dir, CF_MAX_PATHNAME_LENGTH-1 );
|
||||
|
||||
// do we already have a slash? as in the case of a root directory install
|
||||
if ( (strlen(root->path) < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[strlen(root->path)-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
|
||||
}
|
||||
|
||||
// normalize the path to the native path format
|
||||
std::transform(rootPath.begin(), rootPath.end(), rootPath.begin(), normalize_directory_separator);
|
||||
|
||||
cf_root* root = cf_create_root();
|
||||
|
||||
strncpy(root->path, rootPath.c_str(), CF_MAX_PATHNAME_LENGTH-1);
|
||||
strncat(root->path, str_temp, (CF_MAX_PATHNAME_LENGTH - strlen(root->path) - 1));
|
||||
|
||||
root->roottype = CF_ROOTTYPE_PATH;
|
||||
cf_build_pack_list(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
// =========================================================================
|
||||
|
||||
void cf_build_root_list(const char *cdrom_dir)
|
||||
{
|
||||
Num_roots = 0;
|
||||
Num_path_roots = 0;
|
||||
// =========================================================================
|
||||
// set users HOME directory as default for loading and saving files
|
||||
root = cf_create_root();
|
||||
strncpy( root->path, Cfile_user_dir, CF_MAX_PATHNAME_LENGTH-1 );
|
||||
|
||||
cf_root *root = nullptr;
|
||||
// do we already have a slash? as in the case of a root directory install
|
||||
if( (strlen(root->path) < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[strlen(root->path)-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
|
||||
}
|
||||
root->roottype = CF_ROOTTYPE_PATH;
|
||||
|
||||
if (os_is_legacy_mode())
|
||||
{
|
||||
// =========================================================================
|
||||
#ifdef WIN32
|
||||
// Nothing to do here, Windows uses the current directory as the base
|
||||
#else
|
||||
cf_add_mod_roots(Cfile_user_dir_legacy);
|
||||
// set the default player location to here
|
||||
if ( Pilot_file_path == NULL )
|
||||
Pilot_file_path = root->path;
|
||||
|
||||
root = cf_create_root();
|
||||
strncpy(root->path, Cfile_user_dir_legacy, CF_MAX_PATHNAME_LENGTH - 1);
|
||||
|
||||
// do we already have a slash? as in the case of a root directory install
|
||||
if ((strlen(root->path) < (CF_MAX_PATHNAME_LENGTH - 1)) && (root->path[strlen(root->path) - 1] != DIR_SEPARATOR_CHAR)) {
|
||||
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
|
||||
}
|
||||
root->roottype = CF_ROOTTYPE_PATH;
|
||||
|
||||
// If it wasn't set before, set the pilot path
|
||||
if (Pilot_file_path.empty())
|
||||
Pilot_file_path = root->path;
|
||||
|
||||
// Next, check any VP files under the current directory.
|
||||
cf_build_pack_list(root);
|
||||
// Next, check any VP files under the current directory.
|
||||
cf_build_pack_list(root);
|
||||
// =========================================================================
|
||||
#endif
|
||||
// =========================================================================
|
||||
}
|
||||
else if (!Cmdline_portable_mode)
|
||||
{
|
||||
// =========================================================================
|
||||
// now look for mods under the users HOME directory to use before system ones
|
||||
cf_add_mod_roots(Cfile_user_dir);
|
||||
// =========================================================================
|
||||
|
||||
// =========================================================================
|
||||
// set users HOME directory as default for loading and saving files
|
||||
root = cf_create_root();
|
||||
strncpy(root->path, Cfile_user_dir, CF_MAX_PATHNAME_LENGTH - 1);
|
||||
if(Cmdline_mod) {
|
||||
// stackable Mod support -- Kazan
|
||||
for (cur_pos=Cmdline_mod; *cur_pos != '\0'; cur_pos+= (strlen(cur_pos)+1))
|
||||
{
|
||||
memset(str_temp, 0, CF_MAX_PATHNAME_LENGTH);
|
||||
strncpy(str_temp, cur_pos, CF_MAX_PATHNAME_LENGTH-1);
|
||||
|
||||
// do we already have a slash? as in the case of a root directory install
|
||||
if ((strlen(root->path) < (CF_MAX_PATHNAME_LENGTH - 1)) && (root->path[strlen(root->path) - 1] != DIR_SEPARATOR_CHAR)) {
|
||||
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
|
||||
strncat(str_temp, DIR_SEPARATOR_STR, (CF_MAX_PATHNAME_LENGTH - strlen(str_temp) - 1));
|
||||
root = cf_create_root();
|
||||
|
||||
if ( !_getcwd(root->path, CF_MAX_PATHNAME_LENGTH ) ) {
|
||||
Error(LOCATION, "Can't get current working directory -- %d", errno );
|
||||
}
|
||||
|
||||
// truncated string check
|
||||
if ( (strlen(root->path) + strlen(str_temp) + 1) >= CF_MAX_PATHNAME_LENGTH ) {
|
||||
Int3();
|
||||
}
|
||||
|
||||
path_len = strlen(root->path);
|
||||
|
||||
// do we already have a slash? as in the case of a root directory install
|
||||
if ( (path_len < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[path_len-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
|
||||
path_len++;
|
||||
}
|
||||
|
||||
strncat(root->path, str_temp, (CF_MAX_PATHNAME_LENGTH - path_len - 1));
|
||||
root->roottype = CF_ROOTTYPE_PATH;
|
||||
cf_build_pack_list(root);
|
||||
}
|
||||
root->roottype = CF_ROOTTYPE_PATH;
|
||||
|
||||
// set the default player location to here
|
||||
if (Pilot_file_path.empty())
|
||||
Pilot_file_path = root->path;
|
||||
|
||||
// Next, check any VP files under the current directory.
|
||||
cf_build_pack_list(root);
|
||||
// =========================================================================
|
||||
}
|
||||
|
||||
char working_directory[CF_MAX_PATHNAME_LENGTH];
|
||||
|
||||
if ( !_getcwd(working_directory, CF_MAX_PATHNAME_LENGTH ) ) {
|
||||
Error(LOCATION, "Can't get current working directory -- %d", errno );
|
||||
}
|
||||
|
||||
cf_add_mod_roots(working_directory);
|
||||
|
||||
root = cf_create_root();
|
||||
|
||||
strcpy_s(root->path, working_directory);
|
||||
if ( !_getcwd(root->path, CF_MAX_PATHNAME_LENGTH ) ) {
|
||||
Error(LOCATION, "Can't get current working directory -- %d", errno );
|
||||
}
|
||||
|
||||
size_t path_len = strlen(root->path);
|
||||
path_len = strlen(root->path);
|
||||
|
||||
// do we already have a slash? as in the case of a root directory install
|
||||
if ( (path_len < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[path_len-1] != DIR_SEPARATOR_CHAR) ) {
|
||||
@@ -484,8 +476,8 @@ void cf_build_root_list(const char *cdrom_dir)
|
||||
|
||||
root->roottype = CF_ROOTTYPE_PATH;
|
||||
|
||||
// If the path wasn't set before use the working directory
|
||||
if ( Pilot_file_path.empty() )
|
||||
// set the default path for pilot files
|
||||
if ( Pilot_file_path == NULL )
|
||||
Pilot_file_path = root->path;
|
||||
|
||||
//======================================================
|
||||
@@ -511,11 +503,11 @@ void cf_build_root_list(const char *cdrom_dir)
|
||||
// Given a lower case list of file extensions
|
||||
// separated by spaces, return zero if ext is
|
||||
// not in the list.
|
||||
int is_ext_in_list( const char *ext_list, const char *ext )
|
||||
int is_ext_in_list( char *ext_list, char *ext )
|
||||
{
|
||||
char tmp_ext[128];
|
||||
|
||||
strcpy_s( tmp_ext, ext);
|
||||
strncpy( tmp_ext, ext, 127 );
|
||||
strlwr(tmp_ext);
|
||||
if ( strstr(ext_list, tmp_ext )) {
|
||||
return 1;
|
||||
@@ -554,7 +546,7 @@ void cf_search_root_path(int root_index)
|
||||
#if defined _WIN32
|
||||
strcat_s( search_path, "*.*" );
|
||||
|
||||
intptr_t find_handle;
|
||||
int find_handle;
|
||||
_finddata_t find;
|
||||
|
||||
find_handle = _findfirst( search_path, &find );
|
||||
@@ -678,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
|
||||
@@ -702,18 +690,14 @@ 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
|
||||
find.write_time = INTEL_INT( find.write_time ); //-V570
|
||||
find.filename[sizeof(find.filename)-1] = '\0';
|
||||
|
||||
if ( find.size == 0 ) {
|
||||
size_t search_path_len = strlen(search_path);
|
||||
int search_path_len = strlen(search_path);
|
||||
if ( !stricmp( find.filename, ".." )) {
|
||||
char *p = &search_path[search_path_len-1];
|
||||
while( (p > search_path) && (*p != DIR_SEPARATOR_CHAR) ) {
|
||||
@@ -782,7 +766,7 @@ void cf_build_file_list()
|
||||
}
|
||||
|
||||
|
||||
void cf_build_secondary_filelist(const char *cdrom_dir)
|
||||
void cf_build_secondary_filelist(char *cdrom_dir)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -834,28 +818,26 @@ void cf_free_secondary_filelist()
|
||||
Num_files = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a file.
|
||||
*
|
||||
* @note Follows all rules and precedence and searches CD's and pack files.
|
||||
*
|
||||
* @param filespec Filename & extension
|
||||
* @param pathtype See CF_TYPE_ defines in CFILE.H
|
||||
* @param max_out Maximum string length that should be stuffed into pack_filename
|
||||
* @param pack_filename OUTPUT: Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
* @param size OUTPUT: File size
|
||||
* @param offset OUTPUT: Offset into pack file. 0 if not a packfile.
|
||||
* @param localize Undertake localization
|
||||
*
|
||||
* @return If not found returns 0.
|
||||
*/
|
||||
int cf_find_file_location( const char *filespec, int pathtype, int max_out, char *pack_filename, size_t *size, size_t *offset, bool localize )
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files.
|
||||
// Input: filespace - Filename & extension
|
||||
// pathtype - See CF_TYPE_ defines in CFILE.H
|
||||
// max_out - Maximum string length that should be stuffed into pack_filename
|
||||
// Output: pack_filename - Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns 0.
|
||||
int cf_find_file_location( char *filespec, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize )
|
||||
{
|
||||
int i;
|
||||
uint ui;
|
||||
uint i;
|
||||
int cfs_slow_search = 0;
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
#if defined WIN32
|
||||
long findhandle;
|
||||
_finddata_t findstruct;
|
||||
#endif
|
||||
|
||||
Assert( (filespec != NULL) && (strlen(filespec) > 0) ); //-V805
|
||||
Assert( (pack_filename == NULL) || (max_out > 1) );
|
||||
|
||||
@@ -892,7 +874,7 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
if ( CF_TYPE_SPECIFIED(pathtype) ) {
|
||||
search_order[num_search_dirs++] = pathtype;
|
||||
} else {
|
||||
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
|
||||
for (int i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
|
||||
if (i != pathtype)
|
||||
search_order[num_search_dirs++] = i;
|
||||
}
|
||||
@@ -901,8 +883,8 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
memset( longname, 0, sizeof(longname) );
|
||||
|
||||
|
||||
for (ui=0; ui<num_search_dirs; ui++ ) {
|
||||
switch (search_order[ui])
|
||||
for (i=0; i<num_search_dirs; i++ ) {
|
||||
switch (search_order[i])
|
||||
{
|
||||
case CF_TYPE_ROOT:
|
||||
case CF_TYPE_DATA:
|
||||
@@ -921,12 +903,10 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
}
|
||||
|
||||
if (cfs_slow_search) {
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[ui], filespec, localize );
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[i], filespec, localize );
|
||||
|
||||
#if defined _WIN32
|
||||
_finddata_t findstruct;
|
||||
|
||||
intptr_t findhandle = _findfirst(longname, &findstruct);
|
||||
findhandle = _findfirst(longname, &findstruct);
|
||||
if (findhandle != -1) {
|
||||
if (size)
|
||||
*size = findstruct.size;
|
||||
@@ -964,8 +944,9 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
}
|
||||
|
||||
// Search the pak files and CD-ROM.
|
||||
for (ui = 0; ui < Num_files; ui++ ) {
|
||||
cf_file *f = cf_get_file(ui);
|
||||
|
||||
for (i = 0; i < Num_files; i++ ) {
|
||||
cf_file *f = cf_get_file(i);
|
||||
|
||||
// only search paths we're supposed to...
|
||||
if ( (pathtype != CF_TYPE_ANY) && (pathtype != f->pathtype_index) )
|
||||
@@ -982,7 +963,7 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
*size = f->size;
|
||||
|
||||
if (offset)
|
||||
*offset = (size_t)f->pack_offset;
|
||||
*offset = f->pack_offset;
|
||||
|
||||
if (pack_filename) {
|
||||
cf_root *r = cf_get_root(f->root_index);
|
||||
@@ -1010,7 +991,7 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
*size = f->size;
|
||||
|
||||
if (offset)
|
||||
*offset = (size_t)f->pack_offset;
|
||||
*offset = f->pack_offset;
|
||||
|
||||
if (pack_filename) {
|
||||
cf_root *r = cf_get_root(f->root_index);
|
||||
@@ -1037,35 +1018,34 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
}
|
||||
|
||||
// -- from parselo.cpp --
|
||||
extern char *stristr(char *str, const char *substr);
|
||||
extern char *stristr(const char *str, const char *substr);
|
||||
|
||||
/**
|
||||
* Searches for a file.
|
||||
*
|
||||
* @note Follows all rules and precedence and searches CD's and pack files. Searches all locations in order for first filename using filter list.
|
||||
* @note This function is exponentially slow, so don't use it unless truely needed
|
||||
*
|
||||
* @param filename Filename & extension
|
||||
* @param ext_num Number of extensions to look for
|
||||
* @param ext_list Extension filter list
|
||||
* @param pathtype See CF_TYPE_ defines in CFILE.H
|
||||
* @param max_out Maximum string length that should be stuffed into pack_filename
|
||||
* @param pack_filename OUTPUT: Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
* @param size OUTPUT: File size
|
||||
* @param offset OUTPUT: Offset into pack file. 0 if not a packfile.
|
||||
* @param localize Undertake localization
|
||||
*
|
||||
* @return If not found returns -1, else returns offset into ext_list.
|
||||
*/
|
||||
int cf_find_file_location_ext( const char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out, char *pack_filename, size_t *size, size_t *offset, bool localize )
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files. Searches all locations in order for first filename using filter list.
|
||||
// Input: filename - Filename & extension
|
||||
// ext_num - number of extensions to look for
|
||||
// ext_list - extension filter list
|
||||
// pathtype - See CF_TYPE_ defines in CFILE.H
|
||||
// max_out - Maximum string length that should be stuffed into pack_filename
|
||||
// Output: pack_filename - Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns -1, else returns offset into ext_list.
|
||||
// (NOTE: This function is exponentially slow, so don't use it unless truely needed!!)
|
||||
int cf_find_file_location_ext( char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize )
|
||||
{
|
||||
int cur_ext, i;
|
||||
uint ui;
|
||||
uint i;
|
||||
int cur_ext;
|
||||
int cfs_slow_search = 0;
|
||||
char longname[MAX_PATH_LEN];
|
||||
char filespec[MAX_FILENAME_LEN];
|
||||
char *p = NULL;
|
||||
|
||||
|
||||
#if defined WIN32
|
||||
long findhandle;
|
||||
_finddata_t findstruct;
|
||||
#endif
|
||||
|
||||
Assert( (filename != NULL) && (strlen(filename) < MAX_FILENAME_LEN) );
|
||||
Assert( (ext_list != NULL) && (ext_num > 1) ); // if we are searching for just one ext
|
||||
// then this is the wrong function to use
|
||||
@@ -1089,7 +1069,7 @@ int cf_find_file_location_ext( const char *filename, const int ext_num, const ch
|
||||
if ( CF_TYPE_SPECIFIED(pathtype) ) {
|
||||
search_order[num_search_dirs++] = pathtype;
|
||||
} else {
|
||||
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++)
|
||||
for (int i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++)
|
||||
search_order[num_search_dirs++] = i;
|
||||
}
|
||||
|
||||
@@ -1099,14 +1079,14 @@ int cf_find_file_location_ext( const char *filename, const int ext_num, const ch
|
||||
// strip any existing extension
|
||||
strncpy(filespec, filename, MAX_FILENAME_LEN-1);
|
||||
|
||||
for (ui = 0; ui < num_search_dirs; ui++) {
|
||||
for (i = 0; i < num_search_dirs; i++) {
|
||||
// always hit the disk if we are looking in only one path
|
||||
if (num_search_dirs == 1) {
|
||||
cfs_slow_search = 1;
|
||||
}
|
||||
// otherwise hit based on a directory type
|
||||
else {
|
||||
switch (search_order[ui])
|
||||
switch (search_order[i])
|
||||
{
|
||||
case CF_TYPE_ROOT:
|
||||
case CF_TYPE_DATA:
|
||||
@@ -1133,11 +1113,10 @@ int cf_find_file_location_ext( const char *filename, const int ext_num, const ch
|
||||
|
||||
strcat_s( filespec, ext_list[cur_ext] );
|
||||
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[ui], filespec, localize );
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, search_order[i], filespec, localize );
|
||||
|
||||
#if defined _WIN32
|
||||
_finddata_t findstruct;
|
||||
intptr_t findhandle = _findfirst(longname, &findstruct);
|
||||
findhandle = _findfirst(longname, &findstruct);
|
||||
if (findhandle != -1) {
|
||||
if (size)
|
||||
*size = findstruct.size;
|
||||
@@ -1184,11 +1163,11 @@ int cf_find_file_location_ext( const char *filename, const int ext_num, const ch
|
||||
(*p) = 0;
|
||||
|
||||
// go ahead and get our length, which is used to test with later
|
||||
size_t filespec_len = strlen(filespec);
|
||||
int filespec_len = strlen(filespec);
|
||||
|
||||
// get total legnth, with extension, which is iused to test with later
|
||||
// (FIXME: this assumes that everything in ext_list[] is the same length!)
|
||||
size_t filespec_len_big = filespec_len + strlen(ext_list[0]);
|
||||
uint filespec_len_big = filespec_len + strlen(ext_list[0]);
|
||||
|
||||
SCP_vector< cf_file* > file_list_index;
|
||||
int last_root_index = -1;
|
||||
@@ -1197,8 +1176,8 @@ int cf_find_file_location_ext( const char *filename, const int ext_num, const ch
|
||||
file_list_index.reserve( MIN(ext_num * 4, (int)Num_files) );
|
||||
|
||||
// next, run though and pick out base matches
|
||||
for (ui = 0; ui < Num_files; ui++) {
|
||||
cf_file *f = cf_get_file(ui);
|
||||
for (i = 0; i < Num_files; i++) {
|
||||
cf_file *f = cf_get_file(i);
|
||||
|
||||
// ... only search paths that we're supposed to
|
||||
if ( (num_search_dirs == 1) && (pathtype != f->pathtype_index) )
|
||||
@@ -1327,10 +1306,9 @@ int cf_find_file_location_ext( const char *filename, const int ext_num, const ch
|
||||
|
||||
|
||||
// Returns true if filename matches filespec, else zero if not
|
||||
int cf_matches_spec(const char *filespec, const char *filename)
|
||||
int cf_matches_spec(char *filespec, char *filename)
|
||||
{
|
||||
const char *src_ext;
|
||||
const char *dst_ext;
|
||||
char *src_ext, *dst_ext;
|
||||
|
||||
src_ext = strrchr(filespec, '*');
|
||||
if(!src_ext)
|
||||
@@ -1363,7 +1341,7 @@ int cf_matches_spec(const char *filespec, const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
int (*Get_file_list_filter)(const char *filename) = NULL;
|
||||
int (*Get_file_list_filter)(char *filename) = NULL;
|
||||
const char *Get_file_list_child = NULL;
|
||||
int Skip_packfile_search = 0;
|
||||
|
||||
@@ -1392,7 +1370,7 @@ static bool verify_file_list_child()
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cf_file_already_in_list( SCP_vector<SCP_string> &list, const char *filename )
|
||||
static int cf_file_already_in_list( SCP_vector<SCP_string> &list, char *filename )
|
||||
{
|
||||
char name_no_extension[MAX_PATH_LEN];
|
||||
size_t i, size = list.size();
|
||||
@@ -1420,12 +1398,11 @@ static int cf_file_already_in_list( SCP_vector<SCP_string> &list, const char *fi
|
||||
// This one has a 'type', which is a CF_TYPE_* value. Because this specifies the directory
|
||||
// location, 'filter' only needs to be the filter itself, with no path information.
|
||||
// See above descriptions of cf_get_file_list() for more information about how it all works.
|
||||
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *filter, int sort, SCP_vector<file_list_info> *info )
|
||||
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, char *filter, int sort, SCP_vector<file_list_info> *info )
|
||||
{
|
||||
char *ptr;
|
||||
uint i;
|
||||
int own_flag = 0;
|
||||
size_t l;
|
||||
int l, own_flag = 0;
|
||||
SCP_vector<file_list_info> my_info;
|
||||
file_list_info tinfo;
|
||||
|
||||
@@ -1453,14 +1430,17 @@ int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *fi
|
||||
strcat_s(filespec, filter);
|
||||
|
||||
_finddata_t find;
|
||||
intptr_t find_handle;
|
||||
int find_handle;
|
||||
|
||||
find_handle = _findfirst( filespec, &find );
|
||||
if (find_handle != -1) {
|
||||
do {
|
||||
if (strcmp(strrchr(filter, '.'), strrchr(find.name,'.')) != 0)
|
||||
if (strcmp(strstr(filter, "."), strstr(find.name,".")) != 0)
|
||||
continue;
|
||||
|
||||
if ( strlen(find.name) >= MAX_FILENAME_LEN )
|
||||
continue;
|
||||
|
||||
if (!(find.attrib & _A_SUBDIR)) {
|
||||
if ( !Get_file_list_filter || (*Get_file_list_filter)(find.name) ) {
|
||||
if ( check_duplicates && cf_file_already_in_list(list, find.name) ) {
|
||||
@@ -1469,7 +1449,7 @@ int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *fi
|
||||
|
||||
ptr = strrchr(find.name, '.');
|
||||
if (ptr)
|
||||
l = (size_t)(ptr - find.name);
|
||||
l = ptr - find.name;
|
||||
else
|
||||
l = strlen(find.name);
|
||||
|
||||
@@ -1496,6 +1476,9 @@ int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *fi
|
||||
dirp = opendir (filespec);
|
||||
if ( dirp ) {
|
||||
while ((dir = readdir (dirp)) != NULL) {
|
||||
if ( strlen(dir->d_name) >= MAX_FILENAME_LEN ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fnmatch(filter, dir->d_name, 0) != 0)
|
||||
continue;
|
||||
@@ -1520,7 +1503,7 @@ int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *fi
|
||||
|
||||
ptr = strrchr(dir->d_name, '.');
|
||||
if (ptr)
|
||||
l = (size_t)(ptr - dir->d_name);
|
||||
l = ptr - dir->d_name;
|
||||
else
|
||||
l = strlen(dir->d_name);
|
||||
|
||||
@@ -1568,7 +1551,7 @@ int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *fi
|
||||
|
||||
ptr = strrchr(f->name_ext, '.');
|
||||
if (ptr)
|
||||
l = (size_t)(ptr - f->name_ext);
|
||||
l = ptr - f->name_ext;
|
||||
else
|
||||
l = strlen(f->name_ext);
|
||||
|
||||
@@ -1598,7 +1581,7 @@ int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *fi
|
||||
return (int)list.size();
|
||||
}
|
||||
|
||||
int cf_file_already_in_list( int num_files, char **list, const char *filename )
|
||||
int cf_file_already_in_list( int num_files, char **list, char *filename )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1622,12 +1605,11 @@ int cf_file_already_in_list( int num_files, char **list, const char *filename )
|
||||
// This one has a 'type', which is a CF_TYPE_* value. Because this specifies the directory
|
||||
// location, 'filter' only needs to be the filter itself, with no path information.
|
||||
// See above descriptions of cf_get_file_list() for more information about how it all works.
|
||||
int cf_get_file_list( int max, char **list, int pathtype, const char *filter, int sort, file_list_info *info )
|
||||
int cf_get_file_list( int max, char **list, int pathtype, char *filter, int sort, file_list_info *info )
|
||||
{
|
||||
char *ptr;
|
||||
uint i;
|
||||
int num_files = 0, own_flag = 0;
|
||||
size_t l;
|
||||
int l, num_files = 0, own_flag = 0;
|
||||
|
||||
if (max < 1) {
|
||||
Get_file_list_filter = NULL;
|
||||
@@ -1648,7 +1630,7 @@ int cf_get_file_list( int max, char **list, int pathtype, const char *filter, in
|
||||
cf_create_default_path_string( filespec, sizeof(filespec)-1, pathtype, filter );
|
||||
|
||||
_finddata_t find;
|
||||
intptr_t find_handle;
|
||||
int find_handle;
|
||||
|
||||
find_handle = _findfirst( filespec, &find );
|
||||
if (find_handle != -1) {
|
||||
@@ -1656,7 +1638,7 @@ int cf_get_file_list( int max, char **list, int pathtype, const char *filter, in
|
||||
if (num_files >= max)
|
||||
break;
|
||||
|
||||
if (strcmp(strrchr(filter, '.'), strrchr(find.name,'.')) != 0)
|
||||
if (strcmp(strstr(filter, "."), strstr(find.name,".")) != 0)
|
||||
continue;
|
||||
|
||||
if ( strlen(find.name) >= MAX_FILENAME_LEN )
|
||||
@@ -1798,7 +1780,7 @@ int cf_get_file_list( int max, char **list, int pathtype, const char *filter, in
|
||||
return num_files;
|
||||
}
|
||||
|
||||
int cf_file_already_in_list_preallocated( int num_files, char arr[][MAX_FILENAME_LEN], const char *filename )
|
||||
int cf_file_already_in_list_preallocated( int num_files, char arr[][MAX_FILENAME_LEN], char *filename )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1822,7 +1804,7 @@ int cf_file_already_in_list_preallocated( int num_files, char arr[][MAX_FILENAME
|
||||
// This one has a 'type', which is a CF_TYPE_* value. Because this specifies the directory
|
||||
// location, 'filter' only needs to be the filter itself, with no path information.
|
||||
// See above descriptions of cf_get_file_list() for more information about how it all works.
|
||||
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int pathtype, const char *filter, int sort, file_list_info *info )
|
||||
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int pathtype, char *filter, int sort, file_list_info *info )
|
||||
{
|
||||
int num_files = 0, own_flag = 0;
|
||||
|
||||
@@ -1853,7 +1835,7 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
|
||||
#if defined _WIN32
|
||||
cf_create_default_path_string( filespec, sizeof(filespec)-1, pathtype, filter );
|
||||
|
||||
intptr_t find_handle;
|
||||
int find_handle;
|
||||
_finddata_t find;
|
||||
|
||||
find_handle = _findfirst( filespec, &find );
|
||||
@@ -2009,7 +1991,7 @@ int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char *
|
||||
// filename - optional, if set, tacks the filename onto end of path.
|
||||
// Output: path - Fully qualified pathname.
|
||||
//Returns 0 if the result would be too long (invalid result)
|
||||
int cf_create_default_path_string(char *path, uint path_max, int pathtype, const char *filename, bool localize )
|
||||
int cf_create_default_path_string( char *path, uint path_max, int pathtype, char *filename, bool localize )
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
if ( filename && strpbrk(filename,"/") ) {
|
||||
@@ -2032,7 +2014,7 @@ int cf_create_default_path_string(char *path, uint path_max, int pathtype, const
|
||||
|
||||
// force a specific directory to search for player files
|
||||
if ( (pathtype == CF_TYPE_PLAYERS) || (pathtype == CF_TYPE_SINGLE_PLAYERS) || (pathtype == CF_TYPE_MULTI_PLAYERS) ) {
|
||||
strncpy(path, Pilot_file_path.c_str(), path_max);
|
||||
strncpy(path, Pilot_file_path, path_max);
|
||||
} else {
|
||||
strncpy(path, root->path, path_max);
|
||||
}
|
||||
@@ -2046,6 +2028,14 @@ int cf_create_default_path_string(char *path, uint path_max, int pathtype, const
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INF_BUILD
|
||||
// keep pilot files separated for an Inferno build since they aren't compatible
|
||||
if ( pathtype == CF_TYPE_SINGLE_PLAYERS || pathtype == CF_TYPE_MULTI_PLAYERS ) {
|
||||
strcat_s(path, path_max, "inferno");
|
||||
strcat_s(path, path_max, DIR_SEPARATOR_STR);
|
||||
}
|
||||
#endif
|
||||
|
||||
// add filename
|
||||
if (filename) {
|
||||
strcat_s(path, path_max, filename);
|
||||
@@ -2081,7 +2071,7 @@ int cf_create_default_path_string(char *path, uint path_max, int pathtype, const
|
||||
// filename - optional, if set, tacks the filename onto end of path.
|
||||
// Output: path - Fully qualified pathname.
|
||||
//Returns 0 if the result would be too long (invalid result)
|
||||
int cf_create_default_path_string( SCP_string &path, int pathtype, const char *filename, bool localize )
|
||||
int cf_create_default_path_string( SCP_string &path, int pathtype, char *filename, bool localize )
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
if ( filename && strpbrk(filename,"/") ) {
|
||||
@@ -2136,11 +2126,18 @@ int cf_create_default_path_string( SCP_string &path, int pathtype, const char *f
|
||||
void cfile_spew_pack_file_crcs()
|
||||
{
|
||||
int i;
|
||||
char out_path[CFILE_ROOT_DIRECTORY_LEN+MAX_FILENAME_LEN];
|
||||
char datetime[45];
|
||||
uint chksum = 0;
|
||||
time_t my_time;
|
||||
|
||||
FILE *out = fopen(os_get_config_path("vp_crcs.txt").c_str(), "w");
|
||||
#ifdef SCP_UNIX
|
||||
sprintf(out_path, "%s%svp_crcs.txt", Cfile_user_dir, DIR_SEPARATOR_STR);
|
||||
#else
|
||||
sprintf(out_path, "%s%svp_crcs.txt", Cfile_root_dir, DIR_SEPARATOR_STR);
|
||||
#endif
|
||||
|
||||
FILE *out = fopen(out_path, "w");
|
||||
|
||||
if (out == NULL) {
|
||||
Int3();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
// Builds a list of all the files
|
||||
void cf_build_secondary_filelist( const char *cdrom_path );
|
||||
void cf_build_secondary_filelist( char *cdrom_path );
|
||||
void cf_free_secondary_filelist();
|
||||
|
||||
// Internal stuff
|
||||
@@ -39,7 +39,7 @@ extern cf_pathtype Pathtypes[CF_MAX_PATH_TYPES];
|
||||
// filename - optional, if set, tacks the filename onto end of path.
|
||||
// Output: path - Fully qualified pathname.
|
||||
//Returns 0 if result would be too long (invalid result)
|
||||
int cf_create_default_path_string( char *path, uint path_max, int pathtype, const char *filename=NULL, bool localize = false);
|
||||
int cf_create_default_path_string( SCP_string &path, int pathtype, const char *filename=NULL, bool localize = false );
|
||||
int cf_create_default_path_string( char *path, uint path_max, int pathtype, char *filename=NULL, bool localize = false);
|
||||
int cf_create_default_path_string( SCP_string &path, int pathtype, char *filename=NULL, bool localize = false );
|
||||
|
||||
#endif //_CFILESYSTEM_H
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
add_executable(cfilearchiver EXCLUDE_FROM_ALL cfilearchiver.cpp)
|
||||
|
||||
ADD_DEFINITIONS(-DNO_SAFE_STRINGS)
|
||||
include_directories(${CODE_HEADERS})
|
||||
|
||||
set_target_properties(cfilearchiver
|
||||
PROPERTIES
|
||||
FOLDER "FSOTools"
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(cfilearchiver PUBLIC ${SDL_LIBS})
|
||||
TARGET_INCLUDE_DIRECTORIES(cfilearchiver PUBLIC ${GENERATED_SOURCE_DIR})
|
||||
TARGET_INCLUDE_DIRECTORIES(cfilearchiver PUBLIC ${GENERATED_SOURCE_DIR}/code)
|
||||
|
||||
IF(MSVC)
|
||||
set_target_properties(cfilearchiver PROPERTIES
|
||||
COMPILE_DEFINITIONS_DEBUG "_DEBUG;PDB_DEBUGGING=1"
|
||||
)
|
||||
ENDIF(MSVC)
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
add_executable(cfileextractor EXCLUDE_FROM_ALL cfileextractor.cpp)
|
||||
|
||||
ADD_DEFINITIONS(-DNO_SAFE_STRINGS)
|
||||
include_directories(${CODE_HEADERS})
|
||||
|
||||
set_target_properties(cfileextractor
|
||||
PROPERTIES
|
||||
FOLDER "FSOTools"
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(cfileextractor PUBLIC ${SDL_LIBS})
|
||||
TARGET_INCLUDE_DIRECTORIES(cfileextractor PUBLIC ${GENERATED_SOURCE_DIR})
|
||||
TARGET_INCLUDE_DIRECTORIES(cfileextractor PUBLIC ${GENERATED_SOURCE_DIR}/code)
|
||||
|
||||
IF(MSVC)
|
||||
set_target_properties(cfileextractor PROPERTIES
|
||||
COMPILE_DEFINITIONS_DEBUG "_DEBUG;PDB_DEBUGGING=1"
|
||||
)
|
||||
ENDIF(MSVC)
|
||||
+540
-934
File diff suppressed because it is too large.
Load diff
+14
-27
@@ -13,8 +13,9 @@
|
||||
#define FS_CMDLINE_HEADER_FILE
|
||||
|
||||
|
||||
int parse_cmdline(int argc, char *argv[]);
|
||||
int parse_cmdline(char *cmdline);
|
||||
|
||||
int fred2_parse_cmdline(int argc, char *argv[]);
|
||||
// COMMAND LINE SETTINGS
|
||||
// This section is for reference by all the *_init() functions. For example, the multiplayer init function
|
||||
// could check to see if (int Cmdline_multi_stream_chat_to_file) has been set by the command line parser.
|
||||
@@ -47,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 -------------------------------------------------
|
||||
@@ -76,14 +76,10 @@ extern int Cmdline_bloom_intensity;
|
||||
extern bool Cmdline_fxaa;
|
||||
extern int Cmdline_fxaa_preset;
|
||||
extern bool Cmdline_fb_explosions;
|
||||
extern bool Cmdline_fb_thrusters;
|
||||
extern bool Cmdline_no_batching;
|
||||
extern int Cmdline_shadow_quality;
|
||||
extern int Cmdline_no_deferred_lighting;
|
||||
extern int Cmdline_no_emissive;
|
||||
|
||||
// Game Speed related
|
||||
extern int Cmdline_cache_bitmaps;
|
||||
extern int Cmdline_img2dds;
|
||||
extern int Cmdline_NoFPSCap;
|
||||
extern int Cmdline_no_vsync;
|
||||
|
||||
@@ -100,13 +96,11 @@ extern int Cmdline_ship_choice_3d;
|
||||
extern int Cmdline_weapon_choice_3d;
|
||||
extern int Cmdline_warp_flash;
|
||||
extern int Cmdline_autopilot_interruptable;
|
||||
extern int Cmdline_stretch_menu;
|
||||
|
||||
// Audio related
|
||||
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
|
||||
@@ -118,46 +112,39 @@ extern char *Cmdline_spew_mission_crcs;
|
||||
extern char *Cmdline_spew_table_crcs;
|
||||
extern int Cmdline_objupd;
|
||||
|
||||
// Launcher related options
|
||||
extern bool Cmdline_portable_mode;
|
||||
|
||||
// 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;
|
||||
extern int Cmdline_no_fbo;
|
||||
extern int Cmdline_no_pbo;
|
||||
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;
|
||||
extern bool Cmdline_nograb;
|
||||
#ifdef WIN32
|
||||
extern bool Cmdline_alternate_registry_path;
|
||||
#endif
|
||||
|
||||
// Developer/Testing related
|
||||
extern char *Cmdline_start_mission;
|
||||
extern int Cmdline_old_collision_sys;
|
||||
extern int Cmdline_dis_collisions;
|
||||
extern int Cmdline_dis_weapons;
|
||||
extern int Cmdline_noparseerrors;
|
||||
extern int Cmdline_nowarn;
|
||||
extern int Cmdline_extra_warn;
|
||||
extern int Cmdline_show_mem_usage;
|
||||
extern int Cmdline_show_pos;
|
||||
extern int Cmdline_show_stats;
|
||||
extern int Cmdline_save_render_targets;
|
||||
extern int Cmdline_debug_window;
|
||||
extern int Cmdline_verify_vps;
|
||||
#ifdef SCP_UNIX
|
||||
extern int Cmdline_no_grab;
|
||||
#endif
|
||||
extern int Cmdline_reparse_mainhall;
|
||||
extern bool Cmdline_frame_profile;
|
||||
extern bool Cmdline_profile_write_file;
|
||||
extern bool Cmdline_no_unfocus_pause;
|
||||
extern bool Cmdline_benchmark_mode;
|
||||
extern bool Cmdline_noninteractive;
|
||||
extern bool Cmdline_json_pilot;
|
||||
|
||||
#endif
|
||||
@@ -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.
|
||||
@@ -62,7 +61,7 @@ void cmeasure_select_next(ship *shipp)
|
||||
{
|
||||
new_index = (shipp->current_cmeasure + i) % Num_weapon_types;
|
||||
|
||||
if(Weapon_info[new_index].wi_flags[Weapon::Info_Flags::Cmeasure])
|
||||
if(Weapon_info[new_index].wi_flags & WIF_CMEASURE)
|
||||
{
|
||||
shipp->current_cmeasure = new_index;
|
||||
return;
|
||||
@@ -88,12 +87,12 @@ void cmeasure_maybe_alert_success(object *objp)
|
||||
return;
|
||||
}
|
||||
|
||||
Assert(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags[Weapon::Info_Flags::Cmeasure]);
|
||||
Assert(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_CMEASURE);
|
||||
|
||||
if ( objp->parent == OBJ_INDEX(Player_obj) ) {
|
||||
hud_start_text_flash(XSTR("Evaded", 1430), 800);
|
||||
snd_play(&Snds[ship_get_sound(Player_obj, SND_MISSILE_EVADED_POPUP)]);
|
||||
} else if ( Objects[objp->parent].flags[Object::Object_Flags::Player_ship] ) {
|
||||
} else if ( Objects[objp->parent].flags & OF_PLAYER_SHIP ) {
|
||||
send_countermeasure_success_packet( objp->parent );
|
||||
}
|
||||
}
|
||||
@@ -15,14 +15,13 @@
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
|
||||
class object;
|
||||
struct object;
|
||||
|
||||
#define CMEASURE_WAIT 333 // delay in milliseconds between countermeasure firing.
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -10,26 +10,24 @@
|
||||
|
||||
|
||||
|
||||
#include "freespace2/freespace.h"
|
||||
#include "controlconfig/controlsconfig.h"
|
||||
#include "debugconsole/console.h"
|
||||
#include "freespace.h"
|
||||
#include "gamehelp/contexthelp.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 "playerman/managepilot.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"
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -126,7 +124,7 @@ int Conflict_bright = 0;
|
||||
|
||||
static int Num_cc_lines;
|
||||
static struct {
|
||||
const char *label;
|
||||
char *label;
|
||||
int cc_index; // index into Control_config of item
|
||||
int y; // Y coordinate of line
|
||||
int kx, kw, jx, jw; // x start and width of keyboard and joystick bound text
|
||||
@@ -137,7 +135,6 @@ struct config_item_undo {
|
||||
int size;
|
||||
int *index; // array (size) of Control_config indices of replaced elements
|
||||
config_item *list; // array (size) of original elements
|
||||
int reset_to_preset; // if >=0, then we ignore the above list and simply reset to the given preset instead
|
||||
config_item_undo *next;
|
||||
};
|
||||
|
||||
@@ -177,9 +174,6 @@ static int Background_bitmap;
|
||||
static int Conflicts_tabs[NUM_TABS];
|
||||
static UI_BUTTON List_buttons[LIST_BUTTONS_MAX]; // buttons for each line of text in list
|
||||
static UI_WINDOW Ui_window;
|
||||
static unsigned int Defaults_cycle_pos; // the controls preset that was last selected
|
||||
|
||||
int Control_config_overlay_id;
|
||||
|
||||
static struct {
|
||||
int key; // index of other control in conflict with this one
|
||||
@@ -351,70 +345,11 @@ int Config_allowed[] = {
|
||||
#ifndef NDEBUG
|
||||
int Show_controls_info = 0;
|
||||
|
||||
DCF_BOOL(show_controls_info, Show_controls_info);
|
||||
DCF_BOOL(show_controls_info, Show_controls_info)
|
||||
#endif
|
||||
|
||||
static int Axes_origin[JOY_NUM_AXES];
|
||||
|
||||
static int joy_get_unscaled_reading(int raw, int axn)
|
||||
{
|
||||
int rng;
|
||||
|
||||
rng = JOY_AXIS_MAX - JOY_AXIS_MIN;
|
||||
raw -= JOY_AXIS_MIN; // adjust for linear range starting at 0
|
||||
|
||||
// cap at limits
|
||||
if (raw < 0)
|
||||
raw = 0;
|
||||
if (raw > rng)
|
||||
raw = rng;
|
||||
|
||||
return (int) ((std::uint64_t) raw * (std::uint64_t) F1_0 / (std::uint64_t) rng); // convert to 0 - F1_0 range, 64bit ints used to avoid uint overflow
|
||||
}
|
||||
|
||||
int joy_get_scaled_reading(int raw)
|
||||
{
|
||||
int x, d, dead_zone, rng;
|
||||
float percent, sensitivity_percent, non_sensitivity_percent;
|
||||
|
||||
raw -= JOY_AXIS_CENTER;
|
||||
|
||||
dead_zone = (JOY_AXIS_MAX - JOY_AXIS_MIN) * Joy_dead_zone_size / 100;
|
||||
|
||||
if (raw < -dead_zone) {
|
||||
rng = JOY_AXIS_CENTER - JOY_AXIS_MIN - dead_zone;
|
||||
d = -raw - dead_zone;
|
||||
} else if (raw > dead_zone) {
|
||||
rng = JOY_AXIS_MAX - JOY_AXIS_CENTER - dead_zone;
|
||||
d = raw - dead_zone;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
if (d > rng)
|
||||
d = rng;
|
||||
|
||||
Assert(Joy_sensitivity >= 0 && Joy_sensitivity <= 9);
|
||||
|
||||
// compute percentages as a range between 0 and 1
|
||||
sensitivity_percent = (float) Joy_sensitivity / 9.0f;
|
||||
non_sensitivity_percent = (float) (9 - Joy_sensitivity) / 9.0f;
|
||||
|
||||
// find percent of max axis is at
|
||||
percent = (float) d / (float) rng;
|
||||
|
||||
// work sensitivity on axis value
|
||||
percent = (percent * sensitivity_percent + percent * percent * percent * percent * percent * non_sensitivity_percent);
|
||||
|
||||
x = (int) ((float) F1_0 * percent);
|
||||
|
||||
//nprintf(("AI", "d=%6i, sens=%3i, percent=%6.3f, val=%6i, ratio=%6.3f\n", d, Joy_sensitivity, percent, (raw<0) ? -x : x, (float) d/x));
|
||||
|
||||
if (raw < 0)
|
||||
return -x;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void control_config_detect_axis_reset()
|
||||
{
|
||||
joystick_read_raw_axis(JOY_NUM_AXES, Axes_origin);
|
||||
@@ -452,10 +387,21 @@ int control_config_detect_axis()
|
||||
|
||||
void control_config_conflict_check()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
int i, j, a, b, c, 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++) {
|
||||
@@ -464,16 +410,11 @@ void control_config_conflict_check()
|
||||
|
||||
for (i=0; i<CCFG_MAX-1; i++) {
|
||||
for (j=i+1; j<CCFG_MAX; j++) {
|
||||
if ((Control_config[i].key_id >= 0) && (Control_config[i].key_id == Control_config[j].key_id)) {
|
||||
// If one of the conflicting keys is disabled, then this silently clears
|
||||
// the disabled key to prevent the conflict; a conflict is recorded only
|
||||
// if both keys are enabled
|
||||
|
||||
if (Control_config[i].disabled)
|
||||
Control_config[i].key_id = (short) -1;
|
||||
else if (Control_config[j].disabled)
|
||||
Control_config[j].key_id = (short) -1;
|
||||
else {
|
||||
if (Control_config[i].key_id >= 0) {
|
||||
c = 0;
|
||||
a = Control_config[i].key_id;
|
||||
b = Control_config[j].key_id;
|
||||
if (a == b) {
|
||||
Conflicts[i].key = j;
|
||||
Conflicts[j].key = i;
|
||||
Conflicts_tabs[ Control_config[i].tab ] = 1;
|
||||
@@ -482,18 +423,10 @@ void control_config_conflict_check()
|
||||
}
|
||||
|
||||
if ((Control_config[i].joy_id >= 0) && (Control_config[i].joy_id == Control_config[j].joy_id)) {
|
||||
// Same as above
|
||||
|
||||
if (Control_config[i].disabled)
|
||||
Control_config[i].joy_id = (short) -1;
|
||||
else if (Control_config[j].disabled)
|
||||
Control_config[j].joy_id = (short) -1;
|
||||
else {
|
||||
Conflicts[i].joy = j;
|
||||
Conflicts[j].joy = i;
|
||||
Conflicts_tabs[ Control_config[i].tab ] = 1;
|
||||
Conflicts_tabs[ Control_config[j].tab ] = 1;
|
||||
}
|
||||
Conflicts[i].joy = j;
|
||||
Conflicts[j].joy = i;
|
||||
Conflicts_tabs[ Control_config[i].tab ] = 1;
|
||||
Conflicts_tabs[ Control_config[j].tab ] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -516,12 +449,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) {
|
||||
if (Control_config[z].tab == Tab) {
|
||||
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 {
|
||||
@@ -585,8 +521,6 @@ config_item_undo *get_undo_block(int size)
|
||||
ptr->list = NULL;
|
||||
}
|
||||
|
||||
ptr->reset_to_preset = -1;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -619,45 +553,41 @@ int control_config_undo_last()
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (Config_item_undo->reset_to_preset > -1) {
|
||||
control_config_reset_defaults(Config_item_undo->reset_to_preset);
|
||||
if (Config_item_undo->index[0] & JOY_AXIS) {
|
||||
tab = SHIP_TAB;
|
||||
} else {
|
||||
if (Config_item_undo->index[0] & JOY_AXIS) {
|
||||
tab = SHIP_TAB;
|
||||
tab = Control_config[Config_item_undo->index[0]].tab;
|
||||
}
|
||||
|
||||
for (i=1; i<Config_item_undo->size; i++) {
|
||||
if (Config_item_undo->index[i] & JOY_AXIS) {
|
||||
if (tab != SHIP_TAB) {
|
||||
tab = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
tab = Control_config[Config_item_undo->index[0]].tab;
|
||||
}
|
||||
|
||||
for (i=1; i<Config_item_undo->size; i++) {
|
||||
if (Config_item_undo->index[i] & JOY_AXIS) {
|
||||
if (tab != SHIP_TAB) {
|
||||
tab = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (Control_config[Config_item_undo->index[i]].tab != tab) {
|
||||
tab = -1;
|
||||
}
|
||||
if (Control_config[Config_item_undo->index[i]].tab != tab) {
|
||||
tab = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tab >= 0) {
|
||||
Tab = tab;
|
||||
}
|
||||
if (tab >= 0) {
|
||||
Tab = tab;
|
||||
}
|
||||
|
||||
for (i=0; i<Config_item_undo->size; i++) {
|
||||
z = Config_item_undo->index[i];
|
||||
if (z & JOY_AXIS) {
|
||||
config_item *ptr;
|
||||
for (i=0; i<Config_item_undo->size; i++) {
|
||||
z = Config_item_undo->index[i];
|
||||
if (z & JOY_AXIS) {
|
||||
config_item *ptr;
|
||||
|
||||
z &= ~JOY_AXIS;
|
||||
ptr = &Config_item_undo->list[i];
|
||||
Axis_map_to[z] = ptr->joy_id;
|
||||
Invert_axis[z] = ptr->used;
|
||||
z &= ~JOY_AXIS;
|
||||
ptr = &Config_item_undo->list[i];
|
||||
Axis_map_to[z] = ptr->joy_id;
|
||||
Invert_axis[z] = ptr->used;
|
||||
|
||||
} else {
|
||||
Control_config[z] = Config_item_undo->list[i];
|
||||
}
|
||||
} else {
|
||||
Control_config[z] = Config_item_undo->list[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,7 +641,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) {
|
||||
@@ -741,6 +671,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];
|
||||
@@ -892,6 +823,8 @@ int control_config_clear_all()
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern Joy_info joystick;
|
||||
|
||||
int control_config_axis_default(int axis)
|
||||
{
|
||||
Assert(axis >= 0);
|
||||
@@ -901,8 +834,7 @@ int control_config_axis_default(int axis)
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto joystick = io::joystick::getCurrentJoystick();
|
||||
if (joystick == nullptr || Axis_map_to_defaults[axis] >= joystick->numAxes()) {
|
||||
if (!joystick.axis_valid[Axis_map_to_defaults[axis]]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -915,25 +847,10 @@ int control_config_do_reset()
|
||||
int i, j, total = 0;
|
||||
config_item_undo *ptr;
|
||||
config_item item;
|
||||
config_item *preset;
|
||||
bool cycling_presets = false;
|
||||
|
||||
// If there are presets, then we'll cycle to the next preset and reset to that
|
||||
if (Control_config_presets.size() >= 1) {
|
||||
cycling_presets = true;
|
||||
|
||||
if (++Defaults_cycle_pos >= Control_config_presets.size())
|
||||
Defaults_cycle_pos = 0;
|
||||
|
||||
preset = Control_config_presets[Defaults_cycle_pos];
|
||||
} else {
|
||||
// If there are no presets, then we'll always reset to the hardcoded defaults
|
||||
preset = Control_config;
|
||||
}
|
||||
|
||||
|
||||
// first, determine how many bindings need to be changed
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if ((Control_config[i].key_id != preset[i].key_default) || (Control_config[i].joy_id != preset[i].joy_default)) {
|
||||
if ((Control_config[i].key_id != Control_config[i].key_default) || (Control_config[i].joy_id != Control_config[i].joy_default)) {
|
||||
total++;
|
||||
}
|
||||
}
|
||||
@@ -944,7 +861,7 @@ int control_config_do_reset()
|
||||
}
|
||||
}
|
||||
|
||||
if (!total && !cycling_presets) {
|
||||
if (!total) {
|
||||
gamesnd_play_iface(SND_GENERAL_FAIL);
|
||||
return -1;
|
||||
}
|
||||
@@ -952,7 +869,7 @@ int control_config_do_reset()
|
||||
// now, back up the old bindings so we can undo if we want to
|
||||
ptr = get_undo_block(total);
|
||||
for (i=j=0; i<CCFG_MAX; i++) {
|
||||
if ((Control_config[i].key_id != preset[i].key_default) || (Control_config[i].joy_id != preset[i].joy_default)) {
|
||||
if ((Control_config[i].key_id != Control_config[i].key_default) || (Control_config[i].joy_id != Control_config[i].joy_default)) {
|
||||
ptr->index[j] = i;
|
||||
ptr->list[j] = Control_config[i];
|
||||
j++;
|
||||
@@ -971,43 +888,23 @@ int control_config_do_reset()
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(j == total);
|
||||
|
||||
if (cycling_presets)
|
||||
control_config_reset_defaults(Defaults_cycle_pos);
|
||||
else
|
||||
control_config_reset_defaults();
|
||||
|
||||
control_config_reset_defaults();
|
||||
control_config_conflict_check();
|
||||
control_config_list_prepare();
|
||||
gamesnd_play_iface(SND_RESET_PRESSED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This sets all the controls to the default values in the given preset
|
||||
// If no preset is given, the hardcoded defaults of Control_config are used
|
||||
void control_config_reset_defaults(int presetnum)
|
||||
// This sets all the controls to their default values
|
||||
void control_config_reset_defaults()
|
||||
{
|
||||
int i;
|
||||
config_item *preset;
|
||||
|
||||
if (presetnum >= 0)
|
||||
preset = Control_config_presets[presetnum];
|
||||
else
|
||||
preset = Control_config;
|
||||
|
||||
// Reset keyboard defaults
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
// Note that key_default and joy_default are NOT overwritten here;
|
||||
// they should retain the values of the first preset because
|
||||
// for example the key-pressed SEXP works off the defaults of the first preset
|
||||
Control_config[i].key_id = preset[i].key_default;
|
||||
Control_config[i].joy_id = preset[i].joy_default;
|
||||
Control_config[i].tab = preset[i].tab;
|
||||
Control_config[i].hasXSTR = preset[i].hasXSTR;
|
||||
Control_config[i].type = preset[i].type;
|
||||
Control_config[i].disabled = preset[i].disabled;
|
||||
Control_config[i].key_id = Control_config[i].key_default;
|
||||
Control_config[i].joy_id = Control_config[i].joy_default;
|
||||
}
|
||||
|
||||
for (i=0; i<NUM_JOY_AXIS_ACTIONS; i++) {
|
||||
@@ -1306,7 +1203,7 @@ void control_config_button_pressed(int n)
|
||||
}
|
||||
}
|
||||
|
||||
const char *control_config_tooltip_handler(const char *str)
|
||||
char *control_config_tooltip_handler(char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1331,16 +1228,14 @@ void control_config_init()
|
||||
Control_config_backup[i] = Control_config[i];
|
||||
}
|
||||
|
||||
Defaults_cycle_pos = 0;
|
||||
|
||||
common_set_interface_palette(NOX("ControlConfigPalette")); // set the interface palette
|
||||
Ui_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0);
|
||||
Ui_window.set_mask_bmap(Conflict_background_bitmap_mask_fname[gr_screen.res]);
|
||||
Ui_window.tooltip_handler = control_config_tooltip_handler;
|
||||
|
||||
// load in help overlay bitmap
|
||||
Control_config_overlay_id = help_overlay_get_index(CONTROL_CONFIG_OVERLAY);
|
||||
help_overlay_set_state(Control_config_overlay_id,gr_screen.res,0);
|
||||
help_overlay_load(CONTROL_CONFIG_OVERLAY);
|
||||
help_overlay_set_state(CONTROL_CONFIG_OVERLAY,0);
|
||||
|
||||
// reset conflict flashing
|
||||
Conflict_stamp = -1;
|
||||
@@ -1430,6 +1325,9 @@ void control_config_close()
|
||||
while (Config_item_undo){
|
||||
free_undo_block();
|
||||
}
|
||||
|
||||
// unload the overlay bitmap
|
||||
help_overlay_unload(CONTROL_CONFIG_OVERLAY);
|
||||
|
||||
if (Background_bitmap){
|
||||
bm_release(Background_bitmap);
|
||||
@@ -1439,12 +1337,7 @@ void control_config_close()
|
||||
common_free_interface_palette(); // restore game palette
|
||||
hud_squadmsg_save_keys(); // rebuild map for saving/restoring keys in squadmsg mode
|
||||
game_flush();
|
||||
|
||||
if (Game_mode & GM_MULTIPLAYER) {
|
||||
Pilot.save_player();
|
||||
} else {
|
||||
Pilot.save_savefile();
|
||||
}
|
||||
write_pilot_file();
|
||||
|
||||
// free strings
|
||||
for(idx=0; idx<NUM_JOY_AXIS_ACTIONS; idx++){
|
||||
@@ -1481,9 +1374,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], *str, *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;
|
||||
@@ -1528,7 +1420,7 @@ void control_config_do_frame(float frametime)
|
||||
if (Axis_override >= 0) {
|
||||
control_config_bind_axis(z, Axis_override);
|
||||
strcpy_s(bound_string, Joy_axis_text[Axis_override]);
|
||||
font::force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
gr_force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
bound_timestamp = timestamp(2500);
|
||||
control_config_conflict_check();
|
||||
control_config_list_prepare();
|
||||
@@ -1541,7 +1433,7 @@ void control_config_do_frame(float frametime)
|
||||
}
|
||||
|
||||
} else {
|
||||
if (help_overlay_active(Control_config_overlay_id)) {
|
||||
if (help_overlay_active(CONTROL_CONFIG_OVERLAY)) {
|
||||
CC_Buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
|
||||
Ui_window.set_ignore_gadgets(1);
|
||||
}
|
||||
@@ -1551,14 +1443,14 @@ void control_config_do_frame(float frametime)
|
||||
Ui_window.process(0);
|
||||
|
||||
if ( (k > 0) || B1_JUST_RELEASED ) {
|
||||
if (help_overlay_active(Control_config_overlay_id)) {
|
||||
help_overlay_set_state(Control_config_overlay_id, gr_screen.res, 0);
|
||||
if (help_overlay_active(CONTROL_CONFIG_OVERLAY)) {
|
||||
help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 0);
|
||||
Ui_window.set_ignore_gadgets(0);
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !help_overlay_active(Control_config_overlay_id) ) {
|
||||
if ( !help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
|
||||
Ui_window.set_ignore_gadgets(0);
|
||||
}
|
||||
|
||||
@@ -1585,7 +1477,7 @@ void control_config_do_frame(float frametime)
|
||||
}
|
||||
|
||||
if ((k > 0) && !Config_allowed[k & KEY_MASK]) {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "That is a non-bindable key. Please try again.", 207));
|
||||
popup(0, 1, POPUP_OK, XSTR( "That is a non-bindable key. Please try again.", 207));
|
||||
k = 0;
|
||||
}
|
||||
|
||||
@@ -1596,7 +1488,7 @@ void control_config_do_frame(float frametime)
|
||||
control_config_bind_key(z, k);
|
||||
|
||||
strcpy_s(bound_string, textify_scancode(k));
|
||||
font::force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
gr_force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
bound_timestamp = timestamp(2500);
|
||||
control_config_conflict_check();
|
||||
control_config_list_prepare();
|
||||
@@ -1610,7 +1502,7 @@ void control_config_do_frame(float frametime)
|
||||
control_config_bind_joy(z, i);
|
||||
|
||||
strcpy_s(bound_string, Joy_button_text[i]);
|
||||
font::force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
gr_force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
bound_timestamp = timestamp(2500);
|
||||
control_config_conflict_check();
|
||||
control_config_list_prepare();
|
||||
@@ -1634,7 +1526,7 @@ void control_config_do_frame(float frametime)
|
||||
control_config_bind_joy(z, i);
|
||||
|
||||
strcpy_s(bound_string, Joy_button_text[i]);
|
||||
font::force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
gr_force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
bound_timestamp = timestamp(2500);
|
||||
control_config_conflict_check();
|
||||
control_config_list_prepare();
|
||||
@@ -1652,7 +1544,7 @@ void control_config_do_frame(float frametime)
|
||||
}
|
||||
|
||||
} else if (Search_mode) {
|
||||
if (help_overlay_active(Control_config_overlay_id)) {
|
||||
if (help_overlay_active(CONTROL_CONFIG_OVERLAY)) {
|
||||
CC_Buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
|
||||
Ui_window.set_ignore_gadgets(1);
|
||||
}
|
||||
@@ -1662,14 +1554,14 @@ void control_config_do_frame(float frametime)
|
||||
Ui_window.process(0);
|
||||
|
||||
if ( (k > 0) || B1_JUST_RELEASED ) {
|
||||
if ( help_overlay_active(Control_config_overlay_id) ) {
|
||||
help_overlay_set_state(Control_config_overlay_id, gr_screen.res, 0);
|
||||
if ( help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
|
||||
help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 0);
|
||||
Ui_window.set_ignore_gadgets(0);
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !help_overlay_active(Control_config_overlay_id) ) {
|
||||
if ( !help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
|
||||
Ui_window.set_ignore_gadgets(0);
|
||||
}
|
||||
|
||||
@@ -1718,8 +1610,8 @@ void control_config_do_frame(float frametime)
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (Control_config[i].joy_id == j) {
|
||||
z = i;
|
||||
for (size_t buttonid=0; buttonid<NUM_BUTTONS; buttonid++){
|
||||
CC_Buttons[gr_screen.res][buttonid].button.reset();
|
||||
for (j=0; j<NUM_BUTTONS; j++){
|
||||
CC_Buttons[gr_screen.res][j].button.reset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1763,7 +1655,7 @@ void control_config_do_frame(float frametime)
|
||||
|
||||
CC_Buttons[gr_screen.res][UNDO_BUTTON].button.enable(Config_item_undo != NULL);
|
||||
|
||||
if ( help_overlay_active(Control_config_overlay_id) ) {
|
||||
if ( help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
|
||||
CC_Buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
|
||||
Ui_window.set_ignore_gadgets(1);
|
||||
}
|
||||
@@ -1771,14 +1663,14 @@ void control_config_do_frame(float frametime)
|
||||
k = Ui_window.process();
|
||||
|
||||
if ( (k > 0) || B1_JUST_RELEASED ) {
|
||||
if ( help_overlay_active(Control_config_overlay_id) ) {
|
||||
help_overlay_set_state(Control_config_overlay_id, gr_screen.res, 0);
|
||||
if ( help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
|
||||
help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 0);
|
||||
Ui_window.set_ignore_gadgets(0);
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !help_overlay_active(Control_config_overlay_id) ) {
|
||||
if ( !help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
|
||||
Ui_window.set_ignore_gadgets(0);
|
||||
}
|
||||
|
||||
@@ -1884,7 +1776,7 @@ void control_config_do_frame(float frametime)
|
||||
GR_MAYBE_CLEAR_RES(Background_bitmap);
|
||||
if (Background_bitmap >= 0) {
|
||||
gr_set_bitmap(Background_bitmap);
|
||||
gr_bitmap(0, 0, GR_RESIZE_MENU);
|
||||
gr_bitmap(0, 0);
|
||||
}
|
||||
|
||||
// highlight tab with conflict
|
||||
@@ -1905,7 +1797,7 @@ void control_config_do_frame(float frametime)
|
||||
}
|
||||
|
||||
// set color and font
|
||||
font::set_font(font::FONT2);
|
||||
gr_set_font(FONT2);
|
||||
if(Conflict_bright){
|
||||
gr_set_color_fast(&Color_bright_red);
|
||||
} else {
|
||||
@@ -1918,9 +1810,9 @@ void control_config_do_frame(float frametime)
|
||||
int sw, sh;
|
||||
gr_get_string_size(&sw, &sh, conflict_str);
|
||||
|
||||
gr_string((gr_screen.max_w / 2) - (sw / 2), Conflict_warning_coords[gr_screen.res][1], conflict_str, GR_RESIZE_MENU);
|
||||
gr_string((gr_screen.max_w / 2) - (sw / 2), Conflict_warning_coords[gr_screen.res][1], conflict_str);
|
||||
|
||||
font::set_font(font::FONT1);
|
||||
gr_set_font(FONT1);
|
||||
} else {
|
||||
// might as well always reset the conflict stamp
|
||||
Conflict_stamp = -1;
|
||||
@@ -1974,7 +1866,7 @@ void control_config_do_frame(float frametime)
|
||||
if (t % 2) {
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
gr_get_string_size(&w, NULL, XSTR( "?", 208));
|
||||
gr_printf_menu(x - w / 2, y - font_height / 2, XSTR( "?", 208));
|
||||
gr_printf(x - w / 2, y - font_height / 2, XSTR( "?", 208));
|
||||
}
|
||||
|
||||
} else if (!(z & JOY_AXIS) && ((Conflicts[z].key >= 0) || (Conflicts[z].joy >= 0))) {
|
||||
@@ -1986,7 +1878,7 @@ void control_config_do_frame(float frametime)
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
str = XSTR( "Control conflicts with:", 209);
|
||||
gr_get_string_size(&w, NULL, str);
|
||||
gr_printf_menu(x - w / 2, y - font_height, str);
|
||||
gr_printf(x - w / 2, y - font_height, str);
|
||||
|
||||
if (Control_config[i].hasXSTR) {
|
||||
strcpy_s(buf, XSTR(Control_config[i].text, CONTROL_CONFIG_XSTR + i));
|
||||
@@ -1994,14 +1886,14 @@ void control_config_do_frame(float frametime)
|
||||
strcpy_s(buf, Control_config[i].text);
|
||||
}
|
||||
|
||||
font::force_fit_string(buf, 255, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
gr_force_fit_string(buf, 255, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
|
||||
gr_get_string_size(&w, NULL, buf);
|
||||
gr_printf_menu(x - w / 2, y, buf);
|
||||
gr_printf(x - w / 2, y, buf);
|
||||
|
||||
} else if (*bound_string) {
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
gr_get_string_size(&w, NULL, bound_string);
|
||||
gr_printf_menu(x - w / 2, y - font_height / 2, bound_string);
|
||||
gr_printf(x - w / 2, y - font_height / 2, bound_string);
|
||||
if (timestamp_elapsed(bound_timestamp)) {
|
||||
*bound_string = 0;
|
||||
}
|
||||
@@ -2009,7 +1901,7 @@ void control_config_do_frame(float frametime)
|
||||
|
||||
if (Cc_lines[Num_cc_lines - 1].y + font_height > Cc_lines[Scroll_offset].y + Control_list_coords[gr_screen.res][CONTROL_H_COORD]) {
|
||||
gr_set_color_fast(&Color_white);
|
||||
gr_printf_menu(Control_more_coords[gr_screen.res][CONTROL_X_COORD], Control_more_coords[gr_screen.res][CONTROL_Y_COORD], XSTR( "More...", 210));
|
||||
gr_printf(Control_more_coords[gr_screen.res][CONTROL_X_COORD], Control_more_coords[gr_screen.res][CONTROL_Y_COORD], XSTR( "More...", 210));
|
||||
}
|
||||
|
||||
conflict = 0;
|
||||
@@ -2034,19 +1926,20 @@ void control_config_do_frame(float frametime)
|
||||
gr_set_color_fast(c);
|
||||
if (Cc_lines[line].label) {
|
||||
strcpy_s(buf, Cc_lines[line].label);
|
||||
font::force_fit_string(buf, 255, Control_list_ctrl_w[gr_screen.res]);
|
||||
gr_printf_menu(Control_list_coords[gr_screen.res][CONTROL_X_COORD], y, buf);
|
||||
gr_force_fit_string(buf, 255, Control_list_ctrl_w[gr_screen.res]);
|
||||
gr_printf(Control_list_coords[gr_screen.res][CONTROL_X_COORD], y, buf);
|
||||
}
|
||||
|
||||
if (!(z & JOY_AXIS)) {
|
||||
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)) {
|
||||
gr_set_color_fast(&Color_grey);
|
||||
gr_printf_menu(x, y, XSTR( "None", 211));
|
||||
gr_printf(x, y, XSTR( "None", 211));
|
||||
|
||||
} else {
|
||||
if (k >= 0) {
|
||||
@@ -2066,8 +1959,9 @@ void control_config_do_frame(float frametime)
|
||||
gr_set_color_fast(c);
|
||||
}
|
||||
|
||||
gr_printf_menu(x, y, buf);
|
||||
gr_printf(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;
|
||||
@@ -2075,7 +1969,7 @@ void control_config_do_frame(float frametime)
|
||||
|
||||
if (j >= 0) {
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
gr_printf_menu(x, y, XSTR( ", ", 212));
|
||||
gr_printf(x, y, XSTR( ", ", 212));
|
||||
gr_get_string_size(&w, NULL, XSTR( ", ", 212));
|
||||
x += w;
|
||||
}
|
||||
@@ -2098,8 +1992,8 @@ void control_config_do_frame(float frametime)
|
||||
gr_set_color_fast(c);
|
||||
}
|
||||
|
||||
font::force_fit_string(buf, 255, Control_list_key_w[gr_screen.res] + Control_list_key_x[gr_screen.res] - x);
|
||||
gr_printf_menu(x, y, buf);
|
||||
gr_force_fit_string(buf, 255, Control_list_key_w[gr_screen.res] + Control_list_key_x[gr_screen.res] - x);
|
||||
gr_printf(x, y, buf);
|
||||
|
||||
Cc_lines[line].jx = x - Control_list_coords[gr_screen.res][CONTROL_X_COORD];
|
||||
gr_get_string_size(&Cc_lines[line].jw, NULL, buf);
|
||||
@@ -2115,7 +2009,7 @@ void control_config_do_frame(float frametime)
|
||||
|
||||
if (j < 0) {
|
||||
gr_set_color_fast(&Color_grey);
|
||||
gr_printf_menu(x, y, XSTR( "None", 211));
|
||||
gr_printf(x, y, XSTR( "None", 211));
|
||||
|
||||
} else {
|
||||
if (Conflicts_axes[z & ~JOY_AXIS] >= 0) {
|
||||
@@ -2134,7 +2028,7 @@ void control_config_do_frame(float frametime)
|
||||
gr_set_color_fast(c);
|
||||
}
|
||||
|
||||
gr_string(x, y, Joy_axis_text[j], GR_RESIZE_MENU);
|
||||
gr_string(x, y, Joy_axis_text[j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2148,47 +2042,8 @@ 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);
|
||||
help_overlay_maybe_blit(CONTROL_CONFIG_OVERLAY);
|
||||
|
||||
gr_flip();
|
||||
}
|
||||
@@ -2213,8 +2068,6 @@ float check_control_timef(int id)
|
||||
|
||||
// first, see if control actually used (makes sure modifiers match as well)
|
||||
if (!check_control(id)) {
|
||||
Control_config[id].continuous_ongoing = false;
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
@@ -2229,11 +2082,6 @@ float check_control_timef(int id)
|
||||
}
|
||||
|
||||
if (t1 + t2) {
|
||||
// We want to set this to true only after visiting control_used() (above)
|
||||
// to allow it to tell the difference between an ongoing continuous action
|
||||
// started before and a continuous action being started right now.
|
||||
Control_config[id].continuous_ongoing = true;
|
||||
|
||||
return t1 + t2;
|
||||
}
|
||||
|
||||
@@ -2245,14 +2093,14 @@ 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(490, 15, NOX("Ctrls checked: %d"), Control_check_count);
|
||||
}
|
||||
#endif
|
||||
|
||||
Control_check_count = 0;
|
||||
}
|
||||
|
||||
int check_control_used(int id, int key)
|
||||
int check_control(int id, int key)
|
||||
{
|
||||
int z, mask;
|
||||
static int last_key = 0;
|
||||
@@ -2269,9 +2117,6 @@ int check_control_used(int id, int key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Control_config[id].disabled)
|
||||
return 0;
|
||||
|
||||
if (Control_config[id].type == CC_TYPE_CONTINUOUS) {
|
||||
if (joy_down(Control_config[id].joy_id) || joy_down_count(Control_config[id].joy_id, 1)) {
|
||||
control_used(id);
|
||||
@@ -2307,16 +2152,17 @@ int check_control_used(int id, int key)
|
||||
z &= KEY_MASK;
|
||||
|
||||
if (keyd_pressed[z] || key_down_count(z)) {
|
||||
control_used(id);
|
||||
return 1;
|
||||
if ( !hud_squadmsg_read_key(z) ) {
|
||||
control_used(id);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -2325,35 +2171,6 @@ int check_control_used(int id, int key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for check_control_used. Allows the game to ignore the key if told to do so by the ignore-key SEXP.
|
||||
*/
|
||||
int check_control(int id, int key)
|
||||
{
|
||||
if (check_control_used(id, key)) {
|
||||
if (Ignored_keys[id]) {
|
||||
if (Ignored_keys[id] > 0) {
|
||||
Ignored_keys[id]--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Control_config[id].continuous_ongoing) {
|
||||
// If we reach this point, then it means this is a continuous control
|
||||
// which has just been released
|
||||
|
||||
Script_system.SetHookVar("Action", 's', Control_config[id].text);
|
||||
Script_system.RunCondition(CHA_ONACTIONSTOPPED, '\0', NULL, NULL, id);
|
||||
Script_system.RemHookVar("Action");
|
||||
|
||||
Control_config[id].continuous_ongoing = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get heading, pitch, bank, throttle abs. and throttle rel. values.
|
||||
void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr)
|
||||
{
|
||||
@@ -2364,17 +2181,17 @@ void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr)
|
||||
// joy_get_scaled_reading will return a value represents the joystick pos from -1 to +1 (fixed point)
|
||||
*h = 0;
|
||||
if (Axis_map_to[0] >= 0) {
|
||||
*h = joy_get_scaled_reading(axes_values[Axis_map_to[0]]);
|
||||
*h = joy_get_scaled_reading(axes_values[Axis_map_to[0]], Axis_map_to[0]);
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
if (Axis_map_to[1] >= 0) {
|
||||
*p = joy_get_scaled_reading(axes_values[Axis_map_to[1]]);
|
||||
*p = joy_get_scaled_reading(axes_values[Axis_map_to[1]], Axis_map_to[1]);
|
||||
}
|
||||
|
||||
*b = 0;
|
||||
if (Axis_map_to[2] >= 0) {
|
||||
*b = joy_get_scaled_reading(axes_values[Axis_map_to[2]]);
|
||||
*b = joy_get_scaled_reading(axes_values[Axis_map_to[2]], Axis_map_to[2]);
|
||||
}
|
||||
|
||||
*ta = 0;
|
||||
@@ -2384,7 +2201,7 @@ void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr)
|
||||
|
||||
*tr = 0;
|
||||
if (Axis_map_to[4] >= 0) {
|
||||
*tr = joy_get_scaled_reading(axes_values[Axis_map_to[4]]);
|
||||
*tr = joy_get_scaled_reading(axes_values[Axis_map_to[4]], Axis_map_to[4]);
|
||||
}
|
||||
|
||||
if (Invert_axis[0]) {
|
||||
@@ -2406,7 +2223,6 @@ void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr)
|
||||
return;
|
||||
}
|
||||
|
||||
int Last_frame_timestamp;
|
||||
void control_used(int id)
|
||||
{
|
||||
// if we have set this key to be ignored, ignore it
|
||||
@@ -2414,20 +2230,7 @@ void control_used(int id)
|
||||
return;
|
||||
}
|
||||
|
||||
// This check needs to be done because the control code might call this function more than once per frame,
|
||||
// and we don't want to run the hooks more than once per frame
|
||||
if (Control_config[id].used < Last_frame_timestamp) {
|
||||
if (!Control_config[id].continuous_ongoing) {
|
||||
Script_system.SetHookVar("Action", 's', Control_config[id].text);
|
||||
Script_system.RunCondition(CHA_ONACTION, '\0', NULL, NULL, id);
|
||||
Script_system.RemHookVar("Action");
|
||||
|
||||
if (Control_config[id].type == CC_TYPE_CONTINUOUS)
|
||||
Control_config[id].continuous_ongoing = true;
|
||||
}
|
||||
|
||||
Control_config[id].used = timestamp();
|
||||
}
|
||||
Control_config[id].used = timestamp();
|
||||
}
|
||||
|
||||
void control_config_clear_used_status()
|
||||
|
||||
@@ -5,79 +5,55 @@
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef CONTROLS_CONFIG_H
|
||||
#define CONTROLS_CONFIG_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#define CONTROL_CONFIG_XSTR 507
|
||||
|
||||
/*!
|
||||
* These are used to index a corresponding joystick axis value from an array.
|
||||
* Currently only used by ::Axis_map_to[] and ::Axis_map_to_defaults[]
|
||||
*/
|
||||
enum Joy_axis_index {
|
||||
JOY_X_AXIS =0,
|
||||
JOY_Y_AXIS,
|
||||
JOY_Z_AXIS,
|
||||
JOY_RX_AXIS,
|
||||
JOY_RY_AXIS,
|
||||
JOY_RZ_AXIS
|
||||
};
|
||||
#define JOY_X_AXIS 0
|
||||
#define JOY_Y_AXIS 1
|
||||
#define JOY_Z_AXIS 2
|
||||
#define JOY_RX_AXIS 3
|
||||
#define JOY_RY_AXIS 4
|
||||
#define JOY_RZ_AXIS 5
|
||||
|
||||
#define NUM_JOY_AXIS_ACTIONS 5
|
||||
|
||||
/*!
|
||||
* These are used to index a corresponding (analog) action, namely controlling the orientation angles and throttle.
|
||||
*/
|
||||
enum Joy_axis_action_index {
|
||||
JOY_HEADING_AXIS =0,
|
||||
JOY_PITCH_AXIS,
|
||||
JOY_BANK_AXIS,
|
||||
JOY_ABS_THROTTLE_AXIS,
|
||||
JOY_REL_THROTTLE_AXIS,
|
||||
#define JOY_HEADING_AXIS 0
|
||||
#define JOY_PITCH_AXIS 1
|
||||
#define JOY_BANK_AXIS 2
|
||||
#define JOY_ABS_THROTTLE_AXIS 3
|
||||
#define JOY_REL_THROTTLE_AXIS 4
|
||||
|
||||
/*!
|
||||
* This must always be below the last defined item
|
||||
*/
|
||||
NUM_JOY_AXIS_ACTIONS //!< The total number of actions an axis may map to
|
||||
};
|
||||
// --------------------------------------------------
|
||||
// different types of controls that can be assigned
|
||||
// --------------------------------------------------
|
||||
|
||||
#define CC_TYPE_TRIGGER 0
|
||||
#define CC_TYPE_CONTINUOUS 1
|
||||
|
||||
|
||||
/*!
|
||||
* Control Configuration Types. Namely differ in how the control is activated
|
||||
*/
|
||||
enum CC_type {
|
||||
CC_TYPE_TRIGGER =0, //!< A normal, one-shot type control that is activated when a key is or button is pressed
|
||||
CC_TYPE_CONTINUOUS //!< A continous control that is activated as long as the key or button is held down
|
||||
};
|
||||
|
||||
/*!
|
||||
* Control configuration item type.
|
||||
*/
|
||||
typedef struct config_item {
|
||||
short key_default; //!< default key bound to action
|
||||
short joy_default; //!< default joystick button bound to action
|
||||
char tab; //!< what tab (category) it belongs in
|
||||
bool hasXSTR; //!< whether we should translate this with an XSTR
|
||||
char *text; //!< describes the action in the config screen
|
||||
char type; //!< manner control should be checked in
|
||||
short key_id; //!< actual key bound to action
|
||||
short joy_id; //!< joystick button bound to action
|
||||
int used; //!< has control been used yet in mission? If so, this is the timestamp
|
||||
bool disabled; //!< whether this action should be available at all
|
||||
bool continuous_ongoing;//!< whether this action is a continuous one and is currently ongoing
|
||||
short key_default; // default key bound to action
|
||||
short joy_default; // default joystick button bound to action
|
||||
char tab; // what tab (category) it belongs in
|
||||
bool hasXSTR; // whether we should translate this with an XSTR
|
||||
char *text; // describes the action in the config screen
|
||||
char type; // manner control should be checked in
|
||||
short key_id; // actual key bound to action
|
||||
short joy_id; // joystick button bound to action
|
||||
int used; // has control been used yet in mission? If so, this is the timestamp
|
||||
} config_item;
|
||||
|
||||
/*!
|
||||
/**
|
||||
* All available actions
|
||||
* This is the value of the id field in config_item
|
||||
* The first group of items are ship targeting.
|
||||
*/
|
||||
enum IoActionId {
|
||||
// targeting a ship
|
||||
TARGET_NEXT =0, //!< target next
|
||||
TARGET_PREV =1, //!< target previous
|
||||
TARGET_NEXT_CLOSEST_HOSTILE =2, //!< target the next hostile target
|
||||
@@ -90,23 +66,17 @@ enum IoActionId {
|
||||
TARGET_LAST_TRANMISSION_SENDER =9, //!< TARGET_LAST_TRANMISSION_SENDER
|
||||
STOP_TARGETING_SHIP =10, //!< stop targeting ship
|
||||
|
||||
//!< @n
|
||||
//!< Targeting a Ship's Subsystem
|
||||
//!< ------------------------------
|
||||
// targeting a ship's subsystem
|
||||
TARGET_SUBOBJECT_IN_RETICLE =11, //!< target ships subsystem in reticle
|
||||
TARGET_NEXT_SUBOBJECT =12, //!< target next subsystem on current target
|
||||
TARGET_PREV_SUBOBJECT =13, //!< TARGET_PREV_SUBOBJECT
|
||||
STOP_TARGETING_SUBSYSTEM =14, //!< stop targeting subsystems on ship
|
||||
|
||||
//!< @n
|
||||
//!< Speed Matching
|
||||
//!< ----------------
|
||||
// speed matching
|
||||
MATCH_TARGET_SPEED =15, //!< match target speed
|
||||
TOGGLE_AUTO_MATCH_TARGET_SPEED =16, //!< toggle auto-match target speed
|
||||
|
||||
//!< @n
|
||||
//!< Weapons
|
||||
//!< ---------
|
||||
// weapons
|
||||
FIRE_PRIMARY =17, //!< FIRE_PRIMARY
|
||||
FIRE_SECONDARY =18, //!< FIRE_SECONDARY
|
||||
CYCLE_NEXT_PRIMARY =19, //!< cycle to next primary weapon
|
||||
@@ -115,9 +85,7 @@ enum IoActionId {
|
||||
CYCLE_NUM_MISSLES =22, //!< cycle number of missiles fired from secondary bank
|
||||
LAUNCH_COUNTERMEASURE =23, //!< LAUNCH_COUNTERMEASURE
|
||||
|
||||
//!< @n
|
||||
//!< Controls
|
||||
//!< ----------
|
||||
// controls
|
||||
FORWARD_THRUST =24, //!< FORWARD_THRUST
|
||||
REVERSE_THRUST =25, //!< REVERSE_THRUST
|
||||
BANK_LEFT =26, //!< BANK_LEFT
|
||||
@@ -127,9 +95,7 @@ enum IoActionId {
|
||||
YAW_LEFT =30, //!< YAW_LEFT
|
||||
YAW_RIGHT =31, //!< YAW_RIGHT
|
||||
|
||||
//!< @n
|
||||
//!< Throttle Control
|
||||
//!< ------------------
|
||||
// throttle control
|
||||
ZERO_THROTTLE =32, //!< ZERO_THROTTLE
|
||||
MAX_THROTTLE =33, //!< MAX_THROTTLE
|
||||
ONE_THIRD_THROTTLE =34, //!< ONE_THIRD_THROTTLE
|
||||
@@ -137,9 +103,7 @@ enum IoActionId {
|
||||
PLUS_5_PERCENT_THROTTLE =36, //!< PLUS_5_PERCENT_THROTTLE
|
||||
MINUS_5_PERCENT_THROTTLE =37, //!< MINUS_5_PERCENT_THROTTLE
|
||||
|
||||
//!< @n
|
||||
//!< Squadmate Messaging Keys
|
||||
//!< --------------------------
|
||||
// squadmate messaging keys
|
||||
ATTACK_MESSAGE =38, //!< wingman message: attack current target
|
||||
DISARM_MESSAGE =39, //!< wingman message: disarm current target
|
||||
DISABLE_MESSAGE =40, //!< wingman message: disable current target
|
||||
@@ -154,9 +118,7 @@ enum IoActionId {
|
||||
REARM_MESSAGE =49, //!< REARM_MESSAGE
|
||||
TARGET_CLOSEST_SHIP_ATTACKING_SELF =50, //!< target closest ship that is attacking player
|
||||
|
||||
//!< @n
|
||||
//!< Views
|
||||
//!< -------
|
||||
// Views
|
||||
VIEW_CHASE =51, //!< VIEW_CHASE
|
||||
VIEW_EXTERNAL =52, //!< VIEW_EXTERNAL
|
||||
VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK =53, //!< VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK
|
||||
@@ -170,9 +132,6 @@ enum IoActionId {
|
||||
PADLOCK_LEFT =61, //!< PADLOCK_LEFT
|
||||
PADLOCK_RIGHT =62, //!< PADLOCK_RIGHT
|
||||
|
||||
//!< @n
|
||||
//!< Misc Controls 1
|
||||
//!< -----------------
|
||||
RADAR_RANGE_CYCLE =63, //!< cycle to next radar range
|
||||
SQUADMSG_MENU =64, //!< toggle the squadmate messaging menu
|
||||
SHOW_GOALS =65, //!< show the mission goals screen
|
||||
@@ -180,9 +139,6 @@ enum IoActionId {
|
||||
TARGET_TARGETS_TARGET =67, //!< target your target's target
|
||||
AFTERBURNER =68, //!< AFTERBURNER
|
||||
|
||||
//!< @n
|
||||
//!< ETS
|
||||
//!< -----
|
||||
INCREASE_WEAPON =69, //!< increase weapon recharge rate
|
||||
DECREASE_WEAPON =70, //!< decrease weapon recharge rate
|
||||
INCREASE_SHIELD =71, //!< increase shield recharge rate
|
||||
@@ -195,42 +151,34 @@ enum IoActionId {
|
||||
SHIELD_XFER_BOTTOM =78, //!< transfer shield energy to rear
|
||||
SHIELD_XFER_LEFT =79, //!< transfer shield energy to left
|
||||
SHIELD_XFER_RIGHT =80, //!< transfer shield energy to right
|
||||
|
||||
XFER_SHIELD =81, //!< transfer energy to shield from weapons
|
||||
XFER_LASER =82, //!< transfer energy to weapons from shield
|
||||
|
||||
//!< @n
|
||||
//!< Misc Controls 2
|
||||
//!< -----------------
|
||||
//Backslash -- this was a convenient place for Glide When Pressed, since Show Damage Popup isn't used
|
||||
GLIDE_WHEN_PRESSED =83, //!< GLIDE_WHEN_PRESSED
|
||||
//!< @remark Backslash -- this was a convenient place for Glide When Pressed, since Show Damage Popup isn't used
|
||||
BANK_WHEN_PRESSED =84, //!< BANK_WHEN_PRESSED
|
||||
SHOW_NAVMAP =85, //!< SHOW_NAVMAP
|
||||
ADD_REMOVE_ESCORT =86, //!< ADD_REMOVE_ESCORT
|
||||
ESCORT_CLEAR =87, //!< ESCORT_CLEAR
|
||||
|
||||
TARGET_NEXT_ESCORT_SHIP =88, //!< TARGET_NEXT_ESCORT_SHIP
|
||||
TARGET_CLOSEST_REPAIR_SHIP =89, //!< target the closest repair ship
|
||||
TARGET_NEXT_UNINSPECTED_CARGO =90, //!< TARGET_NEXT_UNINSPECTED_CARGO
|
||||
TARGET_PREV_UNINSPECTED_CARGO =91, //!< TARGET_PREV_UNINSPECTED_CARGO
|
||||
TARGET_NEWEST_SHIP =92, //!< TARGET_NEWEST_SHIP
|
||||
|
||||
TARGET_NEXT_LIVE_TURRET =93, //!< TARGET_NEXT_LIVE_TURRET
|
||||
TARGET_PREV_LIVE_TURRET =94, //!< TARGET_PREV_LIVE_TURRET
|
||||
|
||||
TARGET_NEXT_BOMB =95, //!< TARGET_NEXT_BOMB
|
||||
TARGET_PREV_BOMB =96, //!< TARGET_PREV_BOMB
|
||||
|
||||
//!< @n
|
||||
//!< Multiplayer messaging keys
|
||||
//!< ----------------------------
|
||||
// multiplayer messaging keys
|
||||
MULTI_MESSAGE_ALL =97, //!< message all netplayers
|
||||
MULTI_MESSAGE_FRIENDLY =98, //!< message all friendlies
|
||||
MULTI_MESSAGE_HOSTILE =99, //!< message all hostiles
|
||||
MULTI_MESSAGE_TARGET =100, //!< message targeted ship (if player)
|
||||
|
||||
//!< @n
|
||||
//!< Multiplayer misc keys
|
||||
//!< -----------------------
|
||||
// multiplayer misc keys
|
||||
MULTI_OBSERVER_ZOOM_TO =101, //!< if i'm an observer, zoom to my targeted object
|
||||
|
||||
TIME_SPEED_UP =102, //!< TIME_SPEED_UP
|
||||
@@ -242,9 +190,6 @@ enum IoActionId {
|
||||
|
||||
MULTI_SELF_DESTRUCT =106, //!< self destruct (multiplayer only)
|
||||
|
||||
//!< @n
|
||||
//!< Misc Controls 3
|
||||
//!< -----------------
|
||||
TOGGLE_HUD =107, //!< TOGGLE_HUD
|
||||
RIGHT_SLIDE_THRUST =108, //!< RIGHT_SLIDE_THRUST
|
||||
LEFT_SLIDE_THRUST =109, //!< LEFT_SLIDE_THRUST
|
||||
@@ -254,24 +199,15 @@ enum IoActionId {
|
||||
VIEW_TOPDOWN =113, //!< VIEW_TOPDOWN
|
||||
VIEW_TRACK_TARGET =114, //!< VIEW_TRACK_TARGET
|
||||
|
||||
//!< @n
|
||||
//!< AutoPilot - Kazan
|
||||
//!< -------------------
|
||||
//AutoPilot - Kazan
|
||||
AUTO_PILOT_TOGGLE =115, //!< Autopilot key control
|
||||
NAV_CYCLE =116, //!< NAV_CYCLE
|
||||
|
||||
//!< @n
|
||||
//!< Gliding
|
||||
//!< ---------
|
||||
//Gliding
|
||||
TOGGLE_GLIDING =117, //!< TOGGLE_GLIDING
|
||||
|
||||
//!< @n
|
||||
//!< Additional weapon controls
|
||||
//!< ----------------------------
|
||||
CYCLE_PRIMARY_WEAPON_SEQUENCE =118, //!< cycle num primaries to fire at once
|
||||
|
||||
/*!
|
||||
* This must always be below the last defined item
|
||||
/**
|
||||
* This must always be below the last defined action
|
||||
*/
|
||||
CCFG_MAX //!< The total number of defined control actions (or last define + 1)
|
||||
};
|
||||
@@ -288,19 +224,12 @@ extern int Axis_map_to[];
|
||||
extern int Invert_axis[];
|
||||
extern int Invert_axis_defaults[];
|
||||
|
||||
extern int Joy_dead_zone_size;
|
||||
extern int Joy_sensitivity;
|
||||
|
||||
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 config_item Control_config[]; // stores the keyboard configuration
|
||||
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
|
||||
// initialize common control config stuff - call at game startup after localization has been initialized
|
||||
void control_config_common_init();
|
||||
|
||||
void control_config_init();
|
||||
void control_config_do_frame(float frametime);
|
||||
@@ -308,8 +237,8 @@ void control_config_close();
|
||||
|
||||
void control_config_cancel_exit();
|
||||
|
||||
void control_config_reset_defaults(int presetnum=-1);
|
||||
int translate_key_to_index(const char *key, bool find_override=true);
|
||||
void control_config_reset_defaults();
|
||||
int translate_key_to_index(char *key);
|
||||
char *translate_key(char *key);
|
||||
char *textify_scancode(int code);
|
||||
float check_control_timef(int id);
|
||||
@@ -321,6 +250,4 @@ void clear_key_binding(short key);
|
||||
void control_check_indicate();
|
||||
void control_config_clear_used_status();
|
||||
|
||||
int joy_get_scaled_reading(int raw);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
+78
-79
@@ -10,17 +10,17 @@
|
||||
|
||||
|
||||
#include "cutscene/cutscenes.h"
|
||||
#include "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;
|
||||
@@ -35,16 +35,16 @@ char *Cutscene_mask_name[GR_NUM_RESOLUTIONS] = {
|
||||
"2_ViewFootage-m"
|
||||
};
|
||||
|
||||
int Cutscenes_viewable;
|
||||
int Description_index;
|
||||
SCP_vector<cutscene_info> Cutscenes;
|
||||
|
||||
//extern int All_movies_enabled; // If set, all movies may be viewed. Keyed off cheat code.
|
||||
void cutscene_close()
|
||||
{
|
||||
for(SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut)
|
||||
if(cut->description != NULL) {
|
||||
if(cut->description)
|
||||
vm_free(cut->description);
|
||||
cut->description = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// initialization stuff for cutscenes
|
||||
@@ -52,61 +52,54 @@ 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();
|
||||
// open localization
|
||||
lcl_ext_open();
|
||||
|
||||
// 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));
|
||||
lcl_ext_close();
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("cutscenes.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse in all the cutscenes
|
||||
Cutscenes.clear();
|
||||
skip_to_string("#Cutscenes");
|
||||
ignore_white_space();
|
||||
|
||||
while ( required_string_either("#End", "$Filename:") )
|
||||
{
|
||||
memset(&cutinfo, 0, sizeof(cutscene_info));
|
||||
|
||||
required_string("$Filename:");
|
||||
stuff_string( cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN );
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string( cutinfo.name, F_NAME, NAME_LENGTH );
|
||||
|
||||
required_string("$Description:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
cutinfo.description = vm_strdup(buf);
|
||||
|
||||
required_string("$cd:");
|
||||
stuff_int( &cutinfo.cd );
|
||||
|
||||
Cutscenes.push_back(cutinfo);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
Cutscenes_viewable = INTRO_CUTSCENE_FLAG;
|
||||
|
||||
// close localization
|
||||
lcl_ext_close();
|
||||
}
|
||||
|
||||
// function to return 0 based index of which CD a particular movie is on
|
||||
@@ -147,13 +140,11 @@ void cutscene_mark_viewable(char *filename)
|
||||
|
||||
// see if the stripped filename matches the cutscene filename
|
||||
if ( strstr(cut_file, file) != NULL ) {
|
||||
cut->viewable = true;
|
||||
Cutscenes_viewable |= (1<<i);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
Warning(LOCATION, "Could not find cutscene '%s' in listing; cannot mark it viewable...", filename);
|
||||
}
|
||||
|
||||
#define NUM_BUTTONS 8
|
||||
@@ -252,7 +243,7 @@ int Cutscene_max_text_lines[GR_NUM_RESOLUTIONS] = {
|
||||
static int Text_size;
|
||||
static int Text_offset = 0;
|
||||
static int Text_line_size[MAX_TEXT_LINES];
|
||||
static const char *Text_lines[MAX_TEXT_LINES];
|
||||
static char *Text_lines[MAX_TEXT_LINES];
|
||||
|
||||
|
||||
int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
|
||||
@@ -260,7 +251,7 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
|
||||
int cd_present = 0;
|
||||
int cd_drive_num;
|
||||
int cd_mve_is_on;
|
||||
char volume_name[MAX_PATH_LEN];
|
||||
char volume_name[128];
|
||||
|
||||
int num_attempts = 0;
|
||||
|
||||
@@ -320,7 +311,7 @@ void cutscenes_screen_play()
|
||||
strcpy_s(name, Cutscenes[which_cutscene].filename );
|
||||
// full_name = cf_add_ext(name, NOX(".mve"));
|
||||
|
||||
main_hall_stop_music(true);
|
||||
main_hall_stop_music();
|
||||
main_hall_stop_ambient();
|
||||
int rval = movie_play(name);
|
||||
main_hall_start_music();
|
||||
@@ -329,11 +320,11 @@ void cutscenes_screen_play()
|
||||
char str[256];
|
||||
|
||||
if (Cmdline_nomovies)
|
||||
strcpy_s(str, XSTR("Movies are currently disabled.", 1574));
|
||||
sprintf(str, XSTR("Movies are currently disabled.", -1));
|
||||
else
|
||||
sprintf(str, XSTR("Unable to play movie %s.", 204), Cutscenes[which_cutscene].name);
|
||||
|
||||
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, str );
|
||||
popup(0, 1, POPUP_OK, str );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -482,12 +473,20 @@ void cutscenes_screen_init()
|
||||
Scroll_offset = Selected_line = 0;
|
||||
Description_index = -1;
|
||||
|
||||
// when doing a debug version, just put all of the movie files here.
|
||||
#ifndef NDEBUG
|
||||
//Cutscenes_viewable = 0xffffffff; // makes all cutscenes viewble.
|
||||
#endif
|
||||
|
||||
// if (All_movies_enabled)
|
||||
// Cutscenes_viewable = 0xffffffff; // Cheat code enables all movies.
|
||||
|
||||
Cutscene_list.clear();
|
||||
|
||||
int u = 0;
|
||||
for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut, u++) {
|
||||
if ( (*cut).viewable ) {
|
||||
Cutscene_list.push_back(u);
|
||||
size_t size = Cutscenes.size();
|
||||
for (size_t j=0;j < size;j++) {
|
||||
if ( Cutscenes_viewable & (1<<j) ) {
|
||||
Cutscene_list.push_back((int)j);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,7 +579,7 @@ void cutscenes_screen_do_frame()
|
||||
GR_MAYBE_CLEAR_RES(Background_bitmap);
|
||||
if (Background_bitmap >= 0) {
|
||||
gr_set_bitmap(Background_bitmap);
|
||||
gr_bitmap(0, 0, GR_RESIZE_MENU);
|
||||
gr_bitmap(0, 0);
|
||||
}
|
||||
|
||||
Ui_window.draw();
|
||||
@@ -610,7 +609,7 @@ void cutscenes_screen_do_frame()
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
}
|
||||
|
||||
gr_printf_menu(Cutscene_list_coords[gr_screen.res][0], Cutscene_list_coords[gr_screen.res][1] + y, Cutscenes[Cutscene_list[z]].name);
|
||||
gr_printf(Cutscene_list_coords[gr_screen.res][0], Cutscene_list_coords[gr_screen.res][1] + y, Cutscenes[Cutscene_list[z]].name);
|
||||
|
||||
y += font_height;
|
||||
z++;
|
||||
@@ -649,7 +648,7 @@ void cutscenes_screen_do_frame()
|
||||
|
||||
strncpy(line, Text_lines[z], len);
|
||||
line[len] = 0;
|
||||
gr_string(Cutscene_desc_coords[gr_screen.res][0], Cutscene_desc_coords[gr_screen.res][1] + y, line, GR_RESIZE_MENU);
|
||||
gr_string(Cutscene_desc_coords[gr_screen.res][0], Cutscene_desc_coords[gr_screen.res][1] + y, line);
|
||||
|
||||
y += font_height;
|
||||
z++;
|
||||
|
||||
+13
-14
@@ -5,7 +5,9 @@
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _FREESPACE_CUTSCENES_SCREEN_HEADER_FILE
|
||||
#define _FREESPACE_CUTSCENES_SCREEN_HEADER_FILE
|
||||
@@ -13,28 +15,25 @@
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
typedef struct cutscene_info {
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
char name[NAME_LENGTH];
|
||||
char *description;
|
||||
// this cutscene is always available.
|
||||
#define INTRO_CUTSCENE_FLAG (1<<0)
|
||||
|
||||
typedef struct cutscene_info
|
||||
{
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
char name[NAME_LENGTH];
|
||||
char *description;
|
||||
int cd;
|
||||
bool viewable;
|
||||
} cutscene_info;
|
||||
|
||||
#if SCP_COMPILER_IS_GNU
|
||||
#pragma GCC diagnostic push
|
||||
// This suppresses a GCC bug where it thinks that the Cutscenes from the enum class below shadows a global variable
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
extern SCP_vector<cutscene_info> Cutscenes;
|
||||
#if SCP_COMPILER_IS_GNU
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
extern int Cutscenes_viewable;
|
||||
|
||||
// initializa table data
|
||||
void cutscene_init();
|
||||
int cutscene_get_cd_num(char *filename);
|
||||
|
||||
|
||||
void cutscenes_screen_init();
|
||||
void cutscenes_screen_close();
|
||||
void cutscenes_screen_do_frame();
|
||||
|
||||
Loaded 100 of 1561 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user