Compare commits

..
Author SHA1 Message Date
MageKing17 322a152476 Timer cleanup/improved wraparound handling.
Changes timestamp code to hopefully remove any oddities involving timestamps in close proximity to ticker rollover. However, more involved computation probably means performance will be impacted.
2019-01-22 20:29:37 -08:00
500 changed files with 11876 additions and 48005 deletions

No files matched your search

-182
View File
@@ -1,182 +0,0 @@
version: 2
references:
container_config: &container_config
docker:
- image: "debian:stretch"
working_directory: /root/build
restore_repo: &restore_repo
restore_cache:
keys:
- source-repo-{{ .Branch }}-{{ .Revision }}
- source-repo-{{ .Branch }}
- source-repo
cmake_configure: &cmake_configure
run:
name: Creating Build Files
command: |
mkdir build
cd build
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
if [[ "$CC" =~ ^clang.*$ ]]; then
CXXFLAGS="$CXXFLAGS -stdlib=libc++"
fi
eval $CC --version
export CXXFLAGS
export CFLAGS
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON $CMAKE_OPTIONS"
eval $CMAKE -DCMAKE_BUILD_TYPE=$CONFIGURATION -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON ..
compile: &compile
run:
name: Compiling Source code
command: |
cd build
ninja -k 20 all
run_tests: &run_tests
run:
name: Run unit tests
command: |
./build/bin/unittests --gtest_shuffle
compile_steps: &compile_steps
steps:
- *restore_repo
- *cmake_configure
- *compile
- *run_tests
jobs:
checkout_code:
<<: *container_config
steps:
- run:
name: Installing Git
command: 'apt-get update && apt-get -yq install git'
- *restore_repo
- checkout
- run:
name: Updating submodules
command: 'git submodule update --init --recursive'
- save_cache:
key: source-repo-{{ .Branch }}-{{ .Revision }}
paths:
- .
build_gcc_lowest_debug:
docker:
- image: asarium/fso_compile:gcc-lowest
working_directory: /root/build
environment:
CC: gcc
CXX: g++
CONFIGURATION: Debug
<<: *compile_steps
build_gcc_lowest_release:
docker:
- image: asarium/fso_compile:gcc-lowest
working_directory: /root/build
environment:
CC: gcc
CXX: g++
CONFIGURATION: Release
<<: *compile_steps
build_gcc_latest_debug:
docker:
- image: asarium/fso_compile:gcc-latest
working_directory: /root/build
environment:
CC: gcc
CXX: g++
CONFIGURATION: Debug
<<: *compile_steps
build_gcc_latest_release:
docker:
- image: asarium/fso_compile:gcc-latest
working_directory: /root/build
environment:
CC: gcc
CXX: g++
CONFIGURATION: Release
<<: *compile_steps
build_clang_latest_debug:
docker:
- image: asarium/fso_compile:clang-latest
working_directory: /root/build
environment:
CC: clang-8
CXX: clang++-8
CONFIGURATION: Debug
<<: *compile_steps
build_clang_latest_release:
docker:
- image: asarium/fso_compile:clang-latest
working_directory: /root/build
environment:
CC: clang-8
CXX: clang++-8
CONFIGURATION: Release
<<: *compile_steps
build_clang_lowest_debug:
docker:
- image: asarium/fso_compile:clang-lowest
working_directory: /root/build
environment:
CC: clang
CXX: clang++
CONFIGURATION: Debug
<<: *compile_steps
build_clang_lowest_release:
docker:
- image: asarium/fso_compile:clang-lowest
working_directory: /root/build
environment:
CC: clang
CXX: clang++
CONFIGURATION: Release
<<: *compile_steps
workflows:
version: 2
build_test:
jobs:
- checkout_code
- build_gcc_lowest_debug:
requires:
- checkout_code
- build_gcc_lowest_release:
requires:
- checkout_code
- build_gcc_latest_debug:
requires:
- checkout_code
- build_gcc_latest_release:
requires:
- checkout_code
- build_clang_latest_debug:
requires:
- checkout_code
- build_clang_latest_release:
requires:
- checkout_code
- build_clang_lowest_debug:
requires:
- checkout_code
- build_clang_lowest_release:
requires:
- checkout_code
+1 -4
View File
@@ -4,16 +4,13 @@ modernize-*,\
-modernize-raw-string-literal,\
-modernize-use-using,\
-modernize-make-unique,\
-modernize-use-trailing-return-type,\
-modernize-avoid-c-arrays,\
performance-*,\
-performance-type-promotion-in-math-fn,\
misc-*,\
-misc-macro-parentheses,\
-misc-misplaced-widening-cast,\
-misc-static-assert,\
-misc-unused-parameters,\
-misc-non-private-member-variables-in-classes,\
-modernize-make-unique,\
"
WarningsAsErrors: ''
HeaderFilterRegex: 'code/.*$|freespace2/.*$|qtfred/.*$|test/src/.*$|build/.*$'
-7
View File
@@ -1,7 +0,0 @@
# Default for everything
# * text=auto
# For the test data and built-in files to make them consistent on all platforms
*.tbl text eol=lf
*.tbm text eol=lf
*.sdr text eol=lf
-137
View File
@@ -1,137 +0,0 @@
name: Check a pull request
on: [pull_request]
jobs:
build_linux:
strategy:
matrix:
configuration: [Debug, Release]
compiler: [gcc-5, gcc-9, clang-4.0]
name: Linux
runs-on: ubuntu-16.04
steps:
- name: Prepare Environment
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo add-apt-repository ppa:beineri/opt-qt571-xenial
sudo add-apt-repository ppa:msulikowski/valgrind # For fixing a bug with valgrind 3.11 which does not recognize the rdrand instruction
sudo apt-get -yq update
sudo apt-get -yq install cmake ninja-build libopenal-dev libreadline6-dev libpng12-dev libjpeg62-dev liblua5.1-0-dev libjansson-dev libsdl2-dev libfreetype6-dev valgrind qt57base g++-5 g++-9 clang-4.0 clang-tidy-4.0 libc++-dev libc++abi-dev
# Fix a header bug present in ubuntu...
sudo ln -s /usr/include/libcxxabi/__cxxabi_config.h /usr/include/c++/v1/__cxxabi_config.h
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
run: |
if [ "$COMPILER" = "gcc-5" ]; then
export CC=gcc-5
export CXX=g++-5
fi
if [ "$COMPILER" = "gcc-9" ]; then
export CC=gcc-9
export CXX=g++-9
fi
if [ "$COMPILER" = "clang-4.0" ]; then
export CC=clang-4.0
export CXX=clang++-4.0
fi
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
if [[ "$CC" =~ ^clang.*$ ]]; then
CXXFLAGS="$CXXFLAGS -stdlib=libc++"
fi
mkdir build
cd build
export CXXFLAGS
export CFLAGS
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON $CMAKE_OPTIONS"
eval $CMAKE -DCMAKE_BUILD_TYPE=$CONFIGURATION -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=ON ..
- name: Compile
working-directory: ./build
run: ninja -k 20 all
- name: Run Tests
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
run: |
if [ "$CONFIGURATION" = "Debug" ]; then
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
--suppressions="$GITHUB_WORKSPACE/ci/travis/valgrind.supp" ./bin/unittests --gtest_shuffle
else
./bin/unittests --gtest_shuffle
fi
build_windows:
strategy:
matrix:
configuration: [Debug, Release]
compiler: [MSVC, MinGW]
arch: [Win32, x64]
exclude:
- configuration: Debug
compiler: MinGW
arch: x64
- configuration: Release
compiler: MinGW
arch: x64
name: Windows
runs-on: windows-2019
steps:
- name: Prepare Environment
run: choco install ninja
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
shell: bash
run: |
mkdir build
cd build
if [ "$COMPILER" = "MinGW" ]; then
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
-DFSO_BUILD_FRED2="OFF" -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
else
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "Visual Studio 16 2019" -T "v142" -A "$ARCHITECTURE" ..
fi
- name: Compile
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
shell: bash
run: |
if [ "$COMPILER" = "MinGW" ]; then
cmake --build . --config "$CONFIGURATION"
else
cmake --build . --config "$CONFIGURATION" -- /verbosity:minimal
fi
- name: Run Tests
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
shell: bash
run: |
if [ "$COMPILER" = "MinGW" ]; then
./bin/unittests --gtest_shuffle
else
"./bin/$CONFIGURATION/unittests" --gtest_shuffle
fi
+23 -43
View File
@@ -1,11 +1,10 @@
language: bash
sudo: required
dist: xenial
dist: trusty
cache:
directories:
- $HOME/cmake-3.8
- $HOME/.ccache
- $HOME/curl_cache
addons:
apt:
packages: &global_deps
@@ -18,6 +17,7 @@ addons:
- libjansson-dev
- libsdl2-dev
- libfreetype6-dev
- valgrind
- qt57base
coverity_scan:
project:
@@ -42,7 +42,7 @@ env:
deploy:
- provider: releases
api_key:
secure: "q619+eQTe7lv8UVphK4OIzU8Jw84KBbVkuprN2sWIubRcV3IbZr2+WahJoUMt+nyhiy3YjDYtstO2ZgkxupwnZgwGUBVIiD1c4SPuyy+HTjNMOtiVsEUHT2hf+xPAemWpTlK5HcwhMmHAOh6rt6dEj57QOg0gcmGiwD/tCbEriA="
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
skip_cleanup: true
file_glob: true
file: "/tmp/builds/*"
@@ -72,43 +72,33 @@ matrix:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-xenial'
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- g++-5
- os: linux
env: CONFIGURATION="Debug" CC=gcc-9 CXX=g++-9
env: CONFIGURATION="Debug" CC=gcc-8 CXX=g++-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-xenial'
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- g++-9
- g++-8
- *global_deps
- os: linux
env: CONFIGURATION="Debug" CC=clang-4.0 CXX=clang++-4.0 CMAKE_OPTIONS="-DCLANG_USE_LIBCXX=ON"
env: CONFIGURATION="Debug" CC=clang-4.0 CXX=clang++-4.0 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
- sourceline: 'ppa:beineri/opt-qt571-xenial'
- llvm-toolchain-trusty-4.0
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- clang-4.0
- clang-tidy-4.0
- libc++-dev
- libc++abi-dev
- os: linux
env: CONFIGURATION="Debug" CC=clang-9 CXX=clang++-9 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-xenial'
packages:
- *global_deps
- g++-9
script:
- ./ci/travis/script.sh
- ./ci/travis/clang_tidy.sh
@@ -126,46 +116,32 @@ matrix:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-xenial'
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- g++-5
- os: linux
env: CONFIGURATION="Release" CC=gcc-9 CXX=g++-9
env: CONFIGURATION="Release" CC=gcc-8 CXX=g++-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-xenial'
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- g++-9
- g++-8
- *global_deps
- os: linux
env: CONFIGURATION="Release" CC=clang-4.0 CXX=clang++-4.0 CMAKE_OPTIONS="-DCLANG_USE_LIBCXX=ON"
env: CONFIGURATION="Release" CC=clang-4.0 CXX=clang++-4.0
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
- sourceline: 'ppa:beineri/opt-qt571-xenial'
- llvm-toolchain-trusty-4.0
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- clang-4.0
- libc++-dev
- libc++abi-dev
- os: linux
env: CONFIGURATION="Release" CC=clang-9 CXX=clang++-9 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-xenial'
packages:
- *global_deps
- g++-9
script:
- ./ci/travis/script.sh
- ./ci/travis/clang_tidy.sh
- os: osx
env: CONFIGURATION="Release"
@@ -173,10 +149,14 @@ matrix:
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
# There is a GCC compiler bug with MinGW that causes compilation failures on Windows at the moment
# As long as Windows is still experimental on Travis CI, allow failures
allow_failures:
- os: windows
env: CONFIGURATION="Debug" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
fast_finish: true
+29
View File
@@ -0,0 +1,29 @@
Original source (Freespace 2) by Volition, Inc.; see "credits.tbl"
Modifications by the FreeSpace Source Code Project (FSSCP)
http://fs2source.warpcore.org
FS2_OPEN STAFF:
Project leader:
Edward "Inquisitor" Gardner
Programmers:
"Bobboau"
Dennis "DTP" Pedersen
Ian "Goober5000" Warfield
Joe "Righteous1" Dowd
Mike "penguin" Harris
"Mysterial"
"PhReAk"
Thomas "Random Tiger" Whittaker
Will "Unknown PLayer" Rousnel
"WMCoolmon"
Web support:
Icefire and the staff at Volitionwatch.com
Alex "Thunder" Avery and the staff at Hard Light Productions
Special thanks to:
Volition for making FS2 such a great game
Dave Baranec for giving us the code and keeping us sanity checked
-41
View File
@@ -1,41 +0,0 @@
## FreeSpace
FreeSpace: The Great War (Released 1998) and FreeSpace 2 (1999) are mission-based space combat simulators, like X-Wing/TIE Fighter and Wing Commander. Among the greatest games of the genre, they were also effectively the last.
The FreeSpace series follows humanity and their Vasudan allies as they fight to withstand the xenocidal, enigmatic Shivans, a species of unknown origin, vast technological capability, and seemingly limitless malice.
## FreeSpace Open
Thanks to Volition's generosity, we've continued development of FreeSpace 2 as FreeSpace Open, building graphical enhancements to bring the original games up to modern standards, telling new stories set in the FreeSpace universe and original worlds, and creating spectacular total conversions that let players fly in the beloved universes of Babylon 5, Battlestar Galactica, Wing Commander, and Star Wars.
## Hard-Light Productions
HLP is a fan community built on love and open-source code. We're dedicated to bringing modders together and giving them a place to share their own hard work and draw inspiration from the work of others. Thanks to Volition's generosity, we've continued development of FreeSpace 2 as FreeSpace Open, building graphical enhancements to bring the original games up to modern standards, telling new stories set in the FreeSpace universe and original worlds, and creating spectacular total conversions that let players fly in the beloved universes of Babylon 5, Battlestar Galactica, Wing Commander, and Star Wars.
Find us at:
- Our [website](http://www.hard-light.net/) and [forums](http://www.hard-light.net/forums/)
- [Discord](https://discord.gg/YNVP3WR)
- [Facebook](https://www.facebook.com/groups/Hardlightproductions/)
- [Youtube](https://www.youtube.com/channel/UCxKkd609hDtY6yNetR1iT4w)
- [Reddit](https://www.reddit.com/r/freespace/)
- [Twitter](https://twitter.com/hardlightpro)
- [IRC](irc://irc.esper.net/hard-light)
## How to get the game
FreeSpace Open requires a retail installation of FreeSpace 2, which is available at the following stores:
- [GOG.com](https://www.gog.com/game/freespace_2)
- [Steam](https://store.steampowered.com/app/273620/Freespace_2/)
After installing retail FS2, use [Knossos](https://fsnebula.org/knossos/) to upgrade to the most recent release of FSO. Knossos is an advanced mod manager and launcher for FSO.
## Improvements
The new open source game engine has several distingushing features including:
- Linux and Mac OS X support
- OpenGL support
- OpenAL audio support
- Easy mod installation
- OGG support
- Hardware transform, clipping, and lighting
## The FreeSpace Upgrade Project
While the SCP improves the code of the game engine to enable new and exciting features, the FreeSpace Upgrade Project (FSU) creates material that takes advantage of the improved game engine.
The FSU improves the ships, effects, and background elements of FreeSpace 2. Every now and then these improvements are released as a pack called MediaVPs. These assorted improvements enhance the graphics of the game.
While the best way to experience the FSU is by playing the game with it, you can watch this [comparison video](https://www.youtube.com/watch?v=RM1YC_gK-qo) between 1999 and 2019 to have an idea of how much more beautiful FSU makes the game.
^(Much of this content was pulled from existing sources, such as InsaneBaron's "What Is Hard Light Productions" [thread](https://www.hard-light.net/forums/index.php?topic=86650.0), the Wiki's [Getting Started article](https://wiki.hard-light.net/index.php/Getting_started) and more.)
-8
View File
@@ -1,8 +0,0 @@
Original source (Freespace 2) by Volition, Inc.; see "`credits.tbl`"
Modifications by the FreeSpace 2 Source Code Project [(FSO SCP)](https://www.hard-light.net/forums/index.php?board=50.0)
[Project Contributors](https://github.com/scp-fs2open/fs2open.github.com/graphs/contributors)
Special thanks to:
Volition for making FS2 such a great game
Dave Baranec for giving us the code and keeping us sanity checked
+1 -1
View File
@@ -10,7 +10,7 @@ endif()
include(cmake/util.cmake)
# Set a few policies
set_policy(CMP0051 NEW)
set_policy(CMP0051 OLD)
set_policy(CMP0053 NEW)
set_policy(CMP0054 NEW)
+4 -5
View File
@@ -1,15 +1,14 @@
Volition Copyright (applies to original FreeSpace2 source code
developed and released by Volition):
>Copyright (C) Volition, Inc. 1999. All rights reserved.
>
>All source code herein is the property of Volition, Inc. You may not
"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.
created based on the source."
Modifications by members of the FreeSpace Source Code Project are
released under whatever terms the individual authors choose, but the
above notice continues to apply to all fs2_open code.
See [**Licensing**](https://github.com/scp-fs2open/fs2open.github.com/wiki/Licensing) for more information.
+19 -127
View File
@@ -1,130 +1,23 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [19.0.0-RC1] - 2019-08-29 ([Thread](https://www.hard-light.net/forums/index.php?topic=95868.0))
### Meta
- With this release we decided to drop the "`3.Major_revision.Minor_revision`" versioning scheme in favor of a year based scheme since the Major and Minor versions did not have much meaning anymore. Instead the scheme will now be "`<year>.<number that is incremented every release>.0`". The last 0 is still there because some of our systems expect that. It will be gone at some point.
### Added
- Full Unicode text support: You can now use non-ASCII characters without having to worry about special fonts and special characters. This is an opt-in mod flag.
- Translation features for making it easier to only distribute one version of a mod which includes all languages.
- OpenAL Soft is included by default in binary distributions of FSO now.
- System for dynamically adding new SEXPs. With this a Lua script can expose functionality to the mission which can be used exactly the same as a standard SEXP with all the usual editing features in FRED.
- Support for displaying decals on the surface of an object.
- Integrated support for the [Discord Rich Presence API](https://discordapp.com/rich-presence).
- New markup based user interface system using [libRocket](https://github.com/libRocket/libRocket).
### Changed
- Exposed the movie player to the scripting API for advanced display features
- Various OpenGL optimizations for better graphics performance:
- Animations now use texture arrays
- Model uniforms get sent to the GPU using uniform buffers for less overhead
- Various other minor changes
- Converted pilot files from custom binary format to JSON
### Fixed
- Refactored bitmap slot handling and removed the fixed upper limit on the number of bitmaps. No more bmpman corruption!
## [3.8.0] - 2017-08-22 ([Release Thread](https://www.hard-light.net/forums/index.php?topic=93812.0))
### Added
- Support for APNG animations: [APNG](https://en.wikipedia.org/wiki/APNG) is a variant of the established PNG format which allows to store animations instead of single frames in a PNG file. This change allows to use these animation files in FSO which significantly improves usability for modders since they no longer have to store all individual frames as separate images.
- Physically-Based Rendering (PBR): This upgrade of our rendering engine allows to use [PBR](https://en.wikipedia.org/wiki/Physically_based_rendering) assets to make models look more realistic and allow more artistic freedom for modders since they have more control over how a model looks. This also added support for HDR lighting which should improve the overall graphics experience.
- Native particle systems: Particles have always been supported by FSO but the effects that could be created by them were very limited. There were some attempts to fix this by using Lua scripting for more advanced features but that suffered from performance issues. With these new particle systems that feature has been integrated directly into the engine which should improve performance and allow for better effects in the future.
- TrueType Font support: [TrueType](https://en.wikipedia.org/wiki/TrueType) fonts improve the text rendering capabilities of FSO by allowing to use freely scaleable font faces instead of the previous bitmap fonts.
### Changed
- We now use SDL2 on all platforms: SDL is a library for abstracting away the differences between different platforms. We now use SDL2 for all platforms which reduces the amount of platform-specific code tremendously and should result in better usability on all platforms. This was a major change that has been in development for several years. Here are a few key features that were added:
- Pilot and configuration data is now stored in the correct location across all platforms (this allows to run FSO on Windows from the Program Files directory without administrator rights)
- All platforms now use the ini files for storing settings. This fixes a lot of issues with the registry on Windows.
- Better support for input devices. Since SDL handles keyboard, mouse and joystick input we now have better support on newer OS versions. Note: This does not mean that we support multiple joysticks (yet). There is ongoing development effort to support this but this release does not have that yet.
- CMake build system generation: This isn't relevant for players but we are now using [CMake](https://en.wikipedia.org/wiki/CMake) for handling compiling our builds. This improves cross-platform support and allows to implement advanced compilation features across multiple platforms. Modders will like the new "FastDebug" builds which are like the previous "Debug" builds but are compiled with all the optimizations of normal Release builds. That should make modding a lot easier since you can now debug your mod with almost the same performance as a Release build.
- Improved shield effects: Rendering of the shields is now handled by special shaders which improves the overall quality of the effects and allows more freedom for future effects.
- Use OpenGL Core Profile for rendering: This is another major graphical upgrade which adds support for the OpenGL Core profile across all platforms (this was also made possible by the SDL2 integration). This upgrade allows us to use more modern rendering techniques and is especially useful for our Linux users who use the open-source Mesa drivers since our shaders failed to compile with those drivers. Now everyone will be able to enjoy the new graphical features added in this and previous releases. This also made some internal changes to how we handle rendering which improves the usability of our rendering engine within our code.
- Use FFmpeg for video & audio decoding: [FFmpeg](https://www.ffmpeg.org/) is a multi-media library which exposes functionality for decoding video and audio files to their raw form so that we can use that data. Thanks to this library we can now play 1080p cutscenes without any stuttering or frame-timing issues. It also allows to use more advanced audio and video codecs such as H.264 for video or Opus for audio.
## [3.7.4] - 2016-07-04 ([Release thread](http://www.hard-light.net/forums/index.php?topic=92181.0))
### Changed
- Major graphics update including deferred lighting and shadows
- Enhanced sound (up to 128 channels)
### Fixed
- "Tons" of bugfixes
## [3.7.2] - 2015-04-23 ([Release thread](http://www.hard-light.net/forums/index.php?topic=89597.0))
### Added
- MediaVPS 2014 Support
- Autospread on model point shields
- WebUI based multiplayer standalone server (for non-Windows platforms)
- Toggle subsytem scanning, scannable, cargo revealed, hidden from sensors, stealth and friendly stealth added to the `alter-ship-flag` SEXP
- Support added to add more languages besides English, French, German and Polish, leading the way to better localization!
- `player-is-cheating` SEXP
- 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`)
- Experimental configurations to make AVX builds (see [this post](http://www.hard-light.net/forums/index.php?topic=85566.0) for more explanations)
- Frame profiling code, see what exactly is slowing down FreeSpace. (Mostly for devs or coders)
### Changed
- Unstretched interface screens
- Automatically non stretched HUD gauges and simpler modder options for placing HUD gauges
- `show-subtitle-text` can now display messages as well as raw text
- Allow a user-specified number of credit images
- 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
- Allow the specification of the positions of medals, callsigns and labels on the medal screen.
- The number of medals is now dynamic!
- `is-facing` now works for things that aren't ships (like waypoints!)
- allowing `fade-in` and `fade-out` sexps to use any color, not just black, white and red.
## [3.7.0] - 2013-08-31 ([Release thread](http://www.hard-light.net/forums/index.php?topic=85435.0))
### Major Change
- New Flexible Pilot Save File Code (combines single/multi pilots & allows safe switching between unfinished campaigns)
### Changed
- Raised the per-model debris limit to 48 (previously 32).
- Increased the per-frame debris limit to 96 (previously 64)
## [3.6.18] - 2013-03-01 ([Release thread](http://www.hard-light.net/forums/index.php?topic=83889.0))
### Fixed
- Critical damage bug which caused heavy balance issues in the game
## [3.6.16] - 2013-01-31 ([Release thread](http://www.hard-light.net/forums/index.php?topic=83577.0))
### Added
- Diaspora TC support
### Changed
- Performance Improvements
## [3.6.14] - 2012-10-23 - ([Release thread](https://www.hard-light.net/forums/index.php?topic=82648.0))
### Added
- Objecttype tables support for deciding how enemies respond to ship classes when disabled
- Allow modders to set a [mood](http://www.hard-light.net/forums/index.php?topic=81991.msg1639770#msg1639770) for builtin messages and then switch the mood for the mission on the fly using a SEXP
- Allow modders to set the chance of builtin messages being sent, how many will be sent per mission and how long is the delay between two messages
- Allow campaigns to be hidden in the campaign and tech rooms ([Game settings.tbl](https://wiki.hard-light.net/index.php/Game_settings.tbl#.23Ignored_Campaign_File_Names))
- Allow mods to set a default campaign ([Game settings.tbl](https://wiki.hard-light.net/index.php/Game_settings.tbl#.24Default_Campaign_File_Name:))
- New SEXPs
- `set-player-orders`
- `is-event\goal-true\false-msecs-delay`
- `get\set-num-countermeasures`
- `directive-value`
- `invalidate-all-arguments`
- `validate-all-arguments`
- `has-primary-weapon`
- `has-secondary-weapon`
- [`hud-display-gauge`](http://www.hard-light.net/forums/index.php?topic=68837.msg1361711#msg1361711)
- `get-object-speed-x`
- `get-object-speed-y`
- `get-object-speed-z`
### Changed
- Major HUD gauges overhaul
- Split the Locked flag so that you can lock Ships or Weapons on the game loadout screen independently
- Mixed ammo for primary and secondary weapons - [`$Substitute`](http://www.hard-light.net/wiki/index.php/Weapons.tbl#.24Substitute:) - Allows you to have a weapon that fires other weapon ammo in a specific pattern (say a Gatling gun with tracers).
- [`show-subtitle`](https://wiki.hard-light.net/index.php/SCP_SEXPs#show-subtitle) SEXP supports custom fonts
- The active support ship limit per side is now dynamic. See [`set-support-ship`](https://wiki.hard-light.net/index.php/SCP_SEXPs#set-support-ship) for more info.
### Fixed
- Various multiplayer SEXP fixes
- `rotating-subsys-set-time` now accelerates properly
- [Fixed a whole heap of memory, logic and coding errors](http://www.hard-light.net/forums/index.php?topic=78044.0) -- using PVS-Studio: C/C++ source code analysis and checking tool
----
## [Older Changes] - Unformatted
```
ChangeLog for fs2_open. All times are UTC.
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...)
==================================================================
@@ -458,7 +351,7 @@ ChangeLog for fs2_open. All times are UTC.
(2.1.2.4), weapon/weapons.cpp (2.1.2.2):
Sorted out some bits and pieces. The background nebula blends now
which is nice. – RT
which is nice. – RT
2002-09-28 12:20 randomtiger
@@ -1993,4 +1886,3 @@ NOTE:
# generated by cvs2cl.pl
# cvs2cl.pl -r -S --utc -f ChangeLog2
```
Binary file not shown.
+29
View File
@@ -0,0 +1,29 @@
This is still in pretty rough form.
=== for people building fs2_open:
Win32-MSVC:
Use the Freespace2.dsw workspace and build within the IDE.
Win32-MinGW:
make
Linux and other unix variants (NOT YET COMPLETE)
./configure [options]
make
=== for the project maintainers (people who need to
=== keep the makefiles up to date) and those building
=== from CVS:
./autogen.sh (should only has to be done once)
./configure [options]
make
automake v1.6.1+ and
autoconf v2.54+ are required
+32 -1
View File
@@ -7,5 +7,36 @@ FreeSpace2 *S*ource *C*ode *P*roject
Building
--
Before you do anything, make sure you have updated your git submodules, either by running `git submodule update --init --recursive` or by cloning the repository with the `--recursive` flag.<br/>
<br/>
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>
The main instructions for building can be found at our github wiki, on the [Building](https://github.com/scp-fs2open/fs2open.github.com/wiki/Building) page.
### 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
* `CMAKE_BUILD_TYPE`: Sets the binary build type between `Debug` and `Release` (default)
#### 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 automatically 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.
-18
View File
@@ -1,18 +0,0 @@
#Updating Documentation
####The goal of this file is simply to offer a comprehensive checklist of things we must check when updating the documentation.
1. Changelog:
- Is [Changelog.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/Changelog.md) up-to-date with the latest release?
- Is it in the proper [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format?
2. Build instructions:
- If a programmer who never built FSO before read the build instruction at [Readme.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/Readme.md), would they manage to build FSO?
- Is the information in the file up-to-date regarding other matters (such as versions of tools mentioned, links to other guides, etc.)?
- Is the information in the [Building](https://github.com/scp-fs2open/fs2open.github.com/wiki/Building) article, and its sub-articles, still up-to-date?
3. Forums:
- Does the [Forum](https://www.hard-light.net/forums/index.php?board=50.0) contain enough clear information to help a new developer find their way into the up-to-date instructions?
- Is there anything that might mislead a new developer to stumble onto old tools, dead links and/or old versions of the project?
4. General documentation files:
- Is the information in the following files up-to-date?
- [About.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/About.md) (Should contain general information about FS, FS2, HLP, FSO and FSU)
- [Authors.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/Authors.md) (Should contain information about the original developers, a way to see FSO's contributors, and special thanks to Volition and Dave Baranec)
- [Copying.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/Copying.md) (Should contain Volition's Copyright terms and a way to check FSO's Licensing info)
+1 -1
View File
@@ -24,7 +24,7 @@ test_script:
deploy:
- provider: GitHub
auth_token:
secure: h55Scpy+3vmo1Yb7WlSIGA4d9DRnsbzUYc2LYsQdByQHZHbqrqjBpicH0D2FFLEO
secure: 3kV4efHXwRnfXzmJPRAOs8D7+MhwXUXYeayI/P5y114L09kJa6b6L70beXdW7yYr
on:
ReleaseBuild: true # deploy on release push only
+1 -5
View File
@@ -134,7 +134,6 @@ if ($DeployBuild) {
cmake -DCMAKE_INSTALL_PREFIX="$env:APPVEYOR_BUILD_FOLDER/../install" -DFSO_USE_SPEECH="ON" `
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$($buildConfig.SimdType)" `
-DQT5_INSTALL_ROOT="$($buildConfig.QtDir)" -DFSO_BUILD_QTFRED=ON `
-DFSO_INSTALL_DEBUG_FILES="ON" `
-G "$($buildConfig.Generator)" -T "$($buildConfig.Toolset)" ..
$Configs = @("Release", "FastDebug")
@@ -146,11 +145,8 @@ if ($DeployBuild) {
}
}
7z a -xr'!*.pdb' "$($PackageName)-builds-$($buildConfig.PackageType).zip" "$env:APPVEYOR_BUILD_FOLDER/../install/*"
7z a "$($PackageName)-builds-$($buildConfig.PackageType).zip" "$env:APPVEYOR_BUILD_FOLDER/../install/*"
Push-AppveyorArtifact "$($PackageName)-builds-$($buildConfig.PackageType).zip"
7z a "$($PackageName)-debug-$($buildConfig.PackageType).7z" "$env:APPVEYOR_BUILD_FOLDER/../install/*.pdb"
Push-AppveyorArtifact "$($PackageName)-debug-$($buildConfig.PackageType).7z"
} else {
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="ON" -DFSO_BUILD_TESTS="ON" -DMSVC_SIMD_INSTRUCTIONS=SSE2 `
-DFSO_BUILD_QTFRED=ON -DQT5_INSTALL_ROOT="$env:QT_DIR" -DFSO_BUILD_FRED2="ON" `
+2 -8
View File
@@ -3,14 +3,8 @@
set -ex
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
export DEBIAN_FRONTEND=noninteractive
sudo add-apt-repository -y "ppa:msulikowski/valgrind" # For fixing a bug with valgrind 3.11 which does not recognize the rdrand instruction
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo add-apt-repository -y 'deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
sudo apt-get -yq update
# Nothing to do here
:
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
# Nothing to do here
:
+4
View File
@@ -18,6 +18,10 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
if [[ "$CC" =~ ^clang.*$ ]]; then
CXXFLAGS="$CXXFLAGS -stdlib=libc++"
fi
export CXXFLAGS
export CFLAGS
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON $CMAKE_OPTIONS"
+99 -226
View File
@@ -2,9 +2,10 @@
#
#===- clang-tidy-diff.py - ClangTidy Diff Checker ------------*- python -*--===#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
@@ -24,245 +25,117 @@ Example usage for git/svn users:
"""
import argparse
import glob
import json
import multiprocessing
import os
import re
import shutil
import subprocess
import sys
import tempfile
import threading
import traceback
try:
import yaml
except ImportError:
yaml = None
is_py2 = sys.version[0] == '2'
if is_py2:
import Queue as queue
else:
import queue as queue
def run_tidy(task_queue, lock, timeout):
watchdog = None
while True:
command = task_queue.get()
try:
proc = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if timeout is not None:
watchdog = threading.Timer(timeout, proc.kill)
watchdog.start()
stdout, stderr = proc.communicate()
with lock:
sys.stdout.write(stdout.decode('utf-8'))
sys.stdout.flush()
if stderr:
sys.stderr.write(stderr.decode('utf-8'))
sys.stderr.flush()
except Exception as e:
with lock:
sys.stderr.write('Failed: ' + str(e) + ': '.join(command) + '\n')
finally:
with lock:
if (not timeout is None) and (not watchdog is None):
if not watchdog.is_alive():
sys.stderr.write('Terminated by timeout: ' +
' '.join(command) + '\n')
watchdog.cancel()
task_queue.task_done()
def start_workers(max_tasks, tidy_caller, task_queue, lock, timeout):
for _ in range(max_tasks):
t = threading.Thread(target=tidy_caller, args=(task_queue, lock, timeout))
t.daemon = True
t.start()
def merge_replacement_files(tmpdir, mergefile):
"""Merge all replacement files in a directory into a single file"""
# The fixes suggested by clang-tidy >= 4.0.0 are given under
# the top level key 'Diagnostics' in the output yaml files
mergekey = "Diagnostics"
merged = []
for replacefile in glob.iglob(os.path.join(tmpdir, '*.yaml')):
content = yaml.safe_load(open(replacefile, 'r'))
if not content:
continue # Skip empty files.
merged.extend(content.get(mergekey, []))
if merged:
# MainSourceFile: The key is required by the definition inside
# include/clang/Tooling/ReplacementsYaml.h, but the value
# is actually never used inside clang-apply-replacements,
# so we set it to '' here.
output = { 'MainSourceFile': '', mergekey: merged }
with open(mergefile, 'w') as out:
yaml.safe_dump(output, out)
else:
# Empty the file:
open(mergefile, 'w').close()
def main():
parser = argparse.ArgumentParser(description=
'Run clang-tidy against changed files, and '
'output diagnostics only for modified '
'lines.')
parser.add_argument('-clang-tidy-binary', metavar='PATH',
default='clang-tidy',
help='path to clang-tidy binary')
parser.add_argument('-p', metavar='NUM', default=0,
help='strip the smallest prefix containing P slashes')
parser.add_argument('-regex', metavar='PATTERN', default=None,
help='custom pattern selecting file paths to check '
'(case sensitive, overrides -iregex)')
parser.add_argument('-iregex', metavar='PATTERN', default=
r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc)',
help='custom pattern selecting file paths to check '
'(case insensitive, overridden by -regex)')
parser.add_argument('-j', type=int, default=1,
help='number of tidy instances to be run in parallel.')
parser.add_argument('-timeout', type=int, default=None,
help='timeout per each file in seconds.')
parser.add_argument('-fix', action='store_true', default=False,
help='apply suggested fixes')
parser.add_argument('-checks',
help='checks filter, when not specified, use clang-tidy '
'default',
default='')
parser.add_argument('-path', dest='build_path',
help='Path used to read a compile command database.')
if yaml:
parser.add_argument('-export-fixes', metavar='FILE', dest='export_fixes',
help='Create a yaml file to store suggested fixes in, '
'which can be applied with clang-apply-replacements.')
parser.add_argument('-extra-arg', dest='extra_arg',
action='append', default=[],
help='Additional argument to append to the compiler '
'command line.')
parser.add_argument('-extra-arg-before', dest='extra_arg_before',
action='append', default=[],
help='Additional argument to prepend to the compiler '
'command line.')
parser.add_argument('-quiet', action='store_true', default=False,
help='Run clang-tidy in quiet mode')
clang_tidy_args = []
argv = sys.argv[1:]
if '--' in argv:
clang_tidy_args.extend(argv[argv.index('--'):])
argv = argv[:argv.index('--')]
parser = argparse.ArgumentParser(description=
'Run clang-tidy against changed files, and '
'output diagnostics only for modified '
'lines.')
parser.add_argument('-clang-tidy-binary', metavar='PATH',
default='clang-tidy',
help='path to clang-tidy binary')
parser.add_argument('-p', metavar='NUM', default=0,
help='strip the smallest prefix containing P slashes')
parser.add_argument('-regex', metavar='PATTERN', default=None,
help='custom pattern selecting file paths to check '
'(case sensitive, overrides -iregex)')
parser.add_argument('-iregex', metavar='PATTERN', default=
r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc)',
help='custom pattern selecting file paths to check '
'(case insensitive, overridden by -regex)')
args = parser.parse_args(argv)
parser.add_argument('-fix', action='store_true', default=False,
help='apply suggested fixes')
parser.add_argument('-checks',
help='checks filter, when not specified, use clang-tidy '
'default',
default='')
parser.add_argument('-path', dest='build_path',
help='Path used to read a compile command database.')
parser.add_argument('-extra-arg', dest='extra_arg',
action='append', default=[],
help='Additional argument to append to the compiler '
'command line.')
parser.add_argument('-extra-arg-before', dest='extra_arg_before',
action='append', default=[],
help='Additional argument to prepend to the compiler '
'command line.')
parser.add_argument('-quiet', action='store_true', default=False,
help='Run clang-tidy in quiet mode')
clang_tidy_args = []
argv = sys.argv[1:]
if '--' in argv:
clang_tidy_args.extend(argv[argv.index('--'):])
argv = argv[:argv.index('--')]
# Extract changed lines for each file.
filename = None
lines_by_file = {}
for line in sys.stdin:
match = re.search('^\+\+\+\ \"?(.*?/){%s}([^ \t\n\"]*)' % args.p, line)
if match:
filename = match.group(2)
if filename is None:
continue
args = parser.parse_args(argv)
if args.regex is not None:
if not re.match('^%s$' % args.regex, filename):
continue
else:
if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
continue
# Extract changed lines for each file.
filename = None
lines_by_file = {}
for line in sys.stdin:
match = re.search('^\+\+\+\ \"?(.*?/){%s}([^ \t\n\"]*)' % args.p, line)
if match:
filename = match.group(2)
if filename == None:
continue
match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
if match:
start_line = int(match.group(1))
line_count = 1
if match.group(3):
line_count = int(match.group(3))
if line_count == 0:
continue
end_line = start_line + line_count - 1
lines_by_file.setdefault(filename, []).append([start_line, end_line])
if args.regex is not None:
if not re.match('^%s$' % args.regex, filename):
continue
else:
if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
continue
if not any(lines_by_file):
print("No relevant changes found.")
sys.exit(0)
match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
if match:
start_line = int(match.group(1))
line_count = 1
if match.group(3):
line_count = int(match.group(3))
if line_count == 0:
continue
end_line = start_line + line_count - 1;
lines_by_file.setdefault(filename, []).append([start_line, end_line])
max_task_count = args.j
if max_task_count == 0:
max_task_count = multiprocessing.cpu_count()
max_task_count = min(len(lines_by_file), max_task_count)
if len(lines_by_file) == 0:
print("No relevant changes found.")
sys.exit(0)
tmpdir = None
if yaml and args.export_fixes:
tmpdir = tempfile.mkdtemp()
line_filter_json = json.dumps(
[{"name" : name, "lines" : lines_by_file[name]} for name in lines_by_file],
separators = (',', ':'))
# Tasks for clang-tidy.
task_queue = queue.Queue(max_task_count)
# A lock for console output.
lock = threading.Lock()
quote = "";
if sys.platform == 'win32':
line_filter_json=re.sub(r'"', r'"""', line_filter_json)
else:
quote = "'";
# Run a pool of clang-tidy workers.
start_workers(max_task_count, run_tidy, task_queue, lock, args.timeout)
# Form the common args list.
common_clang_tidy_args = []
if args.fix:
common_clang_tidy_args.append('-fix')
if args.checks != '':
common_clang_tidy_args.append('-checks=' + args.checks)
if args.quiet:
common_clang_tidy_args.append('-quiet')
if args.build_path is not None:
common_clang_tidy_args.append('-p=%s' % args.build_path)
for arg in args.extra_arg:
common_clang_tidy_args.append('-extra-arg=%s' % arg)
for arg in args.extra_arg_before:
common_clang_tidy_args.append('-extra-arg-before=%s' % arg)
for name in lines_by_file:
line_filter_json = json.dumps(
[{"name": name, "lines": lines_by_file[name]}],
separators=(',', ':'))
# Run clang-tidy on files containing changes.
command = [args.clang_tidy_binary]
command.append('-line-filter=' + line_filter_json)
if yaml and args.export_fixes:
# Get a temporary file. We immediately close the handle so clang-tidy can
# overwrite it.
(handle, tmp_name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir)
os.close(handle)
command.append('-export-fixes=' + tmp_name)
command.extend(common_clang_tidy_args)
command.append(name)
command.extend(clang_tidy_args)
task_queue.put(command)
# Wait for all threads to be done.
task_queue.join()
if yaml and args.export_fixes:
print('Writing fixes to ' + args.export_fixes + ' ...')
try:
merge_replacement_files(tmpdir, args.export_fixes)
except:
sys.stderr.write('Error exporting fixes.\n')
traceback.print_exc()
if tmpdir:
shutil.rmtree(tmpdir)
# Run clang-tidy on files containing changes.
command = [args.clang_tidy_binary]
command.append('-line-filter=' + quote + line_filter_json + quote)
if args.fix:
command.append('-fix')
if args.checks != '':
command.append('-checks=' + quote + args.checks + quote)
if args.quiet:
command.append('-quiet')
if args.build_path is not None:
command.append('-p=%s' % args.build_path)
command.extend(lines_by_file.keys())
for arg in args.extra_arg:
command.append('-extra-arg=%s' % arg)
for arg in args.extra_arg_before:
command.append('-extra-arg-before=%s' % arg)
command.extend(clang_tidy_args)
sys.exit(subprocess.call(' '.join(command), shell=True))
if __name__ == '__main__':
main()
main()
+2 -2
View File
@@ -12,8 +12,8 @@ cd "$TRAVIS_BUILD_DIR"
echo "Running clang-tidy on changed files"
git diff -U0 --no-color $TRAVIS_COMMIT_RANGE | \
$TRAVIS_BUILD_DIR/ci/travis/clang-tidy-diff.py -path "$TRAVIS_BUILD_DIR/build" -p1 \
-regex '(code|freespace2|qtfred|testsrc|build|tools)\/.*\.(cpp|h)' \
-clang-tidy-binary /usr/bin/clang-tidy-9 -j$(nproc) -quiet 2>/dev/null | \
-regex 'code/.*$|freespace2/.*$|qtfred/.*$|test/src/.*$|build/.*$|tools/.*' \
-clang-tidy-binary /usr/bin/clang-tidy-4.0 2>/dev/null | \
tee clang-tidy-output.txt
if [[ -n $(grep "warning: " clang-tidy-output.txt) ]] || [[ -n $(grep "error: " clang-tidy-output.txt) ]]; then
+18 -53
View File
@@ -10,62 +10,27 @@ if [[ ! "$(curl -V)" == *"sftp"* ]]; then
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ -f ~/curl_cache/curl*.deb ]; then
cd ~/curl_cache
sudo dpkg -i libcurl3*.deb
sudo dpkg -i curl*.deb
else
# Since the Travis CI people are not capable of enabling SSH/SCP support for their libcurl we need to build that manually...
# These commands are based on the tutorial from here: http://zeroset.mnim.org/2013/03/14/sftp-support-for-curl-in-ubuntu-12-10-quantal-quetzal-and-later/
mkdir /tmp/curl
cd /tmp/curl
sudo apt-get update
sudo apt-get install build-essential debhelper libssh2-1-dev libgnutls-dev libidn11-dev libkrb5-dev libldap2-dev libnss3-dev librtmp-dev libtool openssh-server quilt
apt-get source curl
sudo apt-get build-dep curl
# Since the Travis CI people are not capable of enabling SSH/SCP support for their libcurl we need to build that manually...
# These commands are based on the tutorial from here: http://zeroset.mnim.org/2013/03/14/sftp-support-for-curl-in-ubuntu-12-10-quantal-quetzal-and-later/
mkdir /tmp/curl
cd /tmp/curl
sudo apt-get update
sudo apt-get install build-essential debhelper libssh2-1-dev libgnutls-dev libidn11-dev libkrb5-dev libldap2-dev libnss3-dev librtmp-dev libtool openssh-server quilt
apt-get source curl
sudo apt-get build-dep curl
cd curl-*
export DEB_BUILD_OPTIONS="nocheck"
sudo dpkg-buildpackage -uc -us -j"$(grep -c ^processor /proc/cpuinfo)"
cd curl-*
export DEB_BUILD_OPTIONS="nocheck"
sudo dpkg-buildpackage -uc -us -j"$(grep -c ^processor /proc/cpuinfo)"
cd ..
dpkg -l | grep curl
ls -al
if [ ! -d ~/curl_cache ]; then
mkdir ~/curl_cache
fi
cp libcurl3*.deb curl*.deb ~/curl_cache
sudo dpkg -i libcurl3*.deb
sudo dpkg -i curl*.deb
fi
cd ..
dpkg -l | grep curl
ls -al
sudo dpkg -i libcurl3*.deb
sudo dpkg -i curl*.deb
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
brew install libssh2
if [ -d ~/curl_cache/curl ]; then
cd ~/curl_cache/curl
sudo make install
else
mkdir /tmp/curl
cd /tmp/curl
curl -LO "https://curl.haxx.se/download/curl-7.64.0.tar.bz2"
tar -xjf curl-7.64.0.tar.bz2
cd curl-7.64.0
./configure --disable-debug --disable-dependency-tracking --disable-silent-rules --with-libssh2 --with-darwinssl --without-ca-bundle --without-ca-path
make -j"$(sysctl hw.logicalcpu | cut -d " " -f 2)"
if [ ! -d ~/curl_cache ]; then
mkdir ~/curl_cache
fi
cp -a . ~/curl_cache/curl
sudo make install
fi
export PATH=/usr/local/bin:$PATH
brew install curl --with-libssh2
export PATH="/usr/local/opt/curl/bin:$PATH"
fi
# After
+2 -15
View File
@@ -1,11 +1,9 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
set -ex
FILENAME=
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
export DEBIAN_FRONTEND=noninteractive
if [ ! -d "$HOME/cmake-3.8/bin" ]; then
# If the cache does not currently contain CMake then download and install it
mkdir -p $HOME/cmake-3.8/
@@ -13,7 +11,7 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
wget -O /tmp/cmake.tar.gz --no-check-certificate https://cmake.org/files/v3.8/cmake-3.8.2-Linux-x86_64.tar.gz
tar -xzf /tmp/cmake.tar.gz -C $HOME/cmake-3.8/ --strip-components=1
fi
export PATH=$HOME/cmake-3.8/bin:$PATH
export PATH=$HOME/cmake-3.8/bin:$PATH
cd $HOME
@@ -24,17 +22,6 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
wget -O linuxdeployqt -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" # (64-bit)
chmod a+x ./linuxdeployqt
fi
sudo apt-get -yq install valgrind
if [[ "$CC" = "clang-9" ]]; then
sudo apt-get -yq install clang-9 clang-tidy-9
fi
if [[ "$CC" = "clang-4.0" ]]; then
# Fix a header bug present in ubuntu...
sudo ln -s /usr/include/libcxxabi/__cxxabi_config.h /usr/include/c++/v1/__cxxabi_config.h
fi
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
gem install xcpretty
+1
View File
@@ -7,6 +7,7 @@ cd build
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
ninja -k 20 all
if [ "$CONFIGURATION" = "Debug" ]; then
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
--suppressions="$TRAVIS_BUILD_DIR/ci/travis/valgrind.supp" ./bin/unittests --gtest_shuffle
-121
View File
@@ -41,124 +41,3 @@
fun:_Z29cf_create_default_path_stringPcjiPKcbj
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
obj:*
obj:*
obj:*
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
fun:_Z7gr_initOSt10unique_ptrIN2os18GraphicsOperationsESt14default_deleteIS1_EEiiii
fun:_ZN4test13FSTestFixture5SetUpEv
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
fun:_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
fun:_ZN7testing4Test3RunEv
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
obj:*
obj:*
obj:*
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
fun:_Z7gr_initOSt10unique_ptrIN2os18GraphicsOperationsESt14default_deleteIS1_EEiiii
fun:_ZN4test13FSTestFixture5SetUpEv
fun:_ZN8FontTest5SetUpEv
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
fun:_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:_Znwm
obj:*
obj:*
obj:*
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
fun:_Z7gr_initONSt3__110unique_ptrIN2os18GraphicsOperationsENS_14default_deleteIS2_EEEEiiii
fun:_ZN4test13FSTestFixture5SetUpEv
fun:_ZN8FontTest5SetUpEv
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:_Znwm
obj:*
obj:*
obj:*
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
fun:_Z7gr_initONSt3__110unique_ptrIN2os18GraphicsOperationsENS_14default_deleteIS2_EEEEiiii
fun:_ZN4test13FSTestFixture5SetUpEv
fun:_ZN8FontTest5SetUpEv
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:_Znwm
obj:*
obj:*
obj:*
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
fun:_Z7gr_initONSt3__110unique_ptrIN2os18GraphicsOperationsENS_14default_deleteIS2_EEEEiiii
fun:_ZN4test13FSTestFixture5SetUpEv
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
fun:_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
}
{
<insert_a_suppression_name_here>
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:*
obj:*
fun:call_init.part.0
fun:call_init
fun:_dl_init
fun:dl_open_worker
}
{
<insert_a_suppression_name_here>
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:*
obj:*
fun:call_init.part.0
fun:call_init
fun:_dl_init
fun:dl_open_worker
}
+1 -1
View File
@@ -3,7 +3,7 @@ INCLUDE(util)
MESSAGE(STATUS "Configuring UNIX specific things and stuff...")
target_compile_definitions(platform INTERFACE SCP_UNIX USE_OPENAL _REENTRANT)
target_compile_definitions(platform INTERFACE SCP_UNIX USE_OPENAL)
# Set RPATH
set(CMAKE_SKIP_BUILD_RPATH TRUE)
+1 -1
View File
@@ -8,7 +8,7 @@ SET(WIN32_LIBS
odbccp32
vfw32
winmm
ws2_32
wsock32
psapi
)
+10 -10
View File
@@ -10,8 +10,8 @@ include(CheckSymbolExists)
include(CheckCXXSymbolExists)
include(CheckTypeSize)
CHECK_INCLUDE_FILE("execinfo.h" SCP_HAVE_EXECINFO_H)
CHECK_INCLUDE_FILE_CXX("cxxabi.h" SCP_HAVE_CXXAPI_H)
CHECK_INCLUDE_FILE("execinfo.h" HAVE_EXECINFO_H)
CHECK_INCLUDE_FILE_CXX("cxxabi.h" HAVE_CXXAPI_H)
CHECK_TYPE_SIZE("max_align_t" MAX_ALIGN_T)
@@ -31,18 +31,18 @@ CHECK_TYPE_SIZE("U'b'" UNICODE_CHAR_LITERAL LANGUAGE CXX)
set(CMAKE_REQUIRED_FLAGS)
CHECK_FUNCTION_EXISTS(strcasecmp SCP_HAVE_STRCASECMP)
CHECK_FUNCTION_EXISTS(strncasecmp SCP_HAVE_STRNCASECMP)
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
CHECK_FUNCTION_EXISTS(strncasecmp HAVE_STRNCASECMP)
CHECK_FUNCTION_EXISTS(_stricmp SCP_HAVE__STRICMP)
CHECK_FUNCTION_EXISTS(_strnicmp SCP_HAVE__STRNICMP)
CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP)
CHECK_FUNCTION_EXISTS(_strnicmp HAVE__STRNICMP)
CHECK_FUNCTION_EXISTS(strlwr SCP_HAVE_STRLWR)
CHECK_FUNCTION_EXISTS(strlwr HAVE_STRLWR)
CHECK_INCLUDE_FILE("strings.h" SCP_HAVE_STRINGS_H)
CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H)
check_symbol_exists(snprintf "stdio.h" SCP_HAVE_SNPRINTF)
check_symbol_exists(_snprintf "stdio.h" SCP_HAVE__SNPRINTF)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF)
set(PLATFORM_CHECK_HEADER "${GENERATED_SOURCE_DIR}/platformChecks.h")
CONFIGURE_FILE(${CMAKE_CURRENT_LIST_DIR}/platformChecks.h.in "${PLATFORM_CHECK_HEADER}")
+14 -14
View File
@@ -3,29 +3,29 @@
#define __PLATFORM_CHECKS_H__
#pragma once
#cmakedefine SCP_HAVE_EXECINFO_H
#cmakedefine SCP_HAVE_CXXAPI_H
#cmakedefine SCP_HAVE_MAX_ALIGN_T
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
#cmakedefine HAVE_EXECINFO_H
#cmakedefine HAVE_CXXAPI_H
#cmakedefine HAVE_MAX_ALIGN_T
#cmakedefine HAVE_STD_MAX_ALIGN_T
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE
#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
#cmakedefine01 IS_64BIT
#cmakedefine01 SCP_HAVE_STRCASECMP
#cmakedefine01 SCP_HAVE_STRNCASECMP
#cmakedefine01 SCP_HAVE__STRICMP
#cmakedefine01 SCP_HAVE__STRNICMP
#cmakedefine01 HAVE_STRCASECMP
#cmakedefine01 HAVE_STRNCASECMP
#cmakedefine01 HAVE__STRICMP
#cmakedefine01 HAVE__STRNICMP
#cmakedefine01 SCP_HAVE_STRLWR
#cmakedefine01 HAVE_STRLWR
#cmakedefine01 SCP_HAVE_STRINGS_H
#cmakedefine01 HAVE_STRINGS_H
#cmakedefine01 HAVE_CHAR32_T
#cmakedefine01 HAVE_UNICODE_CHAR_LITERAL
#cmakedefine01 SCP_HAVE_SNPRINTF
#cmakedefine01 SCP_HAVE__SNPRINTF
#cmakedefine01 HAVE_SNPRINTF
#cmakedefine01 HAVE__SNPRINTF
#endif // __PLATFORM_CHECKS_H__
-10
View File
@@ -7,8 +7,6 @@ MESSAGE(STATUS "Doing configuration specific to clang...")
option(CLANG_ENABLE_LEAK_CHECK "Enable -fsanitize=leak" OFF)
option(CLANG_ENABLE_ADDRESS_SANITIZER "Enable -fsanitize=address" OFF)
option(CLANG_USE_LIBCXX "Use libc++" OFF)
# These are the default values
set(C_BASE_FLAGS "-march=native -pipe")
set(CXX_BASE_FLAGS "-march=native -pipe")
@@ -21,10 +19,6 @@ if(DEFINED ENV{CFLAGS})
set(C_BASE_FLAGS $ENV{CFLAGS})
endif()
if (CLANG_USE_LIBCXX)
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} -stdlib=libc++")
endif()
# Initialize with an empty string to make sure we always get a clean start
set(COMPILER_FLAGS "")
@@ -99,10 +93,6 @@ set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
set(CMAKE_EXE_LINKER_FLAGS "")
if (CLANG_USE_LIBCXX)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lc++abi")
endif()
if (SANITIZE_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZE_FLAGS}")
endif()
+7 -7
View File
@@ -37,23 +37,21 @@ set(WARNING_FLAGS
$<$<CONFIG:Release>:/wd4101> # In release mode there are unreferenced variables because debug needs them
/wd4995 # "'vsprintf': name was marked as #pragma deprecated" is being caused by our custom definition of vsprintf. I have no idea what causes this or how to fix it - m!m
/wd4723 # "potential divide by 0" is caused by some code that definitely will not divide by zero - m!m
/wd4121 # "alignment of a member was sensitive to packing" happens in a Windows header - m!m
)
target_compile_options(compiler INTERFACE ${WARNING_FLAGS})
# Base
set(CMAKE_C_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /Zc:forScope /Gd /EHsc /nologo /Zm200")
set(CMAKE_CXX_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /Zc:forScope /Gd /EHsc /nologo /Zm200")
set(CMAKE_C_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo /Zm200")
set(CMAKE_CXX_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo /Zm200")
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 /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
set(CMAKE_CXX_FLAGS_RELEASE "/GL /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
# /DEBUG:FULL so that we get PDBs which is needed for debugging crashdumps
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/OPT:REF /LTCG /INCREMENTAL:NO /DEBUG:FULL")
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()
@@ -65,6 +63,8 @@ if (MSVC_RELEASE_DEBUGGING)
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)
-2
View File
@@ -41,8 +41,6 @@ target_link_libraries(code PUBLIC discord-rpc)
target_link_libraries(code PUBLIC libRocket)
target_link_libraries(code PUBLIC pcp)
enable_clang_tidy(code)
IF (FSO_USE_SPEECH)
+4 -9
View File
@@ -51,19 +51,14 @@ namespace AI {
};
FLAG_LIST(Maneuver_Override_Flags) {
Full_rot, // full sexp control over pitch/bank/heading rotation
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, // Sexp forced vertical movement
Sideways, // Sexp forced horizontal movement
Forward, // Sexp forced forward movement
Dont_bank_when_turning, // maps to CIF_DONT_BANK_WHEN_TURNING
Dont_clamp_max_velocity, // maps to CIF_DONT_CLAMP_MAX_VELOCITY
Instantaneous_acceleration, // maps to CIF_INSTANTANEOUS_ACCELERATION
Never_expire, // don't clear the maneuver when the timestamp is up
Up, // vertical movement
Sideways, // horizontal movement
Forward, // forward movement
NUM_VALUES
};
+4
View File
@@ -517,6 +517,10 @@ void parse_ai_profiles_tbl(const char *filename)
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : "<default ai_profiles.tbl>", e.what()));
return;
}
// add tbl/tbm to multiplayer validation list
extern void fs2netd_add_table_validation(const char *tblname);
fs2netd_add_table_validation(filename);
}
void ai_profiles_init()
+75 -113
View File
@@ -58,9 +58,6 @@
#include "physics/physics.h"
#include "playerman/player.h"
#include "render/3d.h"
#include "scripting/api/objs/waypoint.h"
#include "scripting/api/objs/wing.h"
#include "scripting/scripting.h"
#include "ship/afterburner.h"
#include "ship/awacs.h"
#include "ship/ship.h"
@@ -1315,9 +1312,7 @@ ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int pare
}
if ( aip == Player_ai ) {
if (aip->last_subsys_target != aip->targeted_subsys) {
hud_lock_reset(0.5f);
}
hud_lock_reset(0.5f);
}
} else {
@@ -1350,7 +1345,6 @@ void ai_object_init(object * obj, int ai_index)
aip->wing = -1; // Member of what wing? -1 means none.
aip->ai_class = Ship_info[Ships[obj->instance].ship_info_index].ai_class;
aip->behavior = AIM_NONE;
aip->mode = aip->behavior;
}
/**
@@ -4592,12 +4586,6 @@ void ai_waypoints()
ai_mission_wing_goal_complete( Ships[Pl_objp->instance].wingnum, &(aip->goals[aip->active_goal]) );
mission_log_add_entry( LOG_WAYPOINTS_DONE, Wings[Ships[Pl_objp->instance].wingnum].name, aip->wp_list->get_name(), -1 );
}
// adds scripting hook for 'On Waypoints Done' --wookieejedi
Script_system.SetHookObject("Ship", &Objects[Ships[Pl_objp->instance].objnum]);
Script_system.SetHookVar("Wing", 'o', scripting::api::l_Wing.Set(Ships[Pl_objp->instance].wingnum));
Script_system.SetHookVar("Waypointlist", 'o', scripting::api::l_WaypointList.Set(scripting::api::waypointlist_h(aip->wp_list)));
Script_system.RunCondition(CHA_ONWAYPOINTSDONE);
Script_system.RemHookVars(3, "Ship", "Wing", "Waypointlist");
}
}
}
@@ -5322,7 +5310,9 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
{
if (swp->current_primary_bank >= 0)
{
int bank_index = swp->current_primary_bank;
int bank_index;
bank_index = swp->current_primary_bank;
if (Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Puncture])
{
@@ -5331,9 +5321,11 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
}
for (int i=0; i<swp->num_primary_banks; i++)
{
int weapon_info_index = swp->primary_bank_weapons[i];
int weapon_info_index;
if (weapon_info_index >= 0)
weapon_info_index = swp->primary_bank_weapons[i];
if (weapon_info_index > -1)
{
if (Weapon_info[weapon_info_index].wi_flags[Weapon::Info_Flags::Puncture])
{
@@ -5344,51 +5336,44 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
}
}
auto other_is_ship = (other_objp->type == OBJ_SHIP);
float enemy_remaining_shield = get_shield_pct(other_objp);
if ( other_is_ship && (Ship_info[Ships[other_objp->instance].ship_info_index].is_big_or_huge() ) )
if ( (other_objp->type == OBJ_SHIP) && (Ship_info[Ships[other_objp->instance].ship_info_index].is_big_or_huge() ) )
{
//Check if we have a capital+ weapon on board
for (int i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if (wip->wi_flags[Weapon::Info_Flags::Capital_plus])
if (Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus])
{
// handle shielded big/huge ships (non FS-verse)
// only pick capital+ if the target has no shields; or the weapon is an ok shield-breaker anyway
if (enemy_remaining_shield <= 0.05f || (wip->shield_factor * 1.33f > wip->armor_factor))
{
swp->current_primary_bank = i;
nprintf(("AI", "%i: Ship %s selecting weapon %s (capital+) vs target %s\n", Framecount, Ships[objp->instance].ship_name, wip->name, Ships[other_objp->instance].ship_name));
return i;
}
swp->current_primary_bank = i;
nprintf(("AI", "%i: Ship %s selecting weapon %s\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[i]].name));
return i;
}
}
}
}
float enemy_remaining_shield = get_shield_pct(other_objp);
// Is the target shielded by say only 5%?
if (enemy_remaining_shield <= 0.05f)
{
// Then it is safe to start using a heavy hull damage weapon such as the maxim
int i;
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
// Find the weapon with the highest hull * damage / fire delay factor
for (int i = 0; i < swp->num_primary_banks; i++)
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if ((((wip->armor_factor) * (wip->damage)) / wip->fire_wait) > i_hullfactor_prev)
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((wip->armor_factor) * (wip->damage)) / wip->fire_wait );
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
}
}
@@ -5399,7 +5384,6 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
i_hullfactor_prev_bank = 0; // Just switch to the first one
}
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (no shields) vs target %s\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_hullfactor_prev_bank]].name, (other_is_ship ? Ships[other_objp->instance].ship_name : "non-ship") ));
return i_hullfactor_prev_bank; // Return
}
@@ -5408,23 +5392,26 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
{
if (swp->current_primary_bank >= 0)
{
auto wip = &Weapon_info[swp->primary_bank_weapons[swp->current_primary_bank]];
int bank_index;
if ((wip->wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]))
bank_index = swp->current_primary_bank;
if ((Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Capital_plus]))
{
nprintf(("AI", "%i: Ship %s selecting weapon %s (>10%% shields)\n", Framecount, shipp->ship_name, wip->name));
return swp->current_primary_bank;
}
}
for (int i=0; i<swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0)
int weapon_info_index;
weapon_info_index = swp->primary_bank_weapons[i];
if (weapon_info_index > -1)
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if ((wip->wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]))
if ((Weapon_info[weapon_info_index].wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]))
{
swp->current_primary_bank = i;
nprintf(("AI", "%i: Ship %s selecting weapon %s (>10%% shields)\n", Framecount, shipp->ship_name, wip->name));
return i;
}
}
@@ -5434,63 +5421,61 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
// Is the target shielded by less then 50%?
if (enemy_remaining_shield <= 0.50f)
{
// Should be using best balanced shield/hull gun
float i_balancedfactor_prev = 0; // Previous weapon bank "balanced" factor (this is the safe way to do it)
int i_balancedfactor_prev_bank = -1; // Bank which gave us this "balanced" factor
// Should be using best balanced shield gun
int i;
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
// Find the weapon with the highest average hull and shield * damage / fire delay factor
for (int i = 0; i < swp->num_primary_banks; i++)
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if ((((wip->armor_factor + wip->shield_factor) * wip->damage) / wip->fire_wait) > i_balancedfactor_prev)
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
{
// This weapon is the new candidate
i_balancedfactor_prev = ((((wip->armor_factor + wip->shield_factor) * wip->damage) / wip->fire_wait));
i_balancedfactor_prev_bank = i;
i_hullfactor_prev = ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait));
i_hullfactor_prev_bank = i;
}
}
}
}
if (i_balancedfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
if (i_hullfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
{
i_balancedfactor_prev_bank = 0; // Just switch to the first one
i_hullfactor_prev_bank = 0; // Just switch to the first one
}
swp->current_primary_bank = i_balancedfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (<50%% shields)\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_balancedfactor_prev_bank]].name));
return i_balancedfactor_prev_bank; // Return
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
return i_hullfactor_prev_bank; // Return
}
else
{
// Should be using best shield destroying gun
float i_shieldfactor_prev = 0; // Previous weapon bank shield factor (this is the safe way to do it)
int i_shieldfactor_prev_bank = -1; // Bank which gave us this shield factor
int i;
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
// Find the weapon with the highest average hull and shield * damage / fire delay factor
for (int i = 0; i < swp->num_primary_banks; i++)
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if ((((wip->shield_factor) * wip->damage) / wip->fire_wait) > i_shieldfactor_prev)
if ((((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
{
// This weapon is the new candidate
i_shieldfactor_prev = ( ((wip->shield_factor) * (wip->damage)) / wip->fire_wait );
i_shieldfactor_prev_bank = i;
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
}
}
}
}
if (i_shieldfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
if (i_hullfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
{
i_shieldfactor_prev_bank = 0; // Just switch to the first one
i_hullfactor_prev_bank = 0; // Just switch to the first one
}
swp->current_primary_bank = i_shieldfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (>50%% shields)\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_shieldfactor_prev_bank]].name));
return i_shieldfactor_prev_bank; // Return
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
return i_hullfactor_prev_bank; // Return
}
}
@@ -5517,9 +5502,7 @@ void set_primary_weapon_linkage(object *objp)
// If trying to destroy a big ship (i.e., not disable/disarm), always unleash all weapons
if ( Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].is_big_ship() ) {
if ( aip->targeted_subsys == NULL ) {
if (!sip->flags[Ship::Info_Flags::No_primary_linking] ) {
shipp->flags.set(Ship::Ship_Flags::Primary_linked);
}
shipp->flags.set(Ship::Ship_Flags::Primary_linked);
shipp->flags.set(Ship::Ship_Flags::Secondary_dual_fire);
return;
}
@@ -14079,74 +14062,53 @@ void ai_frame(int objnum)
}
}
static void ai_control_info_check(ai_info *aip, physics_info *pi)
static void ai_control_info_check(ai_info *aip)
{
if (aip->ai_override_flags.none_set())
if(aip->ai_override_flags.none_set())
return;
if (!aip->ai_override_flags[AI::Maneuver_Override_Flags::Never_expire] && timestamp_elapsed(aip->ai_override_timestamp))
{
if(timestamp_elapsed(aip->ai_override_timestamp)) {
aip->ai_override_flags.reset();
}
else
{
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Full_rot])
} else {
if(aip->ai_override_flags[AI::Maneuver_Override_Flags::Full])
{
AI_ci.pitch = aip->ai_override_ci.pitch;
AI_ci.heading = aip->ai_override_ci.heading;
AI_ci.bank = aip->ai_override_ci.bank;
}
else
{
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Pitch])
} else {
if(aip->ai_override_flags[AI::Maneuver_Override_Flags::Pitch])
{
AI_ci.pitch = aip->ai_override_ci.pitch;
}
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Heading])
if(aip->ai_override_flags[AI::Maneuver_Override_Flags::Heading])
{
AI_ci.heading = aip->ai_override_ci.heading;
}
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Roll])
if(aip->ai_override_flags[AI::Maneuver_Override_Flags::Roll])
{
AI_ci.bank = aip->ai_override_ci.bank;
}
}
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Full_lat])
if(aip->ai_override_flags[AI::Maneuver_Override_Flags::Full_lat])
{
AI_ci.vertical = aip->ai_override_ci.vertical;
AI_ci.sideways = aip->ai_override_ci.sideways;
AI_ci.forward = aip->ai_override_ci.forward;
}
else
{
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Up])
} else {
if(aip->ai_override_flags[AI::Maneuver_Override_Flags::Up])
{
AI_ci.vertical = aip->ai_override_ci.vertical;
}
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Sideways])
if(aip->ai_override_flags[AI::Maneuver_Override_Flags::Sideways])
{
AI_ci.sideways = aip->ai_override_ci.sideways;
}
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Forward])
if(aip->ai_override_flags[AI::Maneuver_Override_Flags::Forward])
{
AI_ci.forward = aip->ai_override_ci.forward;
}
}
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Dont_bank_when_turning])
AI_ci.control_flags |= CIF_DONT_BANK_WHEN_TURNING;
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Dont_clamp_max_velocity])
AI_ci.control_flags |= CIF_DONT_CLAMP_MAX_VELOCITY;
if (aip->ai_override_flags[AI::Maneuver_Override_Flags::Instantaneous_acceleration])
AI_ci.control_flags |= CIF_INSTANTANEOUS_ACCELERATION;
}
// set physics flag according to whether we are instantaneously accelerating
if (AI_ci.control_flags & CIF_INSTANTANEOUS_ACCELERATION)
pi->flags |= PF_NO_DAMP;
else
pi->flags &= ~PF_NO_DAMP;
}
int Last_ai_obj = -1;
@@ -14201,7 +14163,7 @@ void ai_process( object * obj, int ai_index, float frametime )
if (rfc == 1) {
// Wanderer - sexp based override goes here - only if rfc is valid though
ai_control_info_check(aip, &obj->phys_info);
ai_control_info_check(aip);
vec3d copy_desired_rotvel = obj->phys_info.rotvel;
physics_read_flying_controls( &obj->orient, &obj->phys_info, &AI_ci, frametime);
// if obj is in formation and not flight leader, don't update rotvel
+4 -42
View File
@@ -21,7 +21,6 @@
#include "object/waypoint.h"
#include "parse/sexp.h"
#include "playerman/player.h"
#include "scripting/scripting.h"
#include "ship/ship.h"
#include "weapon/weapon.h"
@@ -269,12 +268,6 @@ void ai_clear_ship_goals( ai_info *aip )
{
ai_do_default_behavior( &Objects[Ships[aip->shipnum].objnum] );
}
// add scripting hook for 'On Goals Cleared' --wookieejedi
Script_system.SetHookObject("Ship", &Objects[Ships[aip->shipnum].objnum]);
Script_system.RunCondition(CHA_ONGOALSCLEARED);
Script_system.RemHookVars(1, "Ship");
}
void ai_clear_wing_goals( int wingnum )
@@ -740,12 +733,6 @@ void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, ch
aigp->target_signature = Objects[Weapons[submode].objnum].signature;
}
if ( mode == AI_GOAL_WAYPOINTS_ONCE || mode == AI_GOAL_WAYPOINTS ) {
// should be the same as setting via sexp, see ai_add_goal_sub_sexp
// set to null so the AI code can setup the new waypoint list, see ai_mission_goal_achievable
aigp->wp_list = nullptr;
}
if ( target_name != NULL )
aigp->target_name = ai_get_goal_target_name( target_name, &aigp->target_name_index );
else
@@ -1506,8 +1493,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
Assert ( aigp->ai_submode >= 0 );
ssp = ship_get_indexed_subsys( &Ships[sindex], aigp->ai_submode );
if (ssp != NULL) {
// see MWA 3/20/97 comment above - instead of checking the mission log, check the current hits
status = (ssp->current_hits <= 0.0f) ? 1 : 0;
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));
@@ -1517,36 +1503,12 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
}
case AI_GOAL_DISABLE_SHIP:
{
// shipnum could be -1 depending on if the ship hasn't arrived or died. only look for subsystem
// destroyed when shipnum is valid
sindex = ship_name_lookup(aigp->target_name);
// can't determine the status of this goal if ship not valid
if (sindex < 0) {
status = 0;
} else {
// see MWA 3/20/97 comment above - instead of checking the mission log, check the current hits
status = (Ships[sindex].subsys_info[SUBSYSTEM_ENGINE].aggregate_current_hits <= 0.0f) ? 1 : 0;
}
status = mission_log_get_time( LOG_SHIP_DISABLED, aigp->target_name, NULL, NULL );
break;
}
case AI_GOAL_DISARM_SHIP:
{
// shipnum could be -1 depending on if the ship hasn't arrived or died. only look for subsystem
// destroyed when shipnum is valid
sindex = ship_name_lookup(aigp->target_name);
// can't determine the status of this goal if ship not valid
if (sindex < 0) {
status = 0;
} else {
// see MWA 3/20/97 comment above - instead of checking the mission log, check the current hits
status = (Ships[sindex].subsys_info[SUBSYSTEM_TURRET].aggregate_current_hits <= 0.0f) ? 1 : 0;
}
status = mission_log_get_time( LOG_SHIP_DISARMED, aigp->target_name, NULL, NULL );
break;
}
// to guard or ignore a ship, the goal cannot continue if the ship being guarded is either destroyed
// or has departed.
@@ -1658,7 +1620,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
status = SHIP_STATUS_ARRIVED;
}
// goal ship is still on the arrival list
else if ( mission_check_ship_yet_to_arrive(aigp->target_name) )
else if ( mission_parse_get_arrival_ship(aigp->target_name) )
{
status = SHIP_STATUS_NOT_ARRIVED;
}
+6 -9
View File
@@ -856,11 +856,11 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
// flags for weapon types
if (beam_flag)
eeo.eeo_flags |= EEOF_BEAM;
if (flak_flag)
else if (flak_flag)
eeo.eeo_flags |= EEOF_FLAK;
if (laser_flag)
else if (laser_flag)
eeo.eeo_flags |= EEOF_LASER;
if (missile_flag)
else if (missile_flag)
eeo.eeo_flags |= EEOF_MISSILE;
eeo.enemy_team_mask = enemy_team_mask;
@@ -1678,12 +1678,7 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
wait *= wip->burst_delay;
turret->weapons.burst_counter[weapon_num]++;
} else {
// Random fire delay (DahBlount) used in ship_fire_primary(), added here by wookieejedi to correct oversight
if (wip->max_delay != 0.0f && wip->min_delay != 0.0f) {
wait *= frand_range(wip->min_delay, wip->max_delay);
} else {
wait *= wip->fire_wait;
}
wait *= wip->fire_wait;
if ((wip->burst_shots > 0) && (wip->burst_flags[Weapon::Burst_Flags::Random_length])) {
turret->weapons.burst_counter[weapon_num] = (myrand() % wip->burst_shots);
} else {
@@ -2731,6 +2726,8 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
if(!something_was_ok_to_fire)
{
mprintf(("nothing ok to fire\n"));
if (ss->turret_best_weapon >= 0) {
//Impose a penalty on turret accuracy for losing site of its goal, or just not being able to fire.
turret_update_enemy_in_range(ss, -4*Weapon_info[ss->turret_best_weapon].fire_wait);
+2
View File
@@ -1143,6 +1143,8 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
// SET PHYSICS PARAMETERS
// already have (hitpos - heavy) and light_cm_pos
// get heavy cm pos - already have light_cm_pos
asteroid_hit_info->heavy_collision_cm_pos = zero;
// get r_heavy and r_light
asteroid_hit_info->r_heavy = asteroid_hit_info->hit_pos;
+4 -1
View File
@@ -10,9 +10,12 @@
#define BMPMAN_NDEBUG
#endif
#define WIN32_LEAN_AND_MEAN
#define BMPMAN_INTERNAL
#ifdef _WIN32
#include <windows.h>
#endif
#include "anim/animplay.h"
#include "anim/packunpack.h"
#include "bmpman/bm_internal.h"
+1 -19
View File
@@ -7,10 +7,9 @@
#include "math/vecmat.h"
#include "mod_table/mod_table.h"
#include "model/model.h" //polymodel, model_get
#include "options/Option.h"
#include "parse/parselo.h"
#include "playerman/player.h" //player_get_padlock_orient
#include "ship/ship.h" //compute_slew_matrix
#include "ship/ship.h" //compute_slew_matrix
//*************************IMPORTANT GLOBALS*************************
float VIEWER_ZOOM_DEFAULT = 0.75f; // Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
@@ -25,23 +24,6 @@ SCP_vector<camera*> Cameras;
camid Current_camera;
camid Main_camera;
static SCP_string fov_display(float val)
{
auto degrees = fl_degrees(val);
SCP_string out;
sprintf(out, u8"%.1f\u00B0", degrees);
return out;
}
auto FovOption = options::OptionBuilder<float>("Graphics.FOV", "Field Of View", "The vertical field of view.")
.category("Graphics")
.range(0.436332f, 1.5708f)
.bind_to(&VIEWER_ZOOM_DEFAULT)
.display(fov_display)
.default_val(0.75f)
.level(options::ExpertLevel::Advanced)
.importance(60)
.finish();
//*************************CLASS: camera*************************
//This is where the camera class beings! :D
camera::camera(const char *in_name, int in_signature)
+195 -114
View File
@@ -101,7 +101,8 @@ static int Cfile_stack_pos = 0;
static char Cfile_stack[CFILE_STACK_MAX][CFILE_ROOT_DIRECTORY_LEN];
std::array<CFILE, MAX_CFILE_BLOCKS> Cfile_block_list;
Cfile_block Cfile_block_list[MAX_CFILE_BLOCKS];
static CFILE Cfile_list[MAX_CFILE_BLOCKS];
static const char *Cfile_cdrom_dir = NULL;
@@ -200,6 +201,7 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir)
strncpy(buf, exe_dir, CFILE_ROOT_DIRECTORY_LEN - 1);
buf[CFILE_ROOT_DIRECTORY_LEN - 1] = '\0';
size_t i = strlen(buf);
// are we in a root directory?
if(cfile_in_root_dir(buf)){
@@ -227,8 +229,9 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir)
strcpy_s(Cfile_root_dir, buf);
strcpy_s(Cfile_user_dir, os_get_config_path().c_str());
// Initialize the block list with proper data
Cfile_block_list.fill({});
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();
@@ -862,14 +865,14 @@ CFILE *ctmpfile()
static int cfget_cfile_block()
{
int i;
CFILE* cfile;
Cfile_block *cb;
for ( i = 0; i < MAX_CFILE_BLOCKS; i++ ) {
cfile = &Cfile_block_list[i];
if (cfile->type == CFILE_BLOCK_UNUSED) {
cfile->data = nullptr;
cfile->fp = nullptr;
cfile->type = CFILE_BLOCK_USED;
cb = &Cfile_block_list[i];
if ( cb->type == CFILE_BLOCK_UNUSED ) {
cb->data = NULL;
cb->fp = NULL;
cb->type = CFILE_BLOCK_USED;
return i;
}
}
@@ -897,36 +900,39 @@ int cfclose( CFILE * cfile )
int result;
Assert(cfile != NULL);
Cfile_block *cb;
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
cb = &Cfile_block_list[cfile->id];
result = 0;
if ( cfile->data && cfile->mem_mapped ) {
if ( cb->data && cb->mem_mapped ) {
// close memory mapped file
#if defined _WIN32
result = UnmapViewOfFile((void*)cfile->data);
result = UnmapViewOfFile((void*)cb->data);
Assert(result);
result = CloseHandle(cfile->hInFile);
result = CloseHandle(cb->hInFile);
Assert(result); // Ensure file handle is closed properly
result = CloseHandle(cfile->hMapFile);
result = CloseHandle(cb->hMapFile);
Assert(result); // Ensure file handle is closed properly
result = 0;
#elif defined SCP_UNIX
// FIXME: result is wrong after munmap() but it is successful
//result = munmap(cfile->data, cfile->data_length);
//result = munmap(cb->data, cb->data_length);
//Assert(result);
// This const_cast is safe since the pointer returned by mmap was also non-const
munmap(const_cast<void*>(cfile->data), cfile->data_length);
if ( cfile->fp != nullptr)
result = fclose(cfile->fp);
munmap(const_cast<void*>(cb->data), cb->data_length);
if ( cb->fp != NULL)
result = fclose(cb->fp);
#endif
} else if ( cfile->fp != nullptr ) {
Assert(cfile->fp != nullptr);
result = fclose(cfile->fp);
} else if ( cb->fp != NULL ) {
Assert(cb->fp != NULL);
result = fclose(cb->fp);
} else {
// VP do nothing
}
cfile->type = CFILE_BLOCK_UNUSED;
cb->type = CFILE_BLOCK_UNUSED;
return result;
}
@@ -936,8 +942,13 @@ int cf_is_valid(CFILE *cfile)
if(cfile == NULL)
return 0;
//Does it have a valid ID?
if(cfile->id < 0 || cfile->id >= MAX_CFILE_BLOCKS)
return 0;
//Is it used?
if (cfile->type != CFILE_BLOCK_USED && (cfile->fp != nullptr || cfile->data != nullptr))
Cfile_block *cb = &Cfile_block_list[cfile->id];
if(cb->type != CFILE_BLOCK_USED && (cb->fp != NULL || cb->data != NULL))
return 0;
//It's good, as near as we can tell.
@@ -962,15 +973,20 @@ static CFILE *cf_open_fill_cfblock(const char* source, int line, FILE *fp, int t
fclose(fp);
return NULL;
} else {
CFILE *cfp = &Cfile_block_list[cfile_block_index];
cfp->data = nullptr;
cfp->mem_mapped = false;
cfp->fp = fp;
cfp->dir_type = type;
cfp->max_read_len = 0;
CFILE *cfp;
Cfile_block *cfbp;
cfbp = &Cfile_block_list[cfile_block_index];
cfp = &Cfile_list[cfile_block_index];
cfp->id = cfile_block_index;
cfp->version = 0;
cfbp->data = NULL;
cfbp->mem_mapped = false;
cfbp->fp = fp;
cfbp->dir_type = type;
cfbp->max_read_len = 0;
cfp->source_file = source;
cfp->line_num = line;
cfbp->source_file = source;
cfbp->line_num = line;
int pos = ftell(fp);
if(pos == -1L)
@@ -998,16 +1014,21 @@ static CFILE *cf_open_packed_cfblock(const char* source, int line, FILE *fp, int
fclose(fp);
return NULL;
} else {
CFILE *cfp = &Cfile_block_list[cfile_block_index];
CFILE *cfp;
Cfile_block *cfbp;
cfbp = &Cfile_block_list[cfile_block_index];
cfp = &Cfile_list[cfile_block_index];
cfp->id = cfile_block_index;
cfp->version = 0;
cfbp->data = NULL;
cfbp->fp = fp;
cfbp->mem_mapped = false;
cfbp->dir_type = type;
cfbp->max_read_len = 0;
cfp->data = nullptr;
cfp->fp = fp;
cfp->mem_mapped = false;
cfp->dir_type = type;
cfp->max_read_len = 0;
cfp->source_file = source;
cfp->line_num = line;
cfbp->source_file = source;
cfbp->line_num = line;
cf_init_lowlevel_read_code(cfp,offset, size, 0 );
@@ -1039,39 +1060,44 @@ static CFILE *cf_open_mapped_fill_cfblock(const char* source, int line, FILE *fp
return NULL;
}
else {
CFILE *cfp = &Cfile_block_list[cfile_block_index];
CFILE *cfp;
Cfile_block *cfbp;
cfbp = &Cfile_block_list[cfile_block_index];
cfp->max_read_len = 0;
cfp->fp = nullptr;
cfp->mem_mapped = true;
cfp = &Cfile_list[cfile_block_index];
cfp->id = cfile_block_index;
cfp->version = 0;
cfbp->max_read_len = 0;
cfbp->fp = NULL;
cfbp->mem_mapped = true;
#if defined _WIN32
cfp->hInFile = hFile;
cfbp->hInFile = hFile;
#endif
cfp->dir_type = type;
cfbp->dir_type = type;
cfp->source_file = source;
cfp->line_num = line;
cfbp->source_file = source;
cfbp->line_num = line;
cf_init_lowlevel_read_code(cfp, 0, 0, 0 );
#if defined _WIN32
cfp->hMapFile = CreateFileMapping(cfp->hInFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (cfp->hMapFile == NULL) {
cfbp->hMapFile = CreateFileMapping(cfbp->hInFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (cfbp->hMapFile == NULL) {
nprintf(("Error", "Could not create file-mapping object.\n"));
return NULL;
}
cfp->data = (ubyte*)MapViewOfFile(cfp->hMapFile, FILE_MAP_READ, 0, 0, 0);
Assert( cfp->data != NULL );
cfbp->data = (ubyte*)MapViewOfFile(cfbp->hMapFile, FILE_MAP_READ, 0, 0, 0);
Assert( cfbp->data != NULL );
#elif defined SCP_UNIX
cfp->fp = fp;
cfp->data_length = filelength(fileno(fp));
cfp->data = mmap(nullptr, // start
cfp->data_length, // length
PROT_READ, // prot
MAP_SHARED, // flags
fileno(fp), // fd
0); // offset
Assert(cfp->data != nullptr);
cfbp->fp = fp;
cfbp->data_length = filelength( fileno(fp) );
cfbp->data = mmap(NULL, // start
cfbp->data_length, // length
PROT_READ, // prot
MAP_SHARED, // flags
fileno(fp), // fd
0); // offset
Assert( cfbp->data != NULL );
#endif
return cfp;
@@ -1087,18 +1113,23 @@ static CFILE *cf_open_memory_fill_cfblock(const char* source, int line, const vo
return NULL;
}
else {
CFILE *cfp = &Cfile_block_list[cfile_block_index];
CFILE *cfp;
Cfile_block *cfbp;
cfbp = &Cfile_block_list[cfile_block_index];
cfp->max_read_len = 0;
cfp->fp = nullptr;
cfp->mem_mapped = false;
cfp->dir_type = dir_type;
cfp = &Cfile_list[cfile_block_index];
cfp->id = cfile_block_index;
cfp->version = 0;
cfbp->max_read_len = 0;
cfbp->fp = NULL;
cfbp->mem_mapped = false;
cfbp->dir_type = dir_type;
cfp->source_file = source;
cfp->line_num = line;
cfbp->source_file = source;
cfbp->line_num = line;
cf_init_lowlevel_read_code(cfp, 0, size, 0 );
cfp->data = data;
cfbp->data = data;
return cfp;
}
@@ -1106,7 +1137,7 @@ static CFILE *cf_open_memory_fill_cfblock(const char* source, int line, const vo
int cf_get_dir_type(CFILE *cfile)
{
return cfile->dir_type;
return Cfile_block_list[cfile->id].dir_type;
}
// cf_returndata() returns the data pointer for a memory-mapped file that is associated
@@ -1117,8 +1148,11 @@ int cf_get_dir_type(CFILE *cfile)
const void *cf_returndata(CFILE *cfile)
{
Assert(cfile != NULL);
Assert(cfile->data != nullptr);
return cfile->data;
Cfile_block *cb;
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
cb = &Cfile_block_list[cfile->id];
Assert(cb->data != NULL);
return cb->data;
}
// cutoff point where cfread() will throw an error when it hits this limit
@@ -1126,21 +1160,27 @@ const void *cf_returndata(CFILE *cfile)
void cf_set_max_read_len( CFILE * cfile, size_t len )
{
Assert( cfile != NULL );
Assert( (cfile->id >= 0) && (cfile->id < MAX_CFILE_BLOCKS) );
Cfile_block *cb = &Cfile_block_list[cfile->id];
if (len) {
cfile->max_read_len = cfile->raw_position + len;
cb->max_read_len = cb->raw_position + len;
} else {
cfile->max_read_len = 0;
cb->max_read_len = 0;
}
}
// routines to read basic data types from CFILE's. Put here to
// simplify mac/pc reading from cfiles.
float cfread_float(CFILE* file, float deflt)
float cfread_float(CFILE *file, int ver, float deflt)
{
float f;
if (file->version < ver)
return deflt;
if (cfread( &f, sizeof(f), 1, file) != 1)
return deflt;
@@ -1148,10 +1188,13 @@ float cfread_float(CFILE* file, float deflt)
return f;
}
int cfread_int(CFILE* file, int deflt)
int cfread_int(CFILE *file, int ver, int deflt)
{
int i;
if (file->version < ver)
return deflt;
if (cfread( &i, sizeof(i), 1, file) != 1)
return deflt;
@@ -1159,10 +1202,13 @@ int cfread_int(CFILE* file, int deflt)
return i;
}
uint cfread_uint(CFILE* file, uint deflt)
uint cfread_uint(CFILE *file, int ver, uint deflt)
{
uint i;
if (file->version < ver)
return deflt;
if (cfread( &i, sizeof(i), 1, file) != 1)
return deflt;
@@ -1170,10 +1216,13 @@ uint cfread_uint(CFILE* file, uint deflt)
return i;
}
short cfread_short(CFILE* file, short deflt)
short cfread_short(CFILE *file, int ver, short deflt)
{
short s;
if (file->version < ver)
return deflt;
if (cfread( &s, sizeof(s), 1, file) != 1)
return deflt;
@@ -1181,10 +1230,13 @@ short cfread_short(CFILE* file, short deflt)
return s;
}
ushort cfread_ushort(CFILE* file, ushort deflt)
ushort cfread_ushort(CFILE *file, int ver, ushort deflt)
{
ushort s;
if (file->version < ver)
return deflt;
if (cfread( &s, sizeof(s), 1, file) != 1)
return deflt;
@@ -1192,26 +1244,42 @@ ushort cfread_ushort(CFILE* file, ushort deflt)
return s;
}
ubyte cfread_ubyte(CFILE* file, ubyte deflt)
ubyte cfread_ubyte(CFILE *file, int ver, ubyte deflt)
{
ubyte b;
if (file->version < ver)
return deflt;
if (cfread( &b, sizeof(b), 1, file) != 1)
return deflt;
return b;
}
void cfread_vector(vec3d* vec, CFILE* file, vec3d* deflt) {
vec->xyz.x = cfread_float(file, deflt ? deflt->xyz.x : 0.0f);
vec->xyz.y = cfread_float(file, deflt ? deflt->xyz.y : 0.0f);
vec->xyz.z = cfread_float(file, deflt ? deflt->xyz.z : 0.0f);
void cfread_vector(vec3d *vec, CFILE *file, int ver, vec3d *deflt)
{
if (file->version < ver) {
if (deflt)
*vec = *deflt;
else
vec->xyz.x = vec->xyz.y = vec->xyz.z = 0.0f;
return;
}
vec->xyz.x = cfread_float(file, ver, deflt ? deflt->xyz.x : 0.0f);
vec->xyz.y = cfread_float(file, ver, deflt ? deflt->xyz.y : 0.0f);
vec->xyz.z = cfread_float(file, ver, deflt ? deflt->xyz.z : 0.0f);
}
char cfread_char(CFILE* file, char deflt)
char cfread_char(CFILE *file, int ver, char deflt)
{
char b;
if (file->version < ver)
return deflt;
if (cfread( &b, sizeof(b), 1, file) != 1)
return deflt;
@@ -1324,18 +1392,22 @@ int cfwrite_string_len(const char *buf, CFILE *file)
}
// Get the filelength
int cfilelength(CFILE* cfile) {
int cfilelength( CFILE * cfile )
{
Assert(cfile != NULL);
Cfile_block *cb;
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
cb = &Cfile_block_list[cfile->id];
// TODO: return length of memory mapped file
Assert(!cfile->mem_mapped);
// cfile->size gets set at cfopen
Assert( !cb->mem_mapped );
// 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(cfile->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) cfile->size;
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;
}
// cfwrite() writes to the file
@@ -1351,13 +1423,15 @@ int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
if(buf == NULL || elsize == 0 || nelem == 0)
return 0;
if(cfile->lib_offset != 0)
Cfile_block *cb = &Cfile_block_list[cfile->id];
if(cb->lib_offset != 0)
{
Error(LOCATION, "Attempt to write to a VP file (unsupported)");
return 0;
}
if(cfile->data != nullptr)
if(cb->data != NULL)
{
Warning(LOCATION, "Writing is not supported for mem-mapped files");
return EOF;
@@ -1366,16 +1440,16 @@ int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
size_t bytes_written = 0;
size_t size = elsize * nelem;
bytes_written = fwrite(buf, 1, size, cfile->fp);
bytes_written = fwrite(buf, 1, size, cb->fp);
//WMC - update filesize and position
if (bytes_written > 0) {
cfile->size += bytes_written;
cfile->raw_position += bytes_written;
cb->size += bytes_written;
cb->raw_position += bytes_written;
}
#if defined(CHECK_SIZE) && !defined(NDEBUG)
Assert( cfile->size == filelength(fileno(cfile->fp)) );
Assert( cb->size == filelength(fileno(cb->fp)) );
#endif
return (int)(bytes_written / elsize);
@@ -1392,32 +1466,34 @@ int cfputc(int c, CFILE *cfile)
if(!cf_is_valid(cfile))
return EOF;
if(cfile->lib_offset != 0)
Cfile_block *cb = &Cfile_block_list[cfile->id];
if(cb->lib_offset != 0)
{
Error(LOCATION, "Attempt to write character to a VP file (unsupported)");
return EOF;
}
if(cfile->data != nullptr)
if(cb->data != NULL)
{
Warning(LOCATION, "Writing is not supported for mem-mapped files");
return EOF;
}
// writing not supported for memory-mapped files
Assert( !cfile->data );
Assert( !cb->data );
int result = fputc(c, cfile->fp);
int result = fputc(c, cb->fp);
//WMC - update filesize and position
if(result != EOF)
{
cfile->size += 1;
cfile->raw_position += 1;
cb->size += 1;
cb->raw_position += 1;
}
#if defined(CHECK_SIZE) && !defined(NDEBUG)
Assert( cfile->size == filelength(fileno(cfile->fp)) );
Assert( cb->size == filelength(fileno(cb->fp)) );
#endif
return result;
@@ -1436,29 +1512,31 @@ int cfputs(const char *str, CFILE *cfile)
if(str == NULL)
return EOF;
if(cfile->lib_offset != 0)
Cfile_block *cb = &Cfile_block_list[cfile->id];
if(cb->lib_offset != 0)
{
Error(LOCATION, "Attempt to write character to a VP file (unsupported)");
return EOF;
}
if(cfile->data != nullptr)
if(cb->data != NULL)
{
Warning(LOCATION, "Writing is not supported for mem-mapped files");
return EOF;
}
int result = fputs(str, cfile->fp);
int result = fputs(str, cb->fp);
//WMC - update filesize and position
if(result != EOF)
{
cfile->size += strlen(str);
cfile->raw_position += strlen(str);
cb->size += strlen(str);
cb->raw_position += strlen(str);
}
#if defined(CHECK_SIZE) && !defined(NDEBUG)
Assert( cfile->size == filelength(fileno(cfile->fp)) );
Assert( cb->size == filelength(fileno(cb->fp)) );
#endif
return result;
@@ -1820,16 +1898,19 @@ int cf_chksum_long(CFILE *file, uint *chksum, int max_size)
int cflush(CFILE *cfile)
{
Assert(cfile != NULL);
Cfile_block *cb;
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
cb = &Cfile_block_list[cfile->id];
// not supported for memory mapped files
Assert( !cfile->data );
Assert( !cb->data );
Assert(cfile->fp != nullptr);
Assert(cb->fp != NULL);
int result = fflush(cfile->fp);
int result = fflush(cb->fp);
//WMC - update filesize
cfile->size = filelength(fileno(cfile->fp));
cb->size = filelength(fileno(cb->fp));
return result;
}
+13 -29
View File
@@ -13,11 +13,10 @@
#define __CFILE_H__
#include <ctime>
#include "globalincs/pstypes.h"
#include <ctime>
#include <stdexcept>
#include <memory>
#define CF_EOF (-1)
@@ -26,8 +25,10 @@
#define CF_SEEK_CUR (1)
#define CF_SEEK_END (2)
// Opaque file handle
struct CFILE;
typedef struct CFILE {
int id; // Index into cfile.cpp specific structure
int version; // version of this file
} CFILE;
// extra info that can be returned when getting a file listing
typedef struct {
@@ -291,10 +292,6 @@ uint cf_add_chksum_long(uint seed, ubyte *buffer, size_t size);
#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 );
// Creates the directory path if it doesn't exist. Even creates all its
// parent paths.
void cf_create_directory(int dir_type, uint32_t location_flags = CF_LOCATION_ALL);
// changes the attributes of a file
void cf_attrib(const char *name, int set, int clear, int type);
@@ -306,14 +303,14 @@ int cfile_flush_dir(int type);
// These are all high level, built up from
// cfread.
char *cfgets(char *buf, size_t n, CFILE *fp);
char cfread_char(CFILE* file, char deflt = 0);
ubyte cfread_ubyte(CFILE* file, ubyte deflt = 0);
short cfread_short(CFILE* file, short deflt = 0);
ushort cfread_ushort(CFILE* file, ushort deflt = 0);
int cfread_int(CFILE* file, int deflt = 0);
uint cfread_uint(CFILE* file, uint deflt = 0);
float cfread_float(CFILE* file, float deflt = 0.0f);
void cfread_vector(vec3d* vec, CFILE* file, vec3d* deflt = nullptr);
char cfread_char(CFILE *file, int ver = 0, char deflt = 0);
ubyte cfread_ubyte(CFILE *file, int ver = 0, ubyte deflt = 0);
short cfread_short(CFILE *file, int ver = 0, short deflt = 0);
ushort cfread_ushort(CFILE *file, int ver = 0, ushort deflt = 0);
int cfread_int(CFILE *file, int ver = 0, int deflt = 0);
uint cfread_uint(CFILE *file, int ver = 0, uint deflt = 0);
float cfread_float(CFILE *file, int ver = 0, float deflt = 0.0f);
void cfread_vector(vec3d *vec, CFILE *file, int ver = 0, vec3d *deflt = NULL);
// Reads variable length, null-termined string. Will only read up
// to n characters.
@@ -465,17 +462,4 @@ namespace cfile
}
// This allows to use std::unique_ptr with CFILE
namespace std {
template <>
struct default_delete<CFILE> {
void operator()(CFILE* ptr)
{
if (cf_is_valid(ptr)) {
cfclose(ptr);
}
}
};
} // namespace std
#endif /* __CFILE_H__ */
+74 -55
View File
@@ -36,20 +36,24 @@
void cf_init_lowlevel_read_code( CFILE * cfile, size_t lib_offset, size_t size, size_t pos )
{
Assert(cfile != nullptr);
Assert(cfile != NULL);
cfile->lib_offset = lib_offset;
cfile->raw_position = pos;
cfile->size = size;
Cfile_block *cb;
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
cb = &Cfile_block_list[cfile->id];
if ( cfile->fp ) {
if ( cfile->lib_offset ) {
fseek( cfile->fp, (long)cfile->lib_offset, SEEK_SET );
cb->lib_offset = lib_offset;
cb->raw_position = pos;
cb->size = size;
if ( cb->fp ) {
if ( cb->lib_offset ) {
fseek( cb->fp, (long)cb->lib_offset, SEEK_SET );
}
#if defined(CHECK_POSITION) && !defined(NDEBUG)
auto raw_position = ftell(cfile->fp) - cfile->lib_offset;
Assert(raw_position == cfile->raw_position);
auto raw_position = ftell(cb->fp) - cb->lib_offset;
Assert(raw_position == cb->raw_position);
#endif
}
}
@@ -66,16 +70,20 @@ int cfeof(CFILE *cfile)
{
Assert(cfile != NULL);
Cfile_block *cb;
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
cb = &Cfile_block_list[cfile->id];
int result = 0;
#if defined(CHECK_POSITION) && !defined(NDEBUG)
if (cfile->fp) {
auto raw_position = ftell(cfile->fp) - cfile->lib_offset;
Assert(raw_position == cfile->raw_position);
if (cb->fp) {
auto raw_position = ftell(cb->fp) - cb->lib_offset;
Assert(raw_position == cb->raw_position);
}
#endif
if (cfile->raw_position >= cfile->size ) {
if (cb->raw_position >= cb->size ) {
result = 1;
} else {
result = 0;
@@ -92,18 +100,21 @@ int cfeof(CFILE *cfile)
int cftell( CFILE * cfile )
{
Assert(cfile != NULL);
Cfile_block *cb;
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
cb = &Cfile_block_list[cfile->id];
#if defined(CHECK_POSITION) && !defined(NDEBUG)
if (cfile->fp) {
auto raw_position = ftell(cfile->fp) - cfile->lib_offset;
Assert(raw_position == cfile->raw_position);
if (cb->fp) {
auto 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(cfile->raw_position <= static_cast<size_t>(std::numeric_limits<int>::max()),
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) cfile->raw_position;
return (int) cb->raw_position;
}
@@ -116,23 +127,27 @@ int cfseek( CFILE *cfile, int offset, int where )
{
Assert(cfile != NULL);
Cfile_block *cb;
Assert(cfile->id >= 0 && cfile->id < MAX_CFILE_BLOCKS);
cb = &Cfile_block_list[cfile->id];
// TODO: seek to offset in memory mapped file
Assert( !cfile->mem_mapped );
Assert( !cb->mem_mapped );
size_t goal_position;
switch( where ) {
case CF_SEEK_SET:
goal_position = offset+cfile->lib_offset;
goal_position = offset+cb->lib_offset;
break;
case CF_SEEK_CUR:
{
goal_position = cfile->raw_position+offset+cfile->lib_offset;
goal_position = cb->raw_position+offset+cb->lib_offset;
}
break;
case CF_SEEK_END:
goal_position = cfile->size+offset+cfile->lib_offset;
goal_position = cb->size+offset+cb->lib_offset;
break;
default:
Int3();
@@ -140,23 +155,23 @@ int cfseek( CFILE *cfile, int offset, int where )
}
// Make sure we don't seek beyond the end of the file
CAP(goal_position, cfile->lib_offset, cfile->lib_offset + cfile->size);
CAP(goal_position, cb->lib_offset, cb->lib_offset + cb->size);
int result = 0;
if (cfile->fp) {
if (cb->fp) {
// If we have a file pointer we can also seek in that file
result = fseek(cfile->fp, (long)goal_position, SEEK_SET );
Assertion(goal_position >= cfile->lib_offset, "Invalid offset values detected while seeking! Goal was " SIZE_T_ARG ", lib_offset is " SIZE_T_ARG ".", goal_position, cfile->lib_offset);
result = fseek(cb->fp, (long)goal_position, SEEK_SET );
Assertion(goal_position >= cb->lib_offset, "Invalid offset values detected while seeking! Goal was " SIZE_T_ARG ", lib_offset is " SIZE_T_ARG ".", goal_position, cb->lib_offset);
}
// If we only have a data pointer this will do all the work
cfile->raw_position = goal_position - cfile->lib_offset;
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
cb->raw_position = goal_position - cb->lib_offset;
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
#if defined(CHECK_POSITION) && !defined(NDEBUG)
if (cfile->fp) {
auto tmp_offset = ftell(cfile->fp) - cfile->lib_offset;
Assert(tmp_offset == cfile->raw_position);
if (cb->fp) {
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
Assert(tmp_offset == cb->raw_position);
}
#endif
@@ -179,17 +194,19 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
if(buf == NULL || size <= 0)
return 0;
if ( (cfile->raw_position+size) > cfile->size ) {
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
size = cfile->size - cfile->raw_position;
Cfile_block *cb = &Cfile_block_list[cfile->id];
if ( (cb->raw_position+size) > cb->size ) {
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
size = cb->size - cb->raw_position;
if ( size < 1 ) {
return 0;
}
//mprintf(( "CFILE: EOF encountered in file\n" ));
}
if (cfile->max_read_len) {
if ( cfile->raw_position+size > cfile->max_read_len ) {
if (cb->max_read_len) {
if ( cb->raw_position+size > cb->max_read_len ) {
std::ostringstream s_buf;
s_buf << "Attempted to read " << size << "-byte(s) beyond length limit";
@@ -198,22 +215,22 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
}
size_t bytes_read;
if (cfile->data != nullptr) {
if (cb->data != nullptr) {
// This is a file from memory
bytes_read = size;
memcpy(buf, reinterpret_cast<const char*>(cfile->data) + cfile->raw_position, size);
memcpy(buf, reinterpret_cast<const char*>(cb->data) + cb->raw_position, size);
} else {
bytes_read = fread( buf, 1, size, cfile->fp );
bytes_read = fread( buf, 1, size, cb->fp );
}
if ( bytes_read > 0 ) {
cfile->raw_position += bytes_read;
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
cb->raw_position += bytes_read;
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
}
#if defined(CHECK_POSITION) && !defined(NDEBUG)
if (cfile->fp) {
auto tmp_offset = ftell(cfile->fp) - cfile->lib_offset;
Assert(tmp_offset==cfile->raw_position);
if (cb->fp) {
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
Assert(tmp_offset==cb->raw_position);
}
#endif
@@ -229,8 +246,10 @@ int cfread_lua_number(double *buf, CFILE *cfile)
if(buf == NULL)
return 0;
Cfile_block *cb = &Cfile_block_list[cfile->id];
// cfread() not supported for memory-mapped files
if(cfile->data != nullptr)
if(cb->data != NULL)
{
Warning(LOCATION, "Writing is not supported for mem-mapped files");
return 0;
@@ -238,28 +257,28 @@ int cfread_lua_number(double *buf, CFILE *cfile)
size_t advance = 0;
int items_read;
if (cfile->fp) {
long orig_pos = ftell(cfile->fp);
items_read = fscanf(cfile->fp, LUA_NUMBER_SCAN, buf);
advance = (size_t) (ftell(cfile->fp)-orig_pos);
if (cb->fp) {
long orig_pos = ftell(cb->fp);
items_read = fscanf(cb->fp, LUA_NUMBER_SCAN, buf);
advance = (size_t) (ftell(cb->fp)-orig_pos);
} else {
int read;
// %n returns the number of bytes currently read so we append that to the scan format at the end so it will return
// how many bytes we have consumed
items_read = sscanf(reinterpret_cast<const char*>(cfile->data), LUA_NUMBER_SCAN "%n", buf, &read);
items_read = sscanf(reinterpret_cast<const char*>(cb->data), LUA_NUMBER_SCAN "%n", buf, &read);
if (items_read == 2) {
// We need to correct the items read counter since we read one additional item
items_read = 1;
}
advance = (size_t) read;
}
cfile->raw_position += advance;
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
cb->raw_position += advance;
Assertion(cb->raw_position <= cb->size, "Invalid raw_position value detected!");
#if defined(CHECK_POSITION) && !defined(NDEBUG)
if (cfile->fp) {
auto tmp_offset = ftell(cfile->fp) - cfile->lib_offset;
Assert(tmp_offset==cfile->raw_position);
if (cb->fp) {
auto tmp_offset = ftell(cb->fp) - cb->lib_offset;
Assert(tmp_offset==cb->raw_position);
}
#endif
+14 -14
View File
@@ -22,30 +22,30 @@
#define CFILE_BLOCK_UNUSED 0
#define CFILE_BLOCK_USED 1
struct CFILE {
int type = CFILE_BLOCK_UNUSED; // CFILE_BLOCK_UNUSED, CFILE_BLOCK_USED
int dir_type; // directory location
FILE* fp; // File pointer if opening an individual file
const void* data; // Pointer for memory-mapped file access. NULL if not mem-mapped.
bool mem_mapped; // Flag for memory mapped files (if data is not null and this is false it means that it's an embedded file)
typedef struct Cfile_block {
int type; // CFILE_BLOCK_UNUSED, CFILE_BLOCK_USED
int dir_type; // directory location
FILE *fp; // File pointer if opening an individual file
const void *data; // Pointer for memory-mapped file access. NULL if not mem-mapped.
bool mem_mapped; // Flag for memory mapped files (if data is not null and this is false it means that it's an embedded file)
#ifdef _WIN32
HANDLE hInFile; // Handle from CreateFile()
HANDLE hMapFile; // Handle from CreateFileMapping()
#else
size_t data_length; // length of data for mmap
size_t data_length; // length of data for mmap
#endif
size_t lib_offset;
size_t raw_position;
size_t size; // for packed files
size_t max_read_len; // max read offset, for special error handling
size_t lib_offset;
size_t raw_position;
size_t 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 std::array<CFILE, MAX_CFILE_BLOCKS> Cfile_block_list;
extern Cfile_block Cfile_block_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 );
+5 -34
View File
@@ -556,40 +556,17 @@ void cf_search_root_path(int root_index)
int i;
int num_files = 0;
cf_root* root = cf_get_root(root_index);
cf_root *root = cf_get_root(root_index);
mprintf(("Searching root '%s' ... ", root->path));
#ifndef WIN32
try {
auto current = root->path;
const auto prefPathEnd = root->path + strlen(root->path);
while (current != prefPathEnd) {
const auto cp = utf8::next(current, prefPathEnd);
if (cp > 127) {
// On Windows, we currently do not support Unicode paths so catch this early and let the user
// know
const auto invalid_end = current;
utf8::prior(current, root->path);
Error(LOCATION,
"Trying to use path \"%s\" as a data root. That path is not supported since it "
"contains a Unicode character (%s). If possible, change this path to something that only uses "
"ASCII characters.",
root->path, std::string(current, invalid_end).c_str());
}
}
} catch (const std::exception& e) {
Error(LOCATION, "UTF-8 error while checking the root path \"%s\": %s", root->path, e.what());
}
#endif
mprintf(( "Searching root '%s' ... ", root->path ));
char search_path[CF_MAX_PATHNAME_LENGTH];
#ifdef SCP_UNIX
// This map stores the mapping between a specific path type and the actual path that we use for it
// This map stores the mapping between a specific path type and the actual path that we use for it
SCP_unordered_map<int, SCP_string> pathTypeToRealPath;
#endif
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
for (i=CF_TYPE_ROOT; i<CF_MAX_PATH_TYPES; i++ ) {
// we don't want to add player files to the cache - taylor
if ( (i == CF_TYPE_SINGLE_PLAYERS) || (i == CF_TYPE_MULTI_PLAYERS) ) {
@@ -1579,9 +1556,6 @@ 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.
// Note that filesystem listing is always sorted by name *before* sorting by the
// provided sort order. This isn't strictly needed on NTFS, which always provides the list
// sorted by name. But on mac/linux it's always needed.
int cf_get_file_list(SCP_vector<SCP_string>& list, int pathtype, const char* filter, int sort,
SCP_vector<file_list_info>* info, uint32_t location_flags)
{
@@ -1704,10 +1678,6 @@ int cf_get_file_list(SCP_vector<SCP_string>& list, int pathtype, const char* fil
}
#endif
// tcrayford: sort the filesystem listing by name by default to ensure
// a stable order across filesystems
cf_sort_filenames( list, CF_SORT_NAME, info );
bool skip_packfiles = false;
if ( (pathtype == CF_TYPE_PLAYERS) || (pathtype == CF_TYPE_SINGLE_PLAYERS) || (pathtype == CF_TYPE_MULTI_PLAYERS) ) {
skip_packfiles = true;
@@ -1773,6 +1743,7 @@ int cf_get_file_list(SCP_vector<SCP_string>& list, int pathtype, const char* fil
}
}
if (sort != CF_SORT_NONE) {
cf_sort_filenames( list, sort, info );
}
+182 -237
View File
@@ -5,27 +5,27 @@
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
#include "cmdline/cmdline.h"
#include "camera/camera.h" //VIEWER_ZOOM_DEFAULT
#include "cfile/cfilesystem.h"
#include "fireball/fireballs.h"
#include "cmdline/cmdline.h"
#include "globalincs/linklist.h"
#include "globalincs/pstypes.h"
#include "globalincs/systemvars.h"
#include "globalincs/version.h"
#include "graphics/shadows.h"
#include "hud/hudconfig.h"
#include "io/joy.h"
#include "network/multi.h"
#include "options/OptionsManager.h"
#include "osapi/osapi.h"
#include "parse/sexp.h"
#include "scripting/scripting.h"
#include "sound/openal.h"
#include "parse/sexp.h"
#include "globalincs/version.h"
#include "globalincs/pstypes.h"
#include "osapi/osapi.h"
#include "cfile/cfilesystem.h"
#include "sound/speech.h"
#include "starfield/starfield.h"
#include "sound/openal.h"
#include "io/joy.h"
#ifdef _WIN32
#include <io.h>
@@ -82,8 +82,8 @@ public:
int name_found; // true if parameter on command line, otherwise false
const int arg_type; // from enum cmdline_arg_type; used for help
cmdline_parm(const char *name, const char *help, const int arg_type, const bool stacks = false) noexcept;
~cmdline_parm() noexcept;
cmdline_parm(const char *name, const char *help, const int arg_type, const bool stacks = false);
~cmdline_parm();
int found();
int get_int();
float get_float();
@@ -100,13 +100,17 @@ extern int Show_framerate; // from freespace.cpp
enum
{
// DO NOT CHANGE ANYTHING ABOUT THESE FIRST TWO OR WILL MESS UP THE LAUNCHER
EASY_DEFAULT = 1 << 1, // Default FS2 (All features off)
EASY_ALL_ON = 1 << 2, // All features on
EASY_DEFAULT = 1 << 1,
EASY_ALL_ON = 1 << 2,
EASY_HI_MEM_ON = 1 << 3, // High memory usage features on
EASY_HI_MEM_OFF = 1 << 4, // High memory usage features off
EASY_MEM_ON = 1 << 3,
EASY_MEM_OFF = 1 << 4,
// Add new flags here
// Combos
EASY_MEM_ALL_ON = EASY_ALL_ON | EASY_MEM_ON,
EASY_DEFAULT_MEM = EASY_DEFAULT | EASY_MEM_OFF
};
enum BuildCaps
@@ -118,7 +122,6 @@ enum BuildCaps
};
#define PARSE_COMMAND_LINE_STRING "-parse_cmdline_only"
#define GET_FLAGS_STRING "-get_flags"
typedef struct
{
@@ -142,115 +145,109 @@ typedef struct
char name[20]; // The actual flag
char desc[40]; // The text that will appear in the launcher (unless its blank, other name is shown)
bool fso_only; // true if this is a fs2_open only feature
int on_flags; // "Easy setting" which will turn this option on
int off_flags; // "Easy setting" which will turn this option off
int on_flags; // Easy flag which will turn this feature on
int off_flags; // Easy flag which will turn this feature off
char type[16]; // Launcher uses this to put flags under different headings
char web_url[256]; // Link to documentation of feature (please use wiki or somewhere constant)
} Flag;
// clang-format off
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
Flag exe_params[] =
{
{ "-nospec", "Disable specular", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
{ "-noglow", "Disable glow maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
{ "-noenv", "Disable environment maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
{ "-nonormal", "Disable normal maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
{ "-emissive_light", "Enable emissive light from ships", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-emissive_light" },
{ "-noheight", "Disable height/parallax maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-height" },
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
{ "-no_post_process", "Disable post-processing", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_post_process" },
{ "-soft_particles", "Enable soft particles", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-smaa", "Enable SMAA anti-aliasing", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-smaa" },
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
{ "-fb_thrusters", "Enable Framebuffer Thrusters", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_thrusters", },
{ "-no_deferred", "Disable Deferred Lighting", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_deferred"},
{ "-enable_shadows", "Enable Shadows", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_shadows"},
{ "-nospec", "Disable specular", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
{ "-noglow", "Disable glow maps", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
{ "-noenv", "Disable environment maps", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
{ "-nomotiondebris", "Disable motion debris", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomotiondebris",},
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
{ "-nonormal", "Disable normal maps", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
{ "-no_emissive_light", "Disable emissive light from ships", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_emissive_light" },
{ "-noheight", "Disable height/parallax maps", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-height" },
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
{ "-post_process", "Enable post processing", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
{ "-soft_particles", "Enable soft particles", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
{ "-fb_thrusters", "Enable Framebuffer Thrusters", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_thrusters", },
{ "-no_deferred", "Disable Deferred Lighting", true, EASY_DEFAULT_MEM, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_deferred"},
{ "-enable_shadows", "Enable Shadows", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_shadows"},
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
{ "-dualscanlines", "Add another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
{ "-targetinfo", "Enable info next to target", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-targetinfo", },
{ "-orbradar", "Enable 3D radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
{ "-rearm_timer", "Enable rearm/repair completion timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
{ "-ballistic_gauge", "Enable analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
{ "-dualscanlines", "Add another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
{ "-targetinfo", "Enable info next to target", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-targetinfo", },
{ "-orbradar", "Enable 3D radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
{ "-rearm_timer", "Enable rearm/repair completion timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
{ "-ballistic_gauge", "Enable analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
{ "-ship_choice_3d", "Use 3D models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
{ "-weapon_choice_3d", "Use 3D models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
{ "-3dwarp", "Enable 3D warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
{ "-stretch_menu", "Stretch interface to fill screen", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stretch_menu", },
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fullscreen_window", },
{ "-stretch_menu", "Stretch interface to fill screen", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stretch_menu", },
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
{ "-nomotiondebris", "Disable motion debris", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomotiondebris",},
{ "-ship_choice_3d", "Use 3D models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
{ "-weapon_choice_3d", "Use 3D models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
{ "-3dwarp", "Enable 3D warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
{ "-nosound", "Disable all sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
{ "-no_enhanced_sound", "Disable enhanced sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_enhanced_sound", },
{ "-nosound", "Disable all sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
{ "-no_enhanced_sound", "Disable enhanced sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_enhanced_sound", },
{ "-portable_mode", "Store config in portable location", false, 0, EASY_DEFAULT, "Launcher", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-portable_mode", },
{ "-portable_mode", "Store config in portable location", false, 0, EASY_DEFAULT, "Launcher", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-portable_mode", },
{ "-standalone", "Run as standalone server", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-standalone", },
{ "-startgame", "Skip mainhall and start hosting", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-startgame", },
{ "-closed", "Start hosted server as closed", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-closed", },
{ "-restricted", "Host confirms join requests", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-restricted", },
{ "-multilog", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-multilog", },
{ "-clientdamage", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-clientdamage", },
{ "-mpnoreturn", "Disable flight deck option", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
{ "-standalone", "Run as standalone server", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-standalone", },
{ "-startgame", "Skip mainhall and start hosting", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-startgame", },
{ "-closed", "Start hosted server as closed", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-closed", },
{ "-restricted", "Host confirms join requests", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-restricted", },
{ "-multilog", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-multilog", },
{ "-clientdamage", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-clientdamage", },
{ "-mpnoreturn", "Disable flight deck option", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
{ "-gateway_ip", "Set gateway IP address", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gateway_ip", },
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_fbo", },
{ "-disable_pbo", "Disable OpenGL Pixel Buffer Objects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_pbo", },
{ "-ati_swap", "Fix colour issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ati_swap", },
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_3d_sound", },
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT | EASY_HI_MEM_OFF, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-use_gldrawelements", },
{ "-gl_finish", "Fix input lag on some ATI+Linux systems", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gl_finish", },
{ "-no_geo_effects", "Disable geometry shader for effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-set_cpu_affinity", "Sets processor affinity to config value", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-nograb", "Disables mouse grabbing", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", },
{ "-noshadercache", "Disables the shader cache", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noshadercache", },
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_fbo", },
{ "-disable_pbo", "Disable OpenGL Pixel Buffer Objects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_pbo", },
{ "-ati_swap", "Fix colour issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ati_swap", },
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_3d_sound", },
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-use_gldrawelements", },
{ "-gl_finish", "Fix input lag on some ATI+Linux systems", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gl_finish", },
{ "-no_geo_effects", "Disable geometry shader for effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-set_cpu_affinity", "Sets processor affinity to config value", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-nograb", "Disables mouse grabbing", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", },
{ "-noshadercache", "Disables the shader cache", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noshadercache", },
#ifdef WIN32
{ "-fix_registry", "Use a different registry path", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-fix_registry", "Use a different registry path", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
#endif
{ "-ingame_join", "Allow in-game joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
{ "-voicer", "Enable voice recognition", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-voicer", },
{ "-ingame_join", "Allow in-game joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
{ "-voicer", "Enable voice recognition", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-voicer", },
{ "-bmpmanusage", "Show how many BMPMAN slots are in use", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-bmpmanusage", },
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-pofspew", "Generate all ibx files immediately", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
{ "-tablecrcs", "Dump table CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
{ "-missioncrcs", "Dump mission CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
{ "-dis_collisions", "Disable collisions", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_collisions", },
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
{ "-output_sexps", "Output SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
{ "-output_scripting", "Output scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
{ "-output_script_json", "Output scripting doc to scripting.json", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_script_json", },
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-save_render_target", },
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", },
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", },
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
{ "-benchmark_mode", "Puts the game into benchmark mode", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-benchmark_mode", },
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
{ "-json_profiling", "Generate JSON profiling output", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-json_profiling", },
{ "-profile_frame_time","Profile engine subsystems", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_timings", },
{ "-debug_window", "Enable the debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
{ "-bmpmanusage", "Show how many BMPMAN slots are in use", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-bmpmanusage", },
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fullscreen_window", },
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-pofspew", "Generate all ibx files immediately", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
{ "-tablecrcs", "Dump table CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
{ "-missioncrcs", "Dump mission CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
{ "-dis_collisions", "Disable collisions", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_collisions", },
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
{ "-output_sexps", "Output SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
{ "-output_scripting", "Output scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-save_render_target", },
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", },
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", },
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
{ "-benchmark_mode", "Puts the game into benchmark mode", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-benchmark_mode", },
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
{ "-json_profiling", "Generate JSON profiling output", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-json_profiling", },
{ "-profile_frame_time","Profile engine subsystems", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_timings", },
{ "-debug_window", "Enable the debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
};
// clang-format on
// forward declaration
const char * get_param_desc(const char *flag_name);
@@ -305,6 +302,8 @@ int Cmdline_use_last_pilot = 0;
// Graphics related
cmdline_parm fov_arg("-fov", "Vertical field-of-view factor", AT_FLOAT); // Cmdline_fov -- comand line FOV -Bobboau
cmdline_parm clip_dist_arg("-clipdist", "Changes the distance from the viewpoint for the near-clipping plane", AT_FLOAT); // Cmdline_clip_dist
cmdline_parm spec_exp_arg("-spec_exp", "Adjusts the size of shiny spots on ships", AT_FLOAT);
cmdline_parm ogl_spec_arg("-ogl_spec", "Shininess of specular light", AT_FLOAT); // Cmdline_ogl_spec
cmdline_parm spec_static_arg("-spec_static", "Adjusts suns contribution to specular highlights", AT_FLOAT);
cmdline_parm spec_point_arg("-spec_point", "Adjusts laser weapons contribution to specular highlights", AT_FLOAT);
cmdline_parm spec_tube_arg("-spec_tube", "Adjusts beam weapons contribution to specular highlights", AT_FLOAT);
@@ -314,17 +313,15 @@ cmdline_parm glow_arg("-noglow", NULL, AT_NONE); // Cmdline_glow -- use B
cmdline_parm nomotiondebris_arg("-nomotiondebris", NULL, AT_NONE); // Cmdline_nomotiondebris -- Removes those ugly floating rocks -C
cmdline_parm noscalevid_arg("-noscalevid", NULL, AT_NONE); // Cmdline_noscalevid -- disable video scaling that fits to window
cmdline_parm spec_arg("-nospec", NULL, AT_NONE); // Cmdline_spec --
cmdline_parm emissive_arg("-emissive_light", "Enable emissive light from ships", AT_NONE); // Cmdline_no_emissive -- don't use emissive light in OGL
cmdline_parm noemissive_arg("-no_emissive_light", "Disable emissive light from ships", AT_NONE); // Cmdline_no_emissive -- don't use emissive light in OGL
cmdline_parm normal_arg("-nonormal", NULL, AT_NONE); // Cmdline_normal -- disable normal mapping
cmdline_parm height_arg("-noheight", NULL, AT_NONE); // Cmdline_height -- enable support for parallax mapping
cmdline_parm enable_3d_shockwave_arg("-3dshockwave", NULL, AT_NONE);
cmdline_parm softparticles_arg("-soft_particles", NULL, AT_NONE);
cmdline_parm no_postprocess_arg("-no_post_process", "Disables post-processing", AT_NONE);
cmdline_parm bloom_intensity_arg("-bloom_intensity", "Set bloom intensity, requires post-processing", AT_INT);
cmdline_parm postprocess_arg("-post_process", NULL, AT_NONE);
cmdline_parm bloom_intensity_arg("-bloom_intensity", "Set bloom intensity, requires -post_process", AT_INT);
cmdline_parm fxaa_arg("-fxaa", NULL, AT_NONE);
cmdline_parm fxaa_preset_arg("-fxaa_preset", "FXAA quality (0-9), requires post-processing and -fxaa", AT_INT);
cmdline_parm smaa_arg("-smaa", nullptr, AT_NONE);
cmdline_parm smaa_preset_arg("-smaa_preset", "SMAA quality (0-9), requires post-processing and -smaa", AT_INT);
cmdline_parm fxaa_preset_arg("-fxaa_preset", "FXAA quality (0-9), requires -post_process and -fxaa", AT_INT);
cmdline_parm fb_explosions_arg("-fb_explosions", NULL, AT_NONE);
cmdline_parm fb_thrusters_arg("-fb_thrusters", NULL, AT_NONE);
cmdline_parm flightshaftsoff_arg("-nolightshafts", NULL, AT_NONE);
@@ -334,19 +331,29 @@ cmdline_parm no_deferred_lighting_arg("-no_deferred", NULL, AT_NONE); // Cmdline
cmdline_parm anisotropy_level_arg("-anisotropic_filter", NULL, AT_INT);
float Cmdline_clip_dist = Default_min_draw_distance;
float Cmdline_fov = 0.75f;
float Cmdline_ogl_spec = 80.0f;
int Cmdline_ambient_factor = 128;
int Cmdline_env = 1;
int Cmdline_mipmap = 0;
int Cmdline_glow = 1;
int Cmdline_nomotiondebris = 0;
int Cmdline_noscalevid = 0;
int Cmdline_spec = 1;
int Cmdline_emissive = 0;
int Cmdline_no_emissive = 0;
int Cmdline_normal = 1;
int Cmdline_height = 1;
int Cmdline_enable_3d_shockwave = 0;
int Cmdline_softparticles = 0;
int Cmdline_bloom_intensity = 25;
int Cmdline_postprocess = 0;
int Cmdline_bloom_intensity = 75;
bool Cmdline_fxaa = false;
int Cmdline_fxaa_preset = 6;
extern int Fxaa_preset_last_frame;
bool Cmdline_fb_explosions = 0;
bool Cmdline_fb_thrusters = false;
extern bool ls_force_off;
int Cmdline_shadow_quality = 0;
int Cmdline_no_deferred_lighting = 0;
int Cmdline_aniso_level = 0;
@@ -400,14 +407,16 @@ char *Cmdline_mod = NULL; //DTP for mod argument
cmdline_parm almission_arg("-almission", "Autoload multiplayer mission", AT_STRING); // Cmdline_almission -- DTP for autoload Multi mission
cmdline_parm ingamejoin_arg("-ingame_join", NULL, AT_NONE); // Cmdline_ingamejoin
cmdline_parm mpnoreturn_arg("-mpnoreturn", NULL, AT_NONE); // Cmdline_mpnoreturn -- Removes 'Return to Flight Deck' in respawn dialog -C
cmdline_parm missioncrcspew_arg("-missioncrcs", NULL, AT_STRING); // Cmdline_spew_mission_crcs
cmdline_parm tablecrcspew_arg("-tablecrcs", NULL, AT_STRING); // Cmdline_spew_table_crcs
cmdline_parm objupd_arg("-cap_object_update", "Multiplayer object update cap (0-3)", AT_INT);
cmdline_parm gateway_ip_arg("-gateway_ip", "Set gateway IP address", AT_STRING);
char *Cmdline_almission = NULL; //DTP for autoload multi mission.
int Cmdline_ingamejoin = 0;
int Cmdline_mpnoreturn = 0;
char *Cmdline_spew_mission_crcs = NULL;
char *Cmdline_spew_table_crcs = NULL;
int Cmdline_objupd = 3; // client object updates on LAN by default
char *Cmdline_gateway_ip = nullptr;
// Launcher related options
cmdline_parm portable_mode("-portable_mode", NULL, AT_NONE);
@@ -509,10 +518,9 @@ bool Cmdline_show_video_info = false;
bool Cmdline_debug_window = false;
// Other
cmdline_parm get_flags_arg(GET_FLAGS_STRING, "Output the launcher flags file", AT_STRING);
cmdline_parm get_flags_arg("-get_flags", "Output the launcher flags file", AT_STRING);
cmdline_parm output_sexp_arg("-output_sexps", NULL, AT_NONE); //WMC - outputs all SEXPs to sexps.html
cmdline_parm output_scripting_arg("-output_scripting", NULL, AT_NONE); //WMC
cmdline_parm output_script_json_arg("-output_script_json", nullptr, AT_NONE); // m!m
// Deprecated flags - CommanderDJ
cmdline_parm deprecated_spec_arg("-spec", "Deprecated", AT_NONE);
@@ -526,8 +534,6 @@ cmdline_parm deprecated_brieflighting_arg("-brief_lighting", "Deprecated", AT_NO
cmdline_parm deprecated_sndpreload_arg("-snd_preload", "Deprecated", AT_NONE);
cmdline_parm deprecated_missile_lighting_arg("-missile_lighting", "Deprecated", AT_NONE);
cmdline_parm deprecated_cache_bitmaps_arg("-cache_bitmaps", "Deprecated", AT_NONE);
cmdline_parm deprecated_no_emissive_arg("-no_emissive_light", "Deprecated", AT_NONE);
cmdline_parm deprecated_postprocess_arg("-post_process", "Deprecated", AT_NONE);
int Cmdline_deprecated_spec = 0;
int Cmdline_deprecated_glow = 0;
@@ -539,7 +545,6 @@ int Cmdline_deprecated_nohtl = 0;
bool Cmdline_deprecated_brief_lighting = 0;
bool Cmdline_deprecated_missile_lighting = false;
bool Cmdline_deprecated_cache_bitmaps = false;
bool Cmdline_deprecated_postprocess = false;
#ifndef NDEBUG
// NOTE: this assumes that os_init() has already been called but isn't a fatal error if it hasn't
@@ -614,10 +619,6 @@ void cmdline_debug_print_cmdline()
if (Cmdline_deprecated_cache_bitmaps) {
mprintf(("Deprecated flag '-cache_bitmaps' found. Please remove from your cmdline.\n"));
}
if (Cmdline_deprecated_postprocess) {
mprintf(("Deprecated flag '-post_process' found. Please remove from your cmdline.\n"));
}
}
#endif
@@ -922,11 +923,11 @@ void os_process_cmdline(char* cmdline)
delete[] argv;
}
bool has_cmdline_only_or_get_flags(int argc, char *argv[])
bool has_cmdline_only_flag(int argc, char *argv[])
{
for (int i = 0; i < argc; ++i)
{
if (!strcmp(argv[i], PARSE_COMMAND_LINE_STRING) || !strcmp(argv[i], GET_FLAGS_STRING))
if (!strcmp(argv[i], PARSE_COMMAND_LINE_STRING))
{
return true;
}
@@ -958,9 +959,7 @@ void os_init_cmdline(int argc, char *argv[])
FILE *fp;
// Don't parse any command-line config files if we specified PARSE_COMMAND_LINE_STRING (to explicitly prevent it),
// or GET_FLAGS_STRING (because the engine is going to do a quick exit and for GitHub issue #1221)
if (!has_cmdline_only_or_get_flags(argc, argv)) {
if (!has_cmdline_only_flag(argc, argv)) {
// Only parse the config file in the current directory if we are in legacy config mode
if (os_is_legacy_mode()) {
// read the cmdline_fso.cfg file from the data folder, and pass the command line arguments to
@@ -1025,7 +1024,7 @@ void os_init_cmdline(int argc, char *argv[])
fclose(fp);
}
}
} // If cmdline included PARSE_COMMAND_LINE_STRING or GET_FLAGS_STRING
} // If cmdline included PARSE_COMMAND_LINE_STRING
// By parsing cmdline last, anything actually on the command line will take precedence.
os_parse_parms(argc, argv);
@@ -1041,7 +1040,7 @@ void os_init_cmdline(int argc, char *argv[])
* @param arg_type_ parameters arguement type (if any)
* @param stacks_ can the parameter be stacked
*/
cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_type_, const bool stacks_) noexcept:
cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_type_, const bool stacks_):
name(name_), help(help_), stacks(stacks_), arg_type(arg_type_)
{
args = NULL;
@@ -1064,7 +1063,7 @@ cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_t
// destructor - frees any allocated memory
cmdline_parm::~cmdline_parm() noexcept
cmdline_parm::~cmdline_parm()
{
#ifndef FRED
if (args) {
@@ -1470,7 +1469,7 @@ static void write_flags_file() {
}
static flag_output_type get_flags_output_type() {
Assertion(get_flags_arg.found(), "This function is only valid if " GET_FLAGS_STRING " is present!");
Assertion(get_flags_arg.found(), "This function is only valid if -get_flags is present!");
if (!get_flags_arg.has_param()) {
// Default to binary mode
@@ -1545,6 +1544,24 @@ bool SetCmdlineParams()
Cmdline_extra_warn = 1;
}
if ( missioncrcspew_arg.found() ) {
Cmdline_spew_mission_crcs = missioncrcspew_arg.str();
// strip off blank space at end if it's there
if ( Cmdline_spew_mission_crcs[strlen(Cmdline_spew_mission_crcs)-1] == ' ' ) {
Cmdline_spew_mission_crcs[strlen(Cmdline_spew_mission_crcs)-1] = '\0';
}
}
if ( tablecrcspew_arg.found() ) {
Cmdline_spew_table_crcs = tablecrcspew_arg.str();
// strip off blank space at end if it's there
if ( Cmdline_spew_table_crcs[strlen(Cmdline_spew_table_crcs)-1] == ' ' ) {
Cmdline_spew_table_crcs[strlen(Cmdline_spew_table_crcs)-1] = '\0';
}
}
if (!Fred_running) { //There is no standalone FRED
// is this a standalone server??
if (standalone_arg.found()) {
@@ -1635,11 +1652,6 @@ bool SetCmdlineParams()
Cmdline_network_port = port_arg.get_int();
}
// get IP address of gateway, for auto port forwarding
if ( gateway_ip_arg.found() ) {
Cmdline_gateway_ip = gateway_ip_arg.str();
}
// the connect argument specifies to join a game at this particular address
if ( connect_arg.found() ) {
Cmdline_use_last_pilot = 1;
@@ -1673,32 +1685,18 @@ bool SetCmdlineParams()
}
// d3d windowed
if(window_arg.found()) {
// We need to set both values since we don't know if we are going to use the new config system
options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "0");
if(window_arg.found()){
Cmdline_window = 1;
}
if ( fullscreen_window_arg.found( ) )
{
options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "1");
Cmdline_fullscreen_window = 1;
Cmdline_window = 0; /* Make sure no-one sets both */
}
if(res_arg.found()){
Cmdline_res = res_arg.str();
int width = 0;
int height = 0;
if ( sscanf(Cmdline_res, "%dx%d", &width, &height) == 2 ) {
SCP_string override;
sprintf(override, "{\"width\":%d,\"height\":%d}", width, height);
options::OptionsManager::instance()->setOverride("Graphics.Resolution", override);
} else {
mprintf(("Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".", Cmdline_res));
}
}
if(center_res_arg.found()){
Cmdline_center_res = center_res_arg.str();
@@ -1778,7 +1776,7 @@ bool SetCmdlineParams()
}
if ( nomotiondebris_arg.found() ) {
Motion_debris_enabled = false;
Cmdline_nomotiondebris = 1;
}
if( mipmap_arg.found() ) {
@@ -1790,11 +1788,11 @@ bool SetCmdlineParams()
}
if ( fov_arg.found() ) {
auto val = fov_arg.get_float();
if (val > 0.1) {
VIEWER_ZOOM_DEFAULT = val;
Cmdline_fov = fov_arg.get_float();
if (Cmdline_fov > 0.1) {
VIEWER_ZOOM_DEFAULT = Cmdline_fov;
} else {
VIEWER_ZOOM_DEFAULT = 0.75f;
VIEWER_ZOOM_DEFAULT = Cmdline_fov = 0.75f;
}
}
@@ -1808,7 +1806,7 @@ bool SetCmdlineParams()
}
if ( use_3dwarp.found() ) {
Fireball_use_3d_warp = true;
Cmdline_3dwarp = 1;
}
if ( use_warp_flash.found() ) {
@@ -1822,8 +1820,11 @@ bool SetCmdlineParams()
if ( stretch_menu.found() ) {
Cmdline_stretch_menu = 1;
}
// specular comand lines
if ( spec_exp_arg.found() ) {
specular_exponent_value = spec_exp_arg.get_float();
}
if ( spec_point_arg.found() ) {
static_point_factor = spec_point_arg.get_float();
}
@@ -1848,7 +1849,7 @@ bool SetCmdlineParams()
if(no_vsync_arg.found() )
{
Gr_enable_vsync = false;
Cmdline_no_vsync = 1;
}
if ( normal_arg.found() ) {
@@ -1860,44 +1861,13 @@ bool SetCmdlineParams()
}
if (fxaa_arg.found() ) {
Gr_aa_mode = AntiAliasMode::FXAA_Medium;
Cmdline_fxaa = true;
if (fxaa_preset_arg.found()) {
auto val = fxaa_preset_arg.get_int();
if (val > 6) {
Gr_aa_mode = AntiAliasMode::FXAA_High;
} else if (val > 3) {
Gr_aa_mode = AntiAliasMode::FXAA_Medium;
} else {
Gr_aa_mode = AntiAliasMode::FXAA_Low;
}
Cmdline_fxaa_preset = fxaa_preset_arg.get_int();
}
Gr_aa_mode_last_frame = Gr_aa_mode;
}
if (smaa_arg.found()) {
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
if (smaa_preset_arg.found()) {
switch (smaa_preset_arg.get_int()) {
case 0:
Gr_aa_mode = AntiAliasMode::SMAA_Low;
break;
case 1:
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
break;
case 2:
Gr_aa_mode = AntiAliasMode::SMAA_High;
break;
case 3:
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
break;
default:
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
break;
}
}
Fxaa_preset_last_frame = Cmdline_fxaa_preset;
}
if ( glow_arg.found() )
@@ -1922,9 +1892,6 @@ bool SetCmdlineParams()
if ( output_scripting_arg.found() )
Output_scripting_meta = true;
if (output_script_json_arg.found() )
Output_scripting_json = true;
if (output_sexp_arg.found() ) {
Cmdline_output_sexp_info = true;
}
@@ -1998,8 +1965,14 @@ bool SetCmdlineParams()
Cmdline_no_fbo = 1;
}
if ( emissive_arg.found() ) {
Cmdline_emissive = 1;
if ( noemissive_arg.found() ) {
Cmdline_no_emissive = 1;
}
if ( ogl_spec_arg.found() ) {
Cmdline_ogl_spec = ogl_spec_arg.get_float();
CLAMP(Cmdline_ogl_spec, 0.0f, 128.0f);
}
if ( rearm_timer_arg.found() )
@@ -2031,17 +2004,17 @@ bool SetCmdlineParams()
if ( fb_explosions_arg.found() )
{
Gr_framebuffer_effects.set(FramebufferEffects::Shockwaves, true);
Cmdline_fb_explosions = 1;
}
if (fb_thrusters_arg.found())
{
Gr_framebuffer_effects.set(FramebufferEffects::Thrusters, true);
Cmdline_fb_thrusters = true;
}
if ( no_postprocess_arg.found() )
if ( postprocess_arg.found() )
{
Gr_post_processing_enabled = false;
Cmdline_postprocess = 1;
}
if ( bloom_intensity_arg.found() )
@@ -2061,32 +2034,12 @@ bool SetCmdlineParams()
if( enable_shadows_arg.found() )
{
Shadow_quality = ShadowQuality::Medium;
Cmdline_shadow_quality = 2;
}
if( shadow_quality_arg.found() )
{
switch (shadow_quality_arg.get_int()) {
case 0:
Shadow_quality = ShadowQuality::Disabled;
break;
case 1:
Shadow_quality = ShadowQuality::Low;
break;
case 2:
Shadow_quality = ShadowQuality::Medium;
break;
case 3:
Shadow_quality = ShadowQuality::High;
break;
case 4:
Shadow_quality = ShadowQuality::Ultra;
break;
default:
mprintf(("Invalid shadow quality %d. Disabling shadows...\n", shadow_quality_arg.get_int()));
Shadow_quality = ShadowQuality::Disabled;
break;
}
Cmdline_shadow_quality = shadow_quality_arg.get_int();
}
if( no_deferred_lighting_arg.found() )
@@ -2188,14 +2141,6 @@ bool SetCmdlineParams()
Cmdline_deprecated_cache_bitmaps = true;
}
if (deprecated_no_emissive_arg.found()) {
Cmdline_emissive = 0;
}
if (deprecated_postprocess_arg.found()) {
Cmdline_deprecated_postprocess = true;
}
return true;
}
+13 -2
View File
@@ -53,22 +53,32 @@ extern char *Cmdline_center_res;
// FSO OPTIONS -------------------------------------------------
// Graphics related
extern double specular_exponent_value;
extern float Cmdline_clip_dist;
extern float Cmdline_fov;
extern float Cmdline_ogl_spec;
extern float static_light_factor;
extern float static_point_factor;
extern float static_tube_factor;
extern int Cmdline_ambient_factor;
extern int Cmdline_env;
extern int Cmdline_glow;
extern int Cmdline_nomotiondebris;
extern int Cmdline_noscalevid; // disables fit-to-window for movies - taylor
extern int Cmdline_spec;
extern int Cmdline_normal;
extern int Cmdline_height;
extern int Cmdline_enable_3d_shockwave;
extern int Cmdline_softparticles;
extern int Cmdline_postprocess;
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 int Cmdline_shadow_quality;
extern int Cmdline_no_deferred_lighting;
extern int Cmdline_emissive;
extern int Cmdline_no_emissive;
extern int Cmdline_aniso_level;
// Game Speed related
@@ -100,8 +110,9 @@ extern char *Cmdline_mod; // DTP for mod support
extern char *Cmdline_almission; // DTP for autoload mission (for multi only)
extern int Cmdline_ingamejoin;
extern int Cmdline_mpnoreturn;
extern char *Cmdline_spew_mission_crcs;
extern char *Cmdline_spew_table_crcs;
extern int Cmdline_objupd;
extern char *Cmdline_gateway_ip;
// Launcher related options
extern bool Cmdline_portable_mode;
+3 -7
View File
@@ -516,9 +516,7 @@ void control_config_list_prepare()
Num_cc_lines = y = z = 0;
while (z < CCFG_MAX) {
if (Control_config[z].tab == Tab && !Control_config[z].disabled) {
if (Control_config[z].indexXSTR > 1) {
Cc_lines[Num_cc_lines].label = XSTR(Control_config[z].text, Control_config[z].indexXSTR);
} else if (Control_config[z].indexXSTR == 1) {
if (Control_config[z].hasXSTR) {
Cc_lines[Num_cc_lines].label = XSTR(Control_config[z].text, CONTROL_CONFIG_XSTR + z);
} else {
Cc_lines[Num_cc_lines].label = Control_config[z].text;
@@ -1001,7 +999,7 @@ void control_config_reset_defaults(int presetnum)
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].indexXSTR = preset[i].indexXSTR;
Control_config[i].hasXSTR = preset[i].hasXSTR;
Control_config[i].type = preset[i].type;
Control_config[i].disabled = preset[i].disabled;
}
@@ -1984,9 +1982,7 @@ void control_config_do_frame(float frametime)
gr_get_string_size(&w, NULL, str);
gr_printf_menu(x - w / 2, y - font_height, "%s", str);
if (Control_config[i].indexXSTR > 1) {
strcpy_s(buf, XSTR(Control_config[i].text, Control_config[i].indexXSTR));
} else if (Control_config[i].indexXSTR == 1) {
if (Control_config[i].hasXSTR) {
strcpy_s(buf, XSTR(Control_config[i].text, CONTROL_CONFIG_XSTR + i));
} else {
strcpy_s(buf, Control_config[i].text);
+1 -10
View File
@@ -62,7 +62,7 @@ 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
int indexXSTR; //!< what string index we should use to translate this with an XSTR
bool hasXSTR; //!< whether we should translate this with an XSTR
const 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
@@ -270,15 +270,6 @@ enum IoActionId {
//!< ----------------------------
CYCLE_PRIMARY_WEAPON_SEQUENCE =118, //!< cycle num primaries to fire at once
//!< @n
//!< Custom control slots
//!< ----------------------------
CUSTOM_CONTROL_1 = 119,
CUSTOM_CONTROL_2 = 120,
CUSTOM_CONTROL_3 = 121,
CUSTOM_CONTROL_4 = 122,
CUSTOM_CONTROL_5 = 123,
/*!
* This must always be below the last defined item
*/
+124 -130
View File
@@ -42,159 +42,154 @@ int Invert_axis_defaults[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
//XSTR:OFF
config_item Control_config[CCFG_MAX + 1] = {
// targeting a ship
{ KEY_T, -1, TARGET_TAB, 1, "Target Next Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_T, -1, TARGET_TAB, 1, "Target Previous Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_H, 2, TARGET_TAB, 1, "Target Next Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_H, -1, TARGET_TAB, 1, "Target Previous Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_H, -1, TARGET_TAB, 1, "Toggle Auto Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_F, -1, TARGET_TAB, 1, "Target Next Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_F, -1, TARGET_TAB, 1, "Target Previous Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_Y, 4, TARGET_TAB, 1, "Target Ship in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_G, -1, TARGET_TAB, 1, "Target Target's Nearest Attacker", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_Y, -1, TARGET_TAB, 1, "Target Last Ship to Send Transmission", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, 1, "Turn Off Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_T, -1, TARGET_TAB, true, "Target Next Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_T, -1, TARGET_TAB, true, "Target Previous Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_H, 2, TARGET_TAB, true, "Target Next Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_H, -1, TARGET_TAB, true, "Target Previous Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_H, -1, TARGET_TAB, true, "Toggle Auto Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_F, -1, TARGET_TAB, true, "Target Next Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_F, -1, TARGET_TAB, true, "Target Previous Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_Y, 4, TARGET_TAB, true, "Target Ship in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_G, -1, TARGET_TAB, true, "Target Target's Nearest Attacker", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_Y, -1, TARGET_TAB, true, "Target Last Ship to Send Transmission", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, true, "Turn Off Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// targeting a ship's subsystem
{ KEY_V, -1, TARGET_TAB, 1, "Target Subsystem in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_S, -1, TARGET_TAB, 1, "Target Next Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_S, -1, TARGET_TAB, 1, "Target Previous Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, 1, "Turn Off Targeting of Subsystems", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_V, -1, TARGET_TAB, true, "Target Subsystem in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_S, -1, TARGET_TAB, true, "Target Next Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_S, -1, TARGET_TAB, true, "Target Previous Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, true, "Turn Off Targeting of Subsystems", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// matching speed
{ KEY_M, -1, COMPUTER_TAB, 1, "Match Target Speed", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_M, -1, COMPUTER_TAB, 1, "Toggle Auto Speed Matching", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_M, -1, COMPUTER_TAB, true, "Match Target Speed", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_M, -1, COMPUTER_TAB, true, "Toggle Auto Speed Matching", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// weapons
{ KEY_LCTRL, 0, WEAPON_TAB, 1, "Fire Primary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SPACEBAR, 1, WEAPON_TAB, 1, "Fire Secondary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PERIOD, -1, WEAPON_TAB, 1, "Cycle Forward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_COMMA, -1, WEAPON_TAB, 1, "Cycle Backward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DIVIDE, -1, WEAPON_TAB, 1, "Cycle Secondary Weapon Bank", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_DIVIDE, -1, WEAPON_TAB, 1, "Cycle Secondary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_X, 3, WEAPON_TAB, 1, "Launch Countermeasure", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_LCTRL, 0, WEAPON_TAB, true, "Fire Primary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SPACEBAR, 1, WEAPON_TAB, true, "Fire Secondary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PERIOD, -1, WEAPON_TAB, true, "Cycle Forward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_COMMA, -1, WEAPON_TAB, true, "Cycle Backward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Bank", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_X, 3, WEAPON_TAB, true, "Launch Countermeasure", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// controls
{ KEY_A, -1, SHIP_TAB, 1, "Forward Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_Z, -1, SHIP_TAB, 1, "Reverse Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD7, -1, SHIP_TAB, 1, "Bank Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD9, -1, SHIP_TAB, 1, "Bank Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD8, -1, SHIP_TAB, 1, "Pitch Forward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD2, -1, SHIP_TAB, 1, "Pitch Backward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD4, -1, SHIP_TAB, 1, "Turn Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD6, -1, SHIP_TAB, 1, "Turn Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_A, -1, SHIP_TAB, true, "Forward Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_Z, -1, SHIP_TAB, true, "Reverse Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD7, -1, SHIP_TAB, true, "Bank Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD9, -1, SHIP_TAB, true, "Bank Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD8, -1, SHIP_TAB, true, "Pitch Forward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD2, -1, SHIP_TAB, true, "Pitch Backward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD4, -1, SHIP_TAB, true, "Turn Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD6, -1, SHIP_TAB, true, "Turn Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
// throttle controls
{ KEY_BACKSP, -1, SHIP_TAB, 1, "Set Throttle to Zero", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SLASH, -1, SHIP_TAB, 1, "Set Throttle to Max", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_LBRACKET, -1, SHIP_TAB, 1, "Set Throttle to One-Third", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_RBRACKET, -1, SHIP_TAB, 1, "Set Throttle to Two-Thirds", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_EQUAL, -1, SHIP_TAB, 1, "Increase Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_MINUS, -1, SHIP_TAB, 1, "Decrease Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_BACKSP, -1, SHIP_TAB, true, "Set Throttle to Zero", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SLASH, -1, SHIP_TAB, true, "Set Throttle to Max", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_LBRACKET, -1, SHIP_TAB, true, "Set Throttle to One-Third", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_RBRACKET, -1, SHIP_TAB, true, "Set Throttle to Two-Thirds", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_EQUAL, -1, SHIP_TAB, true, "Increase Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_MINUS, -1, SHIP_TAB, true, "Decrease Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// squadmate messaging
{ KEY_SHIFTED | KEY_A, -1, COMPUTER_TAB, 1, "Attack My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_Z, -1, COMPUTER_TAB, 1, "Disarm My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_D, -1, COMPUTER_TAB, 1, "Disable My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, 1, "Attack My Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_X, -1, COMPUTER_TAB, 1, "Capture My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, 1, "Engage Enemy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, 1, "Form on My Wing", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, 1, "Ignore My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, 1, "Protect My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, 1, "Cover Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, 1, "Return to Base", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, 1, "Rearm Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_A, -1, COMPUTER_TAB, true, "Attack My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_Z, -1, COMPUTER_TAB, true, "Disarm My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_D, -1, COMPUTER_TAB, true, "Disable My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, true, "Attack My Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_X, -1, COMPUTER_TAB, true, "Capture My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Engage Enemy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, true, "Form on My Wing", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, true, "Ignore My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, true, "Protect My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, true, "Cover Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, true, "Return to Base", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, true, "Rearm Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_R, 6, TARGET_TAB, 1, "Target Closest Attacking Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_R, 6, TARGET_TAB, true, "Target Closest Attacking Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// Views
{ KEY_PADMULTIPLY, -1, COMPUTER_TAB, 1, "Chase View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADPERIOD, -1, COMPUTER_TAB, 1, "External View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADENTER, -1, COMPUTER_TAB, 1, "Toggle External Camera Lock", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAD0, -1, COMPUTER_TAB, 1, "Free Look View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PADDIVIDE, -1, COMPUTER_TAB, 1, "Current Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADPLUS, -1, COMPUTER_TAB, 1, "Increase View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PADMINUS, -1, COMPUTER_TAB, 1, "Decrease View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD5, -1, COMPUTER_TAB, 1, "Center View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 33, COMPUTER_TAB, 1, "View Up", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 32, COMPUTER_TAB, 1, "View Rear", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 34, COMPUTER_TAB, 1, "View Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 35, COMPUTER_TAB, 1, "View Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PADMULTIPLY, -1, COMPUTER_TAB, true, "Chase View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADPERIOD, -1, COMPUTER_TAB, true, "External View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADENTER, -1, COMPUTER_TAB, true, "Toggle External Camera Lock", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAD0, -1, COMPUTER_TAB, true, "Free Look View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false }, // Not in use anymore (Swifty)
{ KEY_PADDIVIDE, -1, COMPUTER_TAB, true, "Current Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADPLUS, -1, COMPUTER_TAB, true, "Increase View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PADMINUS, -1, COMPUTER_TAB, true, "Decrease View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD5, -1, COMPUTER_TAB, true, "Center View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 33, COMPUTER_TAB, true, "View Up", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 32, COMPUTER_TAB, true, "View Rear", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 34, COMPUTER_TAB, true, "View Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 35, COMPUTER_TAB, true, "View Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_RAPOSTRO, -1, COMPUTER_TAB, 1, "Cycle Radar Range", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_C, -1, COMPUTER_TAB, 1, "Communications Menu", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, -1, 1, "Show Objectives", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_J, -1, COMPUTER_TAB, 1, "Enter Subspace (End Mission)", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_J, -1, TARGET_TAB, 1, "Target Target's Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_TAB, 5, SHIP_TAB, 1, "Afterburner", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_RAPOSTRO, -1, COMPUTER_TAB, true, "Cycle Radar Range", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_C, -1, COMPUTER_TAB, true, "Communications Menu", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, -1, true, "Show Objectives", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_J, -1, COMPUTER_TAB, true, "Enter Subspace (End Mission)", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_J, -1, TARGET_TAB, true, "Target Target's Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_TAB, 5, SHIP_TAB, true, "Afterburner", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_INSERT, -1, COMPUTER_TAB, 1, "Increase Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DELETE, -1, COMPUTER_TAB, 1, "Decrease Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_HOME, -1, COMPUTER_TAB, 1, "Increase Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_END, -1, COMPUTER_TAB, 1, "Decrease Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAGEUP, -1, COMPUTER_TAB, 1, "Increase Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAGEDOWN, -1, COMPUTER_TAB, 1, "Decrease Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_D, -1, COMPUTER_TAB, 1, "Equalize Energy Settings", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_INSERT, -1, COMPUTER_TAB, true, "Increase Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DELETE, -1, COMPUTER_TAB, true, "Decrease Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_HOME, -1, COMPUTER_TAB, true, "Increase Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_END, -1, COMPUTER_TAB, true, "Decrease Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAGEUP, -1, COMPUTER_TAB, true, "Increase Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAGEDOWN, -1, COMPUTER_TAB, true, "Decrease Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_D, -1, COMPUTER_TAB, true, "Equalize Energy Settings", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_Q, 7, COMPUTER_TAB, 1, "Equalize Shields", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_UP, -1, COMPUTER_TAB, 1, "Augment Forward Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DOWN, -1, COMPUTER_TAB, 1, "Augment Rear Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_LEFT, -1, COMPUTER_TAB, 1, "Augment Left Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_RIGHT, -1, COMPUTER_TAB, 1, "Augment Right Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SCROLLOCK, -1, COMPUTER_TAB, 1, "Transfer Energy Laser->Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_SCROLLOCK, -1, COMPUTER_TAB, 1, "Transfer Energy Shield->Laser", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_Q, 7, COMPUTER_TAB, true, "Equalize Shields", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_UP, -1, COMPUTER_TAB, true, "Augment Forward Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DOWN, -1, COMPUTER_TAB, true, "Augment Rear Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_LEFT, -1, COMPUTER_TAB, true, "Augment Left Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_RIGHT, -1, COMPUTER_TAB, true, "Augment Right Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Laser->Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Shield->Laser", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// { -1, -1, -1, true, "Show Damage Popup Window" },
{ -1, -1, SHIP_TAB, 0, "Glide When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, -1, SHIP_TAB, false, "Glide When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
//Backslash -- this was a convenient place for Glide When Pressed, as Show Damage Popup isn't used
{ -1, -1, SHIP_TAB, 1, "Bank When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, -1, -1, 1, "Show Nav Map", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_E, -1, COMPUTER_TAB, 1, "Add or Remove Escort", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, 1, "Clear Escort List", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_E, -1, TARGET_TAB, 1, "Target Next Escort Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_R, -1, TARGET_TAB, 1, "Target Closest Repair Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, SHIP_TAB, true, "Bank When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, -1, -1, true, "Show Nav Map", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_E, -1, COMPUTER_TAB, true, "Add or Remove Escort", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Clear Escort List", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_E, -1, TARGET_TAB, true, "Target Next Escort Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_R, -1, TARGET_TAB, true, "Target Closest Repair Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_U, -1, TARGET_TAB, 1, "Target Next Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_U, -1, TARGET_TAB, 1, "Target Previous Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_N, -1, TARGET_TAB, 1, "Target Newest Ship in Area", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_K, -1, TARGET_TAB, 1, "Target Next Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_K, -1, TARGET_TAB, 1, "Target Previous Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_U, -1, TARGET_TAB, true, "Target Next Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_U, -1, TARGET_TAB, true, "Target Previous Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_N, -1, TARGET_TAB, true, "Target Newest Ship in Area", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_K, -1, TARGET_TAB, true, "Target Next Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_K, -1, TARGET_TAB, true, "Target Previous Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_B, -1, TARGET_TAB, 1, "Target Next Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_B, -1, TARGET_TAB, 1, "Target Previous Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_B, -1, TARGET_TAB, true, "Target Next Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_B, -1, TARGET_TAB, true, "Target Previous Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// multiplayer messaging keys
{ KEY_1, -1, COMPUTER_TAB, 1, "(Multiplayer) Message All", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_2, -1, COMPUTER_TAB, 1, "(Multiplayer) Message Friendly", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_3, -1, COMPUTER_TAB, 1, "(Multiplayer) Message Hostile", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_4, -1, COMPUTER_TAB, 1, "(Multiplayer) Message Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, 1, "(Multiplayer) Observer Zoom to Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, 1, "Increase Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, 1, "Decrease Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_L, -1, COMPUTER_TAB, 1, "Toggle High HUD Contrast", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, 1, "(Multiplayer) Toggle Network Info", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, 1, "(Multiplayer) Self Destruct", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_1, -1, COMPUTER_TAB, true, "(Multiplayer) Message All", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_2, -1, COMPUTER_TAB, true, "(Multiplayer) Message Friendly", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_3, -1, COMPUTER_TAB, true, "(Multiplayer) Message Hostile", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_4, -1, COMPUTER_TAB, true, "(Multiplayer) Message Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, true, "(Multiplayer) Observer Zoom to Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, true, "Increase Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, true, "Decrease Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_L, -1, COMPUTER_TAB, true, "Toggle High HUD Contrast", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, true, "(Multiplayer) Toggle Network Info", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, true, "(Multiplayer) Self Destruct", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// Misc
{ KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, 1, "Toggle HUD", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_3, -1, SHIP_TAB, 1, "Right Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_1, -1, SHIP_TAB, 1, "Left Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PADPLUS, -1, SHIP_TAB, 1, "Up Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PADENTER, -1, SHIP_TAB, 1, "Down Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, 1, "Toggle HUD Wireframe Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, COMPUTER_TAB, 0, "Top-Down View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, COMPUTER_TAB, 0, "Target Padlock View", CC_TYPE_TRIGGER, -1, -1, 0, false, false }, // (Swifty) Toggle for VM_TRACK
{ KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, true, "Toggle HUD", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_3, -1, SHIP_TAB, true, "Right Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_1, -1, SHIP_TAB, true, "Left Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PADPLUS, -1, SHIP_TAB, true, "Up Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PADENTER, -1, SHIP_TAB, true, "Down Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, true, "Toggle HUD Wireframe Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, COMPUTER_TAB, false, "Top-Down View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, COMPUTER_TAB, false, "Target Padlock View", CC_TYPE_TRIGGER, -1, -1, 0, false, false }, // (Swifty) Toggle for VM_TRACK
// Auto Navigation Systen
{ KEY_ALTED | KEY_A, -1, COMPUTER_TAB, 0, "Toggle Auto Pilot", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_N, -1, COMPUTER_TAB, 0, "Cycle Nav Points", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, 0, "Toggle Gliding", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_O, -1, WEAPON_TAB, 0, "Cycle Primary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_1, -1, COMPUTER_TAB, 0, "Custom Control 1", CC_TYPE_TRIGGER, -1, -1, 0, true, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_2, -1, COMPUTER_TAB, 0, "Custom Control 2", CC_TYPE_TRIGGER, -1, -1, 0, true, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_3, -1, COMPUTER_TAB, 0, "Custom Control 3", CC_TYPE_TRIGGER, -1, -1, 0, true, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_4, -1, COMPUTER_TAB, 0, "Custom Control 4", CC_TYPE_TRIGGER, -1, -1, 0, true, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_5, -1, COMPUTER_TAB, 0, "Custom Control 5", CC_TYPE_TRIGGER, -1, -1, 0, true, false },
{ -1, -1, -1, 0, "", CC_TYPE_TRIGGER, -1, -1, 0, false, false }
{ KEY_ALTED | KEY_A, -1, COMPUTER_TAB, false, "Toggle Auto Pilot", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_N, -1, COMPUTER_TAB, false, "Cycle Nav Points", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, false, "Toggle Gliding", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_O, -1, WEAPON_TAB, false, "Cycle Primary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, -1, false, "", CC_TYPE_TRIGGER, -1, -1, 0, false, false }
};
const char *Scan_code_text_german[] = {
@@ -509,9 +504,7 @@ char *translate_key(char *key)
// both key and joystick button are mapped to this control
if ((key_code >= 0 ) && (joy_code >= 0) ) {
strcpy_s(text, key_text);
strcat_s(text, " ");
strcat_s(text, XSTR("or", 1638));
strcat_s(text, " ");
strcat_s(text, " or ");
strcat_s(text, joy_text);
}
// if we only have one
@@ -591,6 +584,7 @@ void control_config_common_load_overrides();
void control_config_common_init()
{
for (int i=0; i<CCFG_MAX; i++) {
Control_config[i].disabled = false;
Control_config[i].continuous_ongoing = false;
}
@@ -847,7 +841,7 @@ void control_config_common_load_overrides()
* short key_default;
* short joy_default;
* char tab;
* int indexXSTR;
* bool hasXSTR;
* char type;
*/
@@ -889,7 +883,7 @@ void control_config_common_load_overrides()
if (optional_string("$Has XStr:")) {
stuff_int(&iTemp);
r_ccConfig.indexXSTR = iTemp;
r_ccConfig.hasXSTR = (iTemp == 1);
}
if (optional_string("$Type:")) {
+9 -18
View File
@@ -83,33 +83,24 @@ void cutscene_init()
if (optional_string("$cd:"))
{
// CD option isn't needed anymore. Consume the token and ignore it
// Option isn't needed anymore. Consume the token and ignore it
int junk;
stuff_int(&junk);
}
cutinfo.flags.reset();
cutinfo.viewable = false;
if (isFirstCutscene)
{
isFirstCutscene = false;
// The original code assumes the first movie is the intro, so make it viewable
cutinfo.flags.set(Cutscene::Cutscene_Flags::Viewable);
// The original code assumes the first movie is the intro, so always viewable
cutinfo.viewable = true;
}
if (optional_string("$Always Viewable:"))
{
bool flag;
stuff_boolean(&flag);
if (flag)
cutinfo.flags.set(Cutscene::Cutscene_Flags::Always_viewable);
}
if (optional_string("$Never Viewable:"))
{
bool flag;
stuff_boolean(&flag);
if (flag)
cutinfo.flags.set(Cutscene::Cutscene_Flags::Never_viewable);
stuff_boolean(&cutinfo.viewable);
}
Cutscenes.push_back(cutinfo);
@@ -152,7 +143,7 @@ void cutscene_mark_viewable(const char* filename)
// see if the stripped filename matches the cutscene filename
if (strstr(cut_file, file) != NULL)
{
cut->flags.set(Cutscene::Cutscene_Flags::Viewable);
cut->viewable = true;
return;
}
i++;
@@ -450,9 +441,9 @@ void cutscenes_screen_init()
Cutscene_list.clear();
int u = 0;
for (auto cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut, ++u)
for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut, u++)
{
if (cut->flags[Cutscene::Cutscene_Flags::Viewable, Cutscene::Cutscene_Flags::Always_viewable] && !cut->flags[Cutscene::Cutscene_Flags::Never_viewable])
if ((*cut).viewable)
{
Cutscene_list.push_back(u);
}
+9 -14
View File
@@ -10,31 +10,26 @@
#ifndef _FREESPACE_CUTSCENES_SCREEN_HEADER_FILE
#define _FREESPACE_CUTSCENES_SCREEN_HEADER_FILE
#include "globalincs/flagset.h"
#include "globalincs/globals.h"
#include "globalincs/pstypes.h"
namespace Cutscene
{
FLAG_LIST(Cutscene_Flags)
{
Viewable = 0,
Always_viewable,
Never_viewable,
NUM_VALUES
};
}
typedef struct cutscene_info
{
char filename[MAX_FILENAME_LEN];
char name[NAME_LENGTH];
char* description;
flagset<Cutscene::Cutscene_Flags> flags;
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
// initializa table data
void cutscene_init();
+2
View File
@@ -974,6 +974,8 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
// SET PHYSICS PARAMETERS
// already have (hitpos - heavy) and light_cm_pos
// get heavy cm pos - already have light_cm_pos
debris_hit_info->heavy_collision_cm_pos = zero;
// get r_heavy and r_light
debris_hit_info->r_heavy = debris_hit_info->hit_pos;
File diff suppressed because it is too large. Load diff
@@ -24,6 +24,7 @@ layout (std140) uniform globalDeferredData {
float middist;
float fardist;
float specFactor;
float invScreenWidth;
float invScreenHeight;
};
+1 -1
View File
@@ -20,7 +20,7 @@ void main()
// If the scene is in fog then we change the color we operate on based on the depth of the pixel
float depth_val = texture(depth_tex, fragTexCoord.xy).x;
// Transform depth value from [-1, 1] to [0, 1]
float depth_normalized = fma(depth_val, 0.5, 0.5);
float depth_normalized = 2.0 * depth_val - 1.0;
// Now we compute the depth value in projection space using the clipping plane information
float view_depth = 2.0 * zNear * zFar / (zFar + zNear - depth_normalized * (zFar - zNear));
+2 -2
View File
@@ -8,7 +8,7 @@ const float SPEC_INTENSITY_POINT = 5.3 ;// Point light
const float SPEC_INTENSITY_DIRECTIONAL = 3.0 ;// Directional light
const float SPECULAR_FACTOR = 1.75;
const float SPECULAR_ALPHA = 0.1;
const float SPEC_FACTOR_NO_SPEC_MAP = 0.1;
const float SPEC_FACTOR_NO_SPEC_MAP = 0.6;
const float ENV_ALPHA_FACTOR = 0.3;
const float GLOW_MAP_INTENSITY = 1.5;
const float AMBIENT_LIGHT_BOOST = 1.0;
@@ -55,4 +55,4 @@ vec3 computeLighting(vec3 specColor, vec3 light, vec3 normal, vec3 halfVec, vec3
#else
return SpecularGGX(specColor, light, normal, halfVec, view, gloss, fresnelFactor, dotNL);
#endif
}
}
@@ -1,23 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 0
#define SMAA_INCLUDE_PS 1
#include "SMAA.sdr"
in vec2 fragTexCoord;
in vec2 fragPixcoord;
in vec4 fragOffset[3];
out vec4 fragOut0;
uniform sampler2D edgesTex;
uniform sampler2D areaTex;
uniform sampler2D searchTex;
void main() {
fragOut0 = SMAABlendingWeightCalculationPS(fragTexCoord, fragPixcoord, fragOffset, edgesTex, areaTex, searchTex, vec4(0.0));
}
@@ -1,22 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 1
#define SMAA_INCLUDE_PS 0
#include "SMAA.sdr"
in vec4 vertPosition;
in vec2 vertTexCoord;
out vec2 fragTexCoord;
out vec2 fragPixcoord;
out vec4 fragOffset[3];
void main() {
gl_Position = vertPosition;
fragTexCoord = vertTexCoord;
SMAABlendingWeightCalculationVS(vertTexCoord, fragPixcoord, fragOffset);
}
@@ -1,20 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 0
#define SMAA_INCLUDE_PS 1
#include "SMAA.sdr"
in vec2 fragTexCoord;
in vec4 fragOffset[3];
out vec4 fragOut0;
uniform sampler2D colorTex;
void main() {
fragOut0 = vec4(SMAALumaEdgeDetectionPS(fragTexCoord, fragOffset, colorTex), 0.0, 1.0);
}
@@ -1,21 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 1
#define SMAA_INCLUDE_PS 0
#include "SMAA.sdr"
in vec4 vertPosition;
in vec2 vertTexCoord;
out vec2 fragTexCoord;
out vec4 fragOffset[3];
void main() {
gl_Position = vertPosition;
fragTexCoord = vertTexCoord;
SMAAEdgeDetectionVS(vertTexCoord, fragOffset);
}
@@ -1,21 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 0
#define SMAA_INCLUDE_PS 1
#include "SMAA.sdr"
in vec2 fragTexCoord;
in vec4 fragOffset;
out vec4 fragOut0;
uniform sampler2D colorTex;
uniform sampler2D blendTex;
void main() {
fragOut0 = SMAANeighborhoodBlendingPS(fragTexCoord, fragOffset, colorTex, blendTex);
}
@@ -1,21 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 1
#define SMAA_INCLUDE_PS 0
#include "SMAA.sdr"
in vec4 vertPosition;
in vec2 vertTexCoord;
out vec2 fragTexCoord;
out vec4 fragOffset;
void main() {
gl_Position = vertPosition;
fragTexCoord = vertTexCoord;
SMAANeighborhoodBlendingVS(vertTexCoord, fragOffset);
}
+6 -14
View File
@@ -1,21 +1,22 @@
/*
* 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.
*
*/
*/
#include "fireball/fireballs.h"
#include "asteroid/asteroid.h"
#include "cmdline/cmdline.h"
#include "fireball/fireballs.h"
#include "gamesnd/gamesnd.h"
#include "graphics/tmapper.h"
#include "localization/localize.h"
#include "model/model.h"
#include "object/object.h"
#include "options/Option.h"
#include "parse/parselo.h"
#include "render/3d.h"
#include "render/batching.h"
@@ -45,15 +46,6 @@ int Num_fireball_types = 0;
bool fireballs_inited = false;
bool fireballs_parsed = false;
bool Fireball_use_3d_warp = false;
static auto WarpOption = options::OptionBuilder<bool>("Graphics.3dWarp", "3D Warp", "Use a 3D model for warp effects")
.category("Graphics")
.default_val(true)
.level(options::ExpertLevel::Advanced)
.bind_to(&Fireball_use_3d_warp)
.importance(65)
.finish();
/**
* Play warp in sound for warp effect
*/
-2
View File
@@ -137,6 +137,4 @@ float fireball_wormhole_intensity( fireball *fb );
// Goober5000
extern int Knossos_warp_ani_used;
extern bool Fireball_use_3d_warp;
#endif /* _FIREBALLS_H */
+7 -5
View File
@@ -49,9 +49,11 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
vm_vec_scale_add( &center, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
// Cyborg17, Initialize the *whole* struct, set some starting values and share with the rest of the array.
verts[0] = {};
verts[0].r = verts[0].g = verts[0].b = verts[0].a = 255;
verts[0].r = 255;
verts[0].g = 255;
verts[0].b = 255;
verts[0].a = 255;
verts[1] = verts[2] = verts[3] = verts[4] = verts[0];
if (warp_glow_bitmap >= 0) {
@@ -98,7 +100,7 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
}
}
if ( (warp_model_id >= 0) && (warp_3d || Fireball_use_3d_warp) ) {
if ( (warp_model_id >= 0) && (warp_3d || Cmdline_3dwarp) ) {
model_render_params render_info;
float scale = radius / 25.0f;
@@ -135,7 +137,7 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
vm_vec_scale_add2( &vecs[3], &orient->vec.rvec, -radius );
vm_vec_scale_add2( &vecs[3], &orient->vec.fvec, Grid_depth );
// vm_vec_scale_add( &vecs[4], center, &orient->vec.fvec, -Grid_depth );
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
vecs[4] = center;
verts[0].texture_position.u = 0.01f;
File diff suppressed because it is too large. Load diff
+84
View File
@@ -0,0 +1,84 @@
/*
* 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 _FS2NETD_CLIENT_H
#define _FS2NETD_CLIENT_H
#include "network/multi.h"
struct net_addr;
class player;
// channel to associate when creating a server
extern char Multi_fs_tracker_channel[];
// channel to use when polling the tracker for games
extern char Multi_fs_tracker_filter[];
typedef struct tracker_game_data {
char name[MAX_GAMENAME_LEN+1];
char mission_name[MAX_GAMENAME_LEN+1];
char title[NAME_LENGTH+1];
char campaign_name[NAME_LENGTH+1];
char chat_channel[MAX_PATH+1];
ubyte campaign_mode;
int flags;
int type_flags;
short players;
short max_players;
ubyte mode;
ubyte rank_base;
ubyte game_state;
ubyte speed;
} tracker_game_data;
extern tracker_game_data Multi_tracker_game_data;
bool fs2netd_is_online();
void fs2netd_reset_connection();
void fs2netd_disconnect();
void fs2netd_close();
bool fs2netd_login();
void fs2netd_maybe_init();
void fs2netd_do_frame();
void fs2netd_gameserver_start();
void fs2netd_gameserver_update(bool force = false);
void fs2netd_gameserver_disconnect();
void fs2netd_send_game_request();
void fs2netd_store_stats();
bool fs2netd_player_banned(net_addr *addr);
void fs2netd_update_ban_list();
bool fs2netd_get_valid_missions();
int fs2netd_update_valid_tables();
int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_call);
void fs2netd_options_config_init();
void fs2netd_add_table_validation(const char *tblname);
void fs2netd_update_game_count(const char *chan_name);
#endif // _FS2NETD_CLIENT_H
+89
View File
@@ -0,0 +1,89 @@
// Protocol.h
// Protocol Definitions for FS2Open PXO
// Derek Meek
// 2-14-2003
// ############## ATTENTION ##########
// Licensed under the Academic Free License version 2.0
// View License at http://www.opensource.org/licenses/afl-2.0.php
// ###################################
#if !defined(__pxo_protocol_h_)
#define __pxo_protocol_h_
#include "globalincs/globals.h"
#include "globalincs/pstypes.h"
#define PXO_PROTO_VER "2.0"
// Packet IDs
#define PCKT_ID_FIRST 0x00
#define PCKT_SLIST_REQUEST 0x01
#define PCKT_SLIST_REPLY 0x02
#define PCKT_SLIST_HB 0x03
#define PCKT_LOGIN_AUTH 0x04
#define PCKT_LOGIN_REPLY 0x05
#define PCKT_MISSIONS_RQST 0x06
#define PCKT_MISSIONS_REPLY 0x07
#define PCKT_TABLES_RQST 0x08
#define PCKT_TABLES_REPLY 0x09
#define PCKT_PILOT_GET 0x0a
#define PCKT_PILOT_REPLY 0x0b
#define PCKT_PILOT_UPDATE 0x0c
#define PCKT_PILOT_UREPLY 0x0d
#define PCKT_PING 0x0e
#define PCKT_PONG 0x0f
#define PCKT_MISSION_CHECK 0x10
#define PCKT_MCHECK_REPLY 0x11
#define PCKT_BANLIST_RQST 0x12
#define PCKT_BANLIST_RPLY 0x13
#define PCKT_NETOWRK_WALL 0x14
#define PCKT_VALID_SID_RQST 0x15
#define PCKT_VALID_SID_REPLY 0x16
#define PCKT_CHAT_CHANNEL_UPD 0x17
#define PCKT_CHAT_CHAN_COUNT_RQST 0x18
#define PCKT_CHAT_CHAN_COUNT_REPLY 0x19
#define PCKT_SLIST_HB_2 0x1a
#define PCKT_SERVER_DISCONNECT 0x1b
#define PCKT_DUP_LOGIN_RQST 0x1c
#define PCKT_DUP_LOGIN_REPLY 0x1d
#define PCKT_SLIST_REQUEST_FILTER 0x1e
#define PCKT_SERVER_START 0x1f
#define PCKT_SERVER_UPDATE 0x20
#define PCKT_ID_LAST 0x21
#define PCKT_INVALID 0xff
#define VALID_PACKET_ID(p) (((p) > PCKT_ID_FIRST) && ((p) < PCKT_ID_LAST))
struct crc_valid_status {
char name[NAME_LENGTH];
uint crc32;
ubyte valid;
};
struct file_record
{
char name[33];
uint crc32;
};
struct fs2open_ship_typekill
{
char name[NAME_LENGTH];
ushort kills;
};
#endif
+848
View File
@@ -0,0 +1,848 @@
// TCP_Client.cpp
// TCP Client Functions for FS2Open PXO
// Derek Meek
// 2-14-2003
// ############## ATTENTION ##########
// Licensed under the Academic Free License version 2.0
// View License at http://www.opensource.org/licenses/afl-2.0.php
// ###################################
#include "fs2netd/fs2netd_client.h"
#include "fs2netd/protocol.h"
#include "fs2netd/tcp_client.h"
#include "fs2netd/tcp_socket.h"
#include "globalincs/pstypes.h"
#include "io/timer.h"
#include "network/multi.h"
#include "network/multi_log.h"
#include "network/multiutil.h"
#include "playerman/player.h"
#include "ship/ship.h"
#include "io/timer.h"
#include "globalincs/pstypes.h"
#include "osapi/osapi.h"
#include <iostream>
#include <string>
#include <climits>
extern SCP_vector<crc_valid_status> Table_valid_status;
int FS2NetD_CheckSingleMission(const char *m_name, uint crc32, bool do_send)
{
int buffer_size, buffer_offset;
bool my_packet = false;
char buffer[100];
if (do_send) {
INIT_PACKET( PCKT_MISSION_CHECK );
PXO_ADD_STRING( m_name );
PXO_ADD_UINT( crc32 );
DONE_PACKET();
if ( FS2NetD_SendData(buffer, buffer_size) == -1 ) {
return 3;
}
} else if ( FS2NetD_DataReady() ) {
int rc;
uint rc_total = 0;
do {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total);
if (rc <= 0) {
break;
}
rc_total += rc;
os_sleep(20);
} while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) );
if (rc < BASE_PACKET_SIZE) {
return 0;
}
VRFY_PACKET2( PCKT_MCHECK_REPLY );
if ( !my_packet ) {
return 0;
}
ubyte status = 0;
PXO_GET_DATA( status );
Assert( (status == 0) || (status == 1) );
// anything beyond 'true' is considered a failure of some kind
if (status > 1) {
status = 0;
}
return status+1;
}
return 0;
}
int FS2NetD_SendPlayerData(const char *player_name, player *pl, bool do_send)
{
int buffer_size, buffer_offset;
bool my_packet = false;
char buffer[16384];
if (do_send) {
int i, num_type_kills = 0;
// send packet... (fs2open_pilot_update)
INIT_PACKET( PCKT_PILOT_UPDATE );
PXO_ADD_INT( Multi_tracker_id );
PXO_ADD_STRING( player_name ); // name
PXO_ADD_STRING( Multi_tracker_login ); // user
PXO_ADD_INT( pl->stats.score ); // points
PXO_ADD_UINT( pl->stats.missions_flown ); // missions
PXO_ADD_UINT( pl->stats.flight_time ); // flighttime
PXO_ADD_INT( pl->stats.last_flown ); // LastFlight
PXO_ADD_INT( pl->stats.kill_count ); // Kills
PXO_ADD_INT( pl->stats.kill_count_ok ); // NonFriendlyKills
PXO_ADD_INT( pl->stats.assists ); // Assists
PXO_ADD_UINT( pl->stats.p_shots_fired ); // PriShots
PXO_ADD_UINT( pl->stats.p_shots_hit ); // PriHits
PXO_ADD_UINT( pl->stats.p_bonehead_hits ); // PriFHits
PXO_ADD_UINT( pl->stats.s_shots_fired ); // SecShots
PXO_ADD_UINT( pl->stats.s_shots_hit ); // SecHits
PXO_ADD_UINT( pl->stats.s_bonehead_hits ); // SecFHits
PXO_ADD_INT( pl->stats.rank ); // rank
for (i = 0; i < MAX_SHIP_CLASSES; i++) {
if (pl->stats.kills[i] > 0) {
Assert( (pl->stats.kills[i] >= 0) && (pl->stats.kills[i] < USHRT_MAX) );
num_type_kills++;
}
}
Assert( (num_type_kills >= 0) && (num_type_kills < USHRT_MAX) );
PXO_ADD_USHORT( (ushort)num_type_kills );
for (i = 0; i < MAX_SHIP_CLASSES; i++) {
if (pl->stats.kills[i] > 0) {
PXO_ADD_STRING( Ship_info[i].name );
PXO_ADD_USHORT( (ushort)pl->stats.kills[i] );
}
}
Assert( (Num_medals >= 0) && (Num_medals < USHRT_MAX) );
PXO_ADD_USHORT( (ushort)Num_medals );
for (i = 0; i < Num_medals; i++) {
PXO_ADD_INT( pl->stats.medal_counts[i] );
}
DONE_PACKET();
if ( FS2NetD_SendData(buffer, buffer_size) == -1 ) {
return -1;
}
} else if ( FS2NetD_DataReady() ) {
int rc;
uint rc_total = 0;
do {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total);
if (rc <= 0) {
break;
}
rc_total += rc;
os_sleep(20);
} while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) );
if (rc < BASE_PACKET_SIZE) {
return -1;
}
VRFY_PACKET2( PCKT_PILOT_UREPLY );
if ( !my_packet ) {
return -1;
}
ubyte status;
PXO_GET_DATA( status );
Assert( (status == 0) || (status == 1) || (status == 2) );
if (status > 2) {
status = 2;
}
return (int)status;
}
return -1;
}
int FS2NetD_GetPlayerData(const char *player_name, player *pl, bool can_create, bool do_send)
{
int buffer_size, buffer_offset;
bool my_packet = false;
char buffer[16384];
if (do_send) {
ubyte create = (ubyte)can_create;
INIT_PACKET( PCKT_PILOT_GET );
PXO_ADD_INT( (can_create) ? Multi_tracker_id : -2 );
PXO_ADD_STRING( player_name );
PXO_ADD_DATA( create );
DONE_PACKET();
if ( FS2NetD_SendData(buffer, buffer_size) == -1 ) {
return -1;
}
} else if ( FS2NetD_DataReady() ) {
const fix end_time = timer_get_fixed_seconds() + (15 * F1_0);
int rc;
uint rc_total = 0;
ubyte reply_type = 0;
int si_index = 0;
ushort bogus __UNUSED;
ushort num_type_kills = 0, num_medals = 0;
char ship_name[NAME_LENGTH];
int idx;
do {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total);
if (rc <= 0) {
break;
}
rc_total += rc;
os_sleep(20);
} while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) );
if (rc < BASE_PACKET_SIZE) {
return -1;
}
VRFY_PACKET2( PCKT_PILOT_REPLY );
if ( !my_packet ) {
return -1;
}
if ( buffer_size > (int)sizeof(buffer) ) {
ml_printf("FS2NetD WARNING: Pilot update data is larger than receive buffer! Some data will be lost!");
}
// make sure that we get the entire packet
while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
if ( FS2NetD_DataReady() ) {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total);
if (rc <= 0) {
continue;
}
rc_total += rc;
}
os_sleep(20);
}
PXO_GET_DATA( reply_type );
// if we weren't retrieved then bail out now
if (reply_type != 0) {
return (int)reply_type;
}
PXO_GET_INT( pl->stats.score ); // points
PXO_GET_UINT( pl->stats.missions_flown ); // missions
PXO_GET_UINT( pl->stats.flight_time ); // flighttime
PXO_GET_INT( pl->stats.last_flown ); // LastFlight
PXO_GET_INT( pl->stats.kill_count ); // Kills
PXO_GET_INT( pl->stats.kill_count_ok ); // NonFriendlyKills
PXO_GET_INT( pl->stats.assists ); // Assists
PXO_GET_UINT( pl->stats.p_shots_fired ); // PriShots
PXO_GET_UINT( pl->stats.p_shots_hit ); // PriHits
PXO_GET_UINT( pl->stats.p_bonehead_hits ); // PriFHits
PXO_GET_UINT( pl->stats.s_shots_fired ); // SecShots
PXO_GET_UINT( pl->stats.s_shots_hit ); // SecHits
PXO_GET_UINT( pl->stats.s_bonehead_hits ); // SecFHits
PXO_GET_INT( pl->stats.rank ); // rank
PXO_GET_USHORT( num_type_kills );
for (idx = 0; idx < (int)num_type_kills; idx++) {
memset( ship_name, 0, sizeof(ship_name) );
PXO_GET_STRING( ship_name );
si_index = ship_info_lookup( ship_name );
if (si_index == -1) {
PXO_GET_USHORT( bogus );
} else {
PXO_GET_USHORT( pl->stats.kills[si_index] );
}
}
PXO_GET_USHORT( num_medals );
for (idx = 0; (idx < Num_medals) && (idx < num_medals); idx++) {
PXO_GET_INT( pl->stats.medal_counts[idx] );
}
return (int)reply_type;
}
return -1;
}
int FS2NetD_GetBanList(SCP_vector<SCP_string> &mask_list, bool do_send)
{
int buffer_size, buffer_offset;
bool my_packet = false;
char buffer[16384];
if (do_send) {
INIT_PACKET( PCKT_BANLIST_RQST );
DONE_PACKET();
if ( FS2NetD_SendData(buffer, buffer_size) == -1 ) {
return -1;
}
} else if ( FS2NetD_DataReady() ) {
const fix end_time = timer_get_fixed_seconds() + (15 * F1_0);
int rc;
uint rc_total = 0;
int num_files = 0;
char ip_mask[32];
int idx;
do {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total);
if (rc <= 0) {
break;
}
rc_total += rc;
os_sleep(20);
} while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) );
if (rc < BASE_PACKET_SIZE) {
return -1;
}
VRFY_PACKET2( PCKT_BANLIST_RPLY );
if ( !my_packet ) {
return 0;
}
if ( buffer_size > (int)sizeof(buffer) ) {
ml_printf("FS2NetD WARNING: Banned user list data is larger than receive buffer! Some data will be lost!");
}
// make sure that we get the entire packet
while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
if ( FS2NetD_DataReady() ) {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total);
if (rc <= 0) {
continue;
}
rc_total += rc;
}
os_sleep(20);
}
PXO_GET_INT( num_files );
for (idx = 0; idx < num_files; idx++) {
PXO_GET_STRING( ip_mask );
mask_list.push_back( ip_mask );
}
return 1;
}
return 0;
}
int FS2NetD_GetMissionsList(SCP_vector<file_record> &m_list, bool do_send)
{
int buffer_size, buffer_offset;
bool my_packet = false;
char buffer[16384];
if (do_send) {
INIT_PACKET( PCKT_MISSIONS_RQST );
DONE_PACKET();
if ( FS2NetD_SendData(buffer, buffer_size) == -1 ) {
return -1;
}
} else if ( FS2NetD_DataReady() ) {
const fix end_time = timer_get_fixed_seconds() + (15 * F1_0);
int rc;
uint rc_total = 0;
int i, num_files = 0;
file_record nrec;
do {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total);
if (rc <= 0) {
break;
}
rc_total += rc;
os_sleep(20);
} while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) );
if (rc < BASE_PACKET_SIZE) {
return 0;
}
VRFY_PACKET2( PCKT_MISSIONS_REPLY );
if ( !my_packet ) {
return 0;
}
if ( buffer_size > (int)sizeof(buffer) ) {
ml_printf("FS2NetD WARNING: Mission list data is larger than receive buffer! Some data will be lost!");
}
// make sure that we get the entire packet
while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
if ( FS2NetD_DataReady() ) {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total);
if (rc <= 0) {
continue;
}
rc_total += rc;
}
os_sleep(20);
}
PXO_GET_INT( num_files );
for (i = 0; i < num_files; i++) {
memset(&nrec, 0, sizeof(file_record));
PXO_GET_STRING( nrec.name );
PXO_GET_UINT( nrec.crc32 );
m_list.push_back( nrec );
}
return 1;
}
return 0;
}
int FS2NetD_Login(const char *username, const char *password, bool do_send)
{
int buffer_size, buffer_offset;
bool my_packet = false;
char buffer[150];
if (do_send) {
INIT_PACKET( PCKT_LOGIN_AUTH );
PXO_ADD_STRING( username );
PXO_ADD_STRING( password );
PXO_ADD_USHORT( Multi_options_g.port );
DONE_PACKET();
if (FS2NetD_SendData(buffer, buffer_size) == -1) {
return -1;
}
} else if ( FS2NetD_DataReady() ) {
int rc;
uint rc_total = 0;
ubyte login_status = 0;
int sid __UNUSED;
short pilots __UNUSED;
do {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total);
if (rc <= 0) {
break;
}
rc_total += rc;
os_sleep(20);
} while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) );
if (rc < BASE_PACKET_SIZE) {
return -1;
}
VRFY_PACKET2( PCKT_LOGIN_REPLY );
if ( !my_packet ) {
return -1;
}
PXO_GET_DATA( login_status );
if ( !login_status ) {
return -2;
}
PXO_GET_INT( sid );
PXO_GET_SHORT( pilots );
return sid;
}
return -1;
}
void FS2NetD_SendServerStart()
{
int buffer_size;
char buffer[550];
ubyte tvar;
INIT_PACKET( PCKT_SERVER_START );
PXO_ADD_STRING( Netgame.name );
PXO_ADD_STRING( Netgame.mission_name );
PXO_ADD_STRING( Netgame.title );
PXO_ADD_STRING( Netgame.campaign_name );
tvar = (ubyte)Netgame.campaign_mode;
PXO_ADD_DATA( tvar );
PXO_ADD_INT( Netgame.flags );
PXO_ADD_INT( Netgame.type_flags );
PXO_ADD_SHORT( (short)multi_num_players() );
PXO_ADD_SHORT( (short)Netgame.max_players );
tvar = (ubyte)Netgame.mode;
PXO_ADD_DATA( tvar );
tvar = (ubyte)Netgame.rank_base;
PXO_ADD_DATA( tvar );
tvar = (ubyte)Netgame.game_state;
PXO_ADD_DATA( tvar );
tvar = (ubyte)multi_get_connection_speed();
PXO_ADD_DATA( tvar );
PXO_ADD_STRING(Multi_fs_tracker_channel);
DONE_PACKET();
if (FS2NetD_SendData(buffer, buffer_size) < 0) {
ml_printf("FS2NetD WARNING: Failed to send server start packet!");
}
}
void FS2NetD_SendServerUpdate()
{
int buffer_size;
char buffer[550];
ubyte tvar;
INIT_PACKET( PCKT_SERVER_UPDATE );
PXO_ADD_STRING( Netgame.mission_name );
PXO_ADD_STRING( Netgame.title );
PXO_ADD_STRING( Netgame.campaign_name );
tvar = (ubyte)Netgame.campaign_mode;
PXO_ADD_DATA( tvar );
PXO_ADD_SHORT( (short)multi_num_players() );
tvar = (ubyte)Netgame.game_state;
PXO_ADD_DATA( tvar );
DONE_PACKET();
if (FS2NetD_SendData(buffer, buffer_size) < 0) {
ml_printf("FS2NetD WARNING: Failed to send server update packet!");
}
}
void FS2NetD_SendServerDisconnect()
{
int buffer_size;
char buffer[BASE_PACKET_SIZE];
INIT_PACKET( PCKT_SERVER_DISCONNECT );
DONE_PACKET();
if (FS2NetD_SendData(buffer, buffer_size) < 0) {
ml_printf("FS2NetD WARNING: Failed to send server disconnect packet!");
}
}
void FS2NetD_RequestServerList()
{
int buffer_size;
char buffer[BASE_PACKET_SIZE+sizeof(int)+sizeof(int)+sizeof(int)+MAX_PATH];
int all = 0xFFFFFFFF;
bool filtered = false;
if ( strlen(Multi_fs_tracker_filter) ) {
filtered = true;
}
// send request packet
INIT_PACKET( (filtered) ? PCKT_SLIST_REQUEST_FILTER : PCKT_SLIST_REQUEST );
PXO_ADD_INT( all ); // type
PXO_ADD_INT( all ); // status
if (filtered) {
PXO_ADD_STRING(Multi_fs_tracker_filter);
}
DONE_PACKET();
FS2NetD_SendData(buffer, buffer_size);
}
void FS2NetD_Ping()
{
int buffer_size;
char buffer[BASE_PACKET_SIZE+sizeof(int)];
INIT_PACKET( PCKT_PING );
int time = timer_get_milliseconds();
PXO_ADD_INT( time );
DONE_PACKET();
if (FS2NetD_SendData(buffer, buffer_size) < 0) {
ml_printf("Failed to send PING packet!");
}
}
void FS2NetD_Pong(int tstamp)
{
int buffer_size;
char buffer[BASE_PACKET_SIZE+sizeof(int)];
INIT_PACKET( PCKT_PONG );
PXO_ADD_INT( tstamp );
DONE_PACKET();
FS2NetD_SendData(buffer, buffer_size);
}
int FS2NetD_CheckValidID()
{
int buffer_size;
char buffer[BASE_PACKET_SIZE+sizeof(int)];
// create and send request packet
INIT_PACKET( PCKT_VALID_SID_RQST );
PXO_ADD_INT( Multi_tracker_id );
DONE_PACKET();
if (FS2NetD_SendData(buffer, buffer_size) == -1) {
return -1;
}
return 0;
}
int FS2NetD_ValidateTableList(bool do_send)
{
int buffer_size, buffer_offset;
bool my_packet = false;
char buffer[4096];
ushort num_tables = 0;
if (do_send) {
// create and send the request packet
INIT_PACKET( PCKT_TABLES_RQST );
num_tables = (ushort)Table_valid_status.size();
PXO_ADD_USHORT( num_tables );
for (SCP_vector<crc_valid_status>::iterator tvs = Table_valid_status.begin(); tvs != Table_valid_status.end(); ++tvs) {
PXO_ADD_STRING(tvs->name );
PXO_ADD_UINT( tvs->crc32 );
}
DONE_PACKET();
if (FS2NetD_SendData(buffer, buffer_size) == -1) {
return -1;
}
} else if ( FS2NetD_DataReady() ) {
int rc;
const fix end_time = timer_get_fixed_seconds() + (15 * F1_0);
ubyte tbl_valid_status = 0;
uint rc_total = 0;
do {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total);
if (rc <= 0) {
break;
}
rc_total += rc;
os_sleep(20);
} while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) );
if (rc < BASE_PACKET_SIZE) {
return -1;
}
VRFY_PACKET2( PCKT_TABLES_REPLY );
if ( !my_packet ) {
return -1;
}
// make sure that we get the entire packet
while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
if ( FS2NetD_DataReady() ) {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total);
if (rc <= 0) {
continue;
}
rc_total += rc;
}
os_sleep(20);
}
PXO_GET_USHORT( num_tables );
if ( !num_tables ) {
return -1;
}
if ( num_tables > (int)Table_valid_status.size() ) {
ml_printf("FS2NetD WARNING: Table list contains %i tables, but we only requested " SIZE_T_ARG "! Invalid data!", num_tables, Table_valid_status.size());
return -1;
}
for (SCP_vector<crc_valid_status>::iterator tvs = Table_valid_status.begin(); tvs != Table_valid_status.end(); ++tvs) {
PXO_GET_DATA( tbl_valid_status );
Assert( (tbl_valid_status == 0) || (tbl_valid_status == 1) );
tvs->valid = tbl_valid_status;
}
return 2;
}
return 0;
}
void FS2NetD_GameCountUpdate(const char *chan_name)
{
int buffer_size;
char buffer[MAX_PATH+BASE_PACKET_SIZE+10];
INIT_PACKET( PCKT_CHAT_CHAN_COUNT_RQST );
PXO_ADD_STRING( chan_name );
DONE_PACKET();
FS2NetD_SendData(buffer, buffer_size);
}
void FS2NetD_CheckDuplicateLogin()
{
int buffer_size;
char buffer[BASE_PACKET_SIZE + sizeof(int) + sizeof(ubyte) + (MAX_PLAYERS * sizeof(int)) + 10];
int ids_count = 0;
int *ids = new int[MAX_PLAYERS];
int idx;
if ( !ids ) {
return;
}
for (idx = 0; idx < MAX_PLAYERS; idx++) {
if ( MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx]) ) {
if ( (Net_players[idx].tracker_player_id >= 0) && (Net_players[idx].tracker_player_id != Multi_tracker_id) ) {
ids[ids_count] = Net_players[idx].tracker_player_id;
ids_count++;
}
}
}
if ( !ids_count ) {
delete [] ids;
return;
}
INIT_PACKET( PCKT_DUP_LOGIN_RQST );
PXO_ADD_INT( Multi_tracker_id );
Assert( MAX_PLAYERS <= 255 );
ubyte tvar = (ubyte)ids_count;
PXO_ADD_DATA( tvar );
for (idx = 0; idx < ids_count; idx++) {
PXO_ADD_INT( ids[idx] );
}
DONE_PACKET();
if (FS2NetD_SendData(buffer, buffer_size) < 0) {
ml_printf("FS2NetD WARNING: Failed to send data packet to server!");
}
delete [] ids;
}
+82
View File
@@ -0,0 +1,82 @@
// Client.h
// Client Functions for FS2Open PXO
// Derek Meek
// 2-14-2003
// ############## ATTENTION ##########
// Licensed under the Academic Free License version 2.0
// View License at http://www.opensource.org/licenses/afl-2.0.php
// ###################################
#if !defined(__pxo_client_h_)
#define __pxo_client_h_
#include "fs2netd/protocol.h"
#include "fs2netd/tcp_socket.h"
#include "globalincs/pstypes.h"
#include <string>
class player;
struct netgame_info;
int FS2NetD_CheckSingleMission(const char *m_name, uint crc32, bool do_send);
int FS2NetD_SendPlayerData(const char *player_name, player *pl, bool do_send);
int FS2NetD_GetPlayerData(const char *player_name, player *pl, bool can_create, bool do_send);
int FS2NetD_GetBanList(SCP_vector<SCP_string> &mask_list, bool do_send);
int FS2NetD_GetMissionsList(SCP_vector<file_record> &m_list, bool do_send);
int FS2NetD_ValidateTableList(bool do_send);
int FS2NetD_Login(const char *username, const char *password, bool do_send);
int FS2NetD_CheckValidID();
void FS2NetD_CheckDuplicateLogin();
void FS2NetD_SendServerStart();
void FS2NetD_SendServerUpdate();
void FS2NetD_SendServerDisconnect();
void FS2NetD_RequestServerList();
void FS2NetD_GameCountUpdate(const char *chan_name);
void FS2NetD_Ping();
void FS2NetD_Pong(int tstamp);
// Some easy to use macros for handling the packet data
#define BASE_PACKET_SIZE (int)(sizeof(ubyte) + sizeof(int))
#define PXO_ADD_DATA(d) do { Assert(buffer_size+sizeof(d) <= sizeof(buffer)); memcpy(buffer+buffer_size, &d, sizeof(d)); buffer_size += sizeof(d); } while (0)
#define PXO_ADD_SHORT(d) do { Assert(buffer_size+sizeof(short) <= sizeof(buffer)); short swap = INTEL_SHORT(d); memcpy(buffer+buffer_size, &swap, sizeof(short)); buffer_size += sizeof(short); } while (0)
#define PXO_ADD_USHORT(d) do { Assert(buffer_size+sizeof(ushort) <= sizeof(buffer)); ushort swap = INTEL_SHORT(d); memcpy(buffer+buffer_size, &swap, sizeof(ushort)); buffer_size += sizeof(ushort); } while (0)
#define PXO_ADD_INT(d) do { Assert(buffer_size+sizeof(int) <= sizeof(buffer)); int swap = INTEL_INT(d); memcpy(buffer+buffer_size, &swap, sizeof(int)); buffer_size += sizeof(int); } while (0)
#define PXO_ADD_UINT(d) do { Assert(buffer_size+sizeof(uint) <= sizeof(buffer)); uint swap = INTEL_INT(d); memcpy(buffer+buffer_size, &swap, sizeof(uint)); buffer_size += sizeof(uint); } while (0)
#define PXO_ADD_STRING(s) do { Assert(buffer_size+strlen(s)+sizeof(int) <= sizeof(buffer)); int len = (int)strlen(s); PXO_ADD_INT(len); if (len > 0) { memcpy(buffer+buffer_size, s, len ); buffer_size += len; } } while(0)
#define PXO_GET_DATA(d) do { Assert(buffer_offset+sizeof(d) <= sizeof(buffer)); memcpy(&d, buffer+buffer_offset, sizeof(d) ); buffer_offset += sizeof(d); } while(0)
#define PXO_GET_SHORT(d) do { Assert(buffer_offset+sizeof(short) <= sizeof(buffer)); short swap; memcpy(&swap, buffer+buffer_offset, sizeof(short) ); d = INTEL_SHORT(swap); buffer_offset += sizeof(short); } while(0)
#define PXO_GET_USHORT(d) do { Assert(buffer_offset+sizeof(ushort) <= sizeof(buffer)); ushort swap; memcpy(&swap, buffer+buffer_offset, sizeof(ushort) ); d = INTEL_SHORT(swap); buffer_offset += sizeof(ushort); } while(0)
#define PXO_GET_INT(d) do { Assert(buffer_offset+sizeof(int) <= sizeof(buffer)); int swap; memcpy(&swap, buffer+buffer_offset, sizeof(int) ); d = INTEL_INT(swap); buffer_offset += sizeof(int); } while(0)
#define PXO_GET_UINT(d) do { Assert(buffer_offset+sizeof(uint) <= sizeof(buffer)); uint swap; memcpy(&swap, buffer+buffer_offset, sizeof(uint) ); d = INTEL_INT(swap); buffer_offset += sizeof(uint); } while(0)
#define PXO_GET_STRING(s) do { Assert(buffer_offset+sizeof(int) <= sizeof(buffer)); s[0] = '\0'; int len; memcpy(&len, buffer+buffer_offset, sizeof(int)); len = INTEL_INT(len); buffer_offset += sizeof(int); if (len > 0) { memcpy(s, buffer+buffer_offset, len); buffer_offset += len; s[len] = '\0'; } } while(0)
// initialize a packet
#define INIT_PACKET(x) { memset(buffer, 0, sizeof(buffer)); buffer_size = 0; ubyte pckt = (x); PXO_ADD_DATA(pckt); PXO_ADD_INT(buffer_size); }
// we are done with a new packet, so update the final packet size
#define DONE_PACKET() { int swap = INTEL_INT(buffer_size); memcpy(buffer+sizeof(ubyte), &swap, sizeof(buffer_size)); }
// verify received packet
#define VRFY_PACKET(x) { buffer_offset = 0; ubyte pckt; PXO_GET_DATA(pckt); if (pckt != (x)) break; my_packet = true; PXO_GET_INT(buffer_size); }
#define VRFY_PACKET2(x) { buffer_offset = 0; ubyte pckt; PXO_GET_DATA(pckt); if (pckt == (x)) my_packet = true; PXO_GET_INT(buffer_size); }
#endif
+349
View File
@@ -0,0 +1,349 @@
// TCP_Socket.cpp
// TCP_Socket for FS2Open PXO
// Derek Meek
// 2-14-2003
// ############## ATTENTION ##########
// Licensed under the Academic Free License version 2.0
// View License at http://www.opensource.org/licenses/afl-2.0.php
// ###################################
#include "fs2netd/tcp_socket.h"
#include "globalincs/pstypes.h"
#include "network/multi_log.h"
#ifdef SCP_UNIX
#include <sys/time.h> // The OS X 10.3 SDK appears to need this for some reason (for timeval struct)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <cstdlib>
#include <unistd.h>
#include <cerrno>
#include <sys/ioctl.h>
#include <csignal>
#ifdef SCP_SOLARIS
#include <sys/filio.h>
#endif
#include <cctype>
#define WSAGetLastError() (errno)
#define RESTART(syscall) \
({ \
__typeof__(syscall) _res; \
do \
_res = syscall; \
while (_res == -1 && errno == EINTR); \
_res; \
})
#else
#include <windows.h>
#include <process.h>
typedef int socklen_t;
#endif
static bool Connecting = false;
static bool Connected = false;
static SOCKET mySocket = INVALID_SOCKET;
static sockaddr_in FS2NetD_addr;
void FS2NetD_Disconnect()
{
if (mySocket != INVALID_SOCKET) {
shutdown(mySocket, 2);
closesocket(mySocket);
mySocket = INVALID_SOCKET;
}
Connected = false;
Connecting = false;
}
int FS2NetD_ConnectToServer(const char *host, const char *port)
{
struct hostent *my_host = NULL;
char host_str[254]; // 253 is max domain name length: http://en.wikipedia.org/wiki/Domain_Name_System#Domain_name_syntax
#ifdef SCP_UNIX
int my_error = 0;
#endif
if ( !Connecting ) {
#ifdef WIN32
WSADATA wsa;
int rc = WSAStartup(MAKEWORD(2,0), &wsa);
if (rc != 0) {
ml_printf("FS2NetD ERROR: Failed to start WinSock!");
return -1;
}
#endif
memset(&FS2NetD_addr, 0, sizeof(sockaddr_in));
FS2NetD_addr.sin_family = AF_INET;
FS2NetD_addr.sin_addr.s_addr = INADDR_ANY;
FS2NetD_addr.sin_port = 0;
mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (mySocket == (SOCKET)SOCKET_ERROR) {
#ifdef SCP_UNIX
my_error = errno;
ml_printf("FS2NetD ERROR: Couldn't get socket (\"%s\")!", strerror(my_error));
#else
ml_printf("FS2NetD ERROR: Couldn't get socket!");
#endif
return -1;
}
if ( bind(mySocket, (sockaddr *)&FS2NetD_addr, sizeof(sockaddr)) == SOCKET_ERROR ) {
#ifdef SCP_UNIX
my_error = errno;
ml_printf("FS2NetD ERROR: Couldn't bind socket (\"%s\")!", strerror(my_error));
#else
ml_printf("FS2NetD ERROR: Couldn't bind socket!");
#endif
return -1;
}
// set to non-blocking mode
ulong arg = 1;
ioctlsocket(mySocket, FIONBIO, &arg);
// Where SO_NOSIGPIPE is defined (currently OS X):
// prevent SIGPIPE, which is generated when sending after receiver disconnected
// on other *nix use MSG_NOSIGNAL flag when sending data, or, failing that, use signal masking
// see FS2NetD_SendData()
#if defined(SCP_UNIX) && defined(SO_NOSIGPIPE)
int nosigpipe = 1;
if (setsockopt(mySocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nosigpipe, sizeof(nosigpipe)) == -1) {
my_error = errno;
ml_printf("FS2NetD ERROR: Couldn't set SO_NOSIGPIPE on socket (\"%s\")!", strerror(my_error));
}
#endif // SCP_UNIX && SO_NOSIGPIPE
// blasted MS, probably need to use getaddrinfo() here for Win32, but I
// want to keep this as clean and simple as possible and that means
// using an actual standard :)
strcpy_s( host_str, host );
// check that we aren't in a dotted format, some gethostbyname() implementations don't like that
// (NOTE: Yes, I'm aware that this is problematic if a host name uses an initial digit)
if ( !isdigit(host_str[0]) ) {
my_host = gethostbyname( host );
if (my_host == NULL) {
// NOTE: that we don't do specific error reporting here since it's totally different
// on Win32, compared to everything else that is actually standard
ml_printf("Failure from gethostbyname() for host '%s'", host);
return -1;
} else if (my_host->h_addrtype != AF_INET) {
ml_printf("Invalid address type returned by gethostbyname()!");
return -1;
} else if (my_host->h_addr_list[0] == NULL) {
ml_printf("Unable to determine IP from host name '%s'", host);
return -1;
}
FS2NetD_addr.sin_addr.s_addr = ((in_addr *)(my_host->h_addr_list[0]))->s_addr;
}
// we might be in dotted format so try using it as such
else {
FS2NetD_addr.sin_addr.s_addr = inet_addr( host );
}
if (FS2NetD_addr.sin_addr.s_addr == INADDR_ANY) {
ml_printf("No valid server address to connect with!");
return -1;
}
// we need to set the correct port before moving on
long m_port = strtol(port, (char**)NULL, 10);
FS2NetD_addr.sin_port = htons( (ushort)m_port );
if ( connect(mySocket, (sockaddr *)&FS2NetD_addr, sizeof(sockaddr)) == SOCKET_ERROR ) {
if ( WSAGetLastError() == WSAEWOULDBLOCK ) {
Connecting = true;
return 0;
} else {
#ifdef SCP_UNIX
int errv = errno;
ml_printf("FS2NetD ERROR: Couldn't connect to remote system at %s (\"%s\")!", inet_ntoa(FS2NetD_addr.sin_addr), strerror(errv));
#else
ml_printf("FS2NetD ERROR: Couldn't connect to remote system at %s!", inet_ntoa(FS2NetD_addr.sin_addr));
#endif
}
return -1;
}
// technically there should always be an error since we should be non-blocking
else {
Connecting = true;
Connected = true;
return 1;
}
}
// done starting the connection, so lets see if we are actually connected yet
else {
if (Connected) {
Int3();
return 1;
}
fd_set write_fds, error_fds;
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 1;
FD_ZERO(&write_fds);
FD_SET(mySocket, &write_fds);
// if it's writeable then we are fully connected
if ( select(static_cast<int>(mySocket + 1), NULL, &write_fds, NULL, &timeout) > 0 ) {
// make sure that we don't have any connect() errors (since it's non-blocking)
int err_val = 0;
size_t err_val_size = sizeof(err_val);
getsockopt(mySocket, SOL_SOCKET, SO_ERROR, (char*)&err_val, (socklen_t*)&err_val_size);
if (err_val) {
// if we aren't still in blocking mode then we can't connect
if (err_val != WSAEWOULDBLOCK) {
return -1;
}
return 0;
}
Connected = true;
return 1;
}
FD_ZERO(&error_fds);
FD_SET(mySocket, &error_fds);
// if it's in error then it has failed to connect
if ( select(static_cast<int>(mySocket + 1), NULL, NULL, &error_fds, &timeout) )
return -1;
// not connected, and haven't failed to connect, so keep in the loop
return 0;
}
}
int FS2NetD_GetData(char *buffer, int blen)
{
int flags = 0;
// clear the buffer
memset(buffer, 0, blen);
socklen_t from_len = sizeof(sockaddr);
return recvfrom(mySocket, buffer, blen, flags, (sockaddr*)&FS2NetD_addr, &from_len);
}
int FS2NetD_SendData(char *buffer, int blen)
{
int flags = 0;
// on Unix with MSG_NOSIGNAL, prevent SIGPIPE, which is generated if receiver has disconnected
// the MSG_NOSIGNAL flag doesn't work on OS X or Solaris
// on OS X, use setsockopt() with SO_NOSIGPIPE instead, see above
#if defined(SCP_UNIX) && defined(MSG_NOSIGNAL)
flags |= MSG_NOSIGNAL;
#endif // SCP_UNIX && MSG_NOSIGNAL
socklen_t to_len = sizeof(sockaddr);
// Borrowed from Kroki:
// https://github.com/kroki/XProbes/blob/1447f3d93b6dbf273919af15e59f35cca58fcc23/src/libxprobes.c#L156
#if defined(SCP_UNIX) && !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
/*
We want to ignore possible SIGPIPE that we can generate on write.
SIGPIPE is delivered *synchronously* and *only* to the thread
doing the write. So if it is reported as already pending (which
means the thread blocks it), then we do nothing: if we generate
SIGPIPE, it will be merged with the pending one (there's no
queuing), and that suits us well. If it is not pending, we block
it in this thread (and we avoid changing signal action, because it
is per-process).
*/
sigset_t pending;
sigset_t sigpipe_mask;
bool sigpipe_pending;
bool sigpipe_unblock;
sigemptyset(&pending);
sigpending(&pending);
sigpipe_pending = sigismember(&pending, SIGPIPE);
if (!sigpipe_pending) {
sigset_t blocked;
sigemptyset(&blocked);
pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &blocked);
/* Maybe is was blocked already? */
sigpipe_unblock = ! sigismember(&blocked, SIGPIPE);
}
#endif /* defined(SCP_UNIX) && ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE) */
auto sent_chars = sendto(mySocket, buffer, blen, flags, (sockaddr*)&FS2NetD_addr, to_len);
#if defined(SCP_UNIX) && !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
/*
If SIGPIPE was pending already we do nothing. Otherwise, if it
become pending (i.e., we generated it), then we sigwait() it (thus
clearing pending status). Then we unblock SIGPIPE, but only if it
were us who blocked it.
*/
if (!sigpipe_pending) {
sigemptyset(&pending);
sigpending(&pending);
if (sigismember(&pending, SIGPIPE)) {
/*
Protect ourselves from a situation when SIGPIPE was sent
by the user to the whole process, and was delivered to
other thread before we had a chance to wait for it.
*/
static const struct timespec nowait = { 0, 0 };
RESTART(sigtimedwait(&sigpipe_mask, NULL, &nowait));
}
if (sigpipe_unblock) {
pthread_sigmask(SIG_UNBLOCK, &sigpipe_mask, NULL);
}
}
#endif /* defined(SCP_UNIX) && ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE) */
return sent_chars;
}
bool FS2NetD_DataReady()
{
timeval wait;
wait.tv_sec = 0;
wait.tv_usec = 1;
fd_set recvs;
FD_ZERO(&recvs);
FD_SET(mySocket, &recvs);
#ifndef SCP_UNIX
int status = select(1, &recvs, NULL, NULL, &wait);
#else
int status = select(mySocket+1, &recvs, NULL, NULL, &wait);
#endif
return ( (status != 0) && (status != -1) && FD_ISSET(mySocket, &recvs) );
}
+28
View File
@@ -0,0 +1,28 @@
// TCP_Socket.h
// TCP_Socket for FS2Open PXO
// Derek Meek
// 2-14-2003
// ############## ATTENTION ##########
// Licensed under the Academic Free License version 2.0
// View License at http://www.opensource.org/licenses/afl-2.0.php
// ###################################
#if !defined(__TCP_SOCKET_H_)
#define __TCP_SOCKET_H_
#include "globalincs/pstypes.h" // make sure _cdecl is defined correctly on *nix
int FS2NetD_ConnectToServer(const char *host, const char *port);
void FS2NetD_Disconnect();
int FS2NetD_GetData(char *buffer, int blen);
int FS2NetD_SendData(char *buffer, int blen);
bool FS2NetD_DataReady();
#endif // __TCP_SOCKET_H_
+1 -1
View File
@@ -246,7 +246,7 @@ enum class GameSounds {
/**
* Interface sounds
*/
enum class InterfaceSounds {
enum InterfaceSounds {
IFACE_MOUSE_CLICK =0, //!< mouse click
ICON_PICKUP =1, //!< pick up a ship icon (Empty in Retail)
ICON_DROP_ON_WING =2, //!< drop a ship icon on a wing slot
-75
View File
@@ -1,75 +0,0 @@
#include "crashdump.h"
#ifdef WIN32
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable:4091) // a microsoft header has warnings. Very nice.
#endif
// clang-format off
#include <windows.h>
#include <dbghelp.h>
// clang-format on
#ifdef _MSC_VER
#pragma warning (pop)
#endif
#include "globalincs/pstypes.h"
void make_minidump(EXCEPTION_POINTERS* e)
{
const auto hDbgHelp = LoadLibraryA("dbghelp");
if (hDbgHelp == nullptr)
return;
const auto pMiniDumpWriteDump = reinterpret_cast<decltype(&MiniDumpWriteDump)>(
reinterpret_cast<void*>(GetProcAddress(hDbgHelp, "MiniDumpWriteDump")));
if (pMiniDumpWriteDump == nullptr)
return;
char name[MAX_PATH];
{
const auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(nullptr), name, MAX_PATH);
SYSTEMTIME t;
GetSystemTime(&t);
wsprintfA(nameEnd - strlen(".exe"), "_%4d%02d%02d_%02d%02d%02d.mdmp", t.wYear, t.wMonth, t.wDay, t.wHour,
t.wMinute, t.wSecond);
}
const auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
return;
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = e;
exceptionInfo.ClientPointers = FALSE;
pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile,
MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
e ? &exceptionInfo : nullptr, nullptr, nullptr);
CloseHandle(hFile);
mprintf(("CRASH DETECTED!!! Wrote crash dump to %s\n", name));
}
LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e)
{
make_minidump(e);
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
namespace crashdump {
void installCrashHandler()
{
#ifdef WIN32
SetUnhandledExceptionFilter(unhandled_handler);
#endif
}
} // namespace crashdump
-7
View File
@@ -1,7 +0,0 @@
#pragma once
namespace crashdump {
void installCrashHandler();
}
-9
View File
@@ -125,17 +125,8 @@ class flagset {
void from_u64(std::uint64_t num) { values = (unsigned long) num; }
std::uint64_t to_u64() const { return (std::uint64_t) values.to_ulong(); }
size_t hash() const { return std::hash<std::bitset<SIZE>>()(values); }
};
namespace std {
template <typename T, size_t N>
struct hash<::flagset<T, N>> {
size_t operator()(const ::flagset<T, N>& val) { return val.hash(); }
};
} // namespace std
#define FLAG_LIST(Type) enum class Type : size_t
template<typename TEnum, size_t SIZE>
+1 -1
View File
@@ -62,7 +62,7 @@ do { \
(elem)->next->prev = (elem)->prev; \
(elem)->next = NULL; \
(elem)->prev = NULL; \
} while(false)
} while(0)
// Moves elem to be after head
#define list_move_append(head, elem) \
+13 -9
View File
@@ -240,11 +240,11 @@ extern int Global_error_count;
// or,
// Error( LOCATION, "Error opening %s", filename );
/*******************NEVER COMMENT Assert ************************************************/
// Please never comment the functionality of Assert in debug
/*******************NEVER UNCOMMENT Assert ************************************************/
// Please never uncomment the functionality of Assert in debug
// The code, as with all development like this is littered with Asserts which are designed to throw
// up an error message if variables are out of range.
// Disabling this functionality is dangerous, crazy values can run rampant unchecked, and the longer it's disabled
// Disabling this functionality is dangerous, crazy values can run rampent unchecked and the longer its disabled
// the more likely you are to have problems getting it working again.
#if defined(NDEBUG)
# define Assert(expr) do { ASSUME(expr); } while (false)
@@ -259,18 +259,22 @@ extern int Global_error_count;
/*******************NEVER COMMENT Assert ************************************************/
// Goober5000 - define Verify for use in both release and debug mode
#define Verify(x) do { if (!(x)){ Error(LOCATION, "Verify failure: %s\n", #x); } ASSUME(x); } while(false)
#define Verify(x) do { if (!(x)){ Error(LOCATION, "Verify failure: %s\n", #x); } ASSUME(x); } while(0)
// Verification (like Assertion)
// VerifyEx
#ifndef _MSC_VER // non MS compilers
# define Verification(x, y, ...) do { if (!(x)) { Error(LOCATION, "Verify failure: %s with help text " #y "\n", #x, ##__VA_ARGS__); } ASSUME(x); } while(false)
# define VerifyEx(x, y, ...) do { if (!(x)) { Error(LOCATION, "Verify failure: %s with help text " #y "\n", #x, ##__VA_ARGS__); } ASSUME(x); } while(0)
#else
# define Verification(x, y, ...) do { if (!(x)) { Error(LOCATION, "Verify failure: %s with help text " #y "\n", #x, __VA_ARGS__); } ASSUME(x); } while(false)
# if _MSC_VER >= 1400 // VC 2005 or greater
# define VerifyEx(x, y, ...) do { if (!(x)) { Error(LOCATION, "Verify failure: %s with help text " #y "\n", #x, __VA_ARGS__); } ASSUME(x); } while(0)
# else // everything else
# define VerifyEx(x, y) Verify(x)
# endif
#endif
#if defined(NDEBUG)
// No debug version of Int3
#define Int3() do { } while (false)
#define Int3() do { } while (0)
#else
void debug_int3(const char *file, int line);
@@ -446,7 +450,7 @@ SCP_string dump_stacktrace();
// DEBUG compile time catch for dangerous uses of memset/memcpy/memmove
// This is disabled for VS2013 and lower since that doesn't support the necessary features
#if !defined(NDEBUG) && !defined(USING_THIRD_PARTY_LIBS) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && defined(SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE)
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && defined(HAVE_STD_IS_TRIVIALLY_COPYABLE)
// feature support seems to be: gcc clang msvc
// auto 4.4 2.9 2010
// std::is_trivial 4.5 ? 2012 (2010 only duplicates std::is_pod)
+1
View File
@@ -4,6 +4,7 @@
#pragma once
#include "scp_compiler_detection.h"
#include "platformChecks.h"
#define SCP_TOKEN_CONCAT1(x, y) x ## y
#define SCP_TOKEN_CONCAT(x, y) SCP_TOKEN_CONCAT1(x, y)
+23 -7
View File
@@ -37,14 +37,30 @@
#define ASSUME(x)
#if defined(NDEBUG)
# define Assertion(expr, msg, ...) do { ASSUME(expr); } while (false)
# if _MSC_VER >= 1400 /* MSVC 2005 or newer */
# define Assertion(expr, msg, ...) do { ASSUME(expr); } while (false)
# else
# define Assertion(expr, msg) do {} while (false)
# endif
#else
# define Assertion(expr, msg, ...) \
do { \
if (!(expr)) { \
os::dialogs::AssertMessage(#expr, __FILE__, __LINE__, msg, __VA_ARGS__); \
} \
} while (false)
/*
* NOTE: Assertion() can only use its proper functionality in compilers
* that support variadic macros.
*/
# if _MSC_VER >= 1400 /* MSVC 2005 or newer */
# define Assertion(expr, msg, ...) \
do { \
if (!(expr)) { \
os::dialogs::AssertMessage(#expr, __FILE__, __LINE__, msg, __VA_ARGS__); \
} \
} while (false)
# else /* Older MSVC compilers */
# define Assertion(expr, msg) \
do { \
if (!(expr)) { \
os::dialogs::AssertMessage(#expr, __FILE__, __LINE__); \
} while (false)
# endif
#endif
/* C++11 Standard Detection */
-1
View File
@@ -61,7 +61,6 @@ version get_executable_version() {
version::version(int major_in, int minor_in, int build_in, int revision_in) :
major(major_in), minor(minor_in), build(build_in), revision(revision_in) {
}
bool version::isValid() const { return major != 0 || minor != 0 || build != 0 || revision != 0; }
bool version::operator<(const version& v) const {
if (major < v.major) {
-2
View File
@@ -57,8 +57,6 @@ struct version {
version(int major, int minor, int build, int revision);
bool isValid() const;
bool operator<(const version& other) const;
bool operator==(const version& other) const;
bool operator!=(const version& other) const;
+7 -41
View File
@@ -3,15 +3,15 @@
/* SCP_vm_allocator - maintained by portej05 (i.e. please don't patch this one yourself!) */
#include <deque>
#include <vector>
#include <list>
#include <map>
#include <queue>
#include <sstream>
#include <string>
#include <type_traits>
#include <sstream>
#include <queue>
#include <deque>
#include <unordered_map>
#include <vector>
#include <sstream>
template< typename T >
using SCP_vector = std::vector< T, std::allocator< T > >;
@@ -35,41 +35,7 @@ using SCP_queue = std::queue< T, std::deque< T, std::allocator< T > > >;
template< typename T >
using SCP_deque = std::deque< T, std::allocator< T > >;
#if __cplusplus < 201402L
template <class T, bool>
struct enum_hasher_util {
inline size_t operator()(const T& elem) { return std::hash<T>()(elem); }
};
template <class T>
struct enum_hasher_util<T, true> {
inline size_t operator()(const T& elem)
{
typedef typename std::underlying_type<T>::type enumType;
return std::hash<enumType>()(static_cast<enumType>(elem));
}
};
/**
* @brief An enum class compatible hashing class
*
* This is the same as std::hash except that is can handle enum classes properly using their underlying type. This is
* only required for C++ < 14 since after that the standard mandates that enum classes should be hashable.
*
* @tparam T The type that should be hashed
*/
template <class T>
struct SCP_hash {
inline size_t operator()(const T& elem) const { return enum_hasher_util<T, std::is_enum<T>::value>()(elem); }
};
#else
// No need for the special hash class so just use the standard hash
template <typename T>
using SCP_hash = std::hash<T>;
#endif
template <typename Key, typename T, typename Hash = SCP_hash<Key>, typename KeyEqual = std::equal_to<Key>>
using SCP_unordered_map = std::unordered_map<Key, T, Hash, KeyEqual, std::allocator<std::pair<const Key, T>>>;
template< typename Key, typename T, typename Hash = std::hash<Key>, typename KeyEqual = std::equal_to<Key> >
using SCP_unordered_map = std::unordered_map< Key, T, Hash, KeyEqual, std::allocator< std::pair<const Key, T> > >;
#endif // _VMALLOCATOR_H_INCLUDED_
+68 -301
View File
@@ -29,14 +29,13 @@
#include "graphics/light.h"
#include "graphics/matrix.h"
#include "graphics/opengl/gropengl.h"
#include "graphics/opengl/gropengldraw.h"
#include "graphics/paths/PathRenderer.h"
#include "graphics/util/GPUMemoryHeap.h"
#include "graphics/util/UniformBuffer.h"
#include "graphics/util/UniformBufferManager.h"
#include "io/keycontrol.h" // m!m
#include "io/timer.h"
#include "libs/jansson.h"
#include "options/Option.h"
#include "osapi/osapi.h"
#include "parse/parselo.h"
#include "popup/popup.h"
@@ -50,7 +49,6 @@
#endif
#include "SDL_surface.h"
#include "material.h"
const char *Resolution_prefixes[GR_NUM_RESOLUTIONS] = { "", "2_" };
@@ -105,249 +103,6 @@ float Gr_save_menu_zoomed_offset_X = 0.0f, Gr_save_menu_zoomed_offset_Y = 0.0f;
bool Save_custom_screen_size;
bool Deferred_lighting = false;
bool High_dynamic_range = false;
static int videodisplay_deserializer(const json_t* value)
{
int id;
json_error_t err;
if (json_unpack_ex((json_t*)value, &err, 0, "i", &id) != 0) {
throw json_exception(err);
}
return id;
}
static json_t* videodisplay_serializer(int value) { return json_pack("i", value); }
static SCP_vector<int> videodisplay_enumerator()
{
SCP_vector<int> vals;
for (int i = 0; i < SDL_GetNumVideoDisplays(); ++i) {
vals.push_back(i);
}
return vals;
}
static SCP_string videodisplay_display(int id)
{
SCP_string out;
sprintf(out, "(%d) %s", id + 1, SDL_GetDisplayName(id));
return out;
}
static bool videodisplay_change(int display, bool initial)
{
if (initial) {
return false;
}
auto window = os::getSDLMainWindow();
if (window == nullptr) {
return false;
}
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(display), SDL_WINDOWPOS_CENTERED_DISPLAY(display));
return true;
}
static auto VideoDisplayOption =
options::OptionBuilder<int>("Graphics.Display", "Primary display", "The display used for rendering.")
.category("Graphics")
.level(options::ExpertLevel::Beginner)
.deserializer(videodisplay_deserializer)
.serializer(videodisplay_serializer)
.enumerator(videodisplay_enumerator)
.display(videodisplay_display)
.default_val(0)
.change_listener(videodisplay_change)
.importance(99)
.finish();
struct ResolutionInfo {
uint32_t width = 0;
uint32_t height = 0;
ResolutionInfo(uint32_t _width, uint32_t _height) : width(_width), height(_height) {}
ResolutionInfo() = default;
friend bool operator==(const ResolutionInfo& lhs, const ResolutionInfo& rhs)
{
return lhs.width == rhs.width && lhs.height == rhs.height;
}
friend bool operator!=(const ResolutionInfo& lhs, const ResolutionInfo& rhs) { return !(rhs == lhs); }
};
static ResolutionInfo resolution_deserializer(const json_t* el)
{
int width;
int height;
json_error_t err;
if (json_unpack_ex((json_t*)el, &err, 0, "{s:i, s:i}", "width", &width, "height", &height) != 0) {
throw json_exception(err);
}
return {(uint32_t)width, (uint32_t)height};
}
static json_t* resolution_serializer(const ResolutionInfo& value)
{
return json_pack("{s:i, s:i}", "width", value.width, "height", value.height);
}
static SCP_vector<ResolutionInfo> resolution_enumerator()
{
SCP_vector<ResolutionInfo> out;
auto display = VideoDisplayOption->getValue();
for (auto i = 0; i < SDL_GetNumDisplayModes(display); ++i) {
SDL_DisplayMode mode;
if (SDL_GetDisplayMode(display, i, &mode) != 0) {
continue;
}
auto res = ResolutionInfo(mode.w, mode.h);
if (std::find(out.begin(), out.end(), res) == out.end()) {
out.push_back(res);
}
}
return out;
}
static SCP_string resolution_display(const ResolutionInfo& info)
{
SCP_string str;
sprintf(str, "%dx%d", info.width, info.height);
return str;
}
static ResolutionInfo resolution_default()
{
SDL_DisplayMode mode;
if (SDL_GetDesktopDisplayMode(VideoDisplayOption->getValue(), &mode) != 0) {
return {};
}
return ResolutionInfo(mode.w, mode.h);
}
static bool resolution_change(const ResolutionInfo& /*info*/, bool initial)
{
if (initial) {
return false;
}
return false;
// The following code should change the size of the window properly but FSO currently can't handle that
/*
auto window = os::getSDLMainWindow();
if (window == nullptr) {
return;
}
auto display = VideoDisplayOption->getValue();
if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) {
SDL_DisplayMode target;
target.w = info.width;
target.h = info.height;
target.format = 0; // don't care
target.refresh_rate = 0; // don't care
target.driverdata = 0; // initialize to 0
SDL_DisplayMode closest;
if (SDL_GetClosestDisplayMode(display, &target, &closest) == nullptr) {
return;
}
SDL_SetWindowDisplayMode(window, &closest);
} else {
SDL_SetWindowSize(window, info.width, info.height);
// Recenter the window
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(display), SDL_WINDOWPOS_CENTERED_DISPLAY(display));
}
*/
}
static auto ResolutionOption =
options::OptionBuilder<ResolutionInfo>("Graphics.Resolution", "Resolution", "The rendering resolution.")
.category("Graphics")
.level(options::ExpertLevel::Beginner)
.deserializer(resolution_deserializer)
.serializer(resolution_serializer)
.enumerator(resolution_enumerator)
.display(resolution_display)
.default_func(resolution_default)
.change_listener(resolution_change)
.importance(100)
.finish();
bool Gr_enable_soft_particles = false;
static auto SoftParticlesOption = options::OptionBuilder<bool>("Graphics.SoftParticles", "Soft Particles",
"Enable or disable soft particle rendering.")
.category("Graphics")
.level(options::ExpertLevel::Advanced)
.default_val(true)
.bind_to_once(&Gr_enable_soft_particles)
.importance(68)
.finish();
flagset<FramebufferEffects> Gr_framebuffer_effects;
static auto FramebufferEffectsOption =
options::OptionBuilder<flagset<FramebufferEffects>>(
"Graphics.FramebufferEffects", "Framebuffer effects",
"Controls which framebuffer effects will be applied to the scene.")
.category("Graphics")
.level(options::ExpertLevel::Advanced)
.values({{{}, "None"},
{{FramebufferEffects::Shockwaves}, "Shockwaves"},
{{FramebufferEffects::Thrusters}, "Thrusters"},
{{FramebufferEffects::Shockwaves, FramebufferEffects::Thrusters}, "All"}})
.default_val({FramebufferEffects::Shockwaves, FramebufferEffects::Thrusters})
.bind_to_once(&Gr_framebuffer_effects)
.importance(77)
.finish();
AntiAliasMode Gr_aa_mode = AntiAliasMode::None;
AntiAliasMode Gr_aa_mode_last_frame = AntiAliasMode::None;
static auto AAOption = options::OptionBuilder<AntiAliasMode>("Graphics.AAMode", "Anti Aliasing",
"Controls the anti aliasing mode of the engine.")
.category("Graphics")
.level(options::ExpertLevel::Advanced)
.values({{AntiAliasMode::None, "None"},
{AntiAliasMode::FXAA_Low, "FXAA Low"},
{AntiAliasMode::FXAA_Medium, "FXAA Medium"},
{AntiAliasMode::FXAA_High, "FXAA High"},
{AntiAliasMode::SMAA_Low, "SMAA Low"},
{AntiAliasMode::SMAA_Medium, "SMAA Medium"},
{AntiAliasMode::SMAA_High, "SMAA High"},
{AntiAliasMode::SMAA_Ultra, "SMAA Ultra"}})
.default_val(AntiAliasMode::None)
.bind_to(&Gr_aa_mode)
.importance(79)
.finish();
bool gr_is_fxaa_mode(AntiAliasMode mode)
{
return mode == AntiAliasMode::FXAA_Low || mode == AntiAliasMode::FXAA_Medium || mode == AntiAliasMode::FXAA_High;
}
bool gr_is_smaa_mode(AntiAliasMode mode) {
return mode == AntiAliasMode::SMAA_Low || mode == AntiAliasMode::SMAA_Medium || mode == AntiAliasMode::SMAA_High || mode == AntiAliasMode::SMAA_Ultra;
}
bool Gr_post_processing_enabled = true;
static auto PostProcessOption =
options::OptionBuilder<bool>("Graphis.PostProcessing", "Post processing",
"Controls whether post processing is enabled in the engine")
.category("Graphics")
.level(options::ExpertLevel::Advanced)
.default_val(false)
.bind_to_once(&Gr_post_processing_enabled)
.importance(69)
.finish();
bool Gr_enable_vsync = true;
static auto VSyncOption = options::OptionBuilder<bool>("Graphis.VSync", "Vertical Sync",
"Controls how the engine does vertical synchronization")
.category("Graphics")
.level(options::ExpertLevel::Advanced)
.default_val(true)
.bind_to_once(&Gr_enable_vsync)
.importance(70)
.finish();
// Forward definitions
static void uniform_buffer_managers_init();
static void uniform_buffer_managers_deinit();
@@ -974,6 +729,17 @@ void gr_set_palette_internal( const char * /*name*/, ubyte * palette, int /*res
}
}
void gr_set_palette( const char *name, ubyte * palette, int restrict_font_to_128 )
{
char *p;
strcpy_s( Gr_current_palette_name, name );
p = strchr( Gr_current_palette_name, '.' );
if ( p ) *p = 0;
gr_screen.signature = Gr_signature++;
gr_set_palette_internal( name, palette, restrict_font_to_128 );
}
void gr_screen_resize(int width, int height)
{
gr_screen.save_center_w = gr_screen.center_w = gr_screen.save_max_w = gr_screen.max_w = gr_screen.max_w_unscaled = gr_screen.max_w_unscaled_zoomed = width;
@@ -1187,77 +953,69 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
}
}
if (Using_in_game_options) {
auto res = ResolutionOption->getValue();
width = res.width;
height = res.height;
} else {
// We cannot continue without this, quit, but try to help the user out first
ptr = os_config_read_string(nullptr, NOX("VideocardFs2open"), nullptr);
// We cannot continue without this, quit, but try to help the user out first
ptr = os_config_read_string(NULL, NOX("VideocardFs2open"), NULL);
// if we don't have a config string then construct one, using OpenGL 1024x768 32-bit as the default
if (ptr == nullptr) {
// If we don't have a display mode, use SDL to get default settings
// We need to initialize SDL to do this
// if we don't have a config string then construct one, using OpenGL 1024x768 32-bit as the default
if (ptr == NULL) {
// If we don't have a display mode, use SDL to get default settings
// We need to initialize SDL to do this
if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0)
if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0)
{
int display = static_cast<int>(os_config_read_uint("Video", "Display", 0));
SDL_DisplayMode displayMode;
if (SDL_GetDesktopDisplayMode(display, &displayMode) == 0)
{
auto display = static_cast<int>(os_config_read_uint("Video", "Display", 0));
SDL_DisplayMode displayMode;
if (SDL_GetDesktopDisplayMode(display, &displayMode) == 0)
{
width = displayMode.w;
height = displayMode.h;
int sdlBits = SDL_BITSPERPIXEL(displayMode.format);
width = displayMode.w;
height = displayMode.h;
int sdlBits = SDL_BITSPERPIXEL(displayMode.format);
if (SDL_ISPIXELFORMAT_ALPHA(displayMode.format))
if (SDL_ISPIXELFORMAT_ALPHA(displayMode.format))
{
depth = sdlBits;
}
else
{
// Fix a few values
if (sdlBits == 24)
{
depth = sdlBits;
depth = 32;
}
else if (sdlBits == 15)
{
depth = 16;
}
else
{
// Fix a few values
if (sdlBits == 24)
{
depth = 32;
}
else if (sdlBits == 15)
{
depth = 16;
}
else
{
depth = sdlBits;
}
depth = sdlBits;
}
SCP_string videomode;
sprintf(videomode, "OGL -(%dx%d)x%d bit", width, height, depth);
os_config_write_string(nullptr, NOX("VideocardFs2open"), videomode.c_str());
}
}
} else {
Assert(ptr != nullptr);
// NOTE: The "ptr+5" is to skip over the initial "????-" in the video string.
// If the format of that string changes you'll have to change this too!!!
if (sscanf(ptr + 5, "(%dx%d)x%d ", &width, &height, &depth) != 3) {
Error(LOCATION, "Can't understand 'VideocardFs2open' config entry!");
SCP_string videomode;
sprintf(videomode, "OGL -(%dx%d)x%d bit", width, height, depth);
os_config_write_string(NULL, NOX("VideocardFs2open"), videomode.c_str());
}
}
} else {
Assert(ptr != NULL);
if (Cmdline_res != nullptr) {
int tmp_width = 0;
int tmp_height = 0;
if ( sscanf(Cmdline_res, "%dx%d", &tmp_width, &tmp_height) == 2 ) {
width = tmp_width;
height = tmp_height;
}
// NOTE: The "ptr+5" is to skip over the initial "????-" in the video string.
// If the format of that string changes you'll have to change this too!!!
if (sscanf(ptr + 5, "(%dx%d)x%d ", &width, &height, &depth) != 3) {
Error(LOCATION, "Can't understand 'VideocardFs2open' config entry!");
}
}
Gr_enable_soft_particles = Cmdline_softparticles != 0;
if (Cmdline_res != NULL) {
int tmp_width = 0;
int tmp_height = 0;
if ( sscanf(Cmdline_res, "%dx%d", &tmp_width, &tmp_height) == 2 ) {
width = tmp_width;
height = tmp_height;
}
}
if (Cmdline_center_res != NULL) {
int tmp_center_width = 0;
@@ -2375,6 +2133,15 @@ bool poly_list::finder::operator()(const uint a, const uint b)
}
}
void gr_shield_icon(coord2d coords[6], int resize_mode)
{
if (gr_screen.mode == GR_STUB) {
return;
}
g3_render_shield_icon(&gr_screen.current_color, coords, resize_mode);
}
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
{
gr_screen.current_alpha = alpha;
+47 -42
View File
@@ -12,15 +12,15 @@
#ifndef _GRAPHICS_H
#define _GRAPHICS_H
#include "graphics/grinternal.h"
#include "osapi/osapi.h"
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "globalincs/flagset.h"
#include "globalincs/pstypes.h"
#include "graphics/grinternal.h"
#include "graphics/tmapper.h"
#include "io/cursor.h"
#include "cfile/cfile.h"
#include "math/vecmat.h"
#include "osapi/osapi.h"
#include "io/cursor.h"
// Forward definition
namespace graphics {
@@ -40,36 +40,6 @@ extern int Gr_inited;
extern int gr_zbuffering, gr_zbuffering_mode;
extern int gr_global_zbuffering;
extern bool Gr_enable_soft_particles;
FLAG_LIST(FramebufferEffects){Thrusters = 0, Shockwaves, NUM_VALUES};
extern flagset<FramebufferEffects> Gr_framebuffer_effects;
enum class AntiAliasMode {
None,
FXAA_Low,
FXAA_Medium,
FXAA_High,
SMAA_Low,
SMAA_Medium,
SMAA_High,
SMAA_Ultra,
};
extern AntiAliasMode Gr_aa_mode;
extern AntiAliasMode Gr_aa_mode_last_frame;
bool gr_is_fxaa_mode(AntiAliasMode mode);
bool gr_is_smaa_mode(AntiAliasMode mode);
extern bool Gr_post_processing_enabled;
extern bool Gr_enable_vsync;
extern bool Deferred_lighting;
extern bool High_dynamic_range;
class material;
class model_material;
class particle_material;
@@ -165,6 +135,8 @@ enum primitive_type {
PRIM_TYPE_TRIS,
PRIM_TYPE_TRISTRIP,
PRIM_TYPE_TRIFAN,
PRIM_TYPE_QUADS,
PRIM_TYPE_QUADSTRIP
};
enum shader_type {
@@ -192,11 +164,6 @@ enum shader_type {
SDR_TYPE_DECAL,
SDR_TYPE_SCENE_FOG,
SDR_TYPE_ROCKET_UI,
SDR_TYPE_POST_PROCESS_SMAA_EDGE,
SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT,
SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING,
NUM_SHADER_TYPES
};
@@ -261,6 +228,7 @@ struct vertex_format_data
MODEL_ID,
RADIUS,
UVEC,
WORLD_MATRIX,
};
vertex_format format_type;
@@ -326,7 +294,6 @@ typedef enum gr_capability {
enum class gr_property {
UNIFORM_BUFFER_OFFSET_ALIGNMENT,
UNIFORM_BUFFER_MAX_SIZE,
MAX_ANISOTROPY
};
// stencil buffering stuff
@@ -754,6 +721,10 @@ typedef struct screen {
int (*gf_bm_make_render_target)(int handle, int *width, int *height, int *bpp, int *mm_lvl, int flags );
int (*gf_bm_set_render_target)(int handle, int face);
void (*gf_translate_texture_matrix)(int unit, const vec3d *shift);
void (*gf_push_texture_matrix)(int unit);
void (*gf_pop_texture_matrix)(int unit);
void (*gf_set_texture_addressing)(int);
int (*gf_create_buffer)(BufferType type, BufferUsageHint usage);
@@ -840,7 +811,7 @@ typedef struct screen {
} screen;
// handy macro
#define GR_MAYBE_CLEAR_RES(bmap) do { int bmw = -1; int bmh = -1; if(bmap != -1){ bm_get_info( bmap, &bmw, &bmh, NULL, NULL, NULL); if((bmw != gr_screen.max_w) || (bmh != gr_screen.max_h)){gr_clear();} } else {gr_clear();} } while(false);
#define GR_MAYBE_CLEAR_RES(bmap) do { int bmw = -1; int bmh = -1; if(bmap != -1){ bm_get_info( bmap, &bmw, &bmh, NULL, NULL, NULL); if((bmw != gr_screen.max_w) || (bmh != gr_screen.max_h)){gr_clear();} } else {gr_clear();} } while(0);
//Window's interface to set up graphics:
//--------------------------------------
@@ -915,6 +886,8 @@ extern void gr_get_string_size( int *w, int *h, const char * text, int len = 999
// Returns the height of the current font
extern int gr_get_font_height();
extern void gr_set_palette(const char *name, ubyte *palette, int restrict_to_128 = 0);
extern io::mouse::Cursor* Web_cursor;
// Called by OS when application gets/looses focus
@@ -941,6 +914,8 @@ void gr_set_bitmap(int bitmap_num, int alphablend = GR_ALPHABLEND_NONE, int bitb
#define gr_clear GR_CALL(gr_screen.gf_clear)
void gr_shield_icon(coord2d coords[6], const int resize_mode = GR_RESIZE_FULL);
#define gr_zbuffer_get GR_CALL(gr_screen.gf_zbuffer_get)
#define gr_zbuffer_set GR_CALL(gr_screen.gf_zbuffer_set)
#define gr_zbuffer_clear GR_CALL(gr_screen.gf_zbuffer_clear)
@@ -966,6 +941,11 @@ void gr_set_bitmap(int bitmap_num, int alphablend = GR_ALPHABLEND_NONE, int bitb
#define gr_set_clear_color GR_CALL(gr_screen.gf_set_clear_color)
#define gr_translate_texture_matrix GR_CALL(gr_screen.gf_translate_texture_matrix)
#define gr_push_texture_matrix GR_CALL(gr_screen.gf_push_texture_matrix)
#define gr_pop_texture_matrix GR_CALL(gr_screen.gf_pop_texture_matrix)
// Here be the bitmap functions
#define gr_bm_free_data GR_CALL(gr_screen.gf_bm_free_data)
#define gr_bm_create GR_CALL(gr_screen.gf_bm_create)
@@ -1018,6 +998,7 @@ inline void gr_post_process_restore_zbuffer() {
#define gr_maybe_create_shader GR_CALL(gr_screen.gf_maybe_create_shader)
#define gr_recompile_all_shaders GR_CALL(gr_screen.gf_recompile_all_shaders)
#define gr_set_animated_effect GR_CALL(gr_screen.gf_set_animated_effect)
#define gr_clear_states GR_CALL(gr_screen.gf_clear_states)
@@ -1139,6 +1120,7 @@ inline void gr_sync_delete(gr_sync sync) {
}
// color functions
void gr_get_color( int *r, int *g, int b );
void gr_init_color(color *c, int r, int g, int b);
void gr_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type = AC_TYPE_HUD );
void gr_set_color( int r, int g, int b );
@@ -1148,11 +1130,34 @@ void gr_set_color_fast(color *dst);
void gr_create_shader(shader *shade, ubyte r, ubyte g, ubyte b, ubyte c);
void gr_set_shader(shader *shade);
uint gr_determine_model_shader_flags(
bool lighting,
bool fog,
bool textured,
bool in_shadow_map,
bool thruster_scale,
bool transform,
bool team_color_set,
int tmap_flags,
int spec_map,
int glow_map,
int normal_map,
int height_map,
int ambient_map,
int env_map,
int misc_map
);
// new bitmap functions
void gr_bitmap(int x, int y, int resize_mode = GR_RESIZE_FULL);
void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, int resize_mode = GR_RESIZE_FULL);
void gr_bitmap_list(bitmap_2d_list* list, int n_bm, int resize_mode);
void gr_bitmap_list(bitmap_rect_list* list, int n_bm, int resize_mode);
// texture update functions
ubyte* gr_opengl_get_texture_update_pointer(int bitmap_handle);
void gr_opengl_update_texture(int bitmap_handle, int bpp, const ubyte* data, int width, int height);
// special function for drawing polylines. this function is specifically intended for
// polylines where each section is no more than 90 degrees away from a previous section.
// Moreover, it is _really_ intended for use with 45 degree angles.
@@ -1199,7 +1204,7 @@ class DebugScope {
#ifndef NDEBUG
#define GR_DEBUG_SCOPE(name) ::graphics::DebugScope SCP_TOKEN_CONCAT(gr_scope, __LINE__)(name)
#else
#define GR_DEBUG_SCOPE(name) do {} while(false)
#define GR_DEBUG_SCOPE(name) do {} while(0)
#endif
enum AnimatedShader {
+69 -67
View File
@@ -667,7 +667,7 @@ float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float wid
batch_item *item = NULL;
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
if (it != geometry_map.end()) {
if ( !geometry_map.empty() && it != geometry_map.end() ) {
item = &it->second;
} else {
item = &geometry_map[texture];
@@ -690,12 +690,12 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float
return 1;
}
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && !Gr_enable_soft_particles ) {
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && !Cmdline_softparticles ) {
// don't render this as a soft particle if we don't support soft particles
tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
}
if ( Gr_enable_soft_particles && !Cmdline_no_geo_sdr_effects && (tmap_flags & TMAP_FLAG_VERTEX_GEN) ) {
if ( Cmdline_softparticles && !Cmdline_no_geo_sdr_effects && (tmap_flags & TMAP_FLAG_VERTEX_GEN) ) {
geometry_batch_add_bitmap(texture, tmap_flags, pnt, orient, rad, alpha, depth);
return 0;
} else if ( tmap_flags & TMAP_FLAG_VERTEX_GEN ) {
@@ -706,7 +706,7 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
if (it != geometry_map.end()) {
if ( !geometry_map.empty() && it != geometry_map.end() ) {
item = &it->second;
} else {
item = &geometry_map[texture];
@@ -735,7 +735,7 @@ int geometry_batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orie
g_sdr_batch_item *item = NULL;
SCP_map<int, g_sdr_batch_item>::iterator it = geometry_shader_map.find(texture);
if (it != geometry_shader_map.end()) {
if ( !geometry_shader_map.empty() && it != geometry_shader_map.end() ) {
item = &it->second;
} else {
item = &geometry_shader_map[texture];
@@ -759,7 +759,7 @@ int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float ang
return 1;
}
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && !Gr_enable_soft_particles ) {
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && !Cmdline_softparticles ) {
// don't render this as a soft particle if we don't support soft particles
tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
}
@@ -768,7 +768,7 @@ int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float ang
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
if (it != geometry_map.end()) {
if ( !geometry_map.empty() && it != geometry_map.end() ) {
item = &it->second;
} else {
item = &geometry_map[texture];
@@ -798,7 +798,7 @@ int batch_add_tri(int texture, int tmap_flags, vertex *verts, float alpha)
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
if (it != geometry_map.end()) {
if ( !geometry_map.empty() && it != geometry_map.end() ) {
item = &it->second;
} else {
item = &geometry_map[texture];
@@ -828,7 +828,7 @@ int batch_add_quad(int texture, int tmap_flags, vertex *verts, float alpha)
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
if (it != geometry_map.end()) {
if ( !geometry_map.empty() && it != geometry_map.end() ) {
item = &it->second;
} else {
item = &geometry_map[texture];
@@ -908,7 +908,7 @@ int batch_add_polygon(int texture, int tmap_flags, vec3d *pos, matrix *orient, f
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
if (it != geometry_map.end()) {
if ( !geometry_map.empty() && it != geometry_map.end() ) {
item = &it->second;
} else {
item = &geometry_map[texture];
@@ -938,7 +938,7 @@ int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
if (it != geometry_map.end()) {
if ( !geometry_map.empty() && it != geometry_map.end() ) {
item = &it->second;
} else {
item = &geometry_map[texture];
@@ -959,102 +959,102 @@ int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float
void batch_render_lasers(int buffer_handle)
{
for (auto &bi : geometry_map) {
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
if ( !bi.second.laser )
if ( !bi->second.laser )
continue;
if ( !bi.second.batch.need_to_render() )
if ( !bi->second.batch.need_to_render() )
continue;
Assert( bi.second.texture >= 0 );
gr_set_bitmap(bi.second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
Assert( bi->second.texture >= 0 );
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
if ( buffer_handle >= 0 ) {
bi.second.batch.render_buffer(buffer_handle, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT | TMAP_FLAG_EMISSIVE);
bi->second.batch.render_buffer(buffer_handle, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT | TMAP_FLAG_EMISSIVE);
} else {
bi.second.batch.render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT | TMAP_FLAG_EMISSIVE);
bi->second.batch.render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT | TMAP_FLAG_EMISSIVE);
}
}
}
void batch_load_buffer_lasers(effect_vertex* buffer, int *n_verts)
{
for (auto &bi : geometry_map) {
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
if ( !bi.second.laser )
if ( !bi->second.laser )
continue;
if ( !bi.second.batch.need_to_render() )
if ( !bi->second.batch.need_to_render() )
continue;
Assert( bi.second.texture >= 0 );
bi.second.batch.load_buffer(buffer, n_verts);
Assert( bi->second.texture >= 0 );
bi->second.batch.load_buffer(buffer, n_verts);
}
}
void batch_render_geometry_map_bitmaps(int buffer_handle)
{
for (auto &bi : geometry_map) {
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
if ( bi.second.laser )
if ( bi->second.laser )
continue;
if ( !bi.second.batch.need_to_render() )
if ( !bi->second.batch.need_to_render() )
continue;
Assert( bi.second.texture >= 0 );
gr_set_bitmap(bi.second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi.second.alpha);
Assert( bi->second.texture >= 0 );
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
if ( buffer_handle >= 0 ) {
bi.second.batch.render_buffer(buffer_handle, bi.second.tmap_flags);
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
} else {
bi.second.batch.render( bi.second.tmap_flags);
bi->second.batch.render( bi->second.tmap_flags);
}
}
}
void batch_render_geometry_shader_map_bitmaps(int buffer_handle)
{
for (auto &bi : geometry_shader_map) {
for (SCP_map<int, g_sdr_batch_item>::iterator bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
if ( bi.second.laser )
if ( bi->second.laser )
continue;
if ( !bi.second.batch.need_to_render() )
if ( !bi->second.batch.need_to_render() )
continue;
Assert( bi.second.texture >= 0 );
gr_set_bitmap(bi.second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi.second.alpha);
bi.second.batch.render_buffer(buffer_handle, bi.second.tmap_flags);
Assert( bi->second.texture >= 0 );
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
}
}
void batch_load_buffer_geometry_map_bitmaps(effect_vertex* buffer, int *n_verts)
{
for (auto &bi : geometry_map) {
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
if ( bi.second.laser )
if ( bi->second.laser )
continue;
if ( !bi.second.batch.need_to_render() )
if ( !bi->second.batch.need_to_render() )
continue;
Assert( bi.second.texture >= 0 );
bi.second.batch.load_buffer(buffer, n_verts);
Assert( bi->second.texture >= 0 );
bi->second.batch.load_buffer(buffer, n_verts);
}
}
void batch_load_buffer_geometry_shader_map_bitmaps(particle_pnt* buffer, size_t *n_verts)
{
for (auto &bi : geometry_shader_map) {
for (SCP_map<int, g_sdr_batch_item>::iterator bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
if ( bi.second.laser )
if ( bi->second.laser )
continue;
if ( !bi.second.batch.need_to_render() )
if ( !bi->second.batch.need_to_render() )
continue;
Assert( bi.second.texture >= 0 );
bi.second.batch.load_buffer(buffer, n_verts);
Assert( bi->second.texture >= 0 );
bi->second.batch.load_buffer(buffer, n_verts);
}
}
@@ -1145,7 +1145,7 @@ int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, floa
SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
if (it != distortion_map.end()) {
if ( !distortion_map.empty() && it != distortion_map.end() ) {
item = &it->second;
} else {
item = &distortion_map[texture];
@@ -1175,7 +1175,7 @@ int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, f
SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
if (it != distortion_map.end()) {
if ( !distortion_map.empty() && it != distortion_map.end() ) {
item = &it->second;
} else {
item = &distortion_map[texture];
@@ -1196,53 +1196,54 @@ int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, f
void batch_render_distortion_map_bitmaps(int buffer_handle)
{
for (auto &bi : distortion_map) {
for (SCP_map<int,batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
if ( bi.second.laser )
if ( bi->second.laser )
continue;
if ( !bi.second.batch.need_to_render() )
if ( !bi->second.batch.need_to_render() )
continue;
Assert( bi.second.texture >= 0 );
gr_set_bitmap(bi.second.texture, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, bi.second.alpha);
Assert( bi->second.texture >= 0 );
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
if ( buffer_handle >= 0 ) {
bi.second.batch.render_buffer(buffer_handle, bi.second.tmap_flags);
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
} else {
bi.second.batch.render( bi.second.tmap_flags);
bi->second.batch.render( bi->second.tmap_flags);
}
}
}
void batch_load_buffer_distortion_map_bitmaps(effect_vertex* buffer, int *n_verts)
{
for (auto &bi : distortion_map) {
for (SCP_map<int, batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
if ( bi.second.laser )
if ( bi->second.laser )
continue;
if ( !bi.second.batch.need_to_render() )
if ( !bi->second.batch.need_to_render() )
continue;
Assert( bi.second.texture >= 0 );
bi.second.batch.load_buffer(buffer, n_verts);
Assert( bi->second.texture >= 0 );
bi->second.batch.load_buffer(buffer, n_verts);
}
}
int batch_get_size()
{
int n_to_render = 0;
SCP_map<int, batch_item>::iterator bi;
for (auto &bi : geometry_map) {
n_to_render += bi.second.batch.need_to_render();
for (bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
n_to_render += bi->second.batch.need_to_render();
}
for (auto &bi : distortion_map) {
if ( bi.second.laser )
for (bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
if ( bi->second.laser )
continue;
n_to_render += bi.second.batch.need_to_render();
n_to_render += bi->second.batch.need_to_render();
}
return n_to_render * 3;
@@ -1251,9 +1252,10 @@ int batch_get_size()
size_t geometry_batch_get_size()
{
size_t n_to_render = 0;
SCP_map<int, g_sdr_batch_item>::iterator bi;
for (auto &bi : geometry_shader_map) {
n_to_render += bi.second.batch.need_to_render();
for (bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
n_to_render += bi->second.batch.need_to_render();
}
return n_to_render;
+16
View File
@@ -86,6 +86,10 @@ void gr_stub_get_region(int /*front*/, int /*w*/, int /*h*/, ubyte * /*data*/
{
}
void gr_stub_pop_texture_matrix(int /*unit*/)
{
}
void gr_stub_preload_init()
{
}
@@ -94,6 +98,10 @@ void gr_stub_print_screen(const char * /*filename*/)
{
}
void gr_stub_push_texture_matrix(int /*unit*/)
{
}
void gr_stub_rect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*resize_mode*/)
{
}
@@ -161,6 +169,10 @@ void gr_stub_stuff_secondary_color(vertex * /*v*/, ubyte /*fr*/, ubyte /*fg*/,
{
}
void gr_stub_translate_texture_matrix(int /*unit*/, const vec3d * /*shift*/)
{
}
void gr_stub_zbias_stub(int /*bias*/)
{
}
@@ -451,6 +463,10 @@ bool gr_stub_init()
gr_screen.gf_preload = gr_stub_preload;
gr_screen.gf_push_texture_matrix = gr_stub_push_texture_matrix;
gr_screen.gf_pop_texture_matrix = gr_stub_pop_texture_matrix;
gr_screen.gf_translate_texture_matrix = gr_stub_translate_texture_matrix;
gr_screen.gf_set_texture_addressing = gr_stub_set_texture_addressing;
gr_screen.gf_zbias = gr_stub_zbias_stub;
gr_screen.gf_set_fill_mode = gr_set_fill_mode_stub;
+4 -1
View File
@@ -28,7 +28,7 @@ struct gr_light
// spotlight direction (for tube lights)
vec3d SpotDir;
float SpotCutOff;
float SpotExp, SpotCutOff;
float ConstantAtten, LinearAtten, QuadraticAtten;
int type;
@@ -70,6 +70,8 @@ void FSLight2GLLight(light* FSLight, gr_light* GLLight) {
GLLight->SpotDir.xyz.x = 0.0f;
GLLight->SpotDir.xyz.y = 0.0f;
GLLight->SpotDir.xyz.z = -1.0f;
// spot exponent
GLLight->SpotExp = Cmdline_ogl_spec * 0.5f;
// spot cutoff
GLLight->SpotCutOff = 180.0f; // special value, light in all directions
// defaults to disable attenuation
@@ -254,6 +256,7 @@ void gr_set_center_alpha(int type) {
glight.SpotDir.xyz.x = 0.0f;
glight.SpotDir.xyz.y = 0.0f;
glight.SpotDir.xyz.z = -1.0f;
glight.SpotExp = Cmdline_ogl_spec * 0.5f;
glight.SpotCutOff = 180.0f;
glight.ConstantAtten = 1.0f;
glight.LinearAtten = 0.0f;
+4 -4
View File
@@ -20,7 +20,7 @@
int __temp__ = (a); \
(a) = (b); \
(b) = __temp__; \
} while(false)
} while(0)
//#define INT_SCALE(var,arg,num,den) ((var) = ((arg) * (num)) / (den))
#define INT_SCALE(var,arg,num,den) ((var) = MulDiv(arg, num, den))
@@ -90,13 +90,13 @@
WHEN_CLIPPED; \
} \
} \
} while(false)
} while(0)
#define FL_EXCHG(a,b) do { \
float __temp__ = (a); \
(a) = (b); \
(b) = __temp__; \
} while(false)
} while(0)
#define FL_SCALE(var,arg,num,den) ((var) = ((arg) * (num)) / (den))
@@ -165,6 +165,6 @@
WHEN_CLIPPED; \
} \
} \
} while(false)
} while(0)
#endif
File diff suppressed because it is too large. Load diff
-134
View File
@@ -1,134 +0,0 @@
/**
* Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com)
* Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com)
* Copyright (C) 2013 Belen Masia (bmasia@unizar.es)
* Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com)
* Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to
* do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. As clarification, there
* is no requirement that the copyright notice and permission be included in
* binary distributions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef SEARCHTEX_H
#define SEARCHTEX_H
#define SEARCHTEX_WIDTH 64
#define SEARCHTEX_HEIGHT 16
#define SEARCHTEX_PITCH SEARCHTEX_WIDTH
#define SEARCHTEX_SIZE (SEARCHTEX_HEIGHT * SEARCHTEX_PITCH)
// clang-format off
/**
* Stored in R8 format. Load it in the following format:
* - DX9: D3DFMT_L8
* - DX10: DXGI_FORMAT_R8_UNORM
*/
static const unsigned char searchTexBytes[] = {
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
// clang-format on
#endif
+64 -89
View File
@@ -1,16 +1,8 @@
#include "gropengl.h"
#include "gropenglbmpman.h"
#include "gropengldeferred.h"
#include "gropengldraw.h"
#include "gropenglpostprocessing.h"
#include "gropenglquery.h"
#include "gropenglshader.h"
#include "gropenglstate.h"
#include "gropenglsync.h"
#include "gropengltexture.h"
#include "gropengltnl.h"
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "cmdline/cmdline.h"
@@ -18,22 +10,32 @@
#include "debugconsole/console.h"
#include "globalincs/systemvars.h"
#include "graphics/2d.h"
#include "graphics/line.h"
#include "graphics/matrix.h"
#include "graphics/paths/PathRenderer.h"
#include "gropengl.h"
#include "gropenglbmpman.h"
#include "gropengldraw.h"
#include "gropenglpostprocessing.h"
#include "gropenglquery.h"
#include "gropenglsync.h"
#include "gropenglshader.h"
#include "gropenglstate.h"
#include "gropengltexture.h"
#include "gropengltnl.h"
#include "gropengldeferred.h"
#include "graphics/line.h"
#include "io/mouse.h"
#include "io/timer.h"
#include "libs/renderdoc/renderdoc.h"
#include "math/floating.h"
#include "model/model.h"
#include "nebula/neb.h"
#include "options/Option.h"
#include "libs/renderdoc/renderdoc.h"
#include "osapi/osapi.h"
#include "osapi/osregistry.h"
#include "pngutils/pngutils.h"
#include "popup/popup.h"
#include "render/3d.h"
#include "popup/popup.h"
#include "tracing/tracing.h"
#include "pngutils/pngutils.h"
#if defined(_WIN32)
#include <windows.h>
@@ -97,33 +99,6 @@ static std::unique_ptr<os::OpenGLContext> GL_context = nullptr;
static std::unique_ptr<os::GraphicsOperations> graphic_operations = nullptr;
static os::Viewport* current_viewport = nullptr;
static bool mode_change_func(os::ViewportState state, bool initial)
{
if (initial) {
return false;
}
auto window = os::getMainViewport();
if (window == nullptr) {
return false;
}
window->setState(state);
return true;
}
static auto WindowModeOption = options::OptionBuilder<os::ViewportState>("Graphics.WindowMode", "Window Mode",
"Controls how the game window is created.")
.category("Graphics")
.level(options::ExpertLevel::Beginner)
.values({{os::ViewportState::Fullscreen, "Fullscreen"},
{os::ViewportState::Borderless, "Borderless"},
{os::ViewportState::Windowed, "Windowed"}})
.importance(98)
.default_val(os::ViewportState::Fullscreen)
.change_listener(mode_change_func)
.finish();
void opengl_go_fullscreen()
{
if (Cmdline_fullscreen_window || Cmdline_window || GL_fullscreen || Fred_running)
@@ -834,6 +809,21 @@ void gr_opengl_zbias(int bias)
}
}
void gr_opengl_push_texture_matrix(int /*unit*/)
{
}
void gr_opengl_pop_texture_matrix(int /*unit*/)
{
}
void gr_opengl_translate_texture_matrix(int /*unit*/, const vec3d * /*shift*/)
{
}
void gr_opengl_set_line_width(float width)
{
if (width <= 1.0f) {
@@ -864,16 +854,16 @@ int opengl_check_for_errors(const char *err_at)
return num_errors;
}
void opengl_set_vsync(bool enable)
void opengl_set_vsync(int status)
{
if (enable) {
// Try to use adaptive vsync when supported
if (!GL_context->setSwapInterval(-1)) {
GL_context->setSwapInterval(1);
}
} else {
GL_context->setSwapInterval(0);
if ( (status < 0) || (status > 1) ) {
Int3();
return;
}
GL_context->setSwapInterval(status);
GL_CHECK_FOR_ERRORS("end of set_vsync()");
}
std::unique_ptr<os::Viewport> gr_opengl_create_viewport(const os::ViewPortProperties& props) {
@@ -1031,24 +1021,10 @@ int opengl_init_display_device()
attrs.title = Window_title;
}
if (Using_in_game_options) {
switch (WindowModeOption->getValue()) {
case os::ViewportState::Windowed:
// That's the default
break;
case os::ViewportState::Borderless:
attrs.flags.set(os::ViewPortFlags::Borderless);
break;
case os::ViewportState::Fullscreen:
attrs.flags.set(os::ViewPortFlags::Fullscreen);
break;
}
} else {
if (!Cmdline_window && !Cmdline_fullscreen_window) {
attrs.flags.set(os::ViewPortFlags::Fullscreen);
} else if (Cmdline_fullscreen_window) {
attrs.flags.set(os::ViewPortFlags::Borderless);
}
if (!Cmdline_window && ! Cmdline_fullscreen_window) {
attrs.flags.set(os::ViewPortFlags::Fullscreen);
} else if (Cmdline_fullscreen_window) {
attrs.flags.set(os::ViewPortFlags::Borderless);
}
auto viewport = gr_opengl_create_viewport(attrs);
@@ -1139,6 +1115,10 @@ void opengl_setup_function_pointers()
gr_screen.gf_preload = gr_opengl_preload;
gr_screen.gf_push_texture_matrix = gr_opengl_push_texture_matrix;
gr_screen.gf_pop_texture_matrix = gr_opengl_pop_texture_matrix;
gr_screen.gf_translate_texture_matrix = gr_opengl_translate_texture_matrix;
gr_screen.gf_set_texture_addressing = gr_opengl_set_texture_addressing;
gr_screen.gf_zbias = gr_opengl_zbias;
gr_screen.gf_set_fill_mode = gr_opengl_set_fill_mode;
@@ -1517,7 +1497,7 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
opengl_post_process_init();
// must be called after extensions are setup
opengl_set_vsync(Gr_enable_vsync);
opengl_set_vsync( !Cmdline_no_vsync );
gr_reset_matrices();
gr_setup_viewport();
@@ -1561,7 +1541,7 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
mprintf(( " Can use compressed textures: %s\n", Use_compressed_textures ? NOX("YES") : NOX("NO") ));
mprintf(( " Texture compression available: %s\n", Texture_compression_available ? NOX("YES") : NOX("NO") ));
mprintf(( " Post-processing enabled: %s\n", (Gr_post_processing_enabled) ? "YES" : "NO"));
mprintf(( " Post-processing enabled: %s\n", (Cmdline_postprocess) ? "YES" : "NO"));
mprintf(( " Using %s texture filter.\n", (GL_mipmap_filter) ? NOX("trilinear") : NOX("bilinear") ));
mprintf(( " OpenGL Shader Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION) ));
@@ -1592,9 +1572,9 @@ bool gr_opengl_is_capable(gr_capability capability)
return Cmdline_height ? true : false;
case CAPABILITY_SOFT_PARTICLES:
case CAPABILITY_DISTORTION:
return Gr_enable_soft_particles && !Cmdline_no_fbo;
return Cmdline_softparticles && !Cmdline_no_fbo;
case CAPABILITY_POST_PROCESSING:
return Gr_post_processing_enabled && !Cmdline_no_fbo;
return Cmdline_postprocess && !Cmdline_no_fbo;
case CAPABILITY_DEFERRED_LIGHTING:
return !Cmdline_no_fbo && !Cmdline_no_deferred_lighting;
case CAPABILITY_SHADOWS:
@@ -1612,20 +1592,16 @@ bool gr_opengl_is_capable(gr_capability capability)
return false;
}
bool gr_opengl_get_property(gr_property prop, void* dest)
{
switch (prop) {
case gr_property::UNIFORM_BUFFER_OFFSET_ALIGNMENT:
*((int*)dest) = GL_state.Constants.GetUniformBufferOffsetAlignment();
return true;
case gr_property::UNIFORM_BUFFER_MAX_SIZE:
*((int*)dest) = GL_state.Constants.GetMaxUniformBlockSize();
return true;
case gr_property::MAX_ANISOTROPY:
*((float*)dest) = GL_state.Constants.GetMaxAnisotropy();
return true;
default:
return false;
bool gr_opengl_get_property(gr_property prop, void* dest) {
switch(prop) {
case gr_property::UNIFORM_BUFFER_OFFSET_ALIGNMENT:
*((int*)dest) = GL_state.Constants.GetUniformBufferOffsetAlignment();
return true;
case gr_property::UNIFORM_BUFFER_MAX_SIZE:
*((int*)dest) = GL_state.Constants.GetMaxUniformBlockSize();
return true;
default:
return false;
}
}
@@ -1703,8 +1679,7 @@ DCF(ogl_anisotropy, "toggles anisotropic filtering")
if (dc_optional_string_either("help", "--help")) {
dc_printf("Sets OpenGL anisotropic filtering level.\n");
dc_printf("GL_anisotropy [int] Valid values are 0 to %i. 0 turns off anisotropic filtering.\n",
(int)GL_state.Constants.GetMaxAnisotropy());
dc_printf("GL_anisotropy [int] Valid values are 0 to %i. 0 turns off anisotropic filtering.\n", (int)opengl_get_max_anisotropy());
process = false;
}
+2
View File
@@ -16,6 +16,8 @@
#include "globalincs/pstypes.h"
#include "graphics/grinternal.h"
const ubyte GL_zero_3ub[3] = { 0, 0, 0 };
bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps);
void gr_opengl_cleanup(bool closing, int minimize=1);
int opengl_check_for_errors(const char *err_at = NULL);
+7 -6
View File
@@ -37,7 +37,7 @@ void opengl_clear_deferred_buffers()
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_CLEAR, 0) );
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
opengl_shader_set_current();
@@ -115,7 +115,7 @@ void gr_opengl_deferred_lighting_finish()
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_normal_texture);
GL_state.Texture.Enable(2, GL_TEXTURE_2D, Scene_position_texture);
GL_state.Texture.Enable(3, GL_TEXTURE_2D, Scene_specular_texture);
if (Shadow_quality != ShadowQuality::Disabled) {
if (Cmdline_shadow_quality) {
GL_state.Texture.Enable(4, GL_TEXTURE_2D_ARRAY, Shadow_map_texture);
}
@@ -133,7 +133,7 @@ void gr_opengl_deferred_lighting_finish()
GR_DEBUG_SCOPE("Build buffer data");
auto header = uniformAligner.getHeader<deferred_global_data>();
if (Shadow_quality != ShadowQuality::Disabled) {
if (Cmdline_shadow_quality) {
// Avoid this overhead when we are not going to use these values
header->shadow_mv_matrix = Shadow_view_matrix;
for (size_t i = 0; i < MAX_SHADOW_CASCADES; ++i) {
@@ -149,6 +149,7 @@ void gr_opengl_deferred_lighting_finish()
header->invScreenWidth = 1.0f / gr_screen.max_w;
header->invScreenHeight = 1.0f / gr_screen.max_h;
header->specFactor = Cmdline_ogl_spec;
// Only the first directional light uses shaders so we need to know when we already saw that light
bool first_directional = true;
@@ -172,7 +173,7 @@ void gr_opengl_deferred_lighting_finish()
switch (l.type) {
case Light_Type::Directional:
if (Shadow_quality != ShadowQuality::Disabled) {
if (Cmdline_shadow_quality) {
light_data->enable_shadows = first_directional ? 1 : 0;
}
vec4 light_dir;
@@ -262,7 +263,7 @@ void gr_opengl_deferred_lighting_finish()
uniformAligner.getOffset(element_index),
sizeof(graphics::deferred_light_data),
buffer->bufferHandle());
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
++element_index;
break;
case Light_Type::Cone:
@@ -334,7 +335,7 @@ void gr_opengl_deferred_lighting_finish()
Current_shader->program->Uniforms.setUniformf("zNear", Min_draw_distance);
Current_shader->program->Uniforms.setUniformf("zFar", Max_draw_distance);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
} else {
// Transfer the resolved lighting back to the color texture
// TODO: Maybe this could be improved so that it doesn't require the copy back operation?
+18 -33
View File
@@ -46,6 +46,9 @@ int Distortion_switch = 0;
int Scene_texture_initialized;
bool Scene_framebuffer_in_frame;
bool Deferred_lighting = false;
bool High_dynamic_range = false;
int Scene_texture_width;
int Scene_texture_height;
@@ -85,9 +88,9 @@ void opengl_setup_scene_textures()
Scene_texture_initialized = 0;
if ( Cmdline_no_fbo ) {
Gr_post_processing_enabled = false;
Gr_enable_soft_particles = false;
Gr_framebuffer_effects = {};
Cmdline_postprocess = 0;
Cmdline_softparticles = 0;
Cmdline_fb_explosions = 0;
Scene_ldr_texture = 0;
Scene_color_texture = 0;
@@ -335,13 +338,13 @@ void opengl_setup_scene_textures()
//glDeleteTextures(1, &Scene_fxaa_output_texture);
//Scene_fxaa_output_texture = 0;
Gr_post_processing_enabled = false;
Gr_enable_soft_particles = false;
Cmdline_postprocess = 0;
Cmdline_softparticles = 0;
return;
}
//Setup thruster distortion framebuffer
if (Gr_framebuffer_effects.any_set())
if (Cmdline_fb_thrusters || Cmdline_fb_explosions)
{
glGenFramebuffers(1, &Distortion_framebuffer);
GL_state.BindFrameBuffer(Distortion_framebuffer);
@@ -389,8 +392,8 @@ void opengl_setup_scene_textures()
Scene_color_texture = 0;
Scene_depth_texture = 0;
Gr_post_processing_enabled = false;
Gr_enable_soft_particles = false;
Cmdline_postprocess = 0;
Cmdline_softparticles = 0;
return;
}
@@ -507,7 +510,7 @@ void gr_opengl_scene_texture_begin()
Scene_framebuffer_in_frame = true;
if ( Gr_post_processing_enabled && !PostProcessing_override ) {
if ( Cmdline_postprocess && !PostProcessing_override ) {
High_dynamic_range = true;
}
}
@@ -530,8 +533,8 @@ void gr_opengl_scene_texture_end()
time_buffer = 0.0f;
}
if ( Gr_post_processing_enabled && !PostProcessing_override ) {
gr_opengl_post_process_end();
if ( Cmdline_postprocess && !PostProcessing_override ) {
gr_post_process_end();
} else {
GR_DEBUG_SCOPE("Draw scene texture");
TRACE_SCOPE(tracing::DrawSceneTexture);
@@ -548,7 +551,7 @@ void gr_opengl_scene_texture_end()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
opengl_shader_set_passthrough(true, High_dynamic_range);
opengl_shader_set_passthrough(true);
GL_state.Array.BindArrayBuffer(0);
@@ -647,7 +650,7 @@ void gr_opengl_update_distortion()
GLboolean blend = GL_state.Blend(GL_FALSE);
GLboolean cull = GL_state.CullFace(GL_FALSE);
opengl_shader_set_passthrough(true, High_dynamic_range);
opengl_shader_set_passthrough(true);
GL_state.PushFramebufferState();
GL_state.BindFrameBuffer(Distortion_framebuffer);
@@ -692,7 +695,7 @@ void gr_opengl_update_distortion()
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, vertices, sizeof(vertex) * 4);
opengl_shader_set_passthrough(false, High_dynamic_range);
opengl_shader_set_passthrough(false);
vertex distortion_verts[33];
@@ -861,25 +864,7 @@ void opengl_draw_textured_quad(GLfloat x1,
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(GLfloat) * 4, 0);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD2, sizeof(GLfloat) * 4, sizeof(GLfloat) * 2);
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(glVertices));
}
void opengl_draw_full_screen_textured(GLfloat u1, GLfloat v1, GLfloat u2, GLfloat v2)
{
GR_DEBUG_SCOPE("Draw full screen triangle");
GLfloat glVertices[3][4] = {
{-1.f, -1.f, u1, v1},
{3.f, -1.f, u2 * 2.f, v1},
{-1.f, 3.f, u1, v2 * 2.f},
};
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(GLfloat) * 4, 0);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD2, sizeof(GLfloat) * 4, sizeof(GLfloat) * 2);
opengl_render_primitives_immediate(PRIM_TYPE_TRIS, &vert_def, 3, glVertices, sizeof(glVertices));
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(GLfloat) * 4 * 4);
}
void gr_opengl_render_decals(decal_material* material_info,
+8 -14
View File
@@ -32,6 +32,9 @@ extern GLuint Scene_stencil_buffer;
void gr_opengl_update_distortion();
void opengl_set_spec_mapping(int tmap_type, float *u_scale, float *v_scale, int stage = 0);
void opengl_reset_spec_mapping();
void gr_opengl_sphere(material *material_def, float rad);
void gr_opengl_shadow_map_start(matrix4 *shadow_view_matrix, const matrix *light_orient);
@@ -61,20 +64,6 @@ void gr_opengl_render_rocket_primitives(interface_material* material_info, primi
void opengl_draw_textured_quad(GLfloat x1, GLfloat y1, GLfloat u1, GLfloat v1,
GLfloat x2, GLfloat y2, GLfloat u2, GLfloat v2 );
/**
* @brief Draw "something" so that the entire screen is covered and the corners use the UV values that are provided.
*
* @details This actually draws a a single oversized triangle that covers the screen in such a way so that the provided
* UV values are generated by the GPU in the corners of the screen. This is better than drawing two triangles since then
* the diagonal would be shaded differently for the two triangles causing visual differences.
*
* @param u1 The U value of the lower left corner.
* @param v1 The V value of the lower left corner.
* @param u2 The U value of the upper right corner.
* @param v2 The V value of the upper right corner.
*/
void opengl_draw_full_screen_textured(GLfloat u1, GLfloat v1, GLfloat u2, GLfloat v2);
inline GLenum opengl_primitive_type(primitive_type prim_type);
void gr_opengl_start_decal_pass();
@@ -93,4 +82,9 @@ extern int Scene_texture_height;
extern float Scene_texture_u_scale;
extern float Scene_texture_v_scale;
extern bool Deferred_lighting;
extern bool High_dynamic_range;
extern bool Use_Shaders_for_effect_rendering;
#endif // !GR_OPENGLDRAW_H
+111 -377
View File
@@ -1,17 +1,12 @@
#include "gropenglpostprocessing.h"
#include "ShaderProgram.h"
#include "SmaaAreaTex.h"
#include "SmaaSearchTex.h"
#include "freespace.h"
#include "gropengl.h"
#include "gropengldraw.h"
#include "gropenglshader.h"
#include "gropenglstate.h"
#include "cmdline/cmdline.h"
#include "freespace.h"
#include "def_files/def_files.h"
#include "gropengl.h"
#include "gropengldraw.h"
#include "gropenglpostprocessing.h"
#include "gropenglshader.h"
#include "gropenglstate.h"
#include "io/timer.h"
#include "lighting/lighting.h"
#include "mod_table/mod_table.h"
@@ -19,13 +14,17 @@
#include "parse/parselo.h"
#include "ship/ship.h"
#include "tracing/tracing.h"
#include "ShaderProgram.h"
extern bool PostProcessing_override;
extern int opengl_check_framebuffer();
//Needed to track where the FXAA shaders are
size_t fxaa_shader_id;
//In case we don't find the shaders at all, this override is needed
bool fxaa_unavailable = false;
int Fxaa_preset_last_frame;
bool zbuffer_saved = false;
// lightshaft parameters
@@ -78,18 +77,6 @@ static GLuint Post_framebuffer_id[2] = { 0 };
static int Post_texture_width = 0;
static int Post_texture_height = 0;
static GLuint Smaa_edge_detection_fb = 0;
static GLuint Smaa_edges_tex = 0;
static GLuint Smaa_blending_weight_fb = 0;
static GLuint Smaa_blend_tex = 0;
static GLuint Smaa_neighborhood_blending_fb = 0;
static GLuint Smaa_output_tex = 0;
static GLuint Smaa_search_tex = 0;
static GLuint Smaa_area_tex = 0;
void opengl_post_pass_tonemap()
{
GR_DEBUG_SCOPE("Tonemapping");
@@ -104,7 +91,7 @@ void opengl_post_pass_tonemap()
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_color_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
}
void opengl_post_pass_bloom()
@@ -139,7 +126,7 @@ void opengl_post_pass_bloom()
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_color_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
}
// ------ end bright pass ------
@@ -179,7 +166,7 @@ void opengl_post_pass_bloom()
glViewport(0, 0, bloom_width, bloom_height);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
}
}
}
@@ -203,7 +190,7 @@ void opengl_post_pass_bloom()
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
}
@@ -240,11 +227,8 @@ void gr_opengl_post_process_begin()
}
void recompile_fxaa_shader() {
if (!gr_is_fxaa_mode(Gr_aa_mode)) {
return;
}
mprintf(("Recompiling FXAA shader...\n"));
mprintf(("Recompiling FXAA shader with preset %d\n", Cmdline_fxaa_preset));
// start recompile by grabbing deleting the current shader we have, assuming it's already created
opengl_delete_shader( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
@@ -252,7 +236,7 @@ void recompile_fxaa_shader() {
// then recreate it again. shader loading code will be updated with the new FXAA presets
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0);
Gr_aa_mode_last_frame = Gr_aa_mode;
Fxaa_preset_last_frame = Cmdline_fxaa_preset;
}
void opengl_post_pass_fxaa() {
@@ -260,7 +244,7 @@ void opengl_post_pass_fxaa() {
TRACE_SCOPE(tracing::FXAA);
//If the preset changed, recompile the shader
if (Gr_aa_mode_last_frame != Gr_aa_mode) {
if (Fxaa_preset_last_frame != Cmdline_fxaa_preset) {
recompile_fxaa_shader();
}
@@ -278,7 +262,7 @@ void opengl_post_pass_fxaa() {
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
// set and configure post shader ..
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
@@ -292,124 +276,11 @@ void opengl_post_pass_fxaa() {
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_luminance_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_shader_set_current();
}
static void smaa_detect_edges()
{
GR_DEBUG_SCOPE("SMAA Detect Edges");
TRACE_SCOPE(tracing::SMAAEdgeDetection);
GL_state.BindFrameBuffer(Smaa_edge_detection_fb);
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, clearValues);
// Do the edge detection step
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_EDGE, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setUniformi("colorTex", 0);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
}
static void smaa_calculate_blending_weights()
{
GR_DEBUG_SCOPE("SMAA Blending Weights calculation");
TRACE_SCOPE(tracing::SMAACalculateBlendingWeights);
GL_state.BindFrameBuffer(Smaa_blending_weight_fb);
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, clearValues);
// Do the edge detection step
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setUniformi("edgesTex", 0);
Current_shader->program->Uniforms.setUniformi("areaTex", 1);
Current_shader->program->Uniforms.setUniformi("searchTex", 2);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Smaa_edges_tex);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_area_tex);
GL_state.Texture.Enable(2, GL_TEXTURE_2D, Smaa_search_tex);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
}
static void smaa_neighborhood_blending()
{
GR_DEBUG_SCOPE("SMAA Neighborhood Blending");
TRACE_SCOPE(tracing::SMAANeighborhoodBlending);
GL_state.BindFrameBuffer(Smaa_neighborhood_blending_fb);
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, clearValues);
// Do the edge detection step
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setUniformi("colorTex", 0);
Current_shader->program->Uniforms.setUniformi("blendTex", 1);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_blend_tex);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
}
void smaa_resolve()
{
GR_DEBUG_SCOPE("SMAA Resolve");
TRACE_SCOPE(tracing::SMAAResolve);
opengl_shader_set_passthrough(true, false);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Smaa_output_tex);
// Copy SMAA output back to the original framebuffer
if (GL_rendering_to_texture) {
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, 0.0f, (float)gr_screen.max_w, (float)gr_screen.max_h,
Scene_texture_u_scale, Scene_texture_v_scale);
} else {
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, Scene_texture_v_scale, (float)gr_screen.max_w,
(float)gr_screen.max_h, Scene_texture_u_scale, 0.0f);
}
}
void opengl_post_pass_smaa()
{
GR_DEBUG_SCOPE("SMAA");
TRACE_SCOPE(tracing::SMAA);
GL_state.PushFramebufferState();
GL_state.ColorMask(true, true, true, true);
smaa_detect_edges();
smaa_calculate_blending_weights();
smaa_neighborhood_blending();
GL_state.PopFramebufferState();
smaa_resolve();
}
extern GLuint Shadow_map_depth_texture;
extern GLuint Scene_depth_texture;
extern GLuint Cockpit_depth_texture;
@@ -460,7 +331,7 @@ void opengl_post_lightshafts()
GL_state.Blend(GL_TRUE);
GL_state.SetAlphaBlendMode(ALPHA_BLEND_ADDITIVE);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
GL_state.Blend(GL_FALSE);
break;
@@ -490,14 +361,10 @@ void gr_opengl_post_process_end()
// do tone mapping
opengl_post_pass_tonemap();
// Do Post processing AA
if (!GL_rendering_to_texture) {
if (gr_is_smaa_mode(Gr_aa_mode)) {
opengl_post_pass_smaa();
} else if (gr_is_fxaa_mode(Gr_aa_mode) && !fxaa_unavailable) {
opengl_post_pass_fxaa();
}
}
// Do FXAA
if (Cmdline_fxaa && !fxaa_unavailable && !GL_rendering_to_texture) {
opengl_post_pass_fxaa();
}
// render lightshafts
opengl_post_lightshafts();
@@ -554,7 +421,7 @@ void gr_opengl_post_process_end()
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_depth_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
//Shadow Map debug window
//#define SHADOW_DEBUG
@@ -837,58 +704,9 @@ static bool opengl_post_init_table()
}
}
static void set_fxaa_defines(SCP_stringstream& sflags)
void opengl_post_shader_header(SCP_stringstream &sflags, shader_type shader_t, int flags)
{
// Since we require OpenGL 3.2 we always have support for GLSL 130
sflags << "#define FXAA_GLSL_120 0\n";
sflags << "#define FXAA_GLSL_130 1\n";
if (GLSL_version >= 400) {
// The gather function became part of the standard with GLSL 4.00
sflags << "#define FXAA_GATHER4_ALPHA 1\n";
}
switch (Gr_aa_mode) {
case AntiAliasMode::None:
sflags << "#define FXAA_QUALITY_PRESET 10\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_Low:
sflags << "#define FXAA_QUALITY_PRESET 12\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/8.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/16.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_Medium:
sflags << "#define FXAA_QUALITY_PRESET 26\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/12.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/24.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_High:
sflags << "#define FXAA_QUALITY_PRESET 39\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/15.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/32.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
default:
UNREACHABLE("Unhandled FXAA mode!");
}
}
void set_smaa_defines(SCP_stringstream& sflags)
{
// Define what GLSL version we use
if (GLSL_version >= 400) {
sflags << "#define SMAA_GLSL_4\n";
} else {
sflags << "#define SMAA_GLSL_3\n";
}
}
void opengl_post_shader_header(SCP_stringstream& sflags, shader_type shader_t, int flags)
{
if (shader_t == SDR_TYPE_POST_PROCESS_MAIN) {
if ( shader_t == SDR_TYPE_POST_PROCESS_MAIN ) {
for (size_t idx = 0; idx < Post_effects.size(); idx++) {
if (flags & (1 << idx)) {
sflags << "#define ";
@@ -896,15 +714,83 @@ void opengl_post_shader_header(SCP_stringstream& sflags, shader_type shader_t, i
sflags << "\n";
}
}
} else if (shader_t == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS) {
} else if ( shader_t == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS ) {
char temp[64];
sprintf(temp, "#define SAMPLE_NUM %d\n", ls_samplenum);
sflags << temp;
} else if (shader_t == SDR_TYPE_POST_PROCESS_FXAA) {
set_fxaa_defines(sflags);
} else if (shader_t == SDR_TYPE_POST_PROCESS_SMAA_EDGE || shader_t == SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT ||
shader_t == SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING) {
set_smaa_defines(sflags);
} else if ( shader_t == SDR_TYPE_POST_PROCESS_FXAA ) {
// Since we require OpenGL 3.2 we always have support for GLSL 130
sflags << "#define FXAA_GLSL_120 0\n";
sflags << "#define FXAA_GLSL_130 1\n";
if (GLSL_version >= 400) {
// The gather function became part of the standard with GLSL 4.00
sflags << "#define FXAA_GATHER4_ALPHA 1\n";
}
switch (Cmdline_fxaa_preset) {
case 0:
sflags << "#define FXAA_QUALITY_PRESET 10\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 1:
sflags << "#define FXAA_QUALITY_PRESET 11\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/7.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/14.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 2:
sflags << "#define FXAA_QUALITY_PRESET 12\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/8.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/16.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 3:
sflags << "#define FXAA_QUALITY_PRESET 13\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/9.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/18.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 4:
sflags << "#define FXAA_QUALITY_PRESET 14\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/10.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/20.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 5:
sflags << "#define FXAA_QUALITY_PRESET 25\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/11.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/22.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 6:
sflags << "#define FXAA_QUALITY_PRESET 26\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/12.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/24.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 7:
sflags << "#define FXAA_PC 1\n";
sflags << "#define FXAA_QUALITY_PRESET 27\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/13.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/26.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 8:
sflags << "#define FXAA_QUALITY_PRESET 28\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/14.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/28.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case 9:
sflags << "#define FXAA_QUALITY_PRESET 39\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/15.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/32.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
}
}
}
@@ -933,17 +819,11 @@ bool opengl_post_init_shaders()
Cmdline_bloom_intensity = 0;
}
if (gr_is_fxaa_mode(Gr_aa_mode))
{
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0);
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0);
}
if (gr_is_smaa_mode(Gr_aa_mode)) {
// Precompile the SMAA shaders if enabled
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_EDGE, 0);
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, 0);
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, 0);
if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) < 0 ||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0) < 0 ) {
Cmdline_fxaa = false;
fxaa_unavailable = true;
mprintf(("Error while compiling FXAA shaders. FXAA will be unavailable.\n"));
}
return true;
@@ -981,148 +861,6 @@ void opengl_setup_bloom_textures()
GL_state.BindFrameBuffer(0);
}
void setup_smaa_edges_resources()
{
glGenTextures(1, &Smaa_edges_tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Smaa_edges_tex);
opengl_set_object_label(GL_TEXTURE, Smaa_edges_tex, "SMAA Edge detection texture");
if (GLAD_GL_ARB_texture_storage) {
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenFramebuffers(1, &Smaa_edge_detection_fb);
GL_state.BindFrameBuffer(Smaa_edge_detection_fb);
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_edge_detection_fb, "SMAA Edge detection framebuffer");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_edges_tex, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
void setup_smaa_blending_weight_resources()
{
glGenTextures(1, &Smaa_blend_tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Smaa_blend_tex);
opengl_set_object_label(GL_TEXTURE, Smaa_blend_tex, "SMAA Blending weight calculation texture");
if (GLAD_GL_ARB_texture_storage) {
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenFramebuffers(1, &Smaa_blending_weight_fb);
GL_state.BindFrameBuffer(Smaa_blending_weight_fb);
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_blending_weight_fb, "SMAA Blending widght calculation framebuffer");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_blend_tex, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
void setup_smaa_neighborhood_blending_resources()
{
glGenTextures(1, &Smaa_output_tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Smaa_output_tex);
opengl_set_object_label(GL_TEXTURE, Smaa_output_tex, "SMAA output texture");
if (GLAD_GL_ARB_texture_storage) {
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenFramebuffers(1, &Smaa_neighborhood_blending_fb);
GL_state.BindFrameBuffer(Smaa_neighborhood_blending_fb);
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_neighborhood_blending_fb, "SMAA neighborhood blending framebuffer");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_output_tex, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
static GLuint load_smaa_texture(GLsizei width, GLsizei height, GLenum format, const uint8_t* pixels, const char* name)
{
GLuint tex;
glGenTextures(1, &tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(tex);
opengl_set_object_label(GL_TEXTURE, tex, name);
if (GLAD_GL_ARB_texture_storage) {
glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, format, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
}
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format == GL_RG8 ? GL_RG : GL_RED, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return tex;
}
static void setup_smaa_resources()
{
GL_state.PushFramebufferState();
Smaa_area_tex = load_smaa_texture(AREATEX_WIDTH, AREATEX_HEIGHT, GL_RG8, areaTexBytes, "SMAA Area Texture");
Smaa_search_tex =
load_smaa_texture(SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, GL_R8, searchTexBytes, "SMAA Search Texture");
setup_smaa_edges_resources();
setup_smaa_blending_weight_resources();
setup_smaa_neighborhood_blending_resources();
GL_state.PopFramebufferState();
}
// generate and test the framebuffer and textures that we are going to use
static bool opengl_post_init_framebuffer()
{
@@ -1142,10 +880,6 @@ static bool opengl_post_init_framebuffer()
opengl_setup_bloom_textures();
if (gr_is_smaa_mode(Gr_aa_mode)) {
setup_smaa_resources();
}
GL_state.BindFrameBuffer(0);
rval = true;
@@ -1184,11 +918,11 @@ void opengl_post_process_init()
//We need to read the tbl first. This is mostly for FRED's benefit, as otherwise the list of post effects for the sexp doesn't get updated.
if ( !opengl_post_init_table() ) {
mprintf((" Unable to read post-processing table! Disabling post-processing...\n\n"));
Gr_post_processing_enabled = false;
Cmdline_postprocess = 0;
return;
}
if ( !Gr_post_processing_enabled ) {
if ( !Cmdline_postprocess ) {
return;
}
@@ -1197,19 +931,19 @@ void opengl_post_process_init()
}
if ( Cmdline_no_fbo ) {
Gr_post_processing_enabled = false;
Cmdline_postprocess = 0;
return;
}
if ( !opengl_post_init_shaders() ) {
mprintf((" Unable to initialize post-processing shaders! Disabling post-processing...\n\n"));
Gr_post_processing_enabled = false;
Cmdline_postprocess = 0;
return;
}
if ( !opengl_post_init_framebuffer() ) {
mprintf((" Unable to initialize post-processing framebuffer! Disabling post-processing...\n\n"));
Gr_post_processing_enabled = false;
Cmdline_postprocess = 0;
return;
}
@@ -2,9 +2,6 @@
#ifndef _GROPENGLPOSTPROCESSING_H
#define _GROPENGLPOSTPROCESSING_H
#include "globalincs/pstypes.h"
#include "graphics/opengl/gropenglshader.h"
void opengl_post_process_init();
void opengl_post_process_shutdown();
+5 -16
View File
@@ -143,15 +143,6 @@ static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_ROCKET_UI, "rocketui-v.sdr", "rocketui-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::COLOR, opengl_vert_attrib::TEXCOORD }, "libRocket UI" },
{ SDR_TYPE_POST_PROCESS_SMAA_EDGE, "smaa-edge-v.sdr", "smaa-edge-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Edge detection" },
{ SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, "smaa-blend-v.sdr", "smaa-blend-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Blending weight calculation" },
{ SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, "smaa-neighbour-v.sdr", "smaa-neighbour-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Neighborhood Blending" },
};
// clang-format on
@@ -379,13 +370,11 @@ static SCP_string opengl_shader_get_header(shader_type type_id, int flags, bool
sflags << "#define HAS_GEOMETRY_SHADER\n";
}
if (type_id == SDR_TYPE_POST_PROCESS_MAIN || type_id == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS ||
type_id == SDR_TYPE_POST_PROCESS_FXAA || type_id == SDR_TYPE_POST_PROCESS_SMAA_EDGE ||
type_id == SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT ||
type_id == SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING) {
if (type_id == SDR_TYPE_POST_PROCESS_MAIN || type_id == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS || type_id == SDR_TYPE_POST_PROCESS_FXAA) {
// ignore looking for variants. main post process, lightshafts, and FXAA shaders need special headers to be hacked in
opengl_post_shader_header(sflags, type_id, flags);
} else {
}
else {
for (int i = 0; i < GL_num_shader_variants; ++i) {
opengl_shader_variant_t &variant = GL_shader_variants[i];
@@ -1003,7 +992,7 @@ GLint opengl_shader_get_attribute(opengl_vert_attrib::attrib_id attribute)
return Current_shader->program->getAttributeLocation(attribute);
}
void opengl_shader_set_passthrough(bool textured, bool hdr)
void opengl_shader_set_passthrough(bool textured)
{
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0));
@@ -1015,7 +1004,7 @@ void opengl_shader_set_passthrough(bool textured, bool hdr)
Current_shader->program->Uniforms.setUniformi("alphaTexture", 0);
Current_shader->program->Uniforms.setUniformi("srgb", hdr ? 1 : 0);
Current_shader->program->Uniforms.setUniformi("srgb", High_dynamic_range ? 1 : 0);
Current_shader->program->Uniforms.setUniformf("intensity", 1.0f);
Current_shader->program->Uniforms.setUniformf("alphaThreshold", GL_alpha_threshold);
Loaded 100 of 500 files, more files were not shown because too many files have changed in this diff. Show more