mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
114
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
573a1f2fa3 | ||
|
|
a763d84b56 | ||
|
|
c06ccbb602 | ||
|
|
ffd8a5ae2a | ||
|
|
aa753d5d6e | ||
|
|
1cf042064f | ||
|
|
a4e14a94d2 | ||
|
|
5871d644cc | ||
|
|
145a149873 | ||
|
|
7492c51ee6 | ||
|
|
be4954a69e | ||
|
|
875a95b82e | ||
|
|
f6b129577b | ||
|
|
4d30bbba3e | ||
|
|
8823dc67eb | ||
|
|
8690c9d7f6 | ||
|
|
f70d242903 | ||
|
|
5b4306dbd6 | ||
|
|
013870fc6a | ||
|
|
0e3d4e562f | ||
|
|
48d1ec4575 | ||
|
|
32ad077676 | ||
|
|
9942308fc8 | ||
|
|
af3b97aae5 | ||
|
|
c3c0b0e1f4 | ||
|
|
9d5863bc76 | ||
|
|
4b2d436b04 | ||
|
|
404195d389 | ||
|
|
df29aad213 | ||
|
|
026601e350 | ||
|
|
05a48addc6 | ||
|
|
a1e9e62b6e | ||
|
|
64ea61c93a | ||
|
|
a0bbf8fd54 | ||
|
|
15e9872bb5 | ||
|
|
a1f592ffef | ||
|
|
07de43ffc4 | ||
|
|
522fa4c906 | ||
|
|
7611e0a2d2 | ||
|
|
9290659edf | ||
|
|
3a88c2f9e3 | ||
|
|
a732686bf6 | ||
|
|
2ede27a557 | ||
|
|
8300b018f0 | ||
|
|
93aed25251 | ||
|
|
591563118c | ||
|
|
b59b5dd5d8 | ||
|
|
bb0bde6409 | ||
|
|
66a392ddae | ||
|
|
8bfc9fa709 | ||
|
|
ccbdeeff67 | ||
|
|
0f1176adaf | ||
|
|
b75fce3d5c | ||
|
|
ab68ad4855 | ||
|
|
426cf0b969 | ||
|
|
2d1f7ba50f | ||
|
|
69145e65f1 | ||
|
|
3dcb4b380a | ||
|
|
8e996fdf67 | ||
|
|
7367d8a31f | ||
|
|
d5fcfc773c | ||
|
|
5cdd3a676d | ||
|
|
fd95da4c0a | ||
|
|
1aa613e0f5 | ||
|
|
7d91a35878 | ||
|
|
fa2c566b3f | ||
|
|
f2b7f9718a | ||
|
|
08c0bd3aee | ||
|
|
3a39133e04 | ||
|
|
c3ec5825a4 | ||
|
|
baddd6703d | ||
|
|
0c3733d2cd | ||
|
|
c536d49afd | ||
|
|
b031aee73a | ||
|
|
c480e2c944 | ||
|
|
c7cd913df4 | ||
|
|
58a465e805 | ||
|
|
cf08ff0cd5 | ||
|
|
c839e8168a | ||
|
|
3257777c18 | ||
|
|
1028e14398 | ||
|
|
b733679875 | ||
|
|
723cbd5938 | ||
|
|
0e48ea11ac | ||
|
|
57ab92645c | ||
|
|
2431f5db2c | ||
|
|
34d960638a | ||
|
|
3bb26b10a3 | ||
|
|
3cdc511b2d | ||
|
|
4543d0c80c | ||
|
|
2a740ad2c8 | ||
|
|
7187da0233 | ||
|
|
ab43e4d987 | ||
|
|
8056476db1 | ||
|
|
4b471d6045 | ||
|
|
8b19d7c8eb | ||
|
|
90c6679f03 | ||
|
|
4c73e5fe20 | ||
|
|
dd3a3138a7 | ||
|
|
9e8a091172 | ||
|
|
5d72560a30 | ||
|
|
2a9c65bd3f | ||
|
|
6b4cca55be | ||
|
|
c18139e73f | ||
|
|
be6ee814c2 | ||
|
|
ea6130e542 | ||
|
|
48a566a2d5 | ||
|
|
dab5b293d4 | ||
|
|
2a2cd3c873 | ||
|
|
51ffb56b16 | ||
|
|
211e7a4284 | ||
|
|
24643586f1 | ||
|
|
08986cb47e | ||
|
|
c3d878b1b3 |
No files matched your search
@@ -1,4 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*.{h,cpp}]
|
||||
indent_style = tab
|
||||
-275
@@ -1,275 +0,0 @@
|
||||
*.o
|
||||
*.a
|
||||
.dirstamp
|
||||
libtool
|
||||
ltmain.sh
|
||||
m4/libtool.m4
|
||||
m4/ltoptions.m4
|
||||
m4/ltsugar.m4
|
||||
m4/ltversion.m4
|
||||
m4/lt~obsolete.m4
|
||||
compile
|
||||
.deps/
|
||||
code/.deps/
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.*
|
||||
code/fs2_open_*
|
||||
code/wxFRED2_*
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
.svn
|
||||
*.layout
|
||||
projects/Xcode/Frameworks/
|
||||
|
||||
#========
|
||||
|
||||
#OS junk files
|
||||
[Tt]humbs.db
|
||||
*.DS_Store
|
||||
|
||||
#Visual Studio files
|
||||
*.[Oo]bj
|
||||
*.user
|
||||
*.aps
|
||||
*.pch
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ncb
|
||||
*.suo
|
||||
*.tlb
|
||||
*.tlh
|
||||
*.bak
|
||||
*.[Cc]ache
|
||||
*.ilk
|
||||
*.log
|
||||
*.lib
|
||||
*.sbr
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.unsuccessfulbuild
|
||||
ipch/
|
||||
[Oo]bj/
|
||||
[Bb]in
|
||||
[Dd]ebug*/
|
||||
[Rr]elease*/
|
||||
Ankh.NoLoad
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
#MonoDevelop
|
||||
*.pidb
|
||||
*.userprefs
|
||||
|
||||
#Tooling
|
||||
_ReSharper*/
|
||||
*.resharper
|
||||
[Tt]est[Rr]esult*
|
||||
*.sass-cache
|
||||
|
||||
#Project files
|
||||
[Bb]uild/
|
||||
|
||||
#Subversion files
|
||||
.svn
|
||||
|
||||
# Office Temp Files
|
||||
~$*
|
||||
|
||||
# vim Temp Files
|
||||
*~
|
||||
|
||||
#NuGet
|
||||
packages/
|
||||
*.nupkg
|
||||
|
||||
#ncrunch
|
||||
*ncrunch*
|
||||
*crunch*.local.xml
|
||||
|
||||
# visual studio database projects
|
||||
*.dbmdl
|
||||
|
||||
#Test files
|
||||
*.testsettings
|
||||
|
||||
#===========
|
||||
|
||||
#########################
|
||||
# .gitignore file for Xcode4 and Xcode5 Source projects
|
||||
#
|
||||
# Apple bugs, waiting for Apple to fix/respond:
|
||||
#
|
||||
# 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation?
|
||||
#
|
||||
# Version 2.1
|
||||
# For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects
|
||||
#
|
||||
# 2013 updates:
|
||||
# - fixed the broken "save personal Schemes"
|
||||
# - added line-by-line explanations for EVERYTHING (some were missing)
|
||||
#
|
||||
# NB: if you are storing "built" products, this WILL NOT WORK,
|
||||
# and you should use a different .gitignore (or none at all)
|
||||
# This file is for SOURCE projects, where there are many extra
|
||||
# files that we want to exclude
|
||||
#
|
||||
#########################
|
||||
|
||||
#####
|
||||
# OS X temporary files that should never be committed
|
||||
#
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
.DS_Store
|
||||
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
.Trashes
|
||||
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
*.swp
|
||||
|
||||
# *.lock - this is used and abused by many editors for many different things.
|
||||
# For the main ones I use (e.g. Eclipse), it should be excluded
|
||||
# from source-control, but YMMV
|
||||
|
||||
*.lock
|
||||
|
||||
#
|
||||
# profile - REMOVED temporarily (on double-checking, this seems incorrect; I can't find it in OS X docs?)
|
||||
#profile
|
||||
|
||||
|
||||
####
|
||||
# Xcode temporary files that should never be committed
|
||||
#
|
||||
# NB: NIB/XIB files still exist even on Storyboard projects, so we want this...
|
||||
|
||||
*~.nib
|
||||
|
||||
|
||||
####
|
||||
# Xcode build files -
|
||||
#
|
||||
# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData"
|
||||
|
||||
DerivedData/
|
||||
|
||||
# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build"
|
||||
|
||||
build/
|
||||
|
||||
|
||||
#####
|
||||
# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups)
|
||||
#
|
||||
# This is complicated:
|
||||
#
|
||||
# SOMETIMES you need to put this file in version control.
|
||||
# Apple designed it poorly - if you use "custom executables", they are
|
||||
# saved in this file.
|
||||
# 99% of projects do NOT use those, so they do NOT want to version control this file.
|
||||
# ..but if you're in the 1%, comment out the line "*.pbxuser"
|
||||
|
||||
# .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html
|
||||
|
||||
*.pbxuser
|
||||
|
||||
# .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
|
||||
|
||||
*.mode1v3
|
||||
|
||||
# .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
|
||||
|
||||
*.mode2v3
|
||||
|
||||
# .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file
|
||||
|
||||
*.perspectivev3
|
||||
|
||||
# NB: also, whitelist the default ones, some projects need to use these
|
||||
!default.pbxuser
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.perspectivev3
|
||||
|
||||
|
||||
####
|
||||
# Xcode 4 - semi-personal settings
|
||||
#
|
||||
#
|
||||
# OPTION 1: ---------------------------------
|
||||
# throw away ALL personal settings (including custom schemes!
|
||||
# - unless they are "shared")
|
||||
#
|
||||
# NB: this is exclusive with OPTION 2 below
|
||||
xcuserdata
|
||||
|
||||
# OPTION 2: ---------------------------------
|
||||
# get rid of ALL personal settings, but KEEP SOME OF THEM
|
||||
# - NB: you must manually uncomment the bits you want to keep
|
||||
#
|
||||
# NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X,
|
||||
# or manually install git over the top of the OS X version
|
||||
# NB: this is exclusive with OPTION 1 above
|
||||
#
|
||||
#xcuserdata/**/*
|
||||
|
||||
# (requires option 2 above): Personal Schemes
|
||||
#
|
||||
#!xcuserdata/**/xcschemes/*
|
||||
|
||||
####
|
||||
# XCode 4 workspaces - more detailed
|
||||
#
|
||||
# Workspaces are important! They are a core feature of Xcode - don't exclude them :)
|
||||
#
|
||||
# Workspace layout is quite spammy. For reference:
|
||||
#
|
||||
# /(root)/
|
||||
# /(project-name).xcodeproj/
|
||||
# project.pbxproj
|
||||
# /project.xcworkspace/
|
||||
# contents.xcworkspacedata
|
||||
# /xcuserdata/
|
||||
# /(your name)/xcuserdatad/
|
||||
# UserInterfaceState.xcuserstate
|
||||
# /xcsshareddata/
|
||||
# /xcschemes/
|
||||
# (shared scheme name).xcscheme
|
||||
# /xcuserdata/
|
||||
# /(your name)/xcuserdatad/
|
||||
# (private scheme).xcscheme
|
||||
# xcschememanagement.plist
|
||||
#
|
||||
#
|
||||
|
||||
####
|
||||
# Xcode 4 - Deprecated classes
|
||||
#
|
||||
# Allegedly, if you manually "deprecate" your classes, they get moved here.
|
||||
#
|
||||
# We're using source-control, so this is a "feature" that we do not want!
|
||||
|
||||
*.moved-aside
|
||||
|
||||
# .xccheckout
|
||||
#
|
||||
# Per http://stackoverflow.com/questions/18340453/should-xccheckout-files-in-xcode5-be-ignored-under-vcs
|
||||
#
|
||||
|
||||
*.xccheckout
|
||||
|
||||
####
|
||||
# Documentation
|
||||
#
|
||||
documentation/doxygen/*
|
||||
!documentation/doxygen/.gitkeep
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
language: cpp
|
||||
sudo: true
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libopenal-dev
|
||||
- libogg-dev
|
||||
- libvorbis-dev
|
||||
- build-essential
|
||||
- automake
|
||||
- autoconf
|
||||
- libtheora-dev
|
||||
- libreadline6-dev
|
||||
- libpng12-dev
|
||||
- libjpeg62-dev
|
||||
- liblua5.1-0-dev
|
||||
- libjansson-dev
|
||||
- libtool
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "scp-fs2open/fs2open.github.com"
|
||||
description: "Coverity via Travis CI"
|
||||
notification_email: [email protected]
|
||||
build_command_prepend: "./autogen.sh --enable-debug"
|
||||
build_command: "make -j2"
|
||||
# must match TRAVIS_BRANCH check below
|
||||
branch_pattern: coverity_scan
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
|
||||
matrix:
|
||||
include:
|
||||
# note that gcc Debug MUST be 1st for Coverity
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: CONFIGURATION="Debug"
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: CONFIGURATION="Debug"
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env: CONFIGURATION="Debug" MACOSX_ARCH=x86_64
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: CONFIGURATION="Release"
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: CONFIGURATION="Release"
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env: CONFIGURATION="Release" MACOSX_ARCH=x86_64
|
||||
before_install:
|
||||
# ugly hack; if running a coverity scan abort all except the 1st build
|
||||
# see note re gcc compiler above needing to be 1st
|
||||
# also note that branch_pattern & the TRAVIS_BRANCH check must match
|
||||
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
|
||||
# build process
|
||||
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
|
||||
- ./ci/travis/before_install.sh
|
||||
install:
|
||||
- ./ci/travis/install.sh
|
||||
before_script:
|
||||
- ./ci/travis/before_script.sh
|
||||
script:
|
||||
- ./ci/travis/script.sh
|
||||
@@ -1,29 +0,0 @@
|
||||
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
|
||||
@@ -1,14 +0,0 @@
|
||||
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
|
||||
sell or otherwise commercially exploit the source or things you
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# The "checkoutlist" file is used to support additional version controlled
|
||||
# administrative files in $CVSROOT/CVSROOT, such as template files.
|
||||
#
|
||||
# The first entry on a line is a filename which will be checked out from
|
||||
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
|
||||
# The remainder of the line is an error message to use if the file cannot
|
||||
# be checked out.
|
||||
#
|
||||
# File format:
|
||||
#
|
||||
# [<whitespace>]<filename><whitespace><error message><end-of-line>
|
||||
#
|
||||
# comment lines begin with '#'
|
||||
new_commit_prep Error checking out/updating CVSROOT/new_commit_prep
|
||||
new_log_accum Error checking out/updating CVSROOT/new_log_accum
|
||||
@@ -0,0 +1,17 @@
|
||||
# The "commitinfo" file is used to control pre-commit checks.
|
||||
# The filter on the right is invoked with the repository and a list
|
||||
# of files to check. A non-zero exit of the filter program will
|
||||
# cause the commit to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
||||
DEFAULT $CVSROOT/CVSROOT/new_commit_prep
|
||||
CVSROOT $CVSROOT/CVSROOT/new_commit_prep
|
||||
@@ -0,0 +1,14 @@
|
||||
# Set this to "no" if pserver shouldn't check system users/passwords
|
||||
#SystemAuth=no
|
||||
|
||||
# Put CVS lock files in this directory rather than directly in the repository.
|
||||
#LockDir=/var/lock/cvs
|
||||
|
||||
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
|
||||
# level of the new working directory when using the `cvs checkout'
|
||||
# command.
|
||||
#TopLevelAdmin=no
|
||||
|
||||
# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the
|
||||
# history file, or a subset as needed (ie `TMAR' logs all write operations)
|
||||
#LogHistory=TOFEWGCMAR
|
||||
@@ -0,0 +1,23 @@
|
||||
# This file affects handling of files based on their names.
|
||||
#
|
||||
# The -t/-f options allow one to treat directories of files
|
||||
# as a single file, or to transform a file in other ways on
|
||||
# its way in and out of CVS.
|
||||
#
|
||||
# The -m option specifies whether CVS attempts to merge files.
|
||||
#
|
||||
# The -k option specifies keyword expansion (e.g. -kb for binary).
|
||||
#
|
||||
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
|
||||
#
|
||||
# wildcard [option value][option value]...
|
||||
#
|
||||
# where option is one of
|
||||
# -f from cvs filter value: path to filter
|
||||
# -t to cvs filter value: path to filter
|
||||
# -m update methodology value: MERGE or COPY
|
||||
# -k expansion mode value: b, o, kkv, &c
|
||||
#
|
||||
# and value is a single-quote delimited value.
|
||||
# For example:
|
||||
#*.gif -k 'b'
|
||||
@@ -0,0 +1,21 @@
|
||||
# The "editinfo" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
||||
@@ -0,0 +1,30 @@
|
||||
# The "loginfo" file controls where "cvs commit" log information
|
||||
# is sent. The first entry on a line is a regular expression which must match
|
||||
# the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. If a match is found, then the remainder of the line is a filter
|
||||
# program that should expect log information on its standard input.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name ALL appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or DEFAULT.
|
||||
#
|
||||
# You may specify a format string as part of the
|
||||
# filter. The string is composed of a `%' followed
|
||||
# by a single format character, or followed by a set of format
|
||||
# characters surrounded by `{' and `}' as separators. The format
|
||||
# characters are:
|
||||
#
|
||||
# s = file name
|
||||
# V = old version number (pre-checkin)
|
||||
# v = new version number (post-checkin)
|
||||
#
|
||||
# For example:
|
||||
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
||||
# or
|
||||
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
||||
|
||||
DEFAULT $CVSROOT/CVSROOT/new_log_accum -m [email protected] %{sVv}
|
||||
CVSROOT $CVSROOT/CVSROOT/new_log_accum -m [email protected] %{sVv}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Three different line formats are valid:
|
||||
# key -a aliases...
|
||||
# key [options] directory
|
||||
# key [options] directory files...
|
||||
#
|
||||
# Where "options" are composed of:
|
||||
# -i prog Run "prog" on "cvs commit" from top-level of module.
|
||||
# -o prog Run "prog" on "cvs checkout" of module.
|
||||
# -e prog Run "prog" on "cvs export" of module.
|
||||
# -t prog Run "prog" on "cvs rtag" of module.
|
||||
# -u prog Run "prog" on "cvs update" of module.
|
||||
# -d dir Place module in directory "dir" instead of module name.
|
||||
# -l Top-level directory only -- do not recurse.
|
||||
#
|
||||
# NOTE: If you change any of the "Run" options above, you'll have to
|
||||
# release and re-checkout any working directories of these modules.
|
||||
#
|
||||
# And "directory" is a path to a directory relative to $CVSROOT.
|
||||
#
|
||||
# The "-a" option specifies an alias. An alias is interpreted as if
|
||||
# everything on the right of the "-a" had been typed on the command line.
|
||||
#
|
||||
# You can encode a module within a module by using the special '&'
|
||||
# character to interpose another module into the current module. This
|
||||
# can be useful for creating a module that consists of many directories
|
||||
# spread out over the entire source repository.
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# Copyright (C) 2000 by Kevin L. Mitchell <[email protected]>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
#
|
||||
# Script to store the last visited directory for newlogaccum.pl.
|
||||
#
|
||||
# $Id: new_commit_prep,v 1.1 2002-08-11 23:05:15 drevil Exp $
|
||||
|
||||
use strict;
|
||||
|
||||
# This routine removes everything in a directory
|
||||
sub clear_dir {
|
||||
my ($dir) = @_;
|
||||
my ($file);
|
||||
|
||||
opendir(DIR, $dir) || die "Cannot clear directory $dir: $!";
|
||||
while ($file = readdir(DIR)) {
|
||||
next
|
||||
if ($file eq "." || $file eq "..");
|
||||
|
||||
$file = "$dir/$file";
|
||||
|
||||
if (-d $file) {
|
||||
# It's a directory, recurse into it, then delete it.
|
||||
clear_dir($file);
|
||||
rmdir($file);
|
||||
} else {
|
||||
# It's a file, delete it.
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
closedir(DIR);
|
||||
}
|
||||
|
||||
# This routine prepares a temporary directory, hopefully in a secure
|
||||
# fashion; it uses the process group to make secondary programs be able
|
||||
# to find it.
|
||||
sub tmpdir (;$) {
|
||||
my ($clear) = @_;
|
||||
my ($pgrp, $own, $mode, $tmpdir);
|
||||
|
||||
$pgrp = getpgrp();
|
||||
|
||||
die "Don't run $0 setuid!"
|
||||
unless ($< == $>);
|
||||
|
||||
# Decide on the directory name, using various environment variables
|
||||
$tmpdir = ($ENV{TMPDIR} || $ENV{TMP} || $ENV{TEMP} || "/tmp") .
|
||||
"/.#cvs.$pgrp";
|
||||
|
||||
# Doesn't exist, but we can't create it...
|
||||
die "Can't create temporary directory $tmpdir: $!"
|
||||
unless (-e $tmpdir || mkdir($tmpdir, 0700));
|
||||
|
||||
die "Temporary directory $tmpdir is not a directory"
|
||||
unless (-d $tmpdir);
|
||||
|
||||
# Check ownership and permissions
|
||||
(undef, undef, $mode, undef, $own, undef) = stat($tmpdir);
|
||||
|
||||
die "Temporary directory $tmpdir not owned by $< (owned by $own)"
|
||||
unless ($own == $<);
|
||||
|
||||
die "Temporary directory $tmpdir group-writable"
|
||||
if ($mode & 0020);
|
||||
die "Temporary directory $tmpdir other-writable"
|
||||
if ($mode & 0002);
|
||||
|
||||
# If we're supposed to clear the directory, do so...
|
||||
clear_dir($tmpdir)
|
||||
if ($clear);
|
||||
|
||||
return $tmpdir;
|
||||
}
|
||||
|
||||
# This routine writes a single line to a file
|
||||
sub write_line ($$) {
|
||||
my ($fname, $line) = @_;
|
||||
|
||||
open(FILE, ">$fname") || die "Cannot open file $fname for writing";
|
||||
print FILE "$line\n";
|
||||
close(FILE);
|
||||
}
|
||||
|
||||
# Create and empty the temporary directory
|
||||
my ($tmpdir) = (tmpdir(1));
|
||||
|
||||
# Store the directory name
|
||||
write_line("$tmpdir/lastdir", shift(@ARGV));
|
||||
Executable
+757
@@ -0,0 +1,757 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# Copyright (C) 2000 by Kevin L. Mitchell <[email protected]>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
#
|
||||
# Script to accumulate log messages for an entire tree and send them along
|
||||
# with the diffs; deals correctly with all manner of branching (I hope)
|
||||
#
|
||||
# $Id: new_log_accum,v 1.1 2002-08-11 23:05:15 drevil Exp $
|
||||
#
|
||||
|
||||
use strict;
|
||||
|
||||
use vars qw($MAILER $CVS $debug $boundary);
|
||||
use MD5;
|
||||
|
||||
# Set this to the full path of a mailer that takes a list
|
||||
# of email addresses as arguments...
|
||||
$MAILER = "/usr/sbin/sendmail -oi -oeq";
|
||||
|
||||
# Set this to the path of the CVS binary responsible for this tree...
|
||||
$CVS = "/usr/bin/cvs";
|
||||
|
||||
# Don't touch this; use the -d command line option
|
||||
$debug = 0;
|
||||
|
||||
# This is initialized by build_mailheader()
|
||||
$boundary = '';
|
||||
|
||||
use POSIX qw(setsid);
|
||||
|
||||
# We have to dissociate from our parent, so that the CVS commit can
|
||||
# complete, before we try to extract the diffs
|
||||
sub daemonize {
|
||||
defined(my $pid = fork()) || die "Can't fork: $!";
|
||||
exit(0)
|
||||
if $pid;
|
||||
setsid() || die "Can't start a new session: $!";
|
||||
}
|
||||
|
||||
# Debugging output
|
||||
sub debug (@) {
|
||||
print STDERR @_
|
||||
if ($debug);
|
||||
}
|
||||
|
||||
# Constants used in the FSM below for parsing the log message
|
||||
sub STATE_NONE { 0 }
|
||||
sub STATE_MODIFIED { 1 }
|
||||
sub STATE_ADDED { 2 }
|
||||
sub STATE_REMOVED { 3 }
|
||||
sub STATE_LOG1 { 4 }
|
||||
sub STATE_LOG2 { 5 }
|
||||
|
||||
# This routine removes everything in a directory
|
||||
sub clear_dir {
|
||||
my ($dir) = @_;
|
||||
my ($file);
|
||||
|
||||
opendir(DIR, $dir) || die "Cannot clear directory $dir: $!";
|
||||
while ($file = readdir(DIR)) {
|
||||
next
|
||||
if ($file eq "." || $file eq "..");
|
||||
|
||||
$file = "$dir/$file";
|
||||
|
||||
if (-d $file) {
|
||||
# It's a directory, recurse into it, then delete it.
|
||||
clear_dir($file);
|
||||
rmdir($file);
|
||||
} else {
|
||||
# It's a file, delete it.
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
closedir(DIR);
|
||||
}
|
||||
|
||||
# This routine prepares a temporary directory, hopefully in a secure
|
||||
# fashion; it uses the process group to make secondary programs be able
|
||||
# to find it.
|
||||
sub tmpdir (;$) {
|
||||
my ($clear) = @_;
|
||||
my ($pgrp, $own, $mode, $tmpdir);
|
||||
|
||||
$pgrp = getpgrp();
|
||||
|
||||
die "Don't run $0 setuid!"
|
||||
unless ($< == $>);
|
||||
|
||||
# Decide on the directory name, using various environment variables
|
||||
$tmpdir = ($ENV{TMPDIR} || $ENV{TMP} || $ENV{TEMP} || "/tmp") .
|
||||
"/.#cvs.$pgrp";
|
||||
|
||||
# Doesn't exist, but we can't create it...
|
||||
die "Can't create temporary directory $tmpdir: $!"
|
||||
unless (-e $tmpdir || mkdir($tmpdir, 0700));
|
||||
|
||||
die "Temporary directory $tmpdir is not a directory"
|
||||
unless (-d $tmpdir);
|
||||
|
||||
# Check ownership and permissions
|
||||
(undef, undef, $mode, undef, $own, undef) = stat($tmpdir);
|
||||
|
||||
die "Temporary directory $tmpdir not owned by $< (owned by $own)"
|
||||
unless ($own == $<);
|
||||
|
||||
die "Temporary directory $tmpdir group-writable"
|
||||
if ($mode & 0020);
|
||||
die "Temporary directory $tmpdir other-writable"
|
||||
if ($mode & 0002);
|
||||
|
||||
# If we're supposed to clear the directory, do so...
|
||||
clear_dir($tmpdir)
|
||||
if ($clear);
|
||||
|
||||
return $tmpdir;
|
||||
}
|
||||
|
||||
# Routine to remove the temporary directory when done
|
||||
sub cleanup_dir ($) {
|
||||
# If we're debugging, we may want to look at the contents...
|
||||
return
|
||||
if ($debug);
|
||||
|
||||
clear_dir($_[0]);
|
||||
rmdir($_[0]);
|
||||
}
|
||||
|
||||
# Retrieve a single line from a specified file
|
||||
sub get_line ($) {
|
||||
my ($fname) = @_;
|
||||
|
||||
open(FILE, "<$fname") || die "Cannot open file $fname for reading";
|
||||
my $line = <FILE>;
|
||||
close(FILE);
|
||||
|
||||
# Chomp off the \n
|
||||
chomp $line;
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
# Routine that only allows one value to be pushed on the array;
|
||||
# implemented by making the first element of the array a hash-reference.
|
||||
# When we add a new value, we also increment the count of an element in
|
||||
# the hash with the key being the array value...
|
||||
sub push_once (\@@) {
|
||||
my ($array, @values) = @_;
|
||||
|
||||
# If the array is empty, create our hash ref
|
||||
push @{$array}, {}
|
||||
if (@{$array} == 0);
|
||||
|
||||
foreach my $value (@values) {
|
||||
push @{$array}, $value
|
||||
if (!exists($array->[0]{$value}));
|
||||
|
||||
$array->[0]{$value}++;
|
||||
}
|
||||
|
||||
return @{$array} - 1;
|
||||
}
|
||||
|
||||
# Filter //, /./, and remove leading ./ or / from filenames
|
||||
sub fname_filter ($) {
|
||||
my ($fname) = @_;
|
||||
|
||||
$fname =~ s,//,/,g;
|
||||
$fname =~ s,/\./,/,g;
|
||||
$fname =~ s,^\.?/,,g;
|
||||
|
||||
return $fname;
|
||||
}
|
||||
|
||||
# Store file data in a temporary file
|
||||
sub names_to_file ($$@) {
|
||||
my ($fname, $dir, @names) = @_;
|
||||
|
||||
if (@names > 0) {
|
||||
open(FILE, ">>$fname") || die "Cannot open file $fname for appending";
|
||||
|
||||
# Store the directory data
|
||||
print FILE "D $dir\n";
|
||||
|
||||
foreach my $name (@names) {
|
||||
# Mark record as a file...
|
||||
print FILE "F ";
|
||||
|
||||
# Store the tag, if there is one...
|
||||
print FILE "$name->{tag}"
|
||||
if (defined($name->{tag}));
|
||||
|
||||
# Then store old revision, new revision, and file name
|
||||
print FILE ":$name->{old}:$name->{new}:$name->{file}\n";
|
||||
}
|
||||
|
||||
close(FILE);
|
||||
}
|
||||
}
|
||||
|
||||
# Retrieve file data from temporary file; updates branch tags with what it
|
||||
# reads
|
||||
sub file_to_names (\@$) {
|
||||
my ($btags, $fname) = @_;
|
||||
my ($dir) = (undef);
|
||||
my (@names) = ();
|
||||
|
||||
debug "Reading file names from $fname...\n";
|
||||
|
||||
# We may not have, say, added a file in this subdirectory...
|
||||
return ()
|
||||
if (!-e $fname);
|
||||
|
||||
open(FILE, "<$fname");
|
||||
while(<FILE>) {
|
||||
chomp;
|
||||
|
||||
# Get record type...
|
||||
my ($type, $data) = split(' ', $_, 2);
|
||||
|
||||
# ok, it's a directory, remember that...
|
||||
if ($type eq "D") {
|
||||
$dir = $data;
|
||||
|
||||
debug "Read directory $dir\n";
|
||||
|
||||
next;
|
||||
}
|
||||
|
||||
debug "Read file $data\n";
|
||||
|
||||
# Get all the information about the file
|
||||
my ($tag, $old, $new, $file) = split(':', $data);
|
||||
|
||||
# and store it all
|
||||
push(@names, { tag => $tag, old => $old, new => $new, file => $file,
|
||||
dir => $dir, name => fname_filter("$dir/$file") });
|
||||
|
||||
# Remember the tags...
|
||||
push_once(@{$btags}, $tag)
|
||||
if (defined($tag) && $tag ne "");
|
||||
}
|
||||
close(FILE);
|
||||
|
||||
return @names;
|
||||
}
|
||||
|
||||
# Create a text-formatted list of names
|
||||
sub name_to_list (\@@) {
|
||||
my ($btags, @names) = @_;
|
||||
my (@nlist, @nline) = ();
|
||||
|
||||
debug "Tags:", join(':', @{$btags}), "\n";
|
||||
|
||||
# We group them by tag
|
||||
foreach my $tag ("", @{$btags}[1..$#{$btags}]) {
|
||||
debug "Processing tag $tag...\n";
|
||||
|
||||
@nlist = ();
|
||||
|
||||
# Get a list of files by the tag...
|
||||
foreach my $name (@names) {
|
||||
debug "Processing $name->{file}...\n";
|
||||
|
||||
next
|
||||
if ($name->{tag} ne $tag);
|
||||
|
||||
debug "Pushing $name->{name} on \@nlist...\n";
|
||||
push(@nlist, $name->{name});
|
||||
}
|
||||
|
||||
# If the tag is not the empty string, list the tag...
|
||||
push(@nline, " Tag: $tag", " ")
|
||||
if ($tag ne "");
|
||||
|
||||
# Now list each file name
|
||||
foreach my $name (@nlist) {
|
||||
# indent if we run past the end of line limit
|
||||
push(@nline, " ")
|
||||
if (@nline == 0 || ($nline[$#nline] ne " " &&
|
||||
length($nline[$#nline]) + length($name) + 1 > 70));
|
||||
|
||||
# add the file name to the list
|
||||
debug "Adding $name to \@nline...\n";
|
||||
$nline[$#nline] .= " $name";
|
||||
}
|
||||
}
|
||||
|
||||
return @nline;
|
||||
}
|
||||
|
||||
# write the log message to a temporary file
|
||||
sub write_log ($@) {
|
||||
my ($fname, @text) = @_;
|
||||
|
||||
open(FILE, ">$fname") || die "Cannot open file $fname for writing";
|
||||
print FILE join("\n", @text), "\n";
|
||||
close(FILE);
|
||||
}
|
||||
|
||||
# Build the header of the commit message: CVSROOT, module name, any
|
||||
# branch tags, and the commit time
|
||||
sub build_header ($@) {
|
||||
my ($module, $subject, $mailto, @branch_tags) = @_;
|
||||
my (@text, @mailto);
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time());
|
||||
my ($user, $dummy);
|
||||
my ($digest);
|
||||
|
||||
($user, $dummy, $dummy, $dummy, $dummy, $dummy, $dummy) = getpwuid($<);
|
||||
|
||||
@mailto = @{$mailto};
|
||||
|
||||
# generate a unique boundary by calculating the md5sum of the
|
||||
# current time
|
||||
$digest = new MD5;
|
||||
$digest->reset();
|
||||
$digest->add(time() . rand());
|
||||
$boundary = "----=MIME." . unpack("H*", $digest->digest());
|
||||
|
||||
# Build the mail header
|
||||
push(@text, "From: $user");
|
||||
push(@text, "To: " . join(' ', @mailto));
|
||||
push(@text, "Subject: $subject");
|
||||
push(@text, "MIME-Version: 1.0");
|
||||
push(@text, "Content-Type: multipart/mixed; boundary=\"$boundary\"");
|
||||
push(@text, "");
|
||||
push(@text, "This is a multipart message as defined by RFC2049 (MIME)");
|
||||
push(@text, "");
|
||||
push(@text, "--$boundary");
|
||||
push(@text, "Content-Type: text/plain; charset=us-ascii");
|
||||
push(@text, "Content-Disposition: inline");
|
||||
push(@text, "");
|
||||
|
||||
# Build the commit message header
|
||||
push(@text, "Commiter : $user");
|
||||
push(@text, "CVSROOT : $ENV{CVSROOT}");
|
||||
push(@text, "Module : $module");
|
||||
push(@text, "Branch tags: " . join(' ', @branch_tags[1..$#branch_tags]))
|
||||
if (@branch_tags > 0);
|
||||
push(@text, sprintf("Commit time: %04d-%02d-%02d %02d:%02d:%02d UTC",
|
||||
$year + 1900, $mon + 1, $mday, $hour, $min, $sec));
|
||||
|
||||
return @text, "";
|
||||
}
|
||||
|
||||
# Send the mail message
|
||||
sub send_mail {
|
||||
my ($mailto, $text) = @_;
|
||||
my (@mailto, @text);
|
||||
# I <heart> perl
|
||||
@mailto = @{$mailto};
|
||||
@text = @{$text};
|
||||
|
||||
open(MAIL, "|$MAILER " . join(' ', @mailto));
|
||||
push(@text, "--$boundary--", "");
|
||||
print MAIL join("\n", @text), "\n";
|
||||
close(MAIL);
|
||||
}
|
||||
|
||||
# Find the tmp directory
|
||||
my ($tmpdir) = (tmpdir());
|
||||
|
||||
my (@mailto) = ();
|
||||
my (@files) = ();
|
||||
my (@path) = ();
|
||||
my ($modname, $repdir, $dir) = (undef, undef, undef);
|
||||
|
||||
# Process command line arguments
|
||||
while (@ARGV > 0) {
|
||||
my ($arg) = (shift(@ARGV));
|
||||
|
||||
if ($arg eq '-d') {
|
||||
# Turn on debugging
|
||||
$debug++;
|
||||
} elsif ($arg eq '-M') {
|
||||
# Module name explicitly set -- XXX Not tested, use at your own risk
|
||||
die "Argument for -M missing"
|
||||
unless (@ARGV > 0);
|
||||
|
||||
$modname = shift(@ARGV);
|
||||
} elsif ($arg eq '-m') {
|
||||
# An address to mail the notification to
|
||||
die "Argument for -m missing"
|
||||
unless (@ARGV > 0);
|
||||
|
||||
push(@mailto, shift(@ARGV));
|
||||
} else {
|
||||
# the list of filenames passed by CVS--you *must* use %{sVv}!
|
||||
die "Too many arguments!"
|
||||
unless (@files == 0);
|
||||
|
||||
@files = split(" ", $arg);
|
||||
}
|
||||
}
|
||||
|
||||
die "Nobody to mail to"
|
||||
unless (@mailto > 0);
|
||||
|
||||
die "No files to process"
|
||||
unless (@files > 1);
|
||||
|
||||
# The repository directory
|
||||
$repdir = shift(@files);
|
||||
|
||||
# break it appart...
|
||||
@path = split("/", $repdir);
|
||||
|
||||
# Now we know the module name, if it wasn't explicitly set
|
||||
$modname = $path[0]
|
||||
unless (defined($modname));
|
||||
|
||||
# Figure out what our directory is
|
||||
if (@path == 1) {
|
||||
$dir = ".";
|
||||
} else {
|
||||
$dir = join("/", @path[1..$#path]);
|
||||
}
|
||||
|
||||
# append a / to it...
|
||||
$dir .= "/";
|
||||
|
||||
debug "module = $modname\n";
|
||||
debug "dir = $dir\n";
|
||||
debug "path = ", join(":", @path), "\n";
|
||||
debug "files = ", join(":", @files), "\n";
|
||||
debug "tmpdir = $tmpdir\n";
|
||||
|
||||
my (%fversions);
|
||||
|
||||
# Unless its a new directory or imported sources, create file records
|
||||
unless (defined($files[1]) && defined($files[2]) &&
|
||||
(($files[1] eq "New" && $files[2] eq "directory") ||
|
||||
($files[1] eq "Imported" && $files[2] eq "sources"))) {
|
||||
|
||||
foreach my $fname (@files) {
|
||||
# You *must* use %{sVv} in the call in loginfo!
|
||||
die "Invalid filenames"
|
||||
unless ($fname =~ /^(.*),([0-9.]+|NONE),([0-9.]+|NONE)$/);
|
||||
|
||||
$fversions{$1} = {
|
||||
old => ($2 eq "NONE" ? "0" : $2),
|
||||
new => ($3 eq "NONE" ? "0" : $3),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
# process log message
|
||||
my ($state, $tag) = (STATE_NONE, undef);
|
||||
|
||||
my (@modified, @added, @removed, @log, @branch_tags) = ();
|
||||
|
||||
while (<STDIN>) {
|
||||
chomp;
|
||||
|
||||
debug "State $state, line:$_\n";
|
||||
|
||||
# Ignore empty space at the beginning of the log message
|
||||
next
|
||||
if ($state == STATE_LOG1 && /^\s*$/);
|
||||
|
||||
# We're done ignoring empty space
|
||||
if ($state == STATE_LOG1) {
|
||||
$state = STATE_LOG2;
|
||||
}
|
||||
|
||||
if ($state == STATE_LOG2) {
|
||||
# Don't modify the lines at all if we're processing the log message
|
||||
push(@log, $_);
|
||||
next;
|
||||
} else {
|
||||
# Strip out leading and trailing space
|
||||
s/^\s*(.*?)\s*$/$1/;
|
||||
}
|
||||
|
||||
if (/^Modified Files/) {
|
||||
# Collect list of modified files
|
||||
debug "State switching to STATE_MODIFIED\n";
|
||||
|
||||
$state = STATE_MODIFIED;
|
||||
$tag = undef;
|
||||
|
||||
next;
|
||||
|
||||
} elsif (/^Added Files/) {
|
||||
# Collect list of added files
|
||||
debug "State switching to STATE_ADDED\n";
|
||||
|
||||
$state = STATE_ADDED;
|
||||
$tag = undef;
|
||||
|
||||
next;
|
||||
|
||||
} elsif (/^Removed Files/) {
|
||||
# Collect list of removed files
|
||||
debug "State switching to STATE_REMOVED\n";
|
||||
|
||||
$state = STATE_REMOVED;
|
||||
$tag = undef;
|
||||
|
||||
next;
|
||||
|
||||
} elsif (/^Log Message/) {
|
||||
# Collect log message
|
||||
debug "State switching to STATE_LOG1\n";
|
||||
|
||||
$state = STATE_LOG1;
|
||||
$tag = undef;
|
||||
|
||||
next;
|
||||
|
||||
} elsif (/^Revision\/Branch/) {
|
||||
# Parse old-style Revision/Branch field
|
||||
debug "Found a branch tag\n";
|
||||
|
||||
/^[^:]+:\s*(.*)/;
|
||||
|
||||
push_once(@branch_tags, $1);
|
||||
|
||||
warn "Tag == $tag"
|
||||
if (defined($tag));
|
||||
|
||||
next;
|
||||
}
|
||||
|
||||
# Ignore the stuff at the top of the commit report
|
||||
next
|
||||
if ($state == STATE_NONE);
|
||||
|
||||
if (/^Tag:\s*(.*)$/) {
|
||||
# Remember the tag
|
||||
debug "Setting tag to $1\n";
|
||||
$tag = $1;
|
||||
next;
|
||||
}
|
||||
|
||||
my (@tfiles) = ();
|
||||
|
||||
# Find the file in our command line list of files
|
||||
foreach my $file (split) {
|
||||
die "Nothing known about file $file!"
|
||||
unless (exists($fversions{$file}));
|
||||
|
||||
push @tfiles, {
|
||||
file => $file,
|
||||
tag => $tag,
|
||||
old => $fversions{$file}{old},
|
||||
new => $fversions{$file}{new},
|
||||
};
|
||||
}
|
||||
|
||||
# Store the file list in the correct array
|
||||
push(@modified, @tfiles)
|
||||
if ($state == STATE_MODIFIED);
|
||||
|
||||
push(@added, @tfiles)
|
||||
if ($state == STATE_ADDED);
|
||||
|
||||
push(@removed, @tfiles)
|
||||
if ($state == STATE_REMOVED);
|
||||
}
|
||||
|
||||
# Remove trailing blank lines from the log message
|
||||
while (@log > 0 && $log[$#log] =~ /^\s*$/) {
|
||||
pop(@log);
|
||||
}
|
||||
|
||||
# If a new directory was added, we're done...
|
||||
if (defined($files[1]) && defined($files[2]) &&
|
||||
$files[1] eq "New" && $files[2] eq "directory") {
|
||||
|
||||
my (@text) = ();
|
||||
|
||||
# If there was a sticky tag for the directory, make it a branch tag
|
||||
if ($log[$#log] =~ /^--> Using per-directory sticky tag \`(.*)\'$/) {
|
||||
push_once(@branch_tags, $1);
|
||||
pop(@log);
|
||||
}
|
||||
|
||||
# Build the message...
|
||||
push(@text, build_header($modname, "Module $modname: New directory $dir",
|
||||
\@mailto, @branch_tags));
|
||||
push(@text, "Log message:", "", @log);
|
||||
|
||||
# and send it (synchronously)
|
||||
send_mail(\@mailto, \@text);
|
||||
|
||||
# Clean up after ourselves and exit.
|
||||
cleanup_dir($tmpdir);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
# If an import was done, we're done...
|
||||
if (defined($files[1]) && defined($files[2]) &&
|
||||
$files[1] eq "Imported" && $files[2] eq "sources") {
|
||||
|
||||
my (@text) = ();
|
||||
|
||||
# Build the message...
|
||||
push(@text, build_header($modname, "Module $modname: Imported $dir",
|
||||
\@mailto, @branch_tags));
|
||||
push(@text, "Log message:", "", @log);
|
||||
|
||||
# and send it (synchronously)
|
||||
send_mail(\@mailto, \@text);
|
||||
|
||||
# Clean up after ourselves and exit.
|
||||
cleanup_dir($tmpdir);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
debug "Searching for log file index...";
|
||||
|
||||
my ($i);
|
||||
|
||||
# Look for an empty log file or one that matches our current log message
|
||||
for ($i = 0; ; $i++) {
|
||||
my (@text);
|
||||
|
||||
# found one that doesn't exist...
|
||||
last
|
||||
if (!-e "$tmpdir/logfile.$i");
|
||||
|
||||
# read in the log file
|
||||
open(FILE, "<$tmpdir/logfile.$i");
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
push(@text, $_);
|
||||
}
|
||||
close(FILE);
|
||||
|
||||
# If the log file was empty, use it
|
||||
last
|
||||
if (@text == 0);
|
||||
|
||||
# If the log messages are identical, use that
|
||||
last
|
||||
if (join(' ', @log) eq join(' ', @text));
|
||||
}
|
||||
|
||||
debug "$tmpdir/logfile.$i\n";
|
||||
|
||||
# Store modified, added, and removed file lists, along with the log message
|
||||
names_to_file("$tmpdir/modified.$i", $dir, @modified);
|
||||
names_to_file("$tmpdir/added.$i", $dir, @added);
|
||||
names_to_file("$tmpdir/removed.$i", $dir, @removed);
|
||||
write_log("$tmpdir/logfile.$i", @log);
|
||||
|
||||
# Now check to see if we're at the end of our rope
|
||||
my ($lastdir) = (get_line("$tmpdir/lastdir"));
|
||||
|
||||
debug "Checking $ENV{CVSROOT}/$repdir against lastdir $lastdir\n";
|
||||
|
||||
# Nope, exit instead of sending a message
|
||||
exit(0)
|
||||
if ($lastdir ne "$ENV{CVSROOT}/$repdir");
|
||||
|
||||
debug "At last, we've reached the end\n";
|
||||
|
||||
# We have to daemonize and sleep so that there isn't any lock hanging
|
||||
# around when we get to the cvs rdiff below...
|
||||
daemonize();
|
||||
sleep(10);
|
||||
|
||||
# Build the mail message...
|
||||
my (@text) = ();
|
||||
@files = ();
|
||||
@branch_tags = ();
|
||||
|
||||
for ($i = 0; ; $i++) {
|
||||
# No more log files
|
||||
last
|
||||
if (!-e "$tmpdir/logfile.$i");
|
||||
|
||||
# read and insert the log message
|
||||
open(FILE, "<$tmpdir/logfile.$i");
|
||||
push(@text, "Log message:", "");
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
push(@text, $_);
|
||||
}
|
||||
push(@text, "");
|
||||
close(FILE);
|
||||
|
||||
# read modified list and list all modified files if non-empty
|
||||
@modified = file_to_names(@branch_tags, "$tmpdir/modified.$i");
|
||||
push(@text, "Modified files:", name_to_list(@branch_tags, @modified), "")
|
||||
if (@modified > 0);
|
||||
|
||||
# read added list and list all added files if non-empty
|
||||
@added = file_to_names(@branch_tags, "$tmpdir/added.$i");
|
||||
push(@text, "Added files:", name_to_list(@branch_tags, @added), "")
|
||||
if (@added > 0);
|
||||
|
||||
# read removed list and list all removed files if non-empty
|
||||
@removed = file_to_names(@branch_tags, "$tmpdir/removed.$i");
|
||||
push(@text, "Removed files:", name_to_list(@branch_tags, @removed), "")
|
||||
if (@removed > 0);
|
||||
|
||||
# remember all the files we looked at
|
||||
push(@files, @modified, @added, @removed);
|
||||
}
|
||||
|
||||
# Now that name_to_list has rebuilt our list of branch tags, we can build the
|
||||
# header and prepend it to the message
|
||||
unshift(@text, build_header($modname, "Module $modname: Change committed",
|
||||
\@mailto, @branch_tags));
|
||||
|
||||
# sort the files out for our diff
|
||||
@files = sort { $a->{name} cmp $b->{name} } @files;
|
||||
|
||||
my ($user, $filename);
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time());
|
||||
$user = getpwuid($<);
|
||||
|
||||
$filename = sprintf("%s.%04d%02d%02d.%02d%02d%02d.%s.diff", $modname,
|
||||
$year + 1900, $mon + 1, $mday, $hour, $min, $sec, $user);
|
||||
|
||||
push(@text, "--$boundary");
|
||||
push(@text, "Content-Type: text/plain; name=\"$filename\"");
|
||||
push(@text, "Content-Disposition: attachment; filename=\"$filename\"");
|
||||
push(@text, "Content-Transfer-Encoding: 8bit");
|
||||
push(@text, "");
|
||||
|
||||
foreach my $file (@files) {
|
||||
debug "Diffing file $file->{name}...\n";
|
||||
|
||||
# Run cvs rdiff, extracting a diff between the old version and the new
|
||||
open(DIFF, "$CVS -Q rdiff -u -r $file->{old} -r $file->{new} " .
|
||||
"$modname/$file->{name}|");
|
||||
while (<DIFF>) {
|
||||
chomp;
|
||||
push(@text, $_);
|
||||
}
|
||||
close(DIFF);
|
||||
}
|
||||
|
||||
# send the mail...
|
||||
send_mail(\@mailto, \@text);
|
||||
|
||||
# and clean up after ourselves
|
||||
cleanup_dir($tmpdir);
|
||||
@@ -0,0 +1,12 @@
|
||||
# The "notify" file controls where notifications from watches set by
|
||||
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
|
||||
# a regular expression which is tested against the directory that the
|
||||
# change is being made to, relative to the $CVSROOT. If it matches,
|
||||
# then the remainder of the line is a filter program that should contain
|
||||
# one occurrence of %s for the user to notify, and information on its
|
||||
# standard input.
|
||||
#
|
||||
# "ALL" or "DEFAULT" can be used in place of the regular expression.
|
||||
#
|
||||
# For example:
|
||||
#ALL mail %s -s "CVS notification"
|
||||
@@ -0,0 +1,9 @@
|
||||
drevil:f76FWdDTUBG5c:fs2source
|
||||
mysterial:f7nJUwoIhmSrg:fs2source
|
||||
wmcoolmon:f7JRB.js9Q1sE:fs2source
|
||||
inquisitor:f7BVkOvwjDlWk:fs2source
|
||||
penguin:Jh.dOjaiO2jHk:fs2source
|
||||
DTP:f7M92Z/6/uep.:fs2source
|
||||
unknownplayer:f79BgAn.IzJs6:fs2source
|
||||
phreak:f7WQyGiT/jzlM:fs2source
|
||||
anonymous:oIKtWP1q6GDt6:fs2source
|
||||
@@ -0,0 +1,13 @@
|
||||
# The "rcsinfo" file is used to control templates with which the editor
|
||||
# is invoked on commit and import.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. For the first match that is found, then the remainder of the
|
||||
# line is the name of the file that contains the template.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
||||
@@ -0,0 +1,20 @@
|
||||
# The "taginfo" file is used to control pre-tag checks.
|
||||
# The filter on the right is invoked with the following arguments:
|
||||
#
|
||||
# $1 -- tagname
|
||||
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
|
||||
# $3 -- repository
|
||||
# $4-> file revision [file revision ...]
|
||||
#
|
||||
# A non-zero exit of the filter program will cause the tag to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
||||
@@ -0,0 +1,21 @@
|
||||
# The "verifymsg" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
||||
@@ -0,0 +1,4 @@
|
||||
drevil
|
||||
inquisitor
|
||||
mysterial
|
||||
penguin
|
||||
Binary file not shown.
@@ -1,29 +0,0 @@
|
||||
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
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
# Makefile.am for fs2_open (top level)
|
||||
#
|
||||
# This file uses GNU Automake to generate makefiles
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = mongoose code
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
FS2OpenSCPReadMe.doc \
|
||||
projects/Xcode/English.lproj/InfoPlist.strings \
|
||||
projects/Xcode/FS2_Open.icns \
|
||||
projects/Xcode/FS2_Open.xcodeproj/project.pbxproj \
|
||||
projects/Xcode/Frameworks.tgz \
|
||||
projects/Xcode/Info-debug.plist \
|
||||
projects/Xcode/Info.plist \
|
||||
projects/Xcode/README.Xcode \
|
||||
projects/Xcode/SDLMain.h \
|
||||
projects/Xcode/SDLMain.m
|
||||
|
||||
|
||||
# D_ variants are defaults and should always be used
|
||||
AM_CXXFLAGS = -I./code @D_CFLAGS@
|
||||
AM_LDFLAGS = @D_LDFLAGS@
|
||||
|
||||
EXTRA_PROGRAMS = cfilearchiver cfileextractor
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin utilitites
|
||||
##
|
||||
|
||||
CPPSOURCES=$(wildcard code/*/*.cpp code/*/*.h)
|
||||
|
||||
# cfilearchiver -- to create VPs
|
||||
cfilearchiver_SOURCES = \
|
||||
code/cfilearchiver/cfilearchiver.cpp
|
||||
|
||||
# cfileextractor -- to extract files from VPs
|
||||
cfileextractor_SOURCES = \
|
||||
code/cfileextractor/cfileextractor.cpp
|
||||
|
||||
# catch all to build utilitites
|
||||
tools: cfilearchiver cfileextractor
|
||||
|
||||
# cleaning
|
||||
clean-tools:
|
||||
-test -z "$(EXTRA_PROGRAMS)" || rm -f $(EXTRA_PROGRAMS)
|
||||
|
||||
## cppcheck : check for many code issues
|
||||
cppcheck: ${CPPSOURCES}
|
||||
cppcheck ${CPPSOURCES} --enable=all --platform=unix64 \
|
||||
--std=c99 --inline-suppr --quiet
|
||||
|
||||
##
|
||||
## End utilitites
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
|
||||
# make sure we get this stuff cleaned up
|
||||
clean-generic: clean-tools
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
This file is required to keep autoconf/automake from complaining.
|
||||
|
||||
See the ChangeLog for what's new.
|
||||
@@ -1,11 +0,0 @@
|
||||
The "projects" directory contains ready projects for:
|
||||
Microsoft Visual C++ 6
|
||||
Microsoft Visual C++ 2005
|
||||
Microsoft Visual C++ 2008
|
||||
Micrsofot Visual C++ 2010
|
||||
Apple Xcode
|
||||
Code::Blocks
|
||||
|
||||
|
||||
See the ChangeLog to see what's new.
|
||||
See the INSTALL file for instructions on how to build fs2_open.
|
||||
@@ -1,19 +0,0 @@
|
||||
[](https://scan.coverity.com/projects/870)
|
||||
[](https://travis-ci.org/scp-fs2open/fs2open.github.com)
|
||||
|
||||
Welcome to Freespace Open!
|
||||
|
||||
In 2002 Volition released the source code for Freespace2. In the years since dedicated individuals have added countless new features to create a flexible and powerful space combat simulation engine. More info can be found on our [wiki](http://www.hard-light.net/wiki/index.php/Source_Code_Project)
|
||||
|
||||
People interested in contributing are encouraged to read [this thread](http://www.hard-light.net/forums/index.php?topic=82688.0)
|
||||
|
||||
The "projects" directory contains ready projects for:
|
||||
* Microsoft Visual C++ 6, 2005, 2008, 2010, 2011, 2013, 2015
|
||||
* Apple Xcode
|
||||
* Code::Blocks
|
||||
* Eclipse
|
||||
|
||||
|
||||
Review the commit logs to see what's new.
|
||||
|
||||
See the INSTALL file for instructions on how to build fs2_open, or open the relevant MSVC project
|
||||
@@ -1,16 +0,0 @@
|
||||
version: 1.0.0.{build}
|
||||
shallow_clone: true
|
||||
environment:
|
||||
matrix:
|
||||
- VisualStudioVersion: 10.0
|
||||
PlatformToolset: v100
|
||||
ProjectPath: projects/MSVC_2010/Freespace2.vcxproj
|
||||
- VisualStudioVersion: 12.0
|
||||
PlatformToolset: v120
|
||||
ProjectPath: projects/MSVC_2013/Freespace2.vcxproj
|
||||
- VisualStudioVersion: 14.0
|
||||
PlatformToolset: v140
|
||||
ProjectPath: projects/MSVC_2015/Freespace2.vcxproj
|
||||
build_script:
|
||||
- msbuild "%ProjectPath%" /p:Configuration="Debug SSE2" /m /p:PlatformToolset="%PlatformToolset%" /verbosity:minimal
|
||||
test: off
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
PKG_NAME="fs2_open"
|
||||
|
||||
# check the version of a package
|
||||
check_version() {
|
||||
COMMAND=$1
|
||||
MAJOR=$2
|
||||
MINOR=$3
|
||||
MICRO=$4
|
||||
|
||||
($COMMAND --version) </dev/null >/dev/null 2>&1 || return 1
|
||||
|
||||
ver=`$COMMAND --version|head -n 1|sed 's/^.*) //'|sed 's/ (.*)//'`
|
||||
major=`echo $ver | cut -d. -f1 | sed s/[a-zA-Z\-].*//g`
|
||||
minor=`echo $ver | cut -d. -f2 | sed s/[a-zA-Z\-].*//g`
|
||||
micro=`echo $ver | cut -d. -f3 | sed s/[a-zA-Z\-].*//g`
|
||||
test -z "$major" && major=0
|
||||
test -z "$minor" && minor=0
|
||||
test -z "$micro" && micro=0
|
||||
|
||||
fail=0
|
||||
if [ ! "$major" -gt "$MAJOR" ]; then
|
||||
if [ "$major" -lt "$MAJOR" ]; then
|
||||
fail=1
|
||||
elif [ ! "$minor" -gt "$MINOR" ]; then
|
||||
if [ "$minor" -lt "$MINOR" ]; then
|
||||
fail=1
|
||||
elif [ "$micro" -lt "$MICRO" ]; then
|
||||
fail=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
return "$fail"
|
||||
}
|
||||
|
||||
AUTOMAKE=
|
||||
ACLOCAL=
|
||||
DIE=0
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`autoconf' installed to."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
for AM in automake-1.11 automake-1.10 automake-1.9 automake-1.8 automake-1.7 automake-1.6 automake; do
|
||||
(check_version "$AM" 1 6 1) && {
|
||||
AUTOMAKE="$AM"
|
||||
break
|
||||
}
|
||||
done
|
||||
|
||||
if [ -z "$AUTOMAKE" ]; then
|
||||
echo
|
||||
echo "**Error**: You must have \`automake' version 1.6.1 or greater"
|
||||
echo "installed to compile $PKG_NAME. Download the appropriate package"
|
||||
echo "for your distribution, or get the source tarball at"
|
||||
echo "ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
fi
|
||||
|
||||
# if no automake, don't bother testing for aclocal
|
||||
test -z "$AUTOMAKE" || {
|
||||
for ACL in aclocal-1.11 aclocal-1.10 aclocal-1.9 aclocal-1.8 aclocal-1.7 aclocal-1.6 aclocal; do
|
||||
(check_version "$ACL" 1 6 1) && {
|
||||
ACLOCAL="$ACL"
|
||||
break
|
||||
}
|
||||
done
|
||||
|
||||
if [ -z "$ACLOCAL" ]; then
|
||||
echo
|
||||
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
|
||||
echo "installed seems to be outdated. Get a recent package from"
|
||||
echo "ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
fi
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$*"; then
|
||||
echo "**Warning**: I am going to run \`configure' with no arguments."
|
||||
echo "If you wish to pass any to it, please specify them on the"
|
||||
echo \`$0\'" command line."
|
||||
echo
|
||||
fi
|
||||
|
||||
case $CC in
|
||||
xlc )
|
||||
am_opt=--include-deps;;
|
||||
esac
|
||||
|
||||
for coin in `find $srcdir -name configure.ac -print`
|
||||
do
|
||||
dr=`dirname $coin`
|
||||
if test -f $dr/NO-AUTO-GEN; then
|
||||
echo skipping $dr -- flagged as no auto-gen
|
||||
else
|
||||
echo processing $dr
|
||||
macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
|
||||
( cd $dr
|
||||
aclocalinclude="$ACLOCAL_FLAGS"
|
||||
for k in $macrodirs; do
|
||||
if test -d $k; then
|
||||
aclocalinclude="$aclocalinclude -I $k"
|
||||
##else
|
||||
## echo "**Warning**: No such directory \`$k'. Ignored."
|
||||
fi
|
||||
done
|
||||
echo "Running autoreconf..."
|
||||
autoreconf --install
|
||||
)
|
||||
# DIE if the subshell failed
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
|
||||
|
||||
# to not run configure, call autogen.sh as,
|
||||
# NOCONFIGURE=1 ./autogen.sh
|
||||
if test x$NOCONFIGURE = x; then
|
||||
echo Running $srcdir/configure $conf_flags "$@" ...
|
||||
$srcdir/configure $conf_flags "$@" \
|
||||
&& echo Now type \`make\' to compile $PKG_NAME.
|
||||
else
|
||||
echo Skipping configure process.
|
||||
fi
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
sudo add-apt-repository --yes ppa:zoogie/sdl2-snapshots
|
||||
sudo apt-get update -qq
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
fi
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
# Due to a bug in gcc the array bounds check isn't working correctly
|
||||
# This can be removed when gcc is updated
|
||||
AUTOGEN_CONFIG="--enable-fatal-warnings --enable-generic-architecture"
|
||||
CXXFLAGS="-Wno-array-bounds -Wno-unknown-pragmas"
|
||||
|
||||
if [ "$CONFIGURATION" = "Debug" ]; then
|
||||
AUTOGEN_CONFIG="$AUTOGEN_CONFIG --enable-debug"
|
||||
fi
|
||||
|
||||
export CXXFLAGS
|
||||
./autogen.sh $AUTOGEN_CONFIG
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
cd projects/Xcode
|
||||
tar -xvzf Frameworks.tgz
|
||||
fi
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
sudo apt-get install libsdl2-dev
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
gem install xcpretty thefox-pastebin
|
||||
fi
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
make -j 4
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
cd projects/Xcode
|
||||
|
||||
xcodebuild -project FS2_Open.xcodeproj -configuration "$CONFIGURATION" clean build | tee release.log | xcpretty
|
||||
XCODE_RET=${PIPESTATUS[0]}
|
||||
if [ "$XCODE_RET" -ne "0" ]; then
|
||||
pastebin -e 1d -f release.log
|
||||
exit $XCODE_RET
|
||||
fi
|
||||
fi
|
||||
@@ -1,915 +0,0 @@
|
||||
## code/Makefile.am for fs2_open
|
||||
##
|
||||
## $Id: Makefile.am,v 1.31.2.10 2007-11-22 04:52:12 taylor Exp $
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
freespace2/app_icon.ico \
|
||||
freespace2/freespace.rc \
|
||||
freespace2/freespaceresource.h \
|
||||
freespace2/goal_com.bmp \
|
||||
freespace2/goal_fail.bmp \
|
||||
freespace2/goal_inc.bmp \
|
||||
freespace2/goal_none.bmp \
|
||||
freespace2/goal_ord.bmp \
|
||||
fred2/addvariabledlg.cpp \
|
||||
fred2/addvariabledlg.h \
|
||||
fred2/adjustgriddlg.cpp \
|
||||
fred2/adjustgriddlg.h \
|
||||
fred2/asteroideditordlg.cpp \
|
||||
fred2/asteroideditordlg.h \
|
||||
fred2/bgbitmapdlg.cpp \
|
||||
fred2/bgbitmapdlg.h \
|
||||
fred2/briefingeditordlg.cpp \
|
||||
fred2/briefingeditordlg.h \
|
||||
fred2/campaigneditordlg.cpp \
|
||||
fred2/campaigneditordlg.h \
|
||||
fred2/campaignfilelistbox.cpp \
|
||||
fred2/campaignfilelistbox.h \
|
||||
fred2/campaigntreeview.cpp \
|
||||
fred2/campaigntreeview.h \
|
||||
fred2/campaigntreewnd.cpp \
|
||||
fred2/campaigntreewnd.h \
|
||||
fred2/cmdbrief.cpp \
|
||||
fred2/cmdbrief.h \
|
||||
fred2/createwingdlg.cpp \
|
||||
fred2/createwingdlg.h \
|
||||
fred2/customwingnames.cpp \
|
||||
fred2/customwingnames.h \
|
||||
fred2/debriefingeditordlg.cpp \
|
||||
fred2/debriefingeditordlg.h \
|
||||
fred2/dialog1.cpp \
|
||||
fred2/dialog1.h \
|
||||
fred2/dumpstats.cpp \
|
||||
fred2/dumpstats.h \
|
||||
fred2/editor.h \
|
||||
fred2/eventeditor.cpp \
|
||||
fred2/eventeditor.h \
|
||||
fred2/folderdlg.cpp \
|
||||
fred2/folderdlg.h \
|
||||
fred2/fred.cpp \
|
||||
fred2/fred.h \
|
||||
fred2/fred.rc \
|
||||
fred2/freddoc.cpp \
|
||||
fred2/freddoc.h \
|
||||
fred2/fredrender.cpp \
|
||||
fred2/fredrender.h \
|
||||
fred2/fredstubs.cpp \
|
||||
fred2/fredview.cpp \
|
||||
fred2/fredview.h \
|
||||
fred2/grid.cpp \
|
||||
fred2/grid.h \
|
||||
fred2/ignoreordersdlg.cpp \
|
||||
fred2/ignoreordersdlg.h \
|
||||
fred2/initialships.cpp \
|
||||
fred2/initialships.h \
|
||||
fred2/initialstatus.cpp \
|
||||
fred2/initialstatus.h \
|
||||
fred2/mainfrm.cpp \
|
||||
fred2/mainfrm.h \
|
||||
fred2/makehelp.bat \
|
||||
fred2/management.cpp \
|
||||
fred2/management.h \
|
||||
fred2/messageeditordlg.cpp \
|
||||
fred2/messageeditordlg.h \
|
||||
fred2/missiongoalsdlg.cpp \
|
||||
fred2/missiongoalsdlg.h \
|
||||
fred2/missionnotesdlg.cpp \
|
||||
fred2/missionnotesdlg.h \
|
||||
fred2/missionsave.cpp \
|
||||
fred2/missionsave.h \
|
||||
fred2/modifyvariabledlg.cpp \
|
||||
fred2/modifyvariabledlg.h \
|
||||
fred2/operatorargtypeselect.cpp \
|
||||
fred2/operatorargtypeselect.h \
|
||||
fred2/orienteditor.cpp \
|
||||
fred2/orienteditor.h \
|
||||
fred2/playerstarteditor.cpp \
|
||||
fred2/playerstarteditor.h \
|
||||
fred2/prefsdlg.cpp \
|
||||
fred2/prefsdlg.h \
|
||||
fred2/reinforcementeditordlg.cpp \
|
||||
fred2/reinforcementeditordlg.h \
|
||||
fred2/resource.h \
|
||||
fred2/resource.hm \
|
||||
fred2/setglobalshipflags.cpp \
|
||||
fred2/setglobalshipflags.h \
|
||||
fred2/sexp_tree.cpp \
|
||||
fred2/sexp_tree.h \
|
||||
fred2/shieldsysdlg.cpp \
|
||||
fred2/shieldsysdlg.h \
|
||||
fred2/ship_select.cpp \
|
||||
fred2/ship_select.h \
|
||||
fred2/shipchecklistbox.cpp \
|
||||
fred2/shipchecklistbox.h \
|
||||
fred2/shipclasseditordlg.cpp \
|
||||
fred2/shipclasseditordlg.h \
|
||||
fred2/shipeditordlg.cpp \
|
||||
fred2/shipeditordlg.h \
|
||||
fred2/shipflagsdlg.cpp \
|
||||
fred2/shipflagsdlg.h \
|
||||
fred2/shipgoalsdlg.cpp \
|
||||
fred2/shipgoalsdlg.h \
|
||||
fred2/shipspecialdamage.cpp \
|
||||
fred2/shipspecialdamage.h \
|
||||
fred2/shipspecialhitpoints.cpp \
|
||||
fred2/shipspecialhitpoints.h \
|
||||
fred2/shiptexturesdlg.cpp \
|
||||
fred2/shiptexturesdlg.h \
|
||||
fred2/starfieldeditor.cpp \
|
||||
fred2/starfieldeditor.h \
|
||||
fred2/stdafx.cpp \
|
||||
fred2/stdafx.h \
|
||||
fred2/textviewdlg.cpp \
|
||||
fred2/textviewdlg.h \
|
||||
fred2/voiceactingmanager.cpp \
|
||||
fred2/voiceactingmanager.h \
|
||||
fred2/waypointpathdlg.cpp \
|
||||
fred2/waypointpathdlg.h \
|
||||
fred2/weaponeditordlg.cpp \
|
||||
fred2/weaponeditordlg.h \
|
||||
fred2/wing.cpp \
|
||||
fred2/wing.h \
|
||||
fred2/wing_editor.cpp \
|
||||
fred2/wing_editor.h \
|
||||
fred2/hlp/afxcore.rtf \
|
||||
fred2/hlp/afxhelp.hm \
|
||||
fred2/hlp/afxprint.rtf \
|
||||
fred2/hlp/appexit.bmp \
|
||||
fred2/hlp/bullet.bmp \
|
||||
fred2/hlp/curarw2.bmp \
|
||||
fred2/hlp/curarw4.bmp \
|
||||
fred2/hlp/curhelp.bmp \
|
||||
fred2/hlp/editcopy.bmp \
|
||||
fred2/hlp/editcut.bmp \
|
||||
fred2/hlp/editpast.bmp \
|
||||
fred2/hlp/editundo.bmp \
|
||||
fred2/hlp/filenew.bmp \
|
||||
fred2/hlp/fileopen.bmp \
|
||||
fred2/hlp/fileprnt.bmp \
|
||||
fred2/hlp/filesave.bmp \
|
||||
fred2/hlp/fred.hm \
|
||||
fred2/hlp/fred.hpj \
|
||||
fred2/hlp/help.log \
|
||||
fred2/hlp/hlpsbar.bmp \
|
||||
fred2/hlp/hlptbar.bmp \
|
||||
fred2/hlp/recfirst.bmp \
|
||||
fred2/hlp/reclast.bmp \
|
||||
fred2/hlp/recnext.bmp \
|
||||
fred2/hlp/recprev.bmp \
|
||||
fred2/hlp/scmax.bmp \
|
||||
fred2/hlp/scmenu.bmp \
|
||||
fred2/hlp/scmin.bmp \
|
||||
fred2/res/bitmap1.bmp \
|
||||
fred2/res/black_do.bmp \
|
||||
fred2/res/bmp00001.bmp \
|
||||
fred2/res/chained.bmp \
|
||||
fred2/res/chained_directive.bmp \
|
||||
fred2/res/cursor1.cur \
|
||||
fred2/res/cursor2.cur \
|
||||
fred2/res/data.bmp \
|
||||
fred2/res/fred.ico \
|
||||
fred2/res/fred.rc2 \
|
||||
fred2/res/freddoc.ico \
|
||||
fred2/res/green_do.bmp \
|
||||
fred2/res/root.bmp \
|
||||
fred2/res/root_directive.bmp \
|
||||
fred2/res/toolbar.bmp \
|
||||
fred2/res/toolbar1.bmp \
|
||||
fred2/res/variable.bmp \
|
||||
sound/phrases.xml \
|
||||
sound/gc.exe \
|
||||
wxfred2/res/fred.ico \
|
||||
wxfred2/wxfred.xrc
|
||||
|
||||
|
||||
# D_ variants are defaults and should always be used
|
||||
# FS2_ variants are for game building and wxFRED
|
||||
AM_CXXFLAGS = @D_CFLAGS@ @FS2_CXXFLAGS@ -I./$(VPATH)/../mongoose
|
||||
AM_LDFLAGS = @D_LDFLAGS@ @FS2_LDFLAGS@
|
||||
|
||||
if BUILD_WXFRED
|
||||
LIBCODE=
|
||||
else
|
||||
LIBCODE=libcode.a
|
||||
endif
|
||||
noinst_LIBRARIES = $(LIBCODE)
|
||||
bin_PROGRAMS = @FS2_BINARY@
|
||||
|
||||
EXTRA_PROGRAMS = fs2_open_@PACKAGE_VERSION@ \
|
||||
fs2_open_@PACKAGE_VERSION@_DEBUG \
|
||||
wxFRED2_@PACKAGE_VERSION@ \
|
||||
wxFRED2_@PACKAGE_VERSION@_DEBUG
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin CORE library
|
||||
##
|
||||
|
||||
FS2_SOURCES = \
|
||||
ai/ai.cpp \
|
||||
ai/ai.h \
|
||||
ai/aibig.cpp \
|
||||
ai/aibig.h \
|
||||
ai/aicode.cpp \
|
||||
ai/aigoals.cpp \
|
||||
ai/aigoals.h \
|
||||
ai/aiinternal.h \
|
||||
ai/aiturret.cpp \
|
||||
ai/ai_profiles.cpp \
|
||||
ai/ai_profiles.h \
|
||||
anim/animplay.cpp \
|
||||
anim/animplay.h \
|
||||
anim/packunpack.cpp \
|
||||
anim/packunpack.h \
|
||||
asteroid/asteroid.cpp \
|
||||
asteroid/asteroid.h \
|
||||
autopilot/autopilot.cpp \
|
||||
autopilot/autopilot.h \
|
||||
bmpman/bm_internal.h \
|
||||
bmpman/bmpman.cpp \
|
||||
bmpman/bmpman.h \
|
||||
camera/camera.cpp \
|
||||
camera/camera.h \
|
||||
cfile/cfile.cpp \
|
||||
cfile/cfile.h \
|
||||
cfile/cfilearchive.cpp \
|
||||
cfile/cfilearchive.h \
|
||||
cfile/cfilelist.cpp \
|
||||
cfile/cfilesystem.cpp \
|
||||
cfile/cfilesystem.h \
|
||||
cmdline/cmdline.cpp \
|
||||
cmdline/cmdline.h \
|
||||
cmeasure/cmeasure.cpp \
|
||||
cmeasure/cmeasure.h \
|
||||
controlconfig/controlsconfig.cpp \
|
||||
controlconfig/controlsconfig.h \
|
||||
controlconfig/controlsconfigcommon.cpp \
|
||||
cutscene/cutscenes.cpp \
|
||||
cutscene/cutscenes.h \
|
||||
cutscene/decoder16.cpp \
|
||||
cutscene/decoder8.cpp \
|
||||
cutscene/movie.cpp \
|
||||
cutscene/movie.h \
|
||||
cutscene/mve_audio.cpp \
|
||||
cutscene/mvelib.cpp \
|
||||
cutscene/mvelib.h \
|
||||
cutscene/mveplayer.cpp \
|
||||
cutscene/oggplayer.cpp \
|
||||
cutscene/oggplayer.h \
|
||||
ddsutils/ddsutils.cpp \
|
||||
ddsutils/ddsutils.h \
|
||||
debris/debris.cpp \
|
||||
debris/debris.h \
|
||||
debugconsole/console.cpp \
|
||||
debugconsole/console.h \
|
||||
debugconsole/consolecmds.cpp \
|
||||
debugconsole/consoleparse.cpp \
|
||||
debugconsole/consoleparse.h \
|
||||
exceptionhandler/exceptionhandler.cpp \
|
||||
exceptionhandler/exceptionhandler.h \
|
||||
external_dll/externalcode.h \
|
||||
external_dll/trackirglobal.cpp \
|
||||
external_dll/trackirglobal.h \
|
||||
fireball/fireballs.cpp \
|
||||
fireball/fireballs.h \
|
||||
fireball/warpineffect.cpp \
|
||||
fs2netd/fs2netd_client.cpp \
|
||||
fs2netd/fs2netd_client.h \
|
||||
fs2netd/tcp_client.cpp \
|
||||
fs2netd/tcp_client.h \
|
||||
fs2netd/tcp_socket.cpp \
|
||||
fs2netd/tcp_socket.h \
|
||||
fs2netd/protocol.h \
|
||||
gamehelp/contexthelp.cpp \
|
||||
gamehelp/contexthelp.h \
|
||||
gamehelp/gameplayhelp.cpp \
|
||||
gamehelp/gameplayhelp.h \
|
||||
gamesequence/gamesequence.cpp \
|
||||
gamesequence/gamesequence.h \
|
||||
gamesnd/eventmusic.cpp \
|
||||
gamesnd/eventmusic.h \
|
||||
gamesnd/gamesnd.cpp \
|
||||
gamesnd/gamesnd.h \
|
||||
globalincs/alphacolors.cpp \
|
||||
globalincs/alphacolors.h \
|
||||
globalincs/def_files.cpp \
|
||||
globalincs/def_files.h \
|
||||
globalincs/fsmemory.cpp \
|
||||
globalincs/fsmemory.h \
|
||||
globalincs/globals.h \
|
||||
globalincs/linklist.h \
|
||||
globalincs/profiling.cpp \
|
||||
globalincs/pstypes.h \
|
||||
globalincs/safe_strings.cpp \
|
||||
globalincs/safe_strings.h \
|
||||
globalincs/safe_strings_test.cpp \
|
||||
globalincs/systemvars.cpp \
|
||||
globalincs/systemvars.h \
|
||||
globalincs/version.cpp \
|
||||
globalincs/version.h \
|
||||
graphics/2d.cpp \
|
||||
graphics/2d.h \
|
||||
graphics/font.cpp \
|
||||
graphics/font.h \
|
||||
graphics/generic.cpp \
|
||||
graphics/generic.h \
|
||||
graphics/grbatch.cpp \
|
||||
graphics/grbatch.h \
|
||||
graphics/grinternal.h \
|
||||
graphics/gropengl.cpp \
|
||||
graphics/gropengl.h \
|
||||
graphics/gropenglbmpman.cpp \
|
||||
graphics/gropenglbmpman.h \
|
||||
graphics/gropengldraw.cpp \
|
||||
graphics/gropengldraw.h \
|
||||
graphics/gropenglextension.cpp \
|
||||
graphics/gropenglextension.h \
|
||||
graphics/gropengllight.cpp \
|
||||
graphics/gropengllight.h \
|
||||
graphics/gropenglpostprocessing.cpp \
|
||||
graphics/gropenglpostprocessing.h \
|
||||
graphics/gropenglshader.cpp \
|
||||
graphics/gropenglshader.h \
|
||||
graphics/gropenglstate.cpp \
|
||||
graphics/gropenglstate.h \
|
||||
graphics/gropengltexture.cpp \
|
||||
graphics/gropengltexture.h \
|
||||
graphics/gropengltnl.cpp \
|
||||
graphics/gropengltnl.h \
|
||||
graphics/grstub.cpp \
|
||||
graphics/grstub.h \
|
||||
graphics/line.h \
|
||||
graphics/shadows.cpp \
|
||||
graphics/tmapper.h \
|
||||
hud/hud.cpp \
|
||||
hud/hud.h \
|
||||
hud/hudartillery.cpp \
|
||||
hud/hudartillery.h \
|
||||
hud/hudbrackets.cpp \
|
||||
hud/hudbrackets.h \
|
||||
hud/hudconfig.cpp \
|
||||
hud/hudconfig.h \
|
||||
hud/hudescort.cpp \
|
||||
hud/hudescort.h \
|
||||
hud/hudets.cpp \
|
||||
hud/hudets.h \
|
||||
hud/hudgauges.h \
|
||||
hud/hudlock.cpp \
|
||||
hud/hudlock.h \
|
||||
hud/hudmessage.cpp \
|
||||
hud/hudmessage.h \
|
||||
hud/hudnavigation.cpp \
|
||||
hud/hudnavigation.h \
|
||||
hud/hudobserver.cpp \
|
||||
hud/hudobserver.h \
|
||||
hud/hudparse.cpp \
|
||||
hud/hudparse.h \
|
||||
hud/hudreticle.cpp \
|
||||
hud/hudreticle.h \
|
||||
hud/hudshield.cpp \
|
||||
hud/hudshield.h \
|
||||
hud/hudsquadmsg.cpp \
|
||||
hud/hudsquadmsg.h \
|
||||
hud/hudtarget.cpp \
|
||||
hud/hudtarget.h \
|
||||
hud/hudtargetbox.cpp \
|
||||
hud/hudtargetbox.h \
|
||||
hud/hudwingmanstatus.cpp \
|
||||
hud/hudwingmanstatus.h \
|
||||
iff_defs/iff_defs.cpp \
|
||||
iff_defs/iff_defs.h \
|
||||
inetfile/cftp.cpp \
|
||||
inetfile/cftp.h \
|
||||
inetfile/chttpget.cpp \
|
||||
inetfile/chttpget.h \
|
||||
inetfile/inetgetfile.cpp \
|
||||
inetfile/inetgetfile.h \
|
||||
io/cursor.cpp \
|
||||
io/cursor.h \
|
||||
io/key.cpp \
|
||||
io/key.h \
|
||||
io/keycontrol.cpp \
|
||||
io/keycontrol.h \
|
||||
io/mouse.cpp \
|
||||
io/mouse.h \
|
||||
io/timer.cpp \
|
||||
io/timer.h \
|
||||
jpgutils/jpgutils.cpp \
|
||||
jpgutils/jpgutils.h \
|
||||
jumpnode/jumpnode.cpp \
|
||||
jumpnode/jumpnode.h \
|
||||
lab/lab.cpp \
|
||||
lab/lab.h \
|
||||
lab/wmcgui.cpp \
|
||||
lab/wmcgui.h \
|
||||
lighting/lighting.cpp \
|
||||
lighting/lighting.h \
|
||||
localization/fhash.cpp \
|
||||
localization/fhash.h \
|
||||
localization/localize.cpp \
|
||||
localization/localize.h \
|
||||
math/fix.cpp \
|
||||
math/fix.h \
|
||||
math/floating.cpp \
|
||||
math/floating.h \
|
||||
math/fvi.cpp \
|
||||
math/fvi.h \
|
||||
math/spline.cpp \
|
||||
math/spline.h \
|
||||
math/staticrand.cpp \
|
||||
math/staticrand.h \
|
||||
math/vecmat.cpp \
|
||||
math/vecmat.h \
|
||||
menuui/barracks.cpp \
|
||||
menuui/barracks.h \
|
||||
menuui/credits.cpp \
|
||||
menuui/credits.h \
|
||||
menuui/fishtank.cpp \
|
||||
menuui/fishtank.h \
|
||||
menuui/mainhallmenu.cpp \
|
||||
menuui/mainhallmenu.h \
|
||||
menuui/mainhalltemp.cpp \
|
||||
menuui/mainhalltemp.h \
|
||||
menuui/optionsmenu.cpp \
|
||||
menuui/optionsmenu.h \
|
||||
menuui/optionsmenumulti.cpp \
|
||||
menuui/optionsmenumulti.h \
|
||||
menuui/playermenu.cpp \
|
||||
menuui/playermenu.h \
|
||||
menuui/readyroom.cpp \
|
||||
menuui/readyroom.h \
|
||||
menuui/snazzyui.cpp \
|
||||
menuui/snazzyui.h \
|
||||
menuui/techmenu.cpp \
|
||||
menuui/techmenu.h \
|
||||
menuui/trainingmenu.cpp \
|
||||
menuui/trainingmenu.h \
|
||||
mission/missionbriefcommon.cpp \
|
||||
mission/missionbriefcommon.h \
|
||||
mission/missioncampaign.cpp \
|
||||
mission/missioncampaign.h \
|
||||
mission/missiongoals.cpp \
|
||||
mission/missiongoals.h \
|
||||
mission/missiongrid.cpp \
|
||||
mission/missiongrid.h \
|
||||
mission/missionhotkey.cpp \
|
||||
mission/missionhotkey.h \
|
||||
mission/missionload.cpp \
|
||||
mission/missionload.h \
|
||||
mission/missionlog.cpp \
|
||||
mission/missionlog.h \
|
||||
mission/missionmessage.cpp \
|
||||
mission/missionmessage.h \
|
||||
mission/missionparse.cpp \
|
||||
mission/missionparse.h \
|
||||
mission/missiontraining.cpp \
|
||||
mission/missiontraining.h \
|
||||
missionui/chatbox.cpp \
|
||||
missionui/chatbox.h \
|
||||
missionui/fictionviewer.cpp \
|
||||
missionui/fictionviewer.h \
|
||||
missionui/missionbrief.cpp \
|
||||
missionui/missionbrief.h \
|
||||
missionui/missioncmdbrief.cpp \
|
||||
missionui/missioncmdbrief.h \
|
||||
missionui/missiondebrief.cpp \
|
||||
missionui/missiondebrief.h \
|
||||
missionui/missionloopbrief.cpp \
|
||||
missionui/missionloopbrief.h \
|
||||
missionui/missionpause.cpp \
|
||||
missionui/missionpause.h \
|
||||
missionui/missionscreencommon.cpp \
|
||||
missionui/missionscreencommon.h \
|
||||
missionui/missionshipchoice.cpp \
|
||||
missionui/missionshipchoice.h \
|
||||
missionui/missionweaponchoice.cpp \
|
||||
missionui/missionweaponchoice.h \
|
||||
missionui/redalert.cpp \
|
||||
missionui/redalert.h \
|
||||
mod_table/mod_table.cpp \
|
||||
mod_table/mod_table.h \
|
||||
model/model.h \
|
||||
model/modelanim.cpp \
|
||||
model/modelanim.h \
|
||||
model/modelcollide.cpp \
|
||||
model/modelinterp.cpp \
|
||||
model/modelsinc.h \
|
||||
model/modeloctant.cpp \
|
||||
model/modelread.cpp \
|
||||
model/modelrender.cpp \
|
||||
nebula/neb.cpp \
|
||||
nebula/neb.h \
|
||||
nebula/neblightning.cpp \
|
||||
nebula/neblightning.h \
|
||||
network/chat_api.cpp \
|
||||
network/chat_api.h \
|
||||
network/multi.cpp \
|
||||
network/multi.h \
|
||||
network/multilag.cpp \
|
||||
network/multilag.h \
|
||||
network/multimsgs.cpp \
|
||||
network/multimsgs.h \
|
||||
network/multiteamselect.cpp \
|
||||
network/multiteamselect.h \
|
||||
network/multiui.cpp \
|
||||
network/multiui.h \
|
||||
network/multiutil.cpp \
|
||||
network/multiutil.h \
|
||||
network/multi_campaign.cpp \
|
||||
network/multi_campaign.h \
|
||||
network/multi_data.cpp \
|
||||
network/multi_data.h \
|
||||
network/multi_dogfight.cpp \
|
||||
network/multi_dogfight.h \
|
||||
network/multi_endgame.cpp \
|
||||
network/multi_endgame.h \
|
||||
network/multi_ingame.cpp \
|
||||
network/multi_ingame.h \
|
||||
network/multi_kick.cpp \
|
||||
network/multi_kick.h \
|
||||
network/multi_log.cpp \
|
||||
network/multi_log.h \
|
||||
network/multi_obj.cpp \
|
||||
network/multi_obj.h \
|
||||
network/multi_observer.cpp \
|
||||
network/multi_observer.h \
|
||||
network/multi_options.cpp \
|
||||
network/multi_options.h \
|
||||
network/multi_pause.cpp \
|
||||
network/multi_pause.h \
|
||||
network/multi_pinfo.cpp \
|
||||
network/multi_pinfo.h \
|
||||
network/multi_ping.cpp \
|
||||
network/multi_ping.h \
|
||||
network/multi_pmsg.cpp \
|
||||
network/multi_pmsg.h \
|
||||
network/multi_pxo.cpp \
|
||||
network/multi_pxo.h \
|
||||
network/multi_rate.cpp \
|
||||
network/multi_rate.h \
|
||||
network/multi_respawn.cpp \
|
||||
network/multi_respawn.h \
|
||||
network/multi_sexp.cpp \
|
||||
network/multi_sexp.h \
|
||||
network/multi_team.cpp \
|
||||
network/multi_team.h \
|
||||
network/multi_update.h \
|
||||
network/multi_voice.cpp \
|
||||
network/multi_voice.h \
|
||||
network/multi_xfer.cpp \
|
||||
network/multi_xfer.h \
|
||||
network/psnet2.cpp \
|
||||
network/psnet2.h \
|
||||
network/stand_gui.cpp \
|
||||
network/stand_gui-unix.cpp \
|
||||
network/stand_gui.h \
|
||||
object/collidedebrisship.cpp \
|
||||
object/collidedebrisweapon.cpp \
|
||||
object/collideshipship.cpp \
|
||||
object/collideshipweapon.cpp \
|
||||
object/collideweaponweapon.cpp \
|
||||
object/deadobjectdock.cpp \
|
||||
object/deadobjectdock.h \
|
||||
object/objcollide.cpp \
|
||||
object/objcollide.h \
|
||||
object/objectdock.cpp \
|
||||
object/objectdock.h \
|
||||
object/object.cpp \
|
||||
object/object.h \
|
||||
object/objectshield.cpp \
|
||||
object/objectshield.h \
|
||||
object/objectsnd.cpp \
|
||||
object/objectsnd.h \
|
||||
object/objectsort.cpp \
|
||||
object/parseobjectdock.cpp \
|
||||
object/parseobjectdock.h \
|
||||
object/waypoint.cpp \
|
||||
object/waypoint.h \
|
||||
observer/observer.cpp \
|
||||
observer/observer.h \
|
||||
osapi/dialogs.cpp \
|
||||
osapi/dialogs.h \
|
||||
osapi/osapi.cpp \
|
||||
osapi/osapi.h \
|
||||
osapi/osregistry.cpp \
|
||||
osapi/osregistry.h \
|
||||
osapi/outwnd.cpp \
|
||||
osapi/outwnd.h \
|
||||
palman/palman.cpp \
|
||||
palman/palman.h \
|
||||
parse/encrypt.cpp \
|
||||
parse/encrypt.h \
|
||||
parse/generic_log.cpp \
|
||||
parse/generic_log.h \
|
||||
parse/lua.cpp \
|
||||
parse/lua.h \
|
||||
parse/parselo.cpp \
|
||||
parse/parselo.h \
|
||||
parse/scripting.cpp \
|
||||
parse/scripting.h \
|
||||
parse/sexp.cpp \
|
||||
parse/sexp.h \
|
||||
particle/particle.cpp \
|
||||
particle/particle.h \
|
||||
pcxutils/pcxutils.cpp \
|
||||
pcxutils/pcxutils.h \
|
||||
pilotfile/pilotfile.cpp \
|
||||
pilotfile/pilotfile.h \
|
||||
pilotfile/pilotfile_convert.cpp \
|
||||
pilotfile/pilotfile_convert.h \
|
||||
pilotfile/plr.cpp \
|
||||
pilotfile/csg.cpp \
|
||||
pilotfile/plr_convert.cpp \
|
||||
pilotfile/csg_convert.cpp \
|
||||
pngutils/pngutils.cpp \
|
||||
pngutils/pngutils.h \
|
||||
physics/physics.cpp \
|
||||
physics/physics.h \
|
||||
playerman/managepilot.cpp \
|
||||
playerman/managepilot.h \
|
||||
playerman/player.h \
|
||||
playerman/playercontrol.cpp \
|
||||
popup/popup.cpp \
|
||||
popup/popup.h \
|
||||
popup/popupdead.cpp \
|
||||
popup/popupdead.h \
|
||||
radar/radar.cpp \
|
||||
radar/radar.h \
|
||||
radar/radardradis.cpp \
|
||||
radar/radardradis.h \
|
||||
radar/radarorb.cpp \
|
||||
radar/radarorb.h \
|
||||
radar/radarsetup.cpp \
|
||||
radar/radarsetup.h \
|
||||
render/3d.h \
|
||||
render/3dclipper.cpp \
|
||||
render/3ddraw.cpp \
|
||||
render/3dinternal.h \
|
||||
render/3dlaser.cpp \
|
||||
render/3dmath.cpp \
|
||||
render/3dsetup.cpp \
|
||||
ship/afterburner.cpp \
|
||||
ship/afterburner.h \
|
||||
ship/awacs.cpp \
|
||||
ship/awacs.h \
|
||||
ship/shield.cpp \
|
||||
ship/ship.cpp \
|
||||
ship/ship.h \
|
||||
ship/shipcontrails.cpp \
|
||||
ship/shipcontrails.h \
|
||||
ship/shipfx.cpp \
|
||||
ship/shipfx.h \
|
||||
ship/shiphit.cpp \
|
||||
ship/shiphit.h \
|
||||
ship/subsysdamage.h \
|
||||
sound/audiostr.cpp \
|
||||
sound/audiostr.h \
|
||||
sound/acm.cpp \
|
||||
sound/acm.h \
|
||||
sound/ds.cpp \
|
||||
sound/ds.h \
|
||||
sound/ds3d.cpp \
|
||||
sound/ds3d.h \
|
||||
sound/dscap.cpp \
|
||||
sound/dscap.h \
|
||||
sound/fsspeech.cpp \
|
||||
sound/fsspeech.h \
|
||||
sound/openal.cpp \
|
||||
sound/openal.h \
|
||||
sound/rtvoice.cpp \
|
||||
sound/rtvoice.h \
|
||||
sound/sound.cpp \
|
||||
sound/sound.h \
|
||||
sound/speech.cpp \
|
||||
sound/speech.h \
|
||||
sound/voicerec.cpp \
|
||||
sound/voicerec.h \
|
||||
sound/ogg/ogg.cpp \
|
||||
sound/ogg/ogg.h \
|
||||
species_defs/species_defs.cpp \
|
||||
species_defs/species_defs.h \
|
||||
starfield/nebula.cpp \
|
||||
starfield/nebula.h \
|
||||
starfield/starfield.cpp \
|
||||
starfield/starfield.h \
|
||||
starfield/supernova.cpp \
|
||||
starfield/supernova.h \
|
||||
stats/medals.cpp \
|
||||
stats/medals.h \
|
||||
stats/scoring.cpp \
|
||||
stats/scoring.h \
|
||||
stats/stats.cpp \
|
||||
stats/stats.h \
|
||||
tgautils/tgautils.cpp \
|
||||
tgautils/tgautils.h \
|
||||
ui/button.cpp \
|
||||
ui/checkbox.cpp \
|
||||
ui/gadget.cpp \
|
||||
ui/icon.cpp \
|
||||
ui/inputbox.cpp \
|
||||
ui/keytrap.cpp \
|
||||
ui/listbox.cpp \
|
||||
ui/radio.cpp \
|
||||
ui/scroll.cpp \
|
||||
ui/slider.cpp \
|
||||
ui/slider2.cpp \
|
||||
ui/ui.h \
|
||||
ui/uidefs.h \
|
||||
ui/uidraw.cpp \
|
||||
ui/uimouse.cpp \
|
||||
ui/window.cpp \
|
||||
weapon/beam.cpp \
|
||||
weapon/beam.h \
|
||||
weapon/corkscrew.cpp \
|
||||
weapon/corkscrew.h \
|
||||
weapon/emp.cpp \
|
||||
weapon/emp.h \
|
||||
weapon/flak.cpp \
|
||||
weapon/flak.h \
|
||||
weapon/muzzleflash.cpp \
|
||||
weapon/muzzleflash.h \
|
||||
weapon/shockwave.cpp \
|
||||
weapon/shockwave.h \
|
||||
weapon/swarm.cpp \
|
||||
weapon/swarm.h \
|
||||
weapon/trails.cpp \
|
||||
weapon/trails.h \
|
||||
weapon/weapons.cpp \
|
||||
weapon/weapon.h
|
||||
|
||||
## conditional includes follow:
|
||||
|
||||
## joystic support sources
|
||||
if FS2_OS_WIN32
|
||||
JOY_SOURCES = \
|
||||
io/joy.cpp \
|
||||
io/joy.h \
|
||||
io/joy_ff.cpp \
|
||||
io/joy_ff.h \
|
||||
io/sw_error.hpp \
|
||||
io/sw_force.h \
|
||||
io/sw_guid.hpp \
|
||||
io/swff_lib.cpp
|
||||
endif
|
||||
|
||||
if FS2_OS_UNIX
|
||||
JOY_SOURCES = \
|
||||
io/joy.h \
|
||||
io/joy_ff.h \
|
||||
io/joy_ff-sdl.cpp \
|
||||
io/joy-sdl.cpp
|
||||
endif
|
||||
|
||||
## Win32-specific sources
|
||||
if FS2_OS_WIN32
|
||||
WIN32_SOURCES = \
|
||||
directx/vasync.h \
|
||||
directx/vd3dtypes.h \
|
||||
directx/vddraw.h \
|
||||
directx/vdinput.h \
|
||||
directx/vdplay.h \
|
||||
directx/vdplobby.h \
|
||||
directx/vdsetup.h \
|
||||
directx/vdvp.h \
|
||||
globalincs/windebug.cpp \
|
||||
graphics/gl/GLAUX.H \
|
||||
graphics/gl/GLU.H \
|
||||
graphics/gl/Gl.h \
|
||||
graphics/gl/Glext.h \
|
||||
graphics/gl/wglext.h \
|
||||
osapi/monopub.h
|
||||
endif
|
||||
|
||||
## Unix-specific sources
|
||||
if FS2_OS_UNIX
|
||||
UNIX_SOURCES = \
|
||||
windows_stub/stubs.cpp \
|
||||
windows_stub/config.h
|
||||
endif
|
||||
|
||||
|
||||
## libcode.a
|
||||
libcode_a_SOURCES = ${FS2_SOURCES} ${JOY_SOURCES} ${WIN32_SOURCES} \
|
||||
${UNIX_SOURCES}
|
||||
|
||||
##
|
||||
## End CODE library
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin MAIN fs2 binary
|
||||
##
|
||||
|
||||
FS2OPEN_SOURCES = \
|
||||
freespace2/freespace.cpp \
|
||||
freespace2/freespace.h \
|
||||
freespace2/levelpaging.cpp \
|
||||
freespace2/levelpaging.h
|
||||
|
||||
fs2_open_@PACKAGE_VERSION@_DEBUG_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_@PACKAGE_VERSION@_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_@PACKAGE_VERSION@_DEBUG_LDADD = libcode.a ../mongoose/libmongoose.a
|
||||
fs2_open_@PACKAGE_VERSION@_LDADD = libcode.a ../mongoose/libmongoose.a
|
||||
|
||||
##
|
||||
## End MAIN binary
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
## Begin wxFRED2 binary
|
||||
##
|
||||
|
||||
wxFRED_SOURCES = \
|
||||
wxfred2/res/select.png.h \
|
||||
wxfred2/res/constz.png.h \
|
||||
wxfred2/res/constx.png.h \
|
||||
wxfred2/res/selectrot.png.h \
|
||||
wxfred2/res/constyz.png.h \
|
||||
wxfred2/res/constxy.png.h \
|
||||
wxfred2/res/wingform.png.h \
|
||||
wxfred2/res/zoomsel.png.h \
|
||||
wxfred2/res/constxz.png.h \
|
||||
wxfred2/res/consty.png.h \
|
||||
wxfred2/res/wingdisband.png.h \
|
||||
wxfred2/res/showdist.png.h \
|
||||
wxfred2/res/orbitsel.png.h \
|
||||
wxfred2/res/zoomext.png.h \
|
||||
wxfred2/res/rotlocal.png.h \
|
||||
wxfred2/res/selectmove.png.h \
|
||||
wxfred2/res/selectlock.png.h \
|
||||
wxfred2/res/selectlist.png.h \
|
||||
wxfred2/base/wxfred_base.h \
|
||||
wxfred2/base/wxfred_base.cpp \
|
||||
wxfred2/editors/dlgobjecteditor.h \
|
||||
wxfred2/editors/dlgobjecteditor.cpp \
|
||||
wxfred2/editors/dlgvoiceactingmanager.h \
|
||||
wxfred2/editors/frmdebriefingeditor.h \
|
||||
wxfred2/editors/dlgbackgroundeditor.cpp \
|
||||
wxfred2/editors/dlgmissionobjectiveseditor.cpp \
|
||||
wxfred2/editors/frmbriefingeditor.cpp \
|
||||
wxfred2/editors/frmteamloadouteditor.h \
|
||||
wxfred2/editors/dlgmissionobjectiveseditor.h \
|
||||
wxfred2/editors/dlgmissionspecseditor.h \
|
||||
wxfred2/editors/frmdebriefingeditor.cpp \
|
||||
wxfred2/editors/dlgfictionviewer.cpp \
|
||||
wxfred2/editors/dlgvoiceactingmanager.cpp \
|
||||
wxfred2/editors/dlgsoundenvironment.cpp \
|
||||
wxfred2/editors/frmcommandbriefingeditor.cpp \
|
||||
wxfred2/editors/frmbriefingeditor.h \
|
||||
wxfred2/editors/dlgshieldsystemeditor.h \
|
||||
wxfred2/editors/dlgreinforcementseditor.h \
|
||||
wxfred2/editors/dlgeventseditor.h \
|
||||
wxfred2/editors/frmteamloadouteditor.cpp \
|
||||
wxfred2/editors/frmcommandbriefingeditor.h \
|
||||
wxfred2/editors/frmwaypointeditor.h \
|
||||
wxfred2/editors/dlgasteroidfieldeditor.h \
|
||||
wxfred2/editors/dlgsetglobalshipflagseditor.cpp \
|
||||
wxfred2/editors/dlgshieldsystemeditor.cpp \
|
||||
wxfred2/editors/frmshipseditor.h \
|
||||
wxfred2/editors/dlgfictionviewer.h \
|
||||
wxfred2/editors/dlgreinforcementspicker.cpp \
|
||||
wxfred2/editors/frmcampaigneditor.cpp \
|
||||
wxfred2/editors/dlgasteroidfieldeditor.cpp \
|
||||
wxfred2/editors/dlgreinforcementspicker.h \
|
||||
wxfred2/editors/dlgreinforcementseditor.cpp \
|
||||
wxfred2/editors/frmcampaigneditor.h \
|
||||
wxfred2/editors/dlgbackgroundeditor.h \
|
||||
wxfred2/editors/frmshipseditor.cpp \
|
||||
wxfred2/editors/dlgeventseditor.cpp \
|
||||
wxfred2/editors/dlgsetglobalshipflagseditor.h \
|
||||
wxfred2/editors/frmwingeditor.h \
|
||||
wxfred2/editors/frmwingeditor.cpp \
|
||||
wxfred2/editors/frmwaypointeditor.cpp \
|
||||
wxfred2/editors/dlgsoundenvironment.h \
|
||||
wxfred2/editors/dlgmissionspecseditor.cpp \
|
||||
wxfred2/glcviewport.h \
|
||||
wxfred2/misc/dlgmissionstats.h \
|
||||
wxfred2/misc/dlgmissionstats.cpp \
|
||||
wxfred2/wxfred2.cpp \
|
||||
wxfred2/wxfred2.h \
|
||||
wxfred2/help/dlgsexphelp.h \
|
||||
wxfred2/help/dlgsexphelp.cpp \
|
||||
wxfred2/help/dlgaboutbox.h \
|
||||
wxfred2/help/dlgaboutbox.cpp \
|
||||
wxfred2/frmfred2.h \
|
||||
wxfred2/frmfred2.cpp
|
||||
|
||||
wxFRED2_@PACKAGE_VERSION@_DEBUG_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_@PACKAGE_VERSION@_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
##
|
||||
## End wxFRED2 binary
|
||||
##
|
||||
###############################################################################
|
||||
@@ -1,569 +0,0 @@
|
||||
/*
|
||||
* Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ai/ai_profiles.h"
|
||||
#include "globalincs/def_files.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "localization/localize.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "ship/ship.h"
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
|
||||
// global stuff
|
||||
int Num_ai_profiles;
|
||||
int Default_ai_profile;
|
||||
ai_profile_t Ai_profiles[MAX_AI_PROFILES];
|
||||
|
||||
// local to this file
|
||||
static int Ai_profiles_initted = 0;
|
||||
static char Default_profile_name[NAME_LENGTH];
|
||||
|
||||
|
||||
// utility
|
||||
void set_flag(ai_profile_t *profile, char *name, int flag, int type)
|
||||
{
|
||||
if (optional_string(name))
|
||||
{
|
||||
bool val;
|
||||
stuff_boolean(&val);
|
||||
|
||||
if (type == AIP_FLAG) {
|
||||
if (val)
|
||||
profile->flags |= flag;
|
||||
else
|
||||
profile->flags &= ~flag;
|
||||
} else {
|
||||
if (val)
|
||||
profile->flags2 |= flag;
|
||||
else
|
||||
profile->flags2 &= ~flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *AI_path_types[] = {
|
||||
"normal",
|
||||
"alt1",
|
||||
};
|
||||
|
||||
int Num_ai_path_types = sizeof(AI_path_types)/sizeof(char*);
|
||||
|
||||
int ai_path_type_match(char *p)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < Num_ai_path_types; i++)
|
||||
{
|
||||
if(!stricmp(AI_path_types[i], p))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void parse_ai_profiles_tbl(const char *filename)
|
||||
{
|
||||
int i;
|
||||
char profile_name[NAME_LENGTH];
|
||||
ai_profile_t dummy_profile;
|
||||
char *saved_Mp = NULL;
|
||||
char buf[NAME_LENGTH];
|
||||
|
||||
try
|
||||
{
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("ai_profiles.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
// start parsing
|
||||
required_string("#AI Profiles");
|
||||
|
||||
// new default?
|
||||
if (optional_string("$Default Profile:"))
|
||||
stuff_string(Default_profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// begin reading data
|
||||
while (required_string_either("#End", "$Profile Name:"))
|
||||
{
|
||||
ai_profile_t *profile = &dummy_profile;
|
||||
ai_profile_t *previous_profile = NULL;
|
||||
bool no_create = false;
|
||||
|
||||
// get the name
|
||||
required_string("$Profile Name:");
|
||||
stuff_string(profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// see if it exists
|
||||
for (i = 0; i < Num_ai_profiles; i++)
|
||||
{
|
||||
if (!stricmp(Ai_profiles[i].profile_name, profile_name))
|
||||
{
|
||||
previous_profile = &Ai_profiles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// modular table stuff
|
||||
if (optional_string("+nocreate"))
|
||||
{
|
||||
no_create = true;
|
||||
|
||||
// use the previous one if possible,
|
||||
// otherwise continue to use the dummy one
|
||||
if (previous_profile != NULL)
|
||||
profile = previous_profile;
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't create multiple profiles with the same name
|
||||
if (previous_profile != NULL)
|
||||
{
|
||||
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we're under the limit
|
||||
if (Num_ai_profiles >= MAX_AI_PROFILES)
|
||||
{
|
||||
Warning(LOCATION, "Too many profiles in ai_profiles.tbl! Max is %d.\n", MAX_AI_PROFILES - 1); // -1 because one is built-in
|
||||
skip_to_string("#End", NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
profile = &Ai_profiles[Num_ai_profiles];
|
||||
Num_ai_profiles++;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize profile if we're not building from a previously parsed one
|
||||
if (!no_create)
|
||||
{
|
||||
// base profile, so zero it out
|
||||
if (profile == &Ai_profiles[0])
|
||||
{
|
||||
memset(profile, 0, sizeof(ai_profile_t));
|
||||
}
|
||||
// brand new profile, so set it to the base defaults
|
||||
else
|
||||
{
|
||||
memcpy(profile, &Ai_profiles[0], sizeof(ai_profile_t));
|
||||
}
|
||||
}
|
||||
|
||||
// set the name
|
||||
strcpy_s(profile->profile_name, profile_name);
|
||||
|
||||
|
||||
// fill in any and all settings; they're all optional and can be in any order
|
||||
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
|
||||
{
|
||||
if (optional_string("$Player Afterburner Recharge Scale:"))
|
||||
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Beam Friendly Fire Damage:"))
|
||||
parse_float_list(profile->beam_friendly_damage_cap, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Countermeasure Life Scale:"))
|
||||
parse_float_list(profile->cmeasure_life_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Countermeasure Firing Chance:"))
|
||||
parse_float_list(profile->cmeasure_fire_chance, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI In Range Time:"))
|
||||
parse_float_list(profile->in_range_time, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Always Links Ammo Weapons:"))
|
||||
parse_float_list(profile->link_ammo_levels_always, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Maybe Links Ammo Weapons:"))
|
||||
parse_float_list(profile->link_ammo_levels_maybe, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Primary Ammo Burst Multiplier:"))
|
||||
parse_float_list(profile->primary_ammo_burst_mult, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Always Links Energy Weapons:"))
|
||||
parse_float_list(profile->link_energy_levels_always, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Maybe Links Energy Weapons:"))
|
||||
parse_float_list(profile->link_energy_levels_maybe, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Missles Locked on Player:") || optional_string("$Max Missiles Locked on Player:"))
|
||||
parse_int_list(profile->max_allowed_player_homers, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Player Attackers:"))
|
||||
parse_int_list(profile->max_attackers, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Incoming Asteroids:"))
|
||||
parse_int_list(profile->max_incoming_asteroids, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Damage Factor:") || optional_string("$AI Damage Reduction to Player Hull:"))
|
||||
parse_float_list(profile->player_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Subsys Damage Factor:") || optional_string("$AI Damage Reduction to Player Subsys:"))
|
||||
parse_float_list(profile->subsys_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
// represented in fractions of F1_0
|
||||
if (optional_string("$Predict Position Delay:"))
|
||||
{
|
||||
int iLoop;
|
||||
float temp_list[NUM_SKILL_LEVELS];
|
||||
|
||||
parse_float_list(temp_list, NUM_SKILL_LEVELS);
|
||||
|
||||
for (iLoop = 0; iLoop < NUM_SKILL_LEVELS; iLoop++)
|
||||
profile->predict_position_delay[iLoop] = fl2f(temp_list[iLoop]);
|
||||
}
|
||||
|
||||
if (optional_string("$AI Shield Manage Delay:") || optional_string("$AI Shield Manage Delays:"))
|
||||
parse_float_list(profile->shield_manage_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Friendly AI Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_delay_scale_friendly, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Hostile AI Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_delay_scale_hostile, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Friendly AI Secondary Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_secondary_delay_scale_friendly, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Hostile AI Secondary Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_secondary_delay_scale_hostile, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Turn Time Scale:"))
|
||||
parse_float_list(profile->turn_time_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Glide Attack Percent:")) {
|
||||
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Glide Attack Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_attack_percent[i]);
|
||||
profile->glide_attack_percent[i] = 0.0f;
|
||||
}
|
||||
profile->glide_attack_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Circle Strafe Percent:")) {
|
||||
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Circle Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->circle_strafe_percent[i]);
|
||||
profile->circle_strafe_percent[i] = 0.0f;
|
||||
}
|
||||
profile->circle_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Glide Strafe Percent:")) {
|
||||
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Glide Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_strafe_percent[i]);
|
||||
profile->glide_strafe_percent[i] = 0.0f;
|
||||
}
|
||||
profile->glide_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Random Sidethrust Percent:")) {
|
||||
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Random Sidethrust Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->random_sidethrust_percent[i]);
|
||||
profile->random_sidethrust_percent[i] = 0.0f;
|
||||
}
|
||||
profile->random_sidethrust_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Stalemate Time Threshold:"))
|
||||
parse_float_list(profile->stalemate_time_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Stalemate Distance Threshold:"))
|
||||
parse_float_list(profile->stalemate_dist_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Shield Recharge Scale:"))
|
||||
parse_float_list(profile->shield_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Weapon Recharge Scale:"))
|
||||
parse_float_list(profile->weapon_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Target Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_target, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Player Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_player, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Required For Kill Scale:"))
|
||||
parse_float_list(profile->kill_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Required For Assist Scale:"))
|
||||
parse_float_list(profile->assist_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Awarded For Capship Assist:"))
|
||||
parse_float_list(profile->assist_award_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Repair Penalty:"))
|
||||
parse_int_list(profile->repair_penalty, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Delay Before Allowing Bombs to Be Shot Down:"))
|
||||
parse_float_list(profile->delay_bomb_arm_timer, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Chance AI Has to Fire Missiles at Player:"))
|
||||
parse_int_list(profile->chance_to_use_missiles_on_plr, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Aim Update Delay:"))
|
||||
parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Turret Max Aim Update Delay:"))
|
||||
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Autoaim FOV:"))
|
||||
{
|
||||
float fov_list[NUM_SKILL_LEVELS];
|
||||
parse_float_list(fov_list, NUM_SKILL_LEVELS);
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++)
|
||||
{
|
||||
//Enforce range
|
||||
if (fov_list[i] < 0.0f || fov_list[i] >= 360.0f)
|
||||
{
|
||||
Warning(LOCATION, "$Player Autoaim FOV should be >= 0 and < 360.0 (read %f). Setting to 0.", fov_list[i]);
|
||||
fov_list[i] = 0.0f;
|
||||
}
|
||||
|
||||
//Convert units
|
||||
profile->player_autoaim_fov[i] = fov_list[i] * PI / 180.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Detail Distance Multiplier:"))
|
||||
parse_float_list(profile->detail_distance_mult, NUM_SKILL_LEVELS);
|
||||
|
||||
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart shield management:", AIPF_SMART_SHIELD_MANAGEMENT, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart afterburner management:", AIPF_SMART_AFTERBURNER_MANAGEMENT, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow rapid secondary dumbfire:", AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$huge turret weapons ignore bombs:", AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$don't insert random turret fire delay:", AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$shockwaves damage small ship subsystems:", AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$navigation subsystem governs warpout capability:", AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$include beams for kills and assists:", AIPF_INCLUDE_BEAMS_IN_STAT_CALCS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$score kills based on damage caused:", AIPF_KILL_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$score assists based on damage caused:", AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix linked primary weapon decision bug:", AIPF_FIX_LINKED_PRIMARY_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$prevent turrets targeting too distant bombs:", AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart subsystem targeting for turrets:", AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AIPF_FIX_HEAT_SEEKER_STEALTH_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$multi allow empty primaries:", AIPF_MULTI_ALLOW_EMPTY_PRIMARIES, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$multi allow empty secondaries:", AIPF_MULTI_ALLOW_EMPTY_SECONDARIES, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow turrets target weapons freely:", AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use only single fov for turrets:", AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$force beam turrets to use normal fov:", AIPF_FORCE_BEAM_TURRET_FOV, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix ai class bug:", AIPF_FIX_AI_CLASS_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$perform fewer checks for death screams:", AIPF2_PERFORM_FEWER_SCREAM_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$advanced turret fov edge checks:", AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$require turrets to have target in fov:", AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$ai aims from ship center:", AIPF2_AI_AIMS_FROM_SHIP_CENTER, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$allow primary link at mission start:", AIPF2_ALLOW_PRIMARY_LINK_AT_START, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$allow beams to damage bombs:", AIPF2_BEAMS_DAMAGE_WEAPONS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling for player:", AIPF2_PLAYER_WEAPON_SCALE_FIX, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$countermeasures affect aspect seekers:", AIPF2_ASPECT_LOCK_COUNTERMEASURE, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$ai guards specific ship in wing:", AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING, AIP_FLAG2);
|
||||
|
||||
profile->ai_path_mode = AI_PATH_MODE_NORMAL;
|
||||
if (optional_string("$ai path mode:"))
|
||||
{
|
||||
stuff_string(buf, F_NAME, NAME_LENGTH);
|
||||
int j = ai_path_type_match(buf);
|
||||
if (j >= 0) {
|
||||
profile->ai_path_mode = j;
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Invalid ai path mode '%s' specified", buf);
|
||||
}
|
||||
}
|
||||
|
||||
set_flag(profile, "$no warp camera:", AIPF2_NO_WARP_CAMERA, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$fix ai path order bug:", AIPF2_FIX_AI_PATH_ORDER_BUG, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$strict turret-tagged-only targeting:", AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$aspect bomb invulnerability fix:", AIPF2_ASPECT_INVULNERABILITY_FIX, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$glide decay requires thrust:", AIPF2_GLIDE_DECAY_REQUIRES_THRUST, AIP_FLAG2);
|
||||
|
||||
profile->bay_arrive_speed_mult = 1.0f;
|
||||
profile->bay_depart_speed_mult = 1.0f;
|
||||
if (optional_string("$bay arrive speed multiplier:")) {
|
||||
stuff_float(&profile->bay_arrive_speed_mult);
|
||||
}
|
||||
if (optional_string("$bay depart speed multiplier:")) {
|
||||
stuff_float(&profile->bay_depart_speed_mult);
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
||||
// compatibility
|
||||
if (optional_string("$perform less checks for death screams:"))
|
||||
{
|
||||
mprintf(("Warning: \"$perform less checks for death screams\" flag is deprecated in favor of \"$perform fewer checks for death screams\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
if (temp)
|
||||
profile->flags2 |= AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
|
||||
else
|
||||
profile->flags2 &= ~AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
|
||||
}
|
||||
if (optional_string("$allow primary link delay:"))
|
||||
{
|
||||
mprintf(("Warning: \"$allow primary link delay\" flag is deprecated in favor of \"$allow primary link at mission start\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
if (temp)
|
||||
profile->flags2 &= ~AIPF2_ALLOW_PRIMARY_LINK_AT_START;
|
||||
else
|
||||
profile->flags2 |= AIPF2_ALLOW_PRIMARY_LINK_AT_START;
|
||||
}
|
||||
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if (saved_Mp && (saved_Mp == Mp))
|
||||
{
|
||||
char tmp[60];
|
||||
memset(tmp, 0, 60);
|
||||
strncpy(tmp, Mp, 59);
|
||||
mprintf(("WARNING: Unrecognized parameter in ai_profiles: %s\n", tmp));
|
||||
|
||||
Mp++;
|
||||
}
|
||||
|
||||
// find next valid option
|
||||
skip_to_start_of_string_either("$", "#");
|
||||
saved_Mp = Mp;
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : "<default ai_profiles.tbl>", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
int temp;
|
||||
|
||||
if (Ai_profiles_initted)
|
||||
return;
|
||||
|
||||
Num_ai_profiles = 0;
|
||||
Default_ai_profile = 0;
|
||||
Default_profile_name[0] = '\0';
|
||||
|
||||
// init retail entry first
|
||||
parse_ai_profiles_tbl(NULL);
|
||||
|
||||
// now parse the supplied table (if any)
|
||||
if (cf_exists_full("ai_profiles.tbl", CF_TYPE_TABLES))
|
||||
parse_ai_profiles_tbl("ai_profiles.tbl");
|
||||
|
||||
// parse any modular tables
|
||||
parse_modular_table("*-aip.tbm", parse_ai_profiles_tbl);
|
||||
|
||||
// set default if specified
|
||||
temp = ai_profile_lookup(Default_profile_name);
|
||||
if (temp >= 0)
|
||||
Default_ai_profile = temp;
|
||||
|
||||
Ai_profiles_initted = 1;
|
||||
}
|
||||
|
||||
int ai_profile_lookup(char *name)
|
||||
{
|
||||
for (int i = 0; i < Num_ai_profiles; i++)
|
||||
if (!stricmp(name, Ai_profiles[i].profile_name))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _AI_PROFILES_H_
|
||||
#define _AI_PROFILES_H_
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
|
||||
// flag int defines
|
||||
#define AIP_FLAG 1
|
||||
#define AIP_FLAG2 2
|
||||
|
||||
// flags
|
||||
#define AIPF_SMART_SHIELD_MANAGEMENT (1 << 0)
|
||||
#define AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS (1 << 1)
|
||||
#define AIPF_SMART_PRIMARY_WEAPON_SELECTION (1 << 2)
|
||||
#define AIPF_SMART_SECONDARY_WEAPON_SELECTION (1 << 3)
|
||||
#define AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE (1 << 4)
|
||||
#define AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS (1 << 5)
|
||||
#define AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY (1 << 6)
|
||||
#define AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY (1 << 7)
|
||||
#define AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS (1 << 8)
|
||||
#define AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP (1 << 9)
|
||||
#define AIPF_NO_MIN_DOCK_SPEED_CAP (1 << 10)
|
||||
#define AIPF_DISABLE_LINKED_FIRE_PENALTY (1 << 11)
|
||||
#define AIPF_DISABLE_WEAPON_DAMAGE_SCALING (1 << 12)
|
||||
#define AIPF_USE_ADDITIVE_WEAPON_VELOCITY (1 << 13)
|
||||
#define AIPF_USE_NEWTONIAN_DAMPENING (1 << 14)
|
||||
#define AIPF_INCLUDE_BEAMS_IN_STAT_CALCS (1 << 15)
|
||||
#define AIPF_KILL_SCORING_SCALES_WITH_DAMAGE (1 << 16)
|
||||
#define AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE (1 << 17)
|
||||
#define AIPF_ALLOW_MULTI_EVENT_SCORING (1 << 18)
|
||||
#define AIPF_SMART_AFTERBURNER_MANAGEMENT (1 << 19)
|
||||
#define AIPF_FIX_LINKED_PRIMARY_BUG (1 << 20)
|
||||
#define AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE (1 << 21)
|
||||
#define AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS (1 << 22)
|
||||
#define AIPF_FIX_HEAT_SEEKER_STEALTH_BUG (1 << 23)
|
||||
#define AIPF_MULTI_ALLOW_EMPTY_PRIMARIES (1 << 24)
|
||||
#define AIPF_MULTI_ALLOW_EMPTY_SECONDARIES (1 << 25)
|
||||
#define AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY (1 << 26)
|
||||
#define AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS (1 << 27)
|
||||
#define AIPF_ALLOW_VERTICAL_DODGE (1 << 28) //Allows AI ships to evade weapons vertically as well as horizontally
|
||||
#define AIPF_FORCE_BEAM_TURRET_FOV (1 << 29)
|
||||
#define AIPF_FIX_AI_CLASS_BUG (1 << 30)
|
||||
|
||||
// flags2
|
||||
#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0)
|
||||
#define AIPF2_NO_SPECIAL_PLAYER_AVOID (1 << 1)
|
||||
#define AIPF2_PERFORM_FEWER_SCREAM_CHECKS (1 << 2)
|
||||
#define AIPF2_ALL_SHIPS_MANAGE_SHIELDS (1 << 3)
|
||||
#define AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS (1 << 4)
|
||||
#define AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV (1 << 5)
|
||||
#define AIPF2_AI_AIMS_FROM_SHIP_CENTER (1 << 6)
|
||||
#define AIPF2_ALLOW_PRIMARY_LINK_AT_START (1 << 7)
|
||||
#define AIPF2_BEAMS_DAMAGE_WEAPONS (1 << 8)
|
||||
#define AIPF2_PLAYER_WEAPON_SCALE_FIX (1 << 9)
|
||||
#define AIPF2_NO_WARP_CAMERA (1 << 10)
|
||||
#define AIPF2_ASPECT_LOCK_COUNTERMEASURE (1 << 11)
|
||||
#define AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING (1 << 12)
|
||||
#define AIPF2_FIX_AI_PATH_ORDER_BUG (1 << 13)
|
||||
#define AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING (1 << 14)
|
||||
#define AIPF2_ASPECT_INVULNERABILITY_FIX (1 << 15)
|
||||
#define AIPF2_GLIDE_DECAY_REQUIRES_THRUST (1 << 16)
|
||||
|
||||
// AI Path types
|
||||
#define AI_PATH_MODE_NORMAL 0
|
||||
#define AI_PATH_MODE_ALT1 1
|
||||
|
||||
#define MAX_AI_PROFILES 5
|
||||
|
||||
typedef struct ai_profile_t {
|
||||
|
||||
char profile_name[NAME_LENGTH];
|
||||
|
||||
int flags;
|
||||
int flags2;
|
||||
|
||||
// difficulty-related values
|
||||
int max_incoming_asteroids[NUM_SKILL_LEVELS]; // max number of asteroids thrown at friendlies
|
||||
int max_allowed_player_homers[NUM_SKILL_LEVELS]; // max number of simultaneous homing weapons on player
|
||||
int max_attackers[NUM_SKILL_LEVELS]; // max number of ships that can attack a ship
|
||||
fix predict_position_delay[NUM_SKILL_LEVELS]; // how long until AI predicts a ship position
|
||||
float in_range_time[NUM_SKILL_LEVELS]; // seconds to add to time it takes to get enemy in range (only for player's enemies)
|
||||
float shield_manage_delay[NUM_SKILL_LEVELS]; // how long before AI manages shields (note that the player's team always uses the average skill's delay)
|
||||
|
||||
// AI ships link primaries if energy levels greater than these percents
|
||||
float link_energy_levels_always[NUM_SKILL_LEVELS]; // always link
|
||||
float link_energy_levels_maybe[NUM_SKILL_LEVELS]; // link if hull strength low
|
||||
|
||||
// AI ships link primaries if ammunition levels greater than these percents
|
||||
float link_ammo_levels_always[NUM_SKILL_LEVELS]; // always link
|
||||
float link_ammo_levels_maybe[NUM_SKILL_LEVELS]; // link if hull strength low
|
||||
float primary_ammo_burst_mult[NUM_SKILL_LEVELS]; // SUSHI: Multiplier adjusting burst frequency for ballistic primary weapons
|
||||
|
||||
// difficulty-related scales
|
||||
float cmeasure_life_scale[NUM_SKILL_LEVELS]; // life of countermeasures
|
||||
float cmeasure_fire_chance[NUM_SKILL_LEVELS]; // chance a countermeasure will be fired based on skill level (also scaled by ai_class)
|
||||
float weapon_energy_scale[NUM_SKILL_LEVELS]; // weapon energy available
|
||||
float shield_energy_scale[NUM_SKILL_LEVELS]; // shield energy available
|
||||
float afterburner_recharge_scale[NUM_SKILL_LEVELS]; // speed of afterburner recharge
|
||||
float player_damage_scale[NUM_SKILL_LEVELS]; // damage applied to the player
|
||||
|
||||
float subsys_damage_scale[NUM_SKILL_LEVELS]; // damage applied to a player subsystem
|
||||
float beam_friendly_damage_cap[NUM_SKILL_LEVELS]; // damage cap values for friendly beam fire
|
||||
float turn_time_scale[NUM_SKILL_LEVELS]; // speed at which enemy ships turn
|
||||
float glide_attack_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "glide attack" move
|
||||
float circle_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "circle strafe" move
|
||||
float glide_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use glide when strafing capships
|
||||
float random_sidethrust_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to randomly use sidethrust while dogfihthing
|
||||
float stalemate_time_thresh[NUM_SKILL_LEVELS]; // SUSHI: The amount of time required for the AI to detect (and try to break) dogfight stalemate
|
||||
float stalemate_dist_thresh[NUM_SKILL_LEVELS]; // SUSHI: The maximum distance the AI and target must be within for a stalemate
|
||||
float max_aim_update_delay[NUM_SKILL_LEVELS]; // SUSHI: The maximum delay before the AI updates their aim against small ships
|
||||
float turret_max_aim_update_delay[NUM_SKILL_LEVELS]; // SUSHI: As above, but for turrets updating their aim
|
||||
|
||||
// Multiplicative delay factors for increasing skill levels.
|
||||
float ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS];
|
||||
float ship_fire_delay_scale_friendly[NUM_SKILL_LEVELS];
|
||||
|
||||
// Multiplicative secondary delay factors for increasing skill levels.
|
||||
float ship_fire_secondary_delay_scale_hostile[NUM_SKILL_LEVELS];
|
||||
float ship_fire_secondary_delay_scale_friendly[NUM_SKILL_LEVELS];
|
||||
|
||||
// Maximum turrets of one ship allowed to shoot the same target
|
||||
int max_turret_ownage_target[NUM_SKILL_LEVELS];
|
||||
int max_turret_ownage_player[NUM_SKILL_LEVELS];
|
||||
|
||||
// percentage of damage caused required for a kill/assist
|
||||
float kill_percentage_scale[NUM_SKILL_LEVELS];
|
||||
float assist_percentage_scale[NUM_SKILL_LEVELS];
|
||||
|
||||
// percentage of the capships score given to other team mates on a kill
|
||||
float assist_award_percentage_scale[NUM_SKILL_LEVELS];
|
||||
|
||||
// the number of points subtracted from score for a rearm started on a player
|
||||
int repair_penalty[NUM_SKILL_LEVELS];
|
||||
|
||||
float delay_bomb_arm_timer[NUM_SKILL_LEVELS];
|
||||
|
||||
// the chance (x/7) that ship is allowed to fire missiles at player ship.
|
||||
int chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
|
||||
|
||||
// Player-specific autoaim FOV override
|
||||
float player_autoaim_fov[NUM_SKILL_LEVELS];
|
||||
|
||||
float detail_distance_mult[MAX_DETAIL_LEVEL + 1]; //MAX_DETAIL_LEVEL really needs to be 4
|
||||
|
||||
int ai_path_mode;
|
||||
|
||||
// Ships flying bay paths will gradually accelerate/decelerate instead of
|
||||
// flying the whole path at max speed
|
||||
float bay_arrive_speed_mult;
|
||||
float bay_depart_speed_mult;
|
||||
|
||||
} ai_profile_t;
|
||||
|
||||
|
||||
extern int Num_ai_profiles;
|
||||
extern int Default_ai_profile;
|
||||
extern ai_profile_t Ai_profiles[MAX_AI_PROFILES];
|
||||
|
||||
|
||||
void ai_profiles_init();
|
||||
|
||||
int ai_profile_lookup(char *name);
|
||||
|
||||
#endif
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __AIBIG_H__
|
||||
#define __AIBIG_H__
|
||||
|
||||
class object;
|
||||
struct ai_info;
|
||||
struct vec3d;
|
||||
class ship_subsys;
|
||||
|
||||
void ai_big_ship(object *objp);
|
||||
void ai_big_chase();
|
||||
void ai_big_subsys_path_cleanup(ai_info *aip);
|
||||
|
||||
// strafe functions
|
||||
void ai_big_strafe();
|
||||
int ai_big_maybe_enter_strafe_mode(object *objp, int weapon_objnum, int consider_target_only=0);
|
||||
void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp);
|
||||
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov=1.0f);
|
||||
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _AIGOALS_H
|
||||
#define _AIGOALS_H
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct wing;
|
||||
struct ai_info;
|
||||
struct ai_goal;
|
||||
|
||||
// macros for goals which get set via sexpressions in the mission code
|
||||
|
||||
// IMPORTANT! If you add a new AI_GOAL_x define, be sure to update the functions
|
||||
// ai_update_goal_references() and query_referenced_in_ai_goals() or else risk breaking
|
||||
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
|
||||
// to worry about doing this. Also add it to list in Fred\Management.cpp, and let Hoffoss know!
|
||||
// WMC - Oh and add them to Ai_goal_names plz. TY! :)
|
||||
#define AI_GOAL_CHASE (1<<1) // 0x00000002
|
||||
#define AI_GOAL_DOCK (1<<2) // 0x00000004 // used for undocking as well
|
||||
#define AI_GOAL_WAYPOINTS (1<<3) // 0x00000008
|
||||
#define AI_GOAL_WAYPOINTS_ONCE (1<<4) // 0x00000010
|
||||
#define AI_GOAL_WARP (1<<5) // 0x00000020
|
||||
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6) // 0x00000040
|
||||
#define AI_GOAL_FORM_ON_WING (1<<7) // 0x00000080
|
||||
#define AI_GOAL_UNDOCK (1<<8) // 0x00000100
|
||||
#define AI_GOAL_CHASE_WING (1<<9) // 0x00000200
|
||||
#define AI_GOAL_GUARD (1<<10) // 0x00000400
|
||||
#define AI_GOAL_DISABLE_SHIP (1<<11) // 0x00000800
|
||||
#define AI_GOAL_DISARM_SHIP (1<<12) // 0x00001000
|
||||
#define AI_GOAL_CHASE_ANY (1<<13) // 0x00002000
|
||||
#define AI_GOAL_IGNORE (1<<14) // 0x00004000
|
||||
#define AI_GOAL_GUARD_WING (1<<15) // 0x00008000
|
||||
#define AI_GOAL_EVADE_SHIP (1<<16) // 0x00010000
|
||||
|
||||
// the next goals are for support ships only
|
||||
#define AI_GOAL_STAY_NEAR_SHIP (1<<17) // 0x00020000
|
||||
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18) // 0x00040000
|
||||
#define AI_GOAL_REARM_REPAIR (1<<19) // 0x00080000
|
||||
|
||||
// resume regular goals
|
||||
#define AI_GOAL_STAY_STILL (1<<20) // 0x00100000
|
||||
#define AI_GOAL_PLAY_DEAD (1<<21) // 0x00200000
|
||||
#define AI_GOAL_CHASE_WEAPON (1<<22) // 0x00400000
|
||||
|
||||
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
|
||||
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
|
||||
|
||||
// now the masks for ship types
|
||||
|
||||
// Goober5000: added AI_GOAL_STAY_NEAR_SHIP and AI_GOAL_KEEP_SAFE_DISTANCE as valid for fighters
|
||||
//WMC - Don't need these anymore. Whee!
|
||||
/*
|
||||
#define AI_GOAL_ACCEPT_FIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_DESTROY_SUBSYSTEM | AI_GOAL_CHASE_WING | AI_GOAL_GUARD | AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP | AI_GOAL_CHASE_ANY | AI_GOAL_IGNORE | AI_GOAL_IGNORE_NEW | AI_GOAL_GUARD_WING | AI_GOAL_EVADE_SHIP | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE )
|
||||
#define AI_GOAL_ACCEPT_BOMBER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_STEALTH ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_TRANSPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_CHASE_WING | AI_GOAL_DOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_UNDOCK | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD| AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_FREIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_TRANSPORT | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CRUISER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FREIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CORVETTE ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_GAS_MINER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_AWACS ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_CAPITAL ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CRUISER & ~(AI_GOAL_DOCK | AI_GOAL_UNDOCK) | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_SUPERCAP ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_CAPITAL | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_SUPPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_DOCK | AI_GOAL_UNDOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD)
|
||||
#define AI_GOAL_ACCEPT_ESCAPEPOD ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_TRANSPORT| AI_GOAL_STAY_NEAR_SHIP )
|
||||
*/
|
||||
|
||||
#define MAX_AI_DOCK_NAMES 25
|
||||
|
||||
typedef flag_def_list ai_goal_list;
|
||||
|
||||
extern ai_goal_list Ai_goal_names[];
|
||||
extern int Num_ai_goals;
|
||||
|
||||
extern int Num_ai_dock_names;
|
||||
extern char Ai_dock_names[MAX_AI_DOCK_NAMES][NAME_LENGTH];
|
||||
|
||||
extern const char *Ai_goal_text(int goal);
|
||||
|
||||
// extern function definitions
|
||||
extern void ai_post_process_mission();
|
||||
extern void ai_maybe_add_form_goal( wing *wingp );
|
||||
extern void ai_process_mission_orders( int objnum, ai_info *aip );
|
||||
|
||||
extern int ai_goal_num(ai_goal *goals);
|
||||
|
||||
// adds goals to ships/wing through sexpressions
|
||||
extern void ai_add_ship_goal_scripting(int mode, int submode, int priority, char *shipname, ai_info *aip);
|
||||
extern void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip );
|
||||
extern void ai_add_wing_goal_sexp( int sexp, int type, int wingnum );
|
||||
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp );
|
||||
|
||||
extern int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp );
|
||||
extern void ai_remove_wing_goal_sexp(int sexp, int wingnum);
|
||||
|
||||
// adds goals to ships/sings through player orders
|
||||
extern void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip );
|
||||
extern void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum );
|
||||
|
||||
extern void ai_remove_ship_goal( ai_info *aip, int index );
|
||||
extern void ai_clear_ship_goals( ai_info *aip );
|
||||
extern void ai_clear_wing_goals( int wingnum );
|
||||
|
||||
extern void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip );
|
||||
|
||||
extern void ai_mission_goal_complete( ai_info *aip );
|
||||
extern void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp );
|
||||
|
||||
extern void ai_update_goal_references(ai_goal *goals, int type, const char *old_name, const char *new_name);
|
||||
extern int query_referenced_in_ai_goals(ai_goal *goals, int type, const char *name);
|
||||
extern char *ai_add_dock_name(const char *str);
|
||||
|
||||
extern int ai_query_goal_valid( int ship, int ai_goal_type );
|
||||
|
||||
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
|
||||
extern void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate = 1 );
|
||||
|
||||
#endif
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AIINTERNAL_H
|
||||
#define _AIINTERNAL_H
|
||||
|
||||
#include "ship/ship.h"
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
//Returns true if the specified object is a stealth ship, false if not
|
||||
bool is_object_stealth_ship(object* objp);
|
||||
|
||||
//Number of live turrets on the object attacking
|
||||
int num_turrets_attacking(object *turret_parent, int target_objnum);
|
||||
|
||||
//Determine whether an object is targetable within a nebula (checks for stealth)
|
||||
int object_is_targetable(object *target, ship *viewer);
|
||||
|
||||
//Returns the number of enemy fighters within threshold of pos.
|
||||
int num_nearby_fighters(int enemy_team_mask, vec3d *pos, float threshold);
|
||||
|
||||
//Returns true if OK for *aip to fire its current weapon at its current target.
|
||||
int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip);
|
||||
|
||||
//Does all the stuff needed to aim and fire a turret.
|
||||
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __ANIMPLAY_H__
|
||||
#define __ANIMPLAY_H__
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct anim;
|
||||
struct anim_info;
|
||||
struct anim_instance;
|
||||
|
||||
// structure passed in when playing an anim. Talk about overkill..
|
||||
typedef struct {
|
||||
anim *anim_info;
|
||||
int x;
|
||||
int y;
|
||||
int base_w;
|
||||
int base_h;
|
||||
int start_at;
|
||||
int stop_at;
|
||||
int screen_id;
|
||||
vec3d *world_pos;
|
||||
float radius;
|
||||
int framerate_independent;
|
||||
void *color;
|
||||
int skip_frames;
|
||||
int looped;
|
||||
int ping_pong;
|
||||
} anim_play_struct;
|
||||
|
||||
enum
|
||||
{
|
||||
PAGE_FROM_MEM = 0,
|
||||
PAGE_FROM_DISK = 1,
|
||||
PAGE_FROM_DISK_FORCED = 2
|
||||
};
|
||||
|
||||
extern int Anim_paused;
|
||||
|
||||
void anim_init();
|
||||
void anim_level_init();
|
||||
void anim_level_close();
|
||||
void anim_render_all(int screen_id, float frametime);
|
||||
void anim_render_one(int screen_id, anim_instance *ani, float frametime);
|
||||
void anim_play_init(anim_play_struct *aps, anim *a_info, int x, int y, int max_x = -1, int max_y = -1);
|
||||
anim_instance *anim_play(anim_play_struct *aps);
|
||||
void anim_ignore_next_frametime();
|
||||
int anim_stop_playing(anim_instance* anim_instance);
|
||||
int anim_show_next_frame(anim_instance *instance, float frametime);
|
||||
void anim_release_all_instances(int screen_id = 0);
|
||||
void anim_release_render_instance(anim_instance* instance);
|
||||
anim *anim_load(char *name, int cf_dir_type = CF_TYPE_ANY, int file_mapped = PAGE_FROM_MEM);
|
||||
int anim_free(anim *ptr);
|
||||
int anim_playing(anim_instance *ai);
|
||||
int anim_write_frames_out(char *filename);
|
||||
void anim_display_info(char *filename);
|
||||
void anim_read_header(anim *ptr, CFILE *fp);
|
||||
void anim_reverse_direction(anim_instance *ai); // called automatically for ping-ponging, and can also be called externally
|
||||
void anim_pause(anim_instance *ai);
|
||||
void anim_unpause(anim_instance *ai);
|
||||
|
||||
int anim_instance_is_streamed(anim_instance *ai);
|
||||
unsigned char anim_instance_get_byte(anim_instance *ai, int offset);
|
||||
|
||||
#endif /* __ANIMPLAY_H__ */
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __PACKUNPACK_H__
|
||||
#define __PACKUNPACK_H__
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct CFILE;
|
||||
|
||||
#define ANI_STREAM_CACHE_SIZE 4096
|
||||
|
||||
#define PACKER_CODE 0xEE /// Used by PACKING_METHOD_RLE
|
||||
#define PACKING_METHOD_RLE 0 /// Hoffoss's RLE format
|
||||
#define PACKING_METHOD_RLE_KEY 1 /// Hoffoss's key frame RLE format
|
||||
#define PACKING_METHOD_STD_RLE 2 /// Standard RLE format (high bit is count)
|
||||
#define PACKING_METHOD_STD_RLE_KEY 3 /// Standard RLE format key frame
|
||||
|
||||
#define STD_RLE_CODE 0x80
|
||||
|
||||
typedef struct key_frame {
|
||||
int frame_num; // which frame number this key frame is
|
||||
int offset; // offset from the start of data block
|
||||
} key_frame;
|
||||
|
||||
#define ANF_MEM_MAPPED (1<<0) // animation is memory-mapped file
|
||||
#define ANF_STREAMED (1<<1)
|
||||
#define ANF_XPARENT (1<<2) // animation has transparency
|
||||
#define ANF_ALL_KEYFRAMES (1<<3) // all the frames are keyframes (this is necessary if we want to play the file backwards)
|
||||
|
||||
typedef struct anim {
|
||||
anim *next;
|
||||
char name[MAX_PATH_LEN];
|
||||
ubyte packer_code;
|
||||
int width;
|
||||
int height;
|
||||
int total_frames;
|
||||
int instance_count; // number of instances that are currently playing
|
||||
int ref_count; // number of times this anim has been loaded
|
||||
float time; // playback time in seconds
|
||||
int num_keys;
|
||||
key_frame *keys;
|
||||
ubyte palette[768];
|
||||
ubyte palette_translation[256];
|
||||
ubyte *data; // points to compressed data
|
||||
CFILE* cfile_ptr;
|
||||
int version;
|
||||
int fps;
|
||||
ubyte xparent_r; // red component for the transparent color in source image
|
||||
ubyte xparent_g; // green component for the transparent color in source image
|
||||
ubyte xparent_b; // blue component for the transparent color in source image
|
||||
int flags;
|
||||
uint screen_sig;
|
||||
int file_offset; // file offset to start of frame data
|
||||
int cache_file_offset;
|
||||
ubyte *cache;
|
||||
} anim;
|
||||
|
||||
// the direction to play the anim (forwards or backwards)
|
||||
#define ANIM_DIRECT_FORWARD 0
|
||||
#define ANIM_DIRECT_REVERSE 1
|
||||
|
||||
typedef struct anim_instance {
|
||||
anim_instance *next, *prev;
|
||||
int x,y; // coordinates anim is played at (top left corner of anim)
|
||||
int base_w, base_h; // coordinate scale this anim is played in.
|
||||
vec3d *world_pos; // world (x,y,z) position of explosion
|
||||
float radius; // radius of image, needed for scaling
|
||||
int frame_num; // current frame, or last frame if between frames (first frame is 0)
|
||||
int last_frame_num;// last frame rendered
|
||||
anim *parent; // pointer to anim structure, which holds compressed data
|
||||
ubyte *data; // pointer to next frame's compressed data
|
||||
ubyte *frame; // uncompressed frame
|
||||
float time_elapsed; // how long the anim has played for (in seconds)
|
||||
int start_at; // frame anim playing should start
|
||||
int stop_at; // frame anim playing should stop
|
||||
int framerate_independent; // animation should play back in same amount of time, regardless
|
||||
int skip_frames; // should anim skip frames during framerate independent playback
|
||||
int looped; // should anim keep playing over and over...
|
||||
int stop_now; // flag to indicate time to stop the animation
|
||||
int last_bitmap; // id of last bitmap that was rendered out from animation
|
||||
int screen_id; // 0 means all screens should render, otherwise screen specific
|
||||
void *aa_color; // anti-aliased bitmap color
|
||||
int xlate_pal;
|
||||
int direction; // playing forwards or backwards ?
|
||||
int ping_pong; // should be played ping-pong style
|
||||
int paused; // pause the anim
|
||||
int file_offset; // current offset into frame (like data, put offset into file)
|
||||
int loop_count; // starts at 0, and is incremented each time it loops
|
||||
} anim_instance;
|
||||
|
||||
int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type);
|
||||
int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type);
|
||||
|
||||
ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp);
|
||||
int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp);
|
||||
|
||||
void anim_init();
|
||||
anim_instance *init_anim_instance(anim *ptr, int bpp);
|
||||
void free_anim_instance(anim_instance *inst);
|
||||
int anim_get_next_frame(anim_instance *inst);
|
||||
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp);
|
||||
void anim_set_palette(anim *a);
|
||||
void anim_check_for_palette_change(anim_instance *inst);
|
||||
|
||||
|
||||
#endif /* __PACKUNPACK_H__ */
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __ASTEROID_H__
|
||||
#define __ASTEROID_H__
|
||||
|
||||
#include "globalincs/globals.h" // for NAME_LENGTH
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
|
||||
class object;
|
||||
class polymodel;
|
||||
struct collision_info_struct;
|
||||
class draw_list;
|
||||
|
||||
#define MAX_ASTEROIDS 512
|
||||
|
||||
#define NUM_DEBRIS_SIZES 3
|
||||
#define NUM_DEBRIS_POFS 3 // Number of POFs per debris size
|
||||
|
||||
#define ASTEROID_TYPE_SMALL 0
|
||||
#define ASTEROID_TYPE_MEDIUM 1
|
||||
#define ASTEROID_TYPE_LARGE 2
|
||||
|
||||
// these should always be equal for the benefit of generic asteroids (c.f. asteroid_page_in)
|
||||
#define MAX_ACTIVE_DEBRIS_TYPES NUM_DEBRIS_SIZES
|
||||
|
||||
// Goober5000 - currently same as MAX_SHIP_DETAIL_LEVELS (put here to avoid an #include)
|
||||
#define MAX_ASTEROID_DETAIL_LEVELS 5
|
||||
|
||||
|
||||
// Data structure to track the active asteroids
|
||||
typedef struct asteroid_obj {
|
||||
asteroid_obj *next, *prev;
|
||||
int flags, objnum;
|
||||
} asteroid_obj;
|
||||
extern asteroid_obj Asteroid_obj_list;
|
||||
|
||||
|
||||
// Data structure for determining a type and amount of other asteroids an
|
||||
// asteroid will split to when destroyed.
|
||||
typedef struct asteroid_split_info {
|
||||
int asteroid_type;
|
||||
int min;
|
||||
int max;
|
||||
} asteroid_split_info;
|
||||
|
||||
class asteroid_info
|
||||
{
|
||||
public:
|
||||
char name[NAME_LENGTH]; // name for the asteroid
|
||||
char pof_files[NUM_DEBRIS_POFS][MAX_FILENAME_LEN]; // POF files to load/associate with ship
|
||||
int num_detail_levels; // number of detail levels for this ship
|
||||
int detail_distance[MAX_ASTEROID_DETAIL_LEVELS]; // distance to change detail levels at
|
||||
float max_speed; // cap on speed for asteroid
|
||||
int damage_type_idx; //Damage type of the asteroid
|
||||
int damage_type_idx_sav; // stored value from table used to reset damage_type_idx
|
||||
float inner_rad; // radius within which maximum area effect damage is applied
|
||||
float outer_rad; // radius at which no area effect damage is applied
|
||||
float damage; // maximum damage applied from area effect explosion
|
||||
float blast; // maximum blast impulse from area effect explosion
|
||||
float initial_asteroid_strength; // starting strength of asteroid
|
||||
SCP_vector< asteroid_split_info > split_info;
|
||||
polymodel *modelp[NUM_DEBRIS_POFS];
|
||||
int model_num[NUM_DEBRIS_POFS];
|
||||
SCP_vector<int> explosion_bitmap_anims;
|
||||
float fireball_radius_multiplier; // the model radius is multiplied by this to determine the fireball size
|
||||
|
||||
asteroid_info( )
|
||||
: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx( 0 ),
|
||||
damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
|
||||
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
|
||||
fireball_radius_multiplier( -1 )
|
||||
{
|
||||
name[ 0 ] = 0;
|
||||
memset( detail_distance, 0, sizeof( detail_distance ) );
|
||||
|
||||
for (int i = 0; i < NUM_DEBRIS_POFS; i++)
|
||||
{
|
||||
modelp[i] = NULL;
|
||||
model_num[i] = -1;
|
||||
pof_files[i][0] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define AF_USED (1<<0) // Set means used.
|
||||
|
||||
typedef struct asteroid {
|
||||
int flags;
|
||||
int objnum;
|
||||
int model_instance_num;
|
||||
int asteroid_type; // 0..MAX_DEBRIS_TYPES
|
||||
int asteroid_subtype; // Index in asteroid_info for modelnum and modelp
|
||||
int check_for_wrap; // timestamp to check for asteroid wrapping around field
|
||||
int check_for_collide; // timestamp to check for asteroid colliding with escort ships
|
||||
int final_death_time; // timestamp to swap in new models after explosion starts
|
||||
int collide_objnum; // set to objnum that asteroid will be impacting soon
|
||||
int collide_objsig; // object signature corresponding to collide_objnum
|
||||
vec3d death_hit_pos; // hit pos that caused death
|
||||
int target_objnum; // Yes, hah! Asteroids can have targets. See asteroid_aim_at_target().
|
||||
} asteroid;
|
||||
|
||||
|
||||
// TYPEDEF FOR DEBRIS TYPE
|
||||
typedef enum {
|
||||
DG_ASTEROID,
|
||||
DG_SHIP
|
||||
} debris_genre_t;
|
||||
|
||||
// TYPEDEF FOR FIELD TYPE
|
||||
typedef enum {
|
||||
FT_ACTIVE,
|
||||
FT_PASSIVE
|
||||
} field_type_t;
|
||||
|
||||
typedef struct asteroid_field {
|
||||
vec3d min_bound; // Minimum range of field.
|
||||
vec3d max_bound; // Maximum range of field.
|
||||
float bound_rad;
|
||||
int has_inner_bound;
|
||||
vec3d inner_min_bound;
|
||||
vec3d inner_max_bound;
|
||||
vec3d vel; // Average asteroid moves at this velocity.
|
||||
float speed; // Average speed of field
|
||||
int num_initial_asteroids; // Number of asteroids at creation.
|
||||
field_type_t field_type; // active throws and wraps, passive does not
|
||||
debris_genre_t debris_genre; // type of debris (ship or asteroid) [generic type]
|
||||
int field_debris_type[MAX_ACTIVE_DEBRIS_TYPES]; // one of the debris type defines above
|
||||
} asteroid_field;
|
||||
|
||||
extern SCP_vector< asteroid_info > Asteroid_info;
|
||||
extern asteroid Asteroids[MAX_ASTEROIDS];
|
||||
extern asteroid_field Asteroid_field;
|
||||
|
||||
extern int Num_asteroids;
|
||||
extern int Asteroids_enabled;
|
||||
extern char Asteroid_icon_closeup_model[NAME_LENGTH]; // model for asteroid field briefing icon rendering
|
||||
extern vec3d Asteroid_icon_closeup_position; // closeup position for asteroid field briefing icon rendering
|
||||
extern float Asteroid_icon_closeup_zoom; // zoom position for asteroid field briefing icon rendering
|
||||
|
||||
void asteroid_init();
|
||||
void asteroid_level_init();
|
||||
void asteroid_level_close();
|
||||
void asteroid_create_all();
|
||||
void asteroid_render(object * obj, draw_list *scene);
|
||||
void asteroid_delete( object *asteroid_objp );
|
||||
void asteroid_process_pre( object *asteroid_objp );
|
||||
void asteroid_process_post( object *asteroid_objp);
|
||||
int asteroid_check_collision( object *asteroid_objp, object * other_obj, vec3d * hitpos, collision_info_struct *asteroid_hit_info=NULL );
|
||||
void asteroid_hit( object *pasteroid_objp, object *other_objp, vec3d *hitpos, float damage );
|
||||
int asteroid_count();
|
||||
int asteroid_collide_objnum(object *asteroid_objp);
|
||||
float asteroid_time_to_impact(object *asteroid_objp);
|
||||
void asteroid_show_brackets();
|
||||
void asteroid_target_closest_danger();
|
||||
int asteroid_get_random_in_cone(vec3d *pos, vec3d *dir, float ang, int danger = 0);
|
||||
|
||||
// need to extern for multiplayer
|
||||
void asteroid_sub_create(object *parent_objp, int asteroid_type, vec3d *relvec);
|
||||
|
||||
void asteroid_frame();
|
||||
|
||||
#endif // __ASTEROID_H__
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,168 +0,0 @@
|
||||
// Autopilot.h
|
||||
// Derek Meek
|
||||
// 4-30-2004
|
||||
|
||||
|
||||
|
||||
#if !defined(_AUTOPILOT_H_)
|
||||
#define _AUTOPILOT_H_
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "object/object.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
// milliseconds between updates
|
||||
#define NPS_TICKRATE 125
|
||||
|
||||
#define MAX_NAVPOINTS 8
|
||||
|
||||
#define NP_WAYPOINT 0x0001 // Nav Point is bound to the position of a single node of a waypoint path
|
||||
#define NP_SHIP 0x0002 // Nav Point is bound to the position of a certain ship
|
||||
#define NP_HIDDEN 0x0004 // Nav Point doesn't show on map and isn't selectable
|
||||
#define NP_NOACCESS 0x0008 // Nav Point isn't selectable
|
||||
#define NP_VISITED 0x0100 // Whether we've been within 1,000 meters of this waypoint
|
||||
|
||||
#define NP_NOSELECT ( NP_HIDDEN | NP_NOACCESS )
|
||||
#define NP_VALIDTYPE ( NP_WAYPOINT | NP_SHIP )
|
||||
|
||||
class NavPoint
|
||||
{
|
||||
public:
|
||||
char m_NavName[32];
|
||||
int flags;
|
||||
|
||||
void *target_obj;
|
||||
int waypoint_num; //only used when flags & NP_WAYPOINT
|
||||
|
||||
vec3d *GetPosition();
|
||||
char* GetInternalName();
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_NavName[0] = 0;
|
||||
flags = 0;
|
||||
|
||||
target_obj = NULL;
|
||||
waypoint_num = -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define NP_MSG_FAIL_NOSEL 0
|
||||
#define NP_MSG_FAIL_GLIDING 1
|
||||
#define NP_MSG_FAIL_TOCLOSE 2
|
||||
#define NP_MSG_FAIL_HOSTILES 3
|
||||
#define NP_MSG_MISC_LINKED 4
|
||||
#define NP_MSG_FAIL_HAZARD 5
|
||||
#define NP_MSG_FAIL_SUPPORT_PRESENT 6
|
||||
#define NP_MSG_FAIL_SUPPORT_WORKING 7
|
||||
#define NP_NUM_MESSAGES 8
|
||||
|
||||
struct NavMessage
|
||||
{
|
||||
char message[256];
|
||||
char filename[256]; // can be ""
|
||||
};
|
||||
|
||||
extern bool AutoPilotEngaged;
|
||||
extern int CurrentNav;
|
||||
extern NavPoint Navs[MAX_NAVPOINTS];
|
||||
extern NavMessage NavMsgs[NP_NUM_MESSAGES];
|
||||
extern int LockAPConv;
|
||||
extern SCP_map<int,int> autopilot_wings;
|
||||
|
||||
// Cycles through the NavPoint List
|
||||
bool Sel_NextNav();
|
||||
|
||||
|
||||
// Tell us if autopilot is allowed
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within AutopilotMinEnemyDistance meters
|
||||
// * No asteroids within AutopilotMinAsteroidDistance meters
|
||||
// * Destination > 1,000 meters away
|
||||
// * Support ship not present or is actively leaving
|
||||
bool CanAutopilot(vec3d targetPos, bool send_msg=false);
|
||||
|
||||
// Check if autopilot is allowed at player's current position
|
||||
// See CanAutopilot(vec3d, bool) for more information
|
||||
inline bool CanAutopilot(bool send_msg=false) { return CanAutopilot(Player_obj->pos, send_msg); }
|
||||
|
||||
// Engages autopilot
|
||||
// This does:
|
||||
// * Checks if Autopilot is allowed. See CanAutopilot() for conditions.
|
||||
// * Control switched from player to AI
|
||||
// * Time compression to 32x
|
||||
// * Tell AI to fly to targeted Nav Point (for all nav-status wings/ships)
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
// Returns false if autopilot cannot be started. True otherwise.
|
||||
bool StartAutopilot();
|
||||
|
||||
// Disengages autopilot
|
||||
// this does:
|
||||
// * Time compression to 1x
|
||||
// * Delete AI nav goal
|
||||
// * Control switched from AI to player
|
||||
void EndAutoPilot();
|
||||
|
||||
|
||||
// Checks for changes every NPS_TICKRATE milliseconds
|
||||
// Checks:
|
||||
// * if we've gotten close enough to a nav point for it to be counted as "Visited"
|
||||
// * If we're current AutoNavigating it checks if we need to autodisengage
|
||||
void NavSystem_Do();
|
||||
|
||||
|
||||
// Inits the Nav System
|
||||
void NavSystem_Init();
|
||||
|
||||
// parse autopilot.tbl
|
||||
void parse_autopilot_table(char *filename);
|
||||
|
||||
// Finds a Nav point by name
|
||||
int FindNav(char *Nav);
|
||||
|
||||
// Selects a Nav point by name
|
||||
void SelectNav(char *Nav);
|
||||
|
||||
// Deselects any navpoint selected.
|
||||
void DeselectNav();
|
||||
|
||||
// Set A Nav point to "ZERO"
|
||||
void ZeroNav(int i);
|
||||
|
||||
// Removes a Nav
|
||||
bool DelNavPoint(char *Nav);
|
||||
bool DelNavPoint(int nav);
|
||||
|
||||
// adds a Nav
|
||||
bool AddNav_Ship(char *Nav, char *TargetName, int flags);
|
||||
bool AddNav_Waypoint(char *Nav, char *WP_Path, int node, int flags);
|
||||
|
||||
//Change Flags
|
||||
bool Nav_Alt_Flags(char *Nav, int flags);
|
||||
|
||||
// Sexp Accessors
|
||||
bool Nav_Set_Flag(char *Nav, int flag);
|
||||
bool Nav_UnSet_Flag(char *Nav, int flag);
|
||||
|
||||
bool Nav_Set_Hidden(char *Nav);
|
||||
bool Nav_Set_NoAccess(char *Nav);
|
||||
bool Nav_Set_Visited(char *Nav);
|
||||
|
||||
bool Nav_UnSet_Hidden(char *Nav);
|
||||
bool Nav_UnSet_NoAccess(char *Nav);
|
||||
bool Nav_UnSet_Visited(char *Nav);
|
||||
|
||||
// Useful functions
|
||||
unsigned int DistanceTo(char *nav);
|
||||
unsigned int DistanceTo(int nav);
|
||||
|
||||
bool IsVisited(char *nav);
|
||||
bool IsVisited(int nav);
|
||||
|
||||
void send_autopilot_msg(char *msg, char *snd=NULL);
|
||||
void send_autopilot_msgID(int msgid);
|
||||
#endif
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bm_examples.cpp
|
||||
* This file contains example code for using bmpman.
|
||||
*/
|
||||
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "graphics/2d.h"
|
||||
|
||||
void bm_create_example() {
|
||||
static int test_inited = 0;
|
||||
static int test_bmp;
|
||||
static uint test_bmp_data[128 * 64];
|
||||
|
||||
if (!test_inited) {
|
||||
test_inited = 1;
|
||||
// Create the new bitmap and fill in its data.
|
||||
// When you're done with it completely, call
|
||||
// bm_release to free up the bitmap handle
|
||||
test_bmp = bm_create(32, 128, 64, test_bmp_data);
|
||||
int i, j;
|
||||
for (i = 0; i < 64; i++) {
|
||||
for (j = 0; j < 64; j++) {
|
||||
uint r = i * 4;
|
||||
test_bmp_data[j + i * 128] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// page out the data, so that the next bm_lock will convert the new data to
|
||||
// the correct bpp
|
||||
bm_unload(test_bmp);
|
||||
|
||||
// put in new data
|
||||
int x, y;
|
||||
gr_reset_clip();
|
||||
for (y = 0; y < 64; y++) {
|
||||
for (x = 0; x < 128; x++) {
|
||||
test_bmp_data[y * 128 + x] = 15;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the bitmap, the upper left corner is the origin (0, 0)
|
||||
gr_set_bitmap(test_bmp);
|
||||
gr_bitmap(0, 0);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
#ifndef __BM_INTERNAL_H__
|
||||
#define __BM_INTERNAL_H__
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bm_internal.h
|
||||
* These are functions and types used by bmpman and a few others.
|
||||
*
|
||||
* @details It is a "protected" header that requires BMPMAN_INTERNAL to be defined before it can be included. This is to
|
||||
* provide a small measure of safety since this functions can cause problems if not used correctly
|
||||
*/
|
||||
|
||||
#ifndef BMPMAN_INTERNAL
|
||||
#error The file header "bmpman/bm_internal.h" is protected. Make sure you know what you are doing!
|
||||
#endif
|
||||
|
||||
#include "bmpman/bmpman.h"
|
||||
|
||||
union bm_extra_info {
|
||||
struct {
|
||||
// Stuff needed for animations
|
||||
int first_frame; //!< used for animations -- points to index of first frame
|
||||
int num_frames; //!< used for animations -- number of frames in the animation
|
||||
int keyframe; //!< used for animations -- keyframe info
|
||||
float total_time; //!< used for animations -- total animation time (not always derived from num_frames/fps)
|
||||
ubyte fps; //!< used for animations -- frames per second
|
||||
|
||||
struct {
|
||||
// stuff for static animations
|
||||
BM_TYPE type; //!< type for individual images
|
||||
char filename[MAX_FILENAME_LEN]; //!< filename for individual images
|
||||
} eff;
|
||||
struct {
|
||||
bool is_apng; //!< Is this animation an APNG?
|
||||
float frame_delay; //!< cumulative frame delay
|
||||
} apng;
|
||||
} ani;
|
||||
|
||||
struct {
|
||||
// Stuff needed for user bitmaps
|
||||
void* data; //!< For user bitmaps, this is where the data comes from
|
||||
ubyte bpp; //!< For user bitmaps, this is what format the data is
|
||||
ubyte flags; //!< For user bitmaps, Flags passed to bm_create
|
||||
} user;
|
||||
};
|
||||
|
||||
struct bitmap_entry {
|
||||
// identification
|
||||
char filename[MAX_FILENAME_LEN]; //!< filename for this bitmap
|
||||
|
||||
uint signature; //!< a unique signature identifying the data
|
||||
uint palette_checksum; //!< checksum used to be sure bitmap is in current palette
|
||||
int handle; //!< Handle = id*MAX_BITMAPS + bitmapnum
|
||||
int last_used; //!< When this bitmap was last used
|
||||
|
||||
BM_TYPE type; //!< PCX, USER, ANI, etc
|
||||
BM_TYPE comp_type; //!< What sort of compressed type, BM_TYPE_NONE if not compressed
|
||||
signed char ref_count; //!< Number of locks on bitmap. Can't unload unless ref_count is 0.
|
||||
|
||||
int dir_type; //!< which directory this was loaded from (to skip other locations with same name)
|
||||
|
||||
// compressed bitmap stuff (.dds) - RT please take a look at this and tell me if we really need it
|
||||
size_t mem_taken; //!< How much memory does this bitmap use? - UnknownPlayer
|
||||
int num_mipmaps; //!< number of mipmap levels, we need to read all of them
|
||||
|
||||
// Stuff to keep track of usage
|
||||
ubyte preloaded; //!< If set, then this was loaded from the lst file
|
||||
int preload_count; //!< how many times this gets used in game, for unlocking
|
||||
ubyte used_flags; //!< What flags it was accessed thru
|
||||
int load_count;
|
||||
|
||||
bitmap bm; //!< Bitmap info
|
||||
|
||||
bm_extra_info info; //!< Data for animations and user bitmaps
|
||||
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
// bookeeping
|
||||
ubyte used_last_frame; // If set, then it was used last frame
|
||||
ubyte used_this_frame; // If set, then it was used this frame
|
||||
int data_size; // How much data this bitmap uses
|
||||
int used_count; // How many times it was accessed
|
||||
#endif
|
||||
};
|
||||
|
||||
extern bitmap_entry bm_bitmaps[MAX_BITMAPS];
|
||||
|
||||
// image specific lock functions
|
||||
void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_apng( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_pcx( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, int bpp, ubyte flags );
|
||||
|
||||
|
||||
#endif // __BM_INTERNAL_H__
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,701 +0,0 @@
|
||||
#ifndef _BMPMAN_H
|
||||
#define _BMPMAN_H
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bmpman.h
|
||||
* Header file for the bitmap manager (bmpman)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example bm_examples.cpp
|
||||
* @brief This containes examples of bmpman usage
|
||||
*/
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define BMPMAN_NDEBUG //!< Enables BMPMAN debugging code
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup BMPMAN_CONSTANTS Macro constants used in/with bmpman.h
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief How many bitmaps the game can handle
|
||||
*
|
||||
* @attention MAX_BITMAPS shouldn't need to be bumped again. With the fixed bm_release() and it's proper use even the
|
||||
* largest missions should stay under this number. With the largest retail missions and wasteful content we should
|
||||
* still have about 20% of the slots free. If it still goes over then it's something the artists need to fix.
|
||||
* For instance the Terran Mara fighter, with -spec and -glow and using the Shinepack, needs 117 bitmap slots alone.
|
||||
* 111 of those is just for the glowmaps. This number can be greatly reduced if the number of ani frames for another
|
||||
* LOD than LOD0 has fewer or no ani frames. A 37 frame glow ani for LOD2 is little more than a waste of resources.
|
||||
* Future reports of texture corruption should be initially approached with content as the cause and not code.
|
||||
* If anything we could/should reduce MAX_BITMAPS in the future. Where it's at now should accomidate even the
|
||||
* largest mods. -- Taylor
|
||||
*/
|
||||
#define MAX_BITMAPS 4750
|
||||
|
||||
// Flag positions for bitmap.flags
|
||||
// ***** NOTE: bitmap.flags is an 8-bit value, no more BMP_TEX_* flags can be added unless the type is changed!! ******
|
||||
#define BMP_AABITMAP (1<<0) //!< antialiased bitmap
|
||||
#define BMP_TEX_XPARENT (1<<1) //!< transparent texture
|
||||
#define BMP_TEX_OTHER (1<<2) //!< so we can identify all "normal" textures
|
||||
#define BMP_TEX_DXT1 (1<<3) //!< dxt1 compressed 8r8g8b1a (24bit)
|
||||
#define BMP_TEX_DXT3 (1<<4) //!< dxt3 compressed 8r8g8b4a (32bit)
|
||||
#define BMP_TEX_DXT5 (1<<5) //!< dxt5 compressed 8r8g8b8a (32bit)
|
||||
#define BMP_TEX_CUBEMAP (1<<6) //!< a texture made for cubic environment map
|
||||
|
||||
// Combined flags
|
||||
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 ) //!< Compressed textures
|
||||
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER ) //!< Non-compressed textures
|
||||
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP ) //!< Any texture
|
||||
|
||||
// Flag positions for bitmap.type
|
||||
#define BMP_FLAG_RENDER_TARGET_STATIC (1<<0) //!< Texture is a static type
|
||||
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1) //!< Texture is a dynamic type (animation)
|
||||
#define BMP_FLAG_CUBEMAP (1<<2) //!< Texture is a cubemap
|
||||
|
||||
// Bitmap types
|
||||
enum BM_TYPE
|
||||
{
|
||||
BM_TYPE_NONE = 0, //!< No type
|
||||
BM_TYPE_USER, //!< in-memory
|
||||
BM_TYPE_PCX, //!< PCX
|
||||
BM_TYPE_TGA, //!< 16 or 32 bit targa
|
||||
BM_TYPE_DDS, //!< generic identifier for DDS
|
||||
BM_TYPE_PNG, //!< PNG
|
||||
BM_TYPE_JPG, //!< 32 bit jpeg
|
||||
BM_TYPE_ANI, //!< in-house ANI format
|
||||
BM_TYPE_EFF, //!< specifies any type of animated image, the EFF itself is just text
|
||||
|
||||
// special types
|
||||
BM_TYPE_RENDER_TARGET_STATIC, //!< 24/32 bit setup internally as a static render target
|
||||
BM_TYPE_RENDER_TARGET_DYNAMIC, //!< 24/32 bit setup internally as a dynamic render target
|
||||
|
||||
// Compressed types (bitmap.c_type)
|
||||
BM_TYPE_DXT1, //!< 24 bit with switchable alpha
|
||||
BM_TYPE_DXT3, //!< 32 bit with 4 bit alpha
|
||||
BM_TYPE_DXT5, //!< 32 bit with 8 bit alpha
|
||||
BM_TYPE_CUBEMAP_DDS, //!< generic DDS cubemap (uncompressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT1, //!< 24-bit cubemap (compressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT3, //!< 32-bit cubemap (compressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT5 //!< 32-bit cubemap (compressed cubemap surface)
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
struct bitmap
|
||||
{
|
||||
short w; //!< Width, in number of pixels
|
||||
short h; //!< Height, in number of pixels
|
||||
short rowsize; //!< What you need to add to go to next row
|
||||
int bpp; //!< Requested bitdepth of each pixel. ( 7, 8, 15, 16, 24, 32)
|
||||
int true_bpp; //!< The image's actual bitdepth
|
||||
ubyte flags; //!< Various texture type flags. @see BMPMAN_CONSTANTS
|
||||
ptr_u data; //!< Pointer to data, or maybe offset into VRAM.
|
||||
ubyte *palette; /**< @brief Pointer to this bitmap's palette (if it has one).
|
||||
* @details If BMP_NO_PALETTE_MAP flag is cleared, this palette just points to the screen palette. (gr_palette)
|
||||
*/
|
||||
};
|
||||
|
||||
extern int bm_texture_ram; //!< how many bytes of textures are used.
|
||||
|
||||
extern int Bm_paging; //!< Bool type that indicates if BMPMAN is currently paging.
|
||||
|
||||
extern const BM_TYPE bm_type_list[]; //!< List of valid bitmap types
|
||||
extern const char *bm_ext_list[]; //!< List of extensions for those types
|
||||
extern const int BM_NUM_TYPES; //!< Calculated number of bitmap types
|
||||
extern const BM_TYPE bm_ani_type_list[]; //!< List of valid bitmap animation types
|
||||
extern const char *bm_ani_ext_list[]; //!< List of extensions for those types
|
||||
extern const int BM_ANI_NUM_TYPES; //!< Calculated number of bitmap animation types
|
||||
|
||||
extern int GLOWMAP; //!< References a map that is a fully lit version of its index -Bobboau
|
||||
extern int SPECMAP; //!< References a map that is for specular mapping -Bobboau
|
||||
extern int ENVMAP; //!< References a map that is for environment mapping -Bobboau
|
||||
extern int NORMMAP; //!< Normal mapping
|
||||
extern int HEIGHTMAP; //!< Height map for normal mapping
|
||||
extern int MISCMAP; //!< Utility map, to be utilized for various things shader authors can come up with
|
||||
|
||||
/**
|
||||
* @brief Initilizes the bitmap manager
|
||||
*/
|
||||
void bm_init();
|
||||
|
||||
/**
|
||||
* @brief Closes the bitmap manager, freeing any allocated memory used by bitmaps. Is called at program close.
|
||||
*/
|
||||
void bm_close();
|
||||
|
||||
/**
|
||||
* Gets the cache slot of the bitmap indexed by handle.
|
||||
*
|
||||
* @details if the bitmap is an ani, gets the first frame
|
||||
*
|
||||
* @returns The cache slot index of the bitmap if handle is valid
|
||||
*
|
||||
* @note If the handle is invalid, an Assert() fails
|
||||
*/
|
||||
int bm_get_cache_slot(int bitmap_id, int separate_ani_frames);
|
||||
|
||||
/**
|
||||
* @brief Gets the next available bitmap slot.
|
||||
*/
|
||||
int bm_get_next_handle();
|
||||
|
||||
#define BMP_FLAG_RENDER_TARGET_STATIC (1<<0)
|
||||
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1)
|
||||
#define BMP_FLAG_CUBEMAP (1<<2)
|
||||
#define BMP_FLAG_RENDER_TARGET_MIPMAP (1<<3)
|
||||
|
||||
/**
|
||||
* @brief Allocates memory for the given handle.
|
||||
*
|
||||
* @returns A pointer to the allocated vm if successful,
|
||||
* @returns Null, if unsuccessful
|
||||
*
|
||||
* @note z64 - This function looks fishy. Not only is handle not used in release builds, but bm_bitmaps[handle].size
|
||||
* and bm_texture_size aren't modified unless this is a debug build
|
||||
*/
|
||||
void *bm_malloc(int handle, int size);
|
||||
|
||||
/**
|
||||
* @brief (DEBUG) Similar to bm_malloc, but only updates how much memory is used
|
||||
*
|
||||
* @note z64 - Also fishy (see bm_malloc)
|
||||
*/
|
||||
void bm_update_memory_used(int n, int size);
|
||||
|
||||
class bitmap_lookup {
|
||||
ubyte *Bitmap_data;
|
||||
|
||||
int Width;
|
||||
int Height;
|
||||
int Num_channels;
|
||||
|
||||
float map_texture_address(float address);
|
||||
public:
|
||||
bitmap_lookup(int bitmap_num);
|
||||
~bitmap_lookup();
|
||||
|
||||
bool valid();
|
||||
|
||||
float get_channel_red(float u, float v);
|
||||
float get_channel_green(float u, float v);
|
||||
float get_channel_blue(float u, float v);
|
||||
float get_channel_alpha(float u, float v);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Loads a bitmap so we can draw with it later.
|
||||
*
|
||||
* @param filename
|
||||
*
|
||||
* @returns The bitmap number if successful, else
|
||||
* @returns a negative value if not
|
||||
*/
|
||||
int bm_load(const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Loads a bitmap so we can draw with it later. (Preferred version)
|
||||
*
|
||||
* @param filename
|
||||
*
|
||||
* @returns The bitmap number if successful, else
|
||||
* @returns a negative value if not
|
||||
*/
|
||||
int bm_load(const SCP_string& filename);
|
||||
|
||||
/**
|
||||
* @brief Reloads a bitmap as a duplicate.
|
||||
*
|
||||
* @details This function basically allows you to load a bitmap which already exists (by filename). This is useful
|
||||
* because in some cases we need to have a bitmap which is locked in screen format _and_ texture format, such as
|
||||
* the pilot pics and squad logos
|
||||
*
|
||||
* @param filename
|
||||
*
|
||||
* @returns The bitmap number if successful, else
|
||||
* @returns a negative value if not
|
||||
*/
|
||||
int bm_load_duplicate(const char *filename);
|
||||
|
||||
/**
|
||||
* Loads a bitmap which exists somewhere in the RAM.
|
||||
*
|
||||
* @param bpp The bitdepth of the bitmap
|
||||
* @param w The width of the bitmap
|
||||
* @param h The height of the bitmap
|
||||
* @param[in] data The bitmap's data glob
|
||||
* @param flags
|
||||
*
|
||||
* @note The used RAM cannot be freed until bm_release is called on the created bitmap
|
||||
*/
|
||||
int bm_create(int bpp, int w, int h, void *data = NULL, int flags = 0);
|
||||
|
||||
/**
|
||||
* @brief Unloads a bitmap's data, but not the bitmap info
|
||||
*
|
||||
* @details The bm number (n) may be reused once this function has been called on it. However, it will have to be paged
|
||||
* in the next time it is locked.
|
||||
|
||||
* @param handle The index number of the bitmap to free
|
||||
* @param clear_render_targets If true, release a render target
|
||||
* @param nodebug If true, exclude certain debug messages
|
||||
*
|
||||
* @returns 0 if not successful,
|
||||
* @returns 1 if successful
|
||||
*/
|
||||
int bm_unload(int handle, int clear_render_targets = 0, bool nodebug = false);
|
||||
|
||||
/**
|
||||
* @brief Quickly unloads a bitmap's data, ignoring the load_count
|
||||
*
|
||||
* @details Similar to bm_unload(), except that it can be safely used to free data without worrying about load_count.
|
||||
* It's safe to use in relation to bm_release() and in gr_*_texture functions
|
||||
*
|
||||
* @param handle The bm number of the bitmap to free
|
||||
* @param clear_render_targets If true, release a render target
|
||||
*
|
||||
* @note bm_free_data_fast() is used here and NOT bm_free_data()
|
||||
*/
|
||||
int bm_unload_fast(int handle, int clear_render_targets = 0);
|
||||
|
||||
/**
|
||||
* @brief Frees both a bitmap's data and it's associated slot.
|
||||
*
|
||||
* @details Once called, the bm number 'n' cannot be used until bm_load or bm_create is re-inits the slot.
|
||||
*
|
||||
* @param handle The index number of the bitmap to release
|
||||
* @param clear_render_targets If nonzero, also release render targets
|
||||
*
|
||||
* @returns 1 on success,
|
||||
* @returns 0 otherwise
|
||||
*
|
||||
* @note If the passed handle is that of an ANI, it frees EVERY frame. Be sure to only pass the handle of the first frame!
|
||||
*
|
||||
* @todo upgrade return type and clear_render_targets type to bools
|
||||
*/
|
||||
int bm_release(int handle, int clear_render_targets = 0);
|
||||
|
||||
/**
|
||||
* @brief Loads a bitmap sequance so we can draw with it.
|
||||
*
|
||||
* @param[in] filename
|
||||
* @param[out] nframes If non-null, set to the number of frames the animation has
|
||||
* @param[out] fps If non-null, set to the fps of this animation
|
||||
* @param[out] keyframe if non null, set to the keyframe index of this animation
|
||||
* @param[in] can_drop_frames If set, allows dropped frames
|
||||
* @param[in] dir_type Directory type
|
||||
*
|
||||
* @returns The bm number of the first bitmap in the sequence if successful, or
|
||||
* @returns A negative value if unsuccessful
|
||||
*/
|
||||
int bm_load_animation(const char *filename, int *nframes = nullptr, int *fps = nullptr, int *keyframe = nullptr, float *total_time = nullptr, bool can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
|
||||
|
||||
/**
|
||||
* @brief Loads either animation (bm_load_animation) or still image (bm_load)
|
||||
*
|
||||
* @param[in] filename
|
||||
* @param[out] nframes If non-null and loading was successful, set to the number of frames the animation has
|
||||
* @param[out] fps If non-null and loading was successful, set to the fps of this animation
|
||||
* @param[out] keyframe if non null and loading was successful, set to the keyframe index of this animation
|
||||
* @param[in] can_drop_frames
|
||||
* @param[in] dir_type
|
||||
*
|
||||
* @returns The bm number of the first bitmap in the sequence if successful, or
|
||||
* @returns A negative value if unsuccessful
|
||||
*/
|
||||
int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, bool can_drop_frames = false, int dir_type = CF_TYPE_ANY);
|
||||
|
||||
/**
|
||||
* @brief Locks down the bitmap indexed by bitmapnum.
|
||||
*
|
||||
* @details Also converts the bitmap to the appropriate format specified by bpp and flags. Only lock a bitmap when you
|
||||
* need it!
|
||||
*
|
||||
* @param handle The number indexing the desired bitmap
|
||||
* @param bpp The desired bpp of the bitmep
|
||||
* @param flags The desired bitmap format
|
||||
* @param nodebug
|
||||
|
||||
* @returns A pointer to the bitmap that's valid until bm_unlock is called if successful, or
|
||||
* @returns NULL if unsuccessful
|
||||
*/
|
||||
bitmap* bm_lock(int handle, int bpp, ubyte flags, bool nodebug = false);
|
||||
|
||||
/**
|
||||
* @brief Returns a unique signiature for the bitmap indexed by handle
|
||||
*
|
||||
* @details A signature will change when the bitmap's data changes
|
||||
*/
|
||||
uint bm_get_signature(int handle);
|
||||
|
||||
/**
|
||||
* @brief Returns the image type of the given bitmap handle
|
||||
*/
|
||||
BM_TYPE bm_get_type(int handle);
|
||||
|
||||
/**
|
||||
* @brief Unlocks a bitmap
|
||||
*
|
||||
* @details Decrements the ref_count member of the bitmap_entry struct, A bitmap can only be unloaded when the
|
||||
* ref_count is 0
|
||||
*/
|
||||
void bm_unlock(int handle);
|
||||
|
||||
/**
|
||||
* @brief Checks if the bitmap indexed by handle is valid
|
||||
*
|
||||
* @details Some early known false or out of range handles (such as negative) are checked within
|
||||
* an initial routine pass, followed by a more thorough check routine to ensure the
|
||||
* series of bitmaps within the bm_bitmaps[] structure have not become invalid.
|
||||
*
|
||||
* @returns Nonzero if valid, else
|
||||
* @returns Zero otherwise
|
||||
*
|
||||
* @todo z64 - Returned value is essentially a bool type, need to check all caller functions to see if it can safely
|
||||
* be updated to reflect this
|
||||
*/
|
||||
int bm_is_valid(int handle);
|
||||
|
||||
/**
|
||||
* @brief Gets info on the bitmap indexed by handle.
|
||||
*
|
||||
* @param[out] w If non-null, gets the width
|
||||
* @param[out] h If non-null, gets the heigth
|
||||
* @param[out] flags If non-null, gets the flags
|
||||
* @param[out] nframs If non-null, gets the nframes
|
||||
* @param[out] fps If non-null, gets the fps
|
||||
*
|
||||
* @returns The handle on success, or
|
||||
* @returns The handle to the first frame on success, or
|
||||
* @returns -1 on failure
|
||||
*/
|
||||
int bm_get_info(int handle, int *w = NULL, int * h = NULL, ubyte * flags = NULL, int *nframes = NULL, int *fps = NULL);
|
||||
|
||||
/**
|
||||
* @brief Gets the filename of the bitmap indexed by handle
|
||||
*
|
||||
* @param[out] filename The filename of the bitmap, if successful. Is set to an empty string if unseccessful
|
||||
*
|
||||
* @todo z64 - maybe deprecate this in favor of an SCP_string version
|
||||
*/
|
||||
void bm_get_filename(int bitmapnum, char *filename);
|
||||
|
||||
/**
|
||||
* @brief Gets the filename of the bitmap indexed by handle, which must exist.
|
||||
*
|
||||
* @details If the bitmap does not exist (i.e. the handle is invalid), then an Assertion halts program execution.
|
||||
*
|
||||
* @returns A const char* to the filename of the bitmap
|
||||
*
|
||||
* @todo z64 - maybe deprecate this in favor of an SCP_string version.
|
||||
* @todo z64 - maybe combine this with the other bm_get_filename function like so:
|
||||
* void bm_get_filename(int handle, SCP_string *filename, bool must_exist = false);
|
||||
*/
|
||||
const char *bm_get_filename(int handle);
|
||||
|
||||
/**
|
||||
* @brief Loads all data for all bitmaps that have been requested to be loaded
|
||||
*
|
||||
* @note This function is not defined.
|
||||
*/
|
||||
void bm_gfx_load_all();
|
||||
|
||||
/**
|
||||
* @brief Unloads all used bitmaps, should only ever be called by game_shutdown()
|
||||
*
|
||||
* @todo Maybe move this declaration into bmpman.cpp and then extern this function within game_shutdown() to
|
||||
* ensure it only ever gets called there.
|
||||
*/
|
||||
void bm_unload_all();
|
||||
|
||||
/**
|
||||
* @brief Gets the palette for a given bitmap indexed by handle, and optionally the filename
|
||||
*
|
||||
* @param[out] pal Is set to reference the bitmap's palette
|
||||
* @param[out] name (optional) Is set to the bitmap's filename
|
||||
*
|
||||
* @todo Maybe get rid of the optional filename and have the callers call bm_get_filename. Less efficient, however.
|
||||
*/
|
||||
void bm_get_palette(int handle, ubyte *pal, char *name);
|
||||
|
||||
/**
|
||||
* @brief Hack to get a pixel from a bitmap
|
||||
*
|
||||
* @details only works good in 8bpp mode
|
||||
*
|
||||
* @note This function is not defined.
|
||||
*/
|
||||
void bm_gfx_get_pixel(int bitmap, float u, float v, ubyte *r, ubyte *g, ubyte *b);
|
||||
|
||||
/**
|
||||
* @brief (DEBUG) Gets memory size, in bytes, of the locked bitmaps
|
||||
*
|
||||
* @details Both params are non-optional, and must be non-null. There's currently no safety checks on either.
|
||||
*
|
||||
* @param ntotal[out] Memory size, in bytes, of the locked bitmaps
|
||||
* @param nnew[out] Memory size, in bytes, of the bitmaps that were locked since the last frame
|
||||
*
|
||||
* @note This is a debug function, and is undefined within release builds
|
||||
*/
|
||||
void bm_get_frame_usage(int *ntotal, int *nnew);
|
||||
|
||||
/**
|
||||
* @brief Reloads an existing bmpman slot with different bitmap
|
||||
*
|
||||
* @param[in] filename The filename of the image to load
|
||||
*
|
||||
* @returns The bitmap handle on success, or
|
||||
* @returns A negative value on failure
|
||||
*
|
||||
* @note This should only be used if you are certain the new picture is the same type, has same dimensions, etc.
|
||||
*/
|
||||
int bm_reload(int bitmap_handle, const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Tells bmpman to start keeping track of what bitmaps are used where
|
||||
*/
|
||||
void bm_page_in_start();
|
||||
|
||||
/**
|
||||
* @brief Tells bmpman to stop paging (?)
|
||||
*/
|
||||
void bm_page_in_stop();
|
||||
|
||||
// Paging code in a library should call these functions
|
||||
// in its page in function.
|
||||
|
||||
/**
|
||||
* @brief Marks a texture as being used for this level
|
||||
*
|
||||
* @param[in] num_frames If specified, assumes this is an animated texture
|
||||
*/
|
||||
void bm_page_in_texture(int bitmapnum, int num_frames = 0);
|
||||
|
||||
/**
|
||||
* @brief Marks a textures as being used for level and is transparant
|
||||
*
|
||||
* @param[in] num_frames If specified, assumes this is an animated texture
|
||||
*/
|
||||
void bm_page_in_xparent_texture(int bitmapnum, int num_frames = 1);
|
||||
|
||||
/**
|
||||
* @brief Marks a texture as being used for this level, and is anti-aliased
|
||||
*
|
||||
* @param[in] num_frames If specified, assumes this is an animated texture
|
||||
*/
|
||||
void bm_page_in_aabitmap(int bitmapnum, int num_frames = 1);
|
||||
|
||||
/**
|
||||
* @brief Unloads the bitmap indexed by handle that was previously paged-in
|
||||
*
|
||||
* @returns 0 If the bitmap had already been released, or
|
||||
* @returns 0 If the handle is invalid, or
|
||||
* @returns 1 If successful
|
||||
*/
|
||||
bool bm_page_out(int handle);
|
||||
|
||||
/**
|
||||
* @brief Sets BMPMAN's memory mode
|
||||
*
|
||||
* @details 0 = High memory;
|
||||
* 1 = Low memory (loads every other frame of ani's);
|
||||
* 2 = Debug low memory (only use first frame of each ani)
|
||||
*
|
||||
* @todo This should use an enum, or instead allow an arbitrary number to drop frames (like 1/2, 1/3, etc.)
|
||||
*/
|
||||
void bm_set_low_mem(int mode);
|
||||
|
||||
/**
|
||||
* @brief Sets bm_set_components and bm_get_components to reference screen format functions
|
||||
*/
|
||||
void BM_SELECT_SCREEN_FORMAT();
|
||||
|
||||
/**
|
||||
* @brief Sets bm_set_components and bm_get_components to reference texture format functions
|
||||
*/
|
||||
void BM_SELECT_TEX_FORMAT();
|
||||
|
||||
/**
|
||||
* @brief Sets bm_set_components and bm_get_components to reference texture format functions (with alpha)
|
||||
*/
|
||||
void BM_SELECT_ALPHA_TEX_FORMAT();
|
||||
|
||||
/**
|
||||
* @brief Functional pointer that references any of the bm_set_components functions.
|
||||
*
|
||||
* @details The bm_set_components functions packs the RGBA values into the ubyte array referenced by pixel, whose
|
||||
* format differs according to its bpp value and presence of an alpha channel. The RGBA values are scaled accordingly.
|
||||
*
|
||||
* @param[out] pixel The pixel to set
|
||||
* @param[in] r Red value (may not be NULL)
|
||||
* @param[in] g Green value (may not be NULL)
|
||||
* @param[in] b Blue value (may not be NULL)
|
||||
* @param[in] a Alpha value (currently ignored)
|
||||
*
|
||||
* @note z64 - These functions were made predating the introduction of C++ classes, and are basically the equivalent
|
||||
* of Pixel::set(ubyte *r, ubyte *b, ubyte *g). The original comment mentions that any of the rgba params may be
|
||||
* NULL, but this is by far _NOT_ the case, as a NULL value will cause undefined behavior (really really bad chroma
|
||||
* corruption)
|
||||
*
|
||||
* @note These functions assume the incoming bitdepth will always be >= to the outgoing bitdepth of the pixel. Should
|
||||
* the incoming bitdepth be lower, the outgoing values will appear darker than they should be
|
||||
*/
|
||||
extern void(*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Functional pointer that references any of the bm_set_components_32 functions.
|
||||
*
|
||||
* @details The bm_set_components functions packs the RGBA values into the ubyte array referenced by pixel, whose
|
||||
* format differs according to its bpp value and presence of an alpha channel. The RGBA values are scaled accordingly.
|
||||
*
|
||||
* @see bm_set_components
|
||||
*/
|
||||
extern void(*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Sets the 16bpp screen pixel to the specified RGBA value
|
||||
*
|
||||
* @see bm_set_components
|
||||
*/
|
||||
void bm_set_components_argb_16_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Sets the 32bpp screen pixel to the specified RGBA value
|
||||
*
|
||||
* @see bm_set_components
|
||||
*/
|
||||
void bm_set_components_argb_32_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Sets the 16bpp texture pixel to the specified RGBA value
|
||||
*
|
||||
* @see bm_set_components
|
||||
*/
|
||||
void bm_set_components_argb_16_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Sets the 32bpp texture pixel to the specified RGBA value
|
||||
*
|
||||
* @see bm_set_components
|
||||
*/
|
||||
void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
/**
|
||||
* @brief Gets the RGBA components of a pixel according to the selected mode
|
||||
*
|
||||
* @see BM_SELECT_SCREEN_FORMAT() BM_SELECT_TEX_FORMAT() BM_SELECT_ALPHA_TEX_FORMAT()
|
||||
*/
|
||||
void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
extern int UNLITMAP; //this holds a reference to a map that is optional used instead of the base map for unlit rendering
|
||||
extern int GLOWMAP; //this holds a reference to a map that is a fully lit version of its index -Bobboau
|
||||
extern int SPECMAP; //this holds a reference to a map that is for specular mapping -Bobboau
|
||||
extern int SPECGLOSSMAP; //this holds a reference to a map that is for specular mapping -Bobboau
|
||||
extern int ENVMAP; //this holds a reference to a map that is for environment mapping -Bobboau
|
||||
extern int NORMMAP; // normal mapping
|
||||
extern int HEIGHTMAP; // height map for normal mapping
|
||||
extern int AMBIENTMAP; // ambient occluion map. red channel affects ambient lighting, green channel affects diffuse and specular
|
||||
extern int MISCMAP; // Utility map, to be utilized for various things shader authors can come up with
|
||||
|
||||
/**
|
||||
* @brief Returns the compression type of the bitmap indexed by handle
|
||||
*/
|
||||
int bm_is_compressed(int handle);
|
||||
|
||||
/**
|
||||
* @brief Gets the correct TCACHE_TYPE for compressed graphics (uncompressed are assumed TCACHE_TYPE_NORMAL)
|
||||
*/
|
||||
int bm_get_tcache_type(int handle);
|
||||
|
||||
/**
|
||||
* @brief Gets the size, in bytes, taken up by the bitmap indexed by handle
|
||||
*/
|
||||
size_t bm_get_size(int handle);
|
||||
|
||||
/**
|
||||
* @brief Gets the number of mipmaps of the indexed texture
|
||||
*/
|
||||
int bm_get_num_mipmaps(int handle);
|
||||
|
||||
/**
|
||||
* @brief Checks to see if the indexed bitmap has an alpha channel
|
||||
*
|
||||
* @note Currently just checks if the bitmap is 32bpp and is not a .PCX
|
||||
*/
|
||||
bool bm_has_alpha_channel(int handle);
|
||||
|
||||
/**
|
||||
* @brief (DEBUG) Prints all loaded bitmaps to an outwindow
|
||||
*/
|
||||
void bm_print_bitmaps();
|
||||
|
||||
/**
|
||||
* @brief Creates a render target as close to the desired resolution as possible.
|
||||
*
|
||||
* @returns the handle of an avilable render target if successful, or
|
||||
* @returns -1 if not successful
|
||||
*
|
||||
* @note BM_FLAG_RENDER_TARGET_STATIC are drawn once/infrequently, while BM_FLAG_RENDER_TARGET_DYNAMIC are drawn roughly once every frame
|
||||
*/
|
||||
int bm_make_render_target(int width, int height, int flags);
|
||||
|
||||
/**
|
||||
* @brief Checks to see if the given bitmap indexed by handle is a render target
|
||||
*
|
||||
* @returns The render type (BM_TYPE) if it is a render target, or
|
||||
* @returns 0 if it is not
|
||||
*/
|
||||
int bm_is_render_target(int handle);
|
||||
|
||||
/**
|
||||
* @brief (GR function) Calls gr_bm_set_render target for the given bitmap indexed by handle
|
||||
*
|
||||
* @returns true if successful, or
|
||||
* @returns false if unsuccessful
|
||||
*/
|
||||
bool bm_set_render_target(int handle, int face = -1);
|
||||
|
||||
/**
|
||||
* @brief Loads and parses an .EFF
|
||||
*
|
||||
* @param[in] filename The filename of the .EFF
|
||||
* @param[in] dir_type
|
||||
* @param[out] nframes (optional) If given, is set to the number of frames this .EFF has
|
||||
* @param[out] nfps (optional) If given, is set to the fps of this .EFF
|
||||
* @param[out] key (optional) If given, is set to the keyframe index of this .EFF
|
||||
* @param[out] type (optional) If given, is set to the BM_TYPE of the .EFF
|
||||
*
|
||||
* @returns true If successful
|
||||
* @returns false If not successful
|
||||
*/
|
||||
bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, BM_TYPE *type);
|
||||
|
||||
/**
|
||||
* @brief Calculates & returns the current frame of an animation
|
||||
*
|
||||
* @param[in] frame1_handle Handle of the animation
|
||||
* @param[in] elapsed_time Time in seconds since the animation started playing
|
||||
* @param[in] loop (optional) specifies if the animation should loop, default is false which causes animation to hold on the last frame
|
||||
* @param[in] divisor (optional) if greater than zero, elapsed time will be divided by this value i.e. allows "percentage complete" to be used to determine the frame instead of the animations total time derived from fps * frames
|
||||
*
|
||||
* @returns current frame of the animation (range is zero to the number of frames minus one)
|
||||
*/
|
||||
int bm_get_anim_frame(const int frame1_handle, float elapsed_time, const float divisor = 0.0f, const bool loop = false);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,178 +0,0 @@
|
||||
|
||||
#ifndef _CAMERA_H
|
||||
#define _CAMERA_H
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "object/object.h"
|
||||
#include "physics/physics.h" //for avd
|
||||
|
||||
#include <string>
|
||||
|
||||
#define CAM_STATIONARY_FOV (1<<0)
|
||||
#define CAM_STATIONARY_ORI (1<<1)
|
||||
#define CAM_STATIONARY_POS (1<<2)
|
||||
#define CAM_DEFAULT_FLAGS 0
|
||||
|
||||
class camera
|
||||
{
|
||||
friend class avd_camera;
|
||||
protected:
|
||||
char name[NAME_LENGTH];
|
||||
int sig;
|
||||
int flags;
|
||||
|
||||
object_h object_host;
|
||||
int object_host_submodel;
|
||||
|
||||
object_h object_target;
|
||||
int object_target_submodel;
|
||||
|
||||
void (*func_custom_position)(camera *cam, vec3d *pos);
|
||||
void (*func_custom_orientation)(camera *cam, matrix *ori);
|
||||
|
||||
avd_movement fov;
|
||||
avd_movement pos_x;
|
||||
avd_movement pos_y;
|
||||
avd_movement pos_z;
|
||||
avd_movement ori[9];
|
||||
|
||||
//Cache stuff
|
||||
float c_fov;
|
||||
vec3d c_pos;
|
||||
matrix c_ori;
|
||||
public:
|
||||
camera(char *in_name=NULL, int in_signature=-1);
|
||||
~camera();
|
||||
void clear();
|
||||
void reset();
|
||||
|
||||
//Set
|
||||
void set_name(char *in_name);
|
||||
|
||||
void set_object_host(object *objp, int n_object_host_submodel = -1);
|
||||
void set_object_target(object *objp, int n_object_target_submodel = -1);
|
||||
|
||||
void set_custom_position_function(void (*n_func_custom_position)(camera *cam, vec3d *pos));
|
||||
void set_custom_orientation_function(void (*n_func_custom_orientation)(camera *cam, matrix *ori));
|
||||
|
||||
void set_fov(float in_fov, float in_fov_time = 0.0f, float in_fov_acceleration_time = 0.0f, float in_deceleration_time = 0.0f);
|
||||
|
||||
void set_position(vec3d *in_position = NULL, float in_translation_time = 0.0f, float in_translation_acceleration_time = 0.0f, float in_translation_deceleration_time = 0.0f, float in_end_velocity = 0.0f);
|
||||
void set_translation_velocity(vec3d *in_velocity, float in_acceleration_time = 0.0f);
|
||||
|
||||
void set_rotation(matrix *in_orientation = NULL, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation(angles *in_angles, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation_facing(vec3d *in_target, float in_rotation_time = 0.0f, float in_rotation_acceleration_time = 0.0f, float in_rotation_deceleration_time = 0.0f);
|
||||
void set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time = 0.0f);
|
||||
|
||||
//Get
|
||||
char *get_name() {return name;}
|
||||
int get_signature() {return sig;}
|
||||
object *get_object_host();
|
||||
int get_object_host_submodel();
|
||||
object *get_object_target();
|
||||
int get_object_target_submodel();
|
||||
float get_fov();
|
||||
void get_info(vec3d *position, matrix *orientation);
|
||||
|
||||
//Is
|
||||
bool is_empty(){return sig < 0;}
|
||||
|
||||
//Do
|
||||
void do_frame(float in_frametime);
|
||||
};
|
||||
|
||||
class warp_camera
|
||||
{
|
||||
private:
|
||||
float c_time;
|
||||
float c_damping;
|
||||
|
||||
vec3d c_vel;
|
||||
vec3d c_desired_vel;
|
||||
|
||||
vec3d c_pos;
|
||||
matrix c_ori;
|
||||
public:
|
||||
warp_camera();
|
||||
warp_camera(object *objp);
|
||||
void reset();
|
||||
|
||||
void set_position(vec3d *in_pos);
|
||||
void set_rotation(matrix *in_ori);
|
||||
void set_velocity(vec3d *in_vel, bool instantaneous);
|
||||
|
||||
void do_frame(float in_frametime);
|
||||
|
||||
void get_info(vec3d *position, matrix *orientation);
|
||||
};
|
||||
|
||||
extern warp_camera Warp_camera;
|
||||
|
||||
class subtitle
|
||||
{
|
||||
private:
|
||||
void clone(const subtitle &sub);
|
||||
|
||||
SCP_vector<SCP_string> text_lines;
|
||||
struct { int x; int y; } text_pos;
|
||||
|
||||
float display_time;
|
||||
float fade_time;
|
||||
color text_color;
|
||||
int text_fontnum;
|
||||
|
||||
//Done with set
|
||||
char imageanim[MAX_FILENAME_LEN];
|
||||
int image_id;
|
||||
struct { int x; int y; int w; int h; } image_pos;
|
||||
|
||||
//Time this has been displayed
|
||||
float time_displayed;
|
||||
|
||||
//When to end it
|
||||
float time_displayed_end;
|
||||
|
||||
bool post_shaded;
|
||||
public:
|
||||
subtitle(int in_x_pos, int in_y_pos, const char* in_text = NULL, const char* in_imageanim = NULL,
|
||||
float in_display_time = 0, float in_fade_time = 0.0f, const color *in_text_color = NULL, int in_text_fontnum = -1,
|
||||
bool center_x = false, bool center_y = false, int in_width = 0, int in_height = 0, bool post_shaded=false);
|
||||
~subtitle();
|
||||
|
||||
subtitle(const subtitle &sub) { clone(sub); }
|
||||
const subtitle &operator=(const subtitle &sub);
|
||||
|
||||
void do_frame(float frametime);
|
||||
bool is_post_shaded( ) { return post_shaded; }
|
||||
};
|
||||
|
||||
//Some global stuff
|
||||
extern SCP_vector<subtitle> Subtitles;
|
||||
extern float VIEWER_ZOOM_DEFAULT;
|
||||
extern float Sexp_fov;
|
||||
|
||||
//Helpful functions
|
||||
void cam_init();
|
||||
void cam_close();
|
||||
void cam_do_frame(float frametime);
|
||||
camid cam_create(char *n_name=NULL, vec3d *n_pos=NULL, matrix *n_ori=NULL, object *n_object=NULL, int n_submodel_parent=-1);
|
||||
camid cam_create(char *n_name, vec3d *n_pos, vec3d *n_norm, object *n_object=NULL, int n_submodel_parent=-1);
|
||||
void cam_delete(camid cid);
|
||||
bool cam_set_camera(camid cid);
|
||||
void cam_reset_camera();
|
||||
camid cam_lookup(char *name);
|
||||
camid cam_get_camera(uint index);
|
||||
camid cam_get_current();
|
||||
uint cam_get_num();
|
||||
|
||||
void get_turret_cam_pos(camera *cam, vec3d *pos);
|
||||
void get_turret_cam_orient(camera *cam, matrix *ori);
|
||||
|
||||
void subtitles_close();
|
||||
void subtitles_do_frame(float frametime);
|
||||
void subtitles_do_frame_post_shaded(float frametime);
|
||||
|
||||
#endif // _CAMERA_H
|
||||
@@ -1,397 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __CFILE_H__
|
||||
#define __CFILE_H__
|
||||
|
||||
|
||||
#include <time.h>
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
#define CF_EOF (-1)
|
||||
|
||||
#define CF_SEEK_SET (0)
|
||||
#define CF_SEEK_CUR (1)
|
||||
#define CF_SEEK_END (2)
|
||||
|
||||
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 {
|
||||
time_t write_time;
|
||||
} file_list_info;
|
||||
|
||||
|
||||
#define CF_MAX_FILENAME_LENGTH 32 // Includes null terminater, so real length is 31
|
||||
#define CF_MAX_PATHNAME_LENGTH 256 // Includes null terminater, so real length is 255
|
||||
|
||||
#define CF_TYPE_ANY -1 // Used to check in any directory
|
||||
|
||||
#define CF_TYPE_INVALID 0
|
||||
#define CF_TYPE_ROOT 1 // Root must be 1!!
|
||||
#define CF_TYPE_DATA 2
|
||||
#define CF_TYPE_MAPS 3
|
||||
#define CF_TYPE_TEXT 4
|
||||
#define CF_TYPE_MODELS 5
|
||||
#define CF_TYPE_TABLES 6
|
||||
#define CF_TYPE_SOUNDS 7
|
||||
#define CF_TYPE_SOUNDS_8B22K 8
|
||||
#define CF_TYPE_SOUNDS_16B11K 9
|
||||
#define CF_TYPE_VOICE 10
|
||||
#define CF_TYPE_VOICE_BRIEFINGS 11
|
||||
#define CF_TYPE_VOICE_CMD_BRIEF 12
|
||||
#define CF_TYPE_VOICE_DEBRIEFINGS 13
|
||||
#define CF_TYPE_VOICE_PERSONAS 14
|
||||
#define CF_TYPE_VOICE_SPECIAL 15
|
||||
#define CF_TYPE_VOICE_TRAINING 16
|
||||
#define CF_TYPE_MUSIC 17
|
||||
#define CF_TYPE_MOVIES 18
|
||||
#define CF_TYPE_INTERFACE 19
|
||||
#define CF_TYPE_FONT 20
|
||||
#define CF_TYPE_EFFECTS 21
|
||||
#define CF_TYPE_HUD 22
|
||||
#define CF_TYPE_PLAYERS 23
|
||||
#define CF_TYPE_PLAYER_IMAGES 24
|
||||
#define CF_TYPE_SQUAD_IMAGES 25
|
||||
#define CF_TYPE_SINGLE_PLAYERS 26
|
||||
#define CF_TYPE_MULTI_PLAYERS 27
|
||||
#define CF_TYPE_CACHE 28
|
||||
#define CF_TYPE_MULTI_CACHE 29
|
||||
#define CF_TYPE_MISSIONS 30
|
||||
#define CF_TYPE_CONFIG 31
|
||||
#define CF_TYPE_DEMOS 32
|
||||
#define CF_TYPE_CBANIMS 33
|
||||
#define CF_TYPE_INTEL_ANIMS 34
|
||||
#define CF_TYPE_SCRIPTS 35
|
||||
#define CF_TYPE_FICTION 36
|
||||
|
||||
#define CF_MAX_PATH_TYPES 37 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
|
||||
|
||||
// TRUE if type is specified and valid
|
||||
#define CF_TYPE_SPECIFIED(path_type) (((path_type)>CF_TYPE_INVALID) && ((path_type)<CF_MAX_PATH_TYPES))
|
||||
|
||||
// #define's for the type parameter in cfopen.
|
||||
#define CFILE_NORMAL 0 // open file normally
|
||||
#define CFILE_MEMORY_MAPPED (1<<0) // open file as a memory-mapped file
|
||||
|
||||
#define CF_SORT_NONE 0
|
||||
#define CF_SORT_NAME 1
|
||||
#define CF_SORT_TIME 2
|
||||
#define CF_SORT_REVERSE 3
|
||||
|
||||
#define cfread_fix(file) (fix)cfread_int(file)
|
||||
#define cfwrite_fix(i,file) cfwrite_int(i,file)
|
||||
|
||||
// callback function used for get_file_list() to filter files to be added to list. Return 1
|
||||
// to add file to list, or 0 to not add it.
|
||||
extern int (*Get_file_list_filter)(const char *filename);
|
||||
|
||||
// extra check for child directory under CF_TYPE_*
|
||||
// NOTE: if specified cf_get_file_list() will not search pack files!
|
||||
// NOTE: specified string must not contain ':' or spaces or begin with DIR_SEPARATOR!
|
||||
extern const char *Get_file_list_child;
|
||||
|
||||
// cfile directory. valid after cfile_init() returns successfully
|
||||
#define CFILE_ROOT_DIRECTORY_LEN 256
|
||||
extern char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
extern char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
#ifdef SCP_UNIX
|
||||
extern char Cfile_user_dir_legacy[CFILE_ROOT_DIRECTORY_LEN];
|
||||
#endif
|
||||
|
||||
//================= LOW-LEVEL FUNCTIONS ==================
|
||||
int cfile_init(const char *exe_dir, const char *cdrom_dir=NULL);
|
||||
|
||||
// Call this if pack files got added or removed or the
|
||||
// cdrom changed. This will refresh the list of filenames
|
||||
// stored in packfiles and on the cdrom.
|
||||
void cfile_refresh();
|
||||
|
||||
// add an extension to a filename if it doesn't already have it
|
||||
char *cf_add_ext(const char *filename, const char *ext);
|
||||
|
||||
// return CF_TYPE (directory location type) of a CFILE you called cfopen() successfully on.
|
||||
int cf_get_dir_type(CFILE *cfile);
|
||||
|
||||
|
||||
// Opens the file. If no path is given, use the extension to look into the
|
||||
// default path. If mode is NULL, delete the file.
|
||||
CFILE *_cfopen(const char* source_file, int line, const char *filename, const char *mode,
|
||||
int type = CFILE_NORMAL, int dir_type = CF_TYPE_ANY, bool localize = false);
|
||||
#define cfopen(...) _cfopen(LOCATION, __VA_ARGS__) // Pass source location to the function
|
||||
|
||||
// like cfopen(), but it accepts a fully qualified path only (ie, the result of a cf_find_file_location() call)
|
||||
// NOTE: only supports reading files!!
|
||||
CFILE *_cfopen_special(const char* source_file, int line, const char *file_path, const char *mode,
|
||||
const int size, const int offset, int dir_type = CF_TYPE_ANY);
|
||||
#define cfopen_special(...) _cfopen_special(LOCATION, __VA_ARGS__) // Pass source location to the function
|
||||
|
||||
// Flush the open file buffer
|
||||
int cflush(CFILE *cfile);
|
||||
|
||||
// version number of opened file. Will be 0 unless you put something else here after you
|
||||
// open a file. Once set, you can use minimum version numbers with the read functions.
|
||||
void cf_set_version( CFILE * cfile, int version );
|
||||
|
||||
// will throw an error if cfread*() functions read past this mark
|
||||
// converted to raw offsets when used, but gets passed actual length from current position
|
||||
// setting 'len' to zero will disable the check
|
||||
void cf_set_max_read_len(CFILE *cfile, size_t len);
|
||||
|
||||
// Deletes a file. Returns 0 on error, 1 if successful
|
||||
int cf_delete(const char *filename, int dir_type);
|
||||
|
||||
// Same as _access function to read a file's access bits
|
||||
int cf_access(const char *filename, int dir_type, int mode);
|
||||
|
||||
// Returns 1 if the file exists, 0 if not.
|
||||
// Checks only the file system.
|
||||
int cf_exists(const char *filename, int dir_type);
|
||||
|
||||
// Goober5000
|
||||
// Returns 1 if the file exists, 0 if not.
|
||||
// Checks both the file system and the VPs.
|
||||
int cf_exists_full(const char *filename, int dir_type);
|
||||
// check num_ext worth of ext_list extensions
|
||||
int cf_exists_full_ext(const char *filename, int dir_type, const int num_ext, const char **ext_list);
|
||||
|
||||
// ctmpfile() opens a temporary file stream. File is deleted automatically when closed
|
||||
CFILE *ctmpfile();
|
||||
|
||||
// Closes the file
|
||||
int cfclose(CFILE *cfile);
|
||||
|
||||
//Checks if the given handle is valid
|
||||
int cf_is_valid(CFILE *cfile);
|
||||
|
||||
// Returns size of file...
|
||||
int cfilelength(CFILE *fp);
|
||||
|
||||
// Reads data
|
||||
int cfread(void *buf, int elsize, int nelem, CFILE *fp);
|
||||
|
||||
// cfwrite() writes to the file
|
||||
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
|
||||
// Reads/writes RLE compressed data.
|
||||
int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile);
|
||||
int cfwrite_compressed(void *param_buf, int param_elsize, int param_nelem, CFILE *cfile);
|
||||
|
||||
// Moves the file pointer
|
||||
int cfseek(CFILE *fp, int offset, int where);
|
||||
|
||||
// Returns current position of file.
|
||||
int cftell(CFILE *fp);
|
||||
|
||||
// cfputc() writes a character to a file
|
||||
int cfputc(int c, CFILE *cfile);
|
||||
|
||||
// cfputs() writes a string to a file
|
||||
int cfputs(const char *str, CFILE *cfile);
|
||||
|
||||
// cfgetc() reads a character to a file
|
||||
int cfgetc(CFILE *cfile);
|
||||
|
||||
// cfgets() reads a string from a file
|
||||
char *cfgets(char *buf, int n, CFILE *cfile);
|
||||
|
||||
// cfeof() Tests for end-of-file on a stream
|
||||
int cfeof(CFILE *cfile);
|
||||
|
||||
// Return the data pointer associated with the CFILE structure (for memory mapped files)
|
||||
void *cf_returndata(CFILE *cfile);
|
||||
|
||||
// get the 2 byte checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_short(const char *filename, ushort *chksum, int max_size = -1, int cf_type = CF_TYPE_ANY );
|
||||
|
||||
// get the 2 byte checksum of the passed file - return 0 if operation failed, 1 if succeeded
|
||||
// NOTE : preserves current file position
|
||||
int cf_chksum_short(CFILE *file, ushort *chksum, int max_size = -1);
|
||||
|
||||
// get the 32 bit CRC checksum of the passed filename - return 0 if operation failed, 1 if succeeded
|
||||
int cf_chksum_long(const char *filename, uint *chksum, int max_size = -1, int cf_type = CF_TYPE_ANY );
|
||||
|
||||
// get the 32 bit CRC checksum of the passed file - return 0 if operation failed, 1 if succeeded
|
||||
// NOTE : preserves current file position
|
||||
int cf_chksum_long(CFILE *file, uint *chksum, int max_size = -1);
|
||||
|
||||
int cf_chksum_pack(const char *filename, uint *chk_long, bool full = false);
|
||||
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
ushort cf_add_chksum_short(ushort seed, ubyte *buffer, int size);
|
||||
|
||||
// update cur_chksum with the chksum of the new_data of size new_data_size
|
||||
uint cf_add_chksum_long(uint seed, ubyte *buffer, int size);
|
||||
|
||||
// convenient for misc checksumming purposes ------------------------------------------
|
||||
|
||||
//================= HIGH LEVEL FUNCTIONS ==================
|
||||
int cfexist(const char *filename); // Returns true if file exists on disk (1) or in hog (2).
|
||||
|
||||
// rename a file, utilizing the extension to determine where file is.
|
||||
#define CF_RENAME_SUCCESS 0 // successfully renamed the file
|
||||
#define CF_RENAME_FAIL_ACCESS 1 // new name could not be created
|
||||
#define CF_RENAME_FAIL_EXIST 2 // old name does not exist
|
||||
int cf_rename(const char *old_name, const char *name, int type = CF_TYPE_ANY );
|
||||
|
||||
// changes the attributes of a file
|
||||
void cf_attrib(const char *name, int set, int clear, int type);
|
||||
|
||||
// flush (delete all files in) the passed directory (by type), return the # of files deleted
|
||||
// NOTE : WILL NOT DELETE READ-ONLY FILES
|
||||
int cfile_flush_dir(int type);
|
||||
|
||||
// functions for reading from cfile
|
||||
// These are all high level, built up from
|
||||
// cfread.
|
||||
int cfgetc(CFILE *fp);
|
||||
char *cfgets(char *buf, size_t n, CFILE *fp);
|
||||
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);
|
||||
void cfread_angles(angles *ang, CFILE *file, int ver = 0, angles *deflt = NULL);
|
||||
|
||||
// Reads variable length, null-termined string. Will only read up
|
||||
// to n characters.
|
||||
void cfread_string(char *buf,int n, CFILE *file);
|
||||
/**
|
||||
* @brief Read a fixed length string that is not null-terminated, with the length stored in file
|
||||
*
|
||||
* @param buf Pre-allocated array to store string
|
||||
* @param n Size of pre-allocated array
|
||||
* @param file File to read from
|
||||
*
|
||||
* @note Appends NULL character to string (buf)
|
||||
*/
|
||||
void cfread_string_len(char *buf,int n, CFILE *file);
|
||||
|
||||
// functions for writing cfiles
|
||||
int cfwrite_char(char c, CFILE *file);
|
||||
int cfwrite_float(float f, CFILE *file);
|
||||
int cfwrite_int(int i, CFILE *file);
|
||||
int cfwrite_uint(uint i, CFILE *file);
|
||||
int cfwrite_short(short s, CFILE *file);
|
||||
int cfwrite_ushort(ushort s, CFILE *file);
|
||||
int cfwrite_ubyte(ubyte u, CFILE *file);
|
||||
int cfwrite_vector(vec3d *vec, CFILE *file);
|
||||
int cfwrite_angles(angles *ang, CFILE *file);
|
||||
|
||||
// writes variable length, null-termined string.
|
||||
int cfwrite_string(const char *buf, CFILE *file);
|
||||
|
||||
/**
|
||||
* @brief Write a fixed length string (not including its null terminator), with the length stored in file
|
||||
*
|
||||
* @param buf String to write to file
|
||||
* @param file File to write to
|
||||
*/
|
||||
int cfwrite_string_len(const char *buf, CFILE *file);
|
||||
|
||||
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, const char *filter, int sort = CF_SORT_NONE, SCP_vector<file_list_info> *info = NULL );
|
||||
int cf_get_file_list( int max, char **list, int type, const char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
int cf_get_file_list_preallocated( int max, char arr[][MAX_FILENAME_LEN], char **list, int type, const char *filter, int sort = CF_SORT_NONE, file_list_info *info = NULL );
|
||||
void cf_sort_filenames( int n, char **list, int sort, file_list_info *info = NULL );
|
||||
void cf_sort_filenames( SCP_vector<SCP_string> &list, int sort, SCP_vector<file_list_info> *info = NULL );
|
||||
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files.
|
||||
// Input: filespace - Filename & extension
|
||||
// pathtype - See CF_TYPE_ defines in CFILE.H
|
||||
// max_out - Maximum string size to be stuffed into pack_filename
|
||||
// Output: pack_filename - Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns 0.
|
||||
int cf_find_file_location( const char *filespec, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize = false);
|
||||
|
||||
// Searches for a file. Follows all rules and precedence and searches
|
||||
// CD's and pack files. Searches all locations in order for first filename using ext filter list.
|
||||
// Input: filename - Filename & extension
|
||||
// ext_num - number of extensions to look for
|
||||
// ext_list - extension filter list
|
||||
// pathtype - See CF_TYPE_ defines in CFILE.H
|
||||
// max_out - Maximum string length that should be stuffed into pack_filename
|
||||
// Output: pack_filename - Absolute path and filename of this file. Could be a packfile or the actual file.
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns -1, else returns offset into ext_list.
|
||||
// (NOTE: This function is exponentially slow, so don't use it unless truely needed!!)
|
||||
int cf_find_file_location_ext(const char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out = 0, char *pack_filename = NULL, int *size = NULL, int *offset = NULL, bool localize = false);
|
||||
|
||||
// Functions to change directories
|
||||
int cfile_chdir(const char *dir);
|
||||
|
||||
#ifdef _WIN32
|
||||
int cfile_chdrive(int DriveNum, int flag);
|
||||
#endif
|
||||
|
||||
// push current directory on a 'stack' (so we can restore it) and change the directory
|
||||
int cfile_push_chdir(int type);
|
||||
|
||||
// restore directory on top of the stack
|
||||
int cfile_pop_dir();
|
||||
|
||||
namespace cfile
|
||||
{
|
||||
// exceptions and other errors
|
||||
class cfile_error : public std::exception
|
||||
{
|
||||
public:
|
||||
cfile_error() : m_excuse("CFILE Exception")
|
||||
{
|
||||
}
|
||||
|
||||
cfile_error(const std::string &excuse) : m_excuse(excuse)
|
||||
{
|
||||
}
|
||||
|
||||
~cfile_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return m_excuse.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_excuse;
|
||||
};
|
||||
|
||||
class max_read_length : public cfile_error
|
||||
{
|
||||
public:
|
||||
max_read_length(const std::string &excuse) : cfile_error(excuse)
|
||||
{
|
||||
}
|
||||
|
||||
max_read_length() : cfile_error("Attempted to read beyond length limit")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __CFILE_H__ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _CFILESYSTEM_H
|
||||
#define _CFILESYSTEM_H
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
// Builds a list of all the files
|
||||
void cf_build_secondary_filelist( const char *cdrom_path );
|
||||
void cf_free_secondary_filelist();
|
||||
|
||||
// Internal stuff
|
||||
typedef struct cf_pathtype {
|
||||
int index; // To verify that the CF_TYPE define is correctly indexed into this array
|
||||
char *path; // Path relative to FreeSpace root, has ending backslash.
|
||||
char *extensions; // Extensions used in this pathtype, separated by spaces
|
||||
int parent_index; // Index of this directory's parent. Used for creating directories when writing.
|
||||
} cf_pathtype;
|
||||
|
||||
// During cfile_init, verify that Pathtypes[n].index == n for each item
|
||||
extern cf_pathtype Pathtypes[CF_MAX_PATH_TYPES];
|
||||
|
||||
// Returns the default storage path for files given a
|
||||
// particular pathtype. In other words, the path to
|
||||
// the unpacked, non-cd'd, stored on hard drive path.
|
||||
// If filename isn't null it will also tack the filename
|
||||
// on the end, creating a completely valid filename.
|
||||
// Input: pathtype - CF_TYPE_??
|
||||
// path_max - Maximum characters in the path
|
||||
// filename - optional, if set, tacks the filename onto end of path.
|
||||
// Output: path - Fully qualified pathname.
|
||||
//Returns 0 if result would be too long (invalid result)
|
||||
int cf_create_default_path_string( char *path, uint path_max, int pathtype, const char *filename=NULL, bool localize = false);
|
||||
int cf_create_default_path_string( SCP_string &path, int pathtype, const char *filename=NULL, bool localize = false );
|
||||
|
||||
#endif //_CFILESYSTEM_H
|
||||
@@ -1,432 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <conio.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
static int data_error;
|
||||
static int no_dir;
|
||||
|
||||
// right out of pstypes.h but we don't want to use the INTEL_INT macro here
|
||||
// since it would require SDL which isn't used on WIN32 platforms
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define INT_SWAP(x) ( \
|
||||
(x << 24) | \
|
||||
(((ulong)x) >> 24) | \
|
||||
((x & 0x0000ff00) << 8) | \
|
||||
((x & 0x00ff0000) >> 8) \
|
||||
)
|
||||
#else
|
||||
#define INT_SWAP(x) (x)
|
||||
#endif
|
||||
|
||||
|
||||
size_t fswrite_int(int *wint, FILE *stream)
|
||||
{
|
||||
int tmp = *wint;
|
||||
tmp = INT_SWAP(tmp);
|
||||
|
||||
return fwrite(&tmp, 1, sizeof(int), stream);
|
||||
}
|
||||
|
||||
unsigned int Total_size=16; // Start with size of header
|
||||
unsigned int Num_files =0;
|
||||
FILE *fp_out = NULL;
|
||||
FILE *fp_out_hdr = NULL;
|
||||
|
||||
typedef struct vp_header {
|
||||
char id[4];
|
||||
int version;
|
||||
int index_offset;
|
||||
int num_files;
|
||||
} vp_header;
|
||||
|
||||
//vp_header Vp_header;
|
||||
|
||||
char archive_dat[1024];
|
||||
char archive_hdr[1024];
|
||||
|
||||
#define BLOCK_SIZE (1024*1024)
|
||||
#define VERSION_NUMBER 2;
|
||||
|
||||
char tmp_data[BLOCK_SIZE]; // 1 MB
|
||||
|
||||
void write_header()
|
||||
{
|
||||
int ver = VERSION_NUMBER;
|
||||
|
||||
fseek(fp_out, 0, SEEK_SET);
|
||||
fwrite("VPVP", 1, 4, fp_out);
|
||||
fswrite_int(&ver, fp_out);
|
||||
fswrite_int((int*)&Total_size, fp_out);
|
||||
fswrite_int((int*)&Num_files, fp_out);
|
||||
}
|
||||
|
||||
int write_index(char *hf, char *df)
|
||||
{
|
||||
FILE *h = NULL, *d = NULL;
|
||||
unsigned int i;
|
||||
|
||||
h = fopen(hf, "rb");
|
||||
d = fopen(df, "a+b");
|
||||
|
||||
if ( (h == NULL) || (d == NULL) )
|
||||
{
|
||||
if ( h )
|
||||
fclose( h );
|
||||
if ( d )
|
||||
fclose( d );
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < Num_files; i++) {
|
||||
fread(tmp_data, 32+4+4+4, 1, h);
|
||||
fwrite(tmp_data, 32+4+4+4, 1, d);
|
||||
}
|
||||
|
||||
fclose(h);
|
||||
fclose(d);
|
||||
|
||||
unlink(hf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pack_file( char *filespec, char *filename, int filesize, _fs_time_t time_write )
|
||||
{
|
||||
char path[1024];
|
||||
|
||||
if ( strstr( filename, ".vp" )) {
|
||||
// Don't pack yourself!!
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strstr( filename, ".hdr" )) {
|
||||
// Don't pack yourself!!
|
||||
return;
|
||||
}
|
||||
|
||||
if ( filesize == 0 ) {
|
||||
// Don't pack 0 length files, screws up directory structure!
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strlen(filename) > 31 ) {
|
||||
printf( "Filename '%s' too long! Skipping...\n", filename );
|
||||
return;
|
||||
}
|
||||
|
||||
memset( path, 0, sizeof(path) );
|
||||
strcpy_s( path, filename );
|
||||
|
||||
fswrite_int( (int*)&Total_size, fp_out_hdr );
|
||||
fswrite_int( &filesize, fp_out_hdr );
|
||||
fwrite( &path, 1, 32, fp_out_hdr );
|
||||
fswrite_int( (int*)&time_write, fp_out_hdr );
|
||||
|
||||
Total_size += filesize;
|
||||
Num_files++;
|
||||
|
||||
printf( "Packing %s%s%s...", filespec, DIR_SEPARATOR_STR, filename );
|
||||
|
||||
sprintf( path, "%s%s%s", filespec, DIR_SEPARATOR_STR, filename );
|
||||
|
||||
|
||||
FILE *fp = fopen( path, "rb" );
|
||||
|
||||
if ( fp == NULL ) {
|
||||
printf( "Error opening '%s'\n", path );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int nbytes, nbytes_read=0;
|
||||
|
||||
do {
|
||||
nbytes = fread( tmp_data, 1, BLOCK_SIZE, fp );
|
||||
if ( nbytes > 0 ) {
|
||||
fwrite( tmp_data, 1, nbytes, fp_out );
|
||||
nbytes_read += nbytes;
|
||||
|
||||
}
|
||||
} while( nbytes > 0 );
|
||||
|
||||
fclose(fp);
|
||||
|
||||
printf( " %d bytes\n", nbytes_read );
|
||||
}
|
||||
|
||||
// This function adds a directory marker to the header file
|
||||
void add_directory( char * dirname)
|
||||
{
|
||||
char path[256];
|
||||
char *pathptr = path;
|
||||
char *tmpptr;
|
||||
int i = 0;
|
||||
|
||||
strcpy_s(path, dirname);
|
||||
|
||||
fswrite_int( (int*)&Total_size, fp_out_hdr);
|
||||
fswrite_int( &i, fp_out_hdr);
|
||||
|
||||
// strip out any directories that this dir is a subdir of
|
||||
while ( (tmpptr = strchr(pathptr, DIR_SEPARATOR_CHAR)) != NULL ) {
|
||||
pathptr = tmpptr+1;
|
||||
}
|
||||
|
||||
fwrite(pathptr, 1, 32, fp_out_hdr);
|
||||
fswrite_int( &i, fp_out_hdr); // timestamp = 0
|
||||
|
||||
Num_files++;
|
||||
}
|
||||
|
||||
void pack_directory( char * filespec)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int find_handle;
|
||||
_finddata_t find;
|
||||
#endif
|
||||
char tmp[512];
|
||||
char tmp1[512];
|
||||
char *ts;
|
||||
|
||||
// strip trailing slash
|
||||
ts = filespec + (strlen(filespec) - 1);
|
||||
while ( (*ts == DIR_SEPARATOR_CHAR) && (ts > filespec) )
|
||||
*ts = '\0';
|
||||
|
||||
strcpy_s( tmp1, filespec );
|
||||
|
||||
add_directory(filespec);
|
||||
strcat( tmp1, DIR_SEPARATOR_STR"*.*" );
|
||||
|
||||
printf( "In dir '%s'\n", tmp1 );
|
||||
|
||||
#ifdef _WIN32
|
||||
find_handle = _findfirst( tmp1, &find );
|
||||
if( find_handle != -1 ) {
|
||||
if ( find.attrib & _A_SUBDIR ) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
|
||||
strcpy_s( tmp, filespec );
|
||||
strcat( tmp, "\\" );
|
||||
strcat( tmp, find.name );
|
||||
pack_directory(tmp);
|
||||
}
|
||||
} else {
|
||||
pack_file( filespec, find.name, find.size, find.time_write );
|
||||
}
|
||||
|
||||
while( !_findnext( find_handle, &find ) ) {
|
||||
if ( find.attrib & _A_SUBDIR ) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
|
||||
strcpy_s( tmp, filespec );
|
||||
strcat( tmp, "\\" );
|
||||
strcat( tmp, find.name );
|
||||
pack_directory(tmp);
|
||||
|
||||
}
|
||||
} else {
|
||||
pack_file( filespec, find.name, find.size, find.time_write );
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
DIR *dirp;
|
||||
struct dirent *dir;
|
||||
|
||||
dirp = opendir (filespec);
|
||||
if ( dirp ) {
|
||||
while ((dir = readdir(dirp)) != NULL) {
|
||||
|
||||
char fn[MAX_PATH];
|
||||
snprintf(fn, MAX_PATH-1, "%s/%s", filespec, dir->d_name);
|
||||
fn[MAX_PATH-1] = 0;
|
||||
|
||||
struct stat buf;
|
||||
if (stat(fn, &buf) == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (strcmp(dir->d_name, ".") == 0) || (strcmp(dir->d_name, "..") == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (strcmp(dir->d_name, ".svn") == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISDIR(buf.st_mode)) {
|
||||
strcpy_s( tmp, filespec );
|
||||
strcat( tmp, "/" );
|
||||
strcat( tmp, dir->d_name );
|
||||
pack_directory(tmp);
|
||||
} else {
|
||||
pack_file( filespec, dir->d_name, buf.st_size, buf.st_mtime );
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
} else {
|
||||
printf("Error: Source directory does not exist!\n");
|
||||
no_dir = 1;
|
||||
}
|
||||
#endif
|
||||
add_directory("..");
|
||||
}
|
||||
|
||||
int verify_directory( char *filespec )
|
||||
{
|
||||
char *ts;
|
||||
char *dd;
|
||||
|
||||
// strip trailing '/'
|
||||
ts = filespec+(strlen(filespec)-1);
|
||||
while ( (*ts == DIR_SEPARATOR_CHAR) && (ts > filespec) )
|
||||
*ts = '\0';
|
||||
|
||||
// make sure last directory is named "data", ignoring case
|
||||
dd = filespec + (strlen(filespec) - 4);
|
||||
if ( stricmp( dd, "data" ) )
|
||||
data_error = 1;
|
||||
|
||||
return data_error;
|
||||
}
|
||||
|
||||
void print_instructions()
|
||||
{
|
||||
printf( "Creates a vp archive out of a FreeSpace data tree.\n\n" );
|
||||
printf( "Usage: cfilearchiver archive_name src_dir\n");
|
||||
printf( "Example: cfilearchiver freespace /tmp/freespace/data\n\n");
|
||||
printf( "Directory structure options:\n" );
|
||||
printf( " Effects (.ani .pcx .neb .tga)\n" );
|
||||
printf( " Fonts (.vf)\n" );
|
||||
printf( " Hud (.ani .pcx .tga\n" );
|
||||
printf( " Interface (.pcx .ani .tga)\n" );
|
||||
printf( " Maps (.pcx .ani .tga)\n" );
|
||||
printf( " Missions (.ntl .ssv), FS1(.fsm .fsc), FS2(.fs2 .fc2)\n" );
|
||||
printf( " Models (.pof)\n" );
|
||||
printf( " Music (.wav)\n" );
|
||||
printf( " Sounds/8b22k (.wav)\n" );
|
||||
printf( " Sounds/16b11k (.wav)\n" );
|
||||
printf( " Tables (.tbl)\n" );
|
||||
printf( " Voice/Briefing (.wav)\n" );
|
||||
printf( " Voice/Command briefings (.wav)\n" );
|
||||
printf( " Voice/Debriefing (.wav)\n" );
|
||||
printf( " Voice/Personas (.wav)\n" );
|
||||
printf( " Voice/Special (.wav)\n" );
|
||||
printf( " Voice/Training (.wav)\n" );
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redefine main() which is something
|
||||
// that we don't want since we don't actually link against SDL, this solves the problem...
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[] )
|
||||
{
|
||||
char archive[1024];
|
||||
char *p;
|
||||
|
||||
if ( argc < 3 ) {
|
||||
#ifdef _WIN32
|
||||
printf( "Usage: %s archive_name src_dir\n", argv[0] );
|
||||
printf( "Example: %s freespace c:\\freespace\\data\n", argv[0] );
|
||||
printf( "Creates an archive named freespace out of the\nfreespace data tree\n" );
|
||||
printf( "Press any key to exit...\n" );
|
||||
getch();
|
||||
return 1;
|
||||
#else
|
||||
print_instructions();
|
||||
#endif
|
||||
}
|
||||
|
||||
strcpy_s( archive, argv[1] );
|
||||
p = strchr( archive, '.' );
|
||||
if (p) *p = 0; // remove extension
|
||||
|
||||
strcpy_s( archive_dat, archive );
|
||||
strcat( archive_dat, ".vp" );
|
||||
|
||||
strcpy_s( archive_hdr, archive );
|
||||
strcat( archive_hdr, ".hdr" );
|
||||
|
||||
fp_out = fopen( archive_dat, "wb" );
|
||||
if ( !fp_out ) {
|
||||
printf( "Couldn't open '%s'!\n", archive_dat );
|
||||
#ifdef _WIN32
|
||||
printf( "Press any key to exit...\n" );
|
||||
getch();
|
||||
return 1;
|
||||
#else
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
fp_out_hdr = fopen( archive_hdr, "wb" );
|
||||
if ( !fp_out_hdr ) {
|
||||
printf( "Couldn't open '%s'!\n", archive_hdr );
|
||||
#ifdef _WIN32
|
||||
printf( "Press any key to exit...\n" );
|
||||
getch();
|
||||
return 1;
|
||||
#else
|
||||
exit(2);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( verify_directory( argv[2] ) != 0 ) {
|
||||
printf("Warning! Last directory must be named \"data\" (not case sensitive)\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
write_header();
|
||||
|
||||
pack_directory( argv[2] );
|
||||
|
||||
// in case the directory doesn't exist
|
||||
if ( no_dir )
|
||||
exit(4);
|
||||
|
||||
write_header();
|
||||
|
||||
fclose(fp_out);
|
||||
fclose(fp_out_hdr);
|
||||
|
||||
printf( "Data files written, appending index...\n" );
|
||||
|
||||
if (!write_index(archive_hdr, archive_dat)) {
|
||||
printf("Error appending index!\n");
|
||||
#ifdef _WIN32
|
||||
printf("Press any key to exit...\n");
|
||||
getch();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "%d total KB.\n", Total_size/1024 );
|
||||
return 0;
|
||||
}
|
||||
@@ -1,497 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Taylor Richards
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GLOBAL FUNCTIONS AND VARIABLES
|
||||
//
|
||||
|
||||
// right out of pstypes.h but we don't want to use the INTEL_INT macro here
|
||||
// since it would require SDL which isn't used on WIN32 platforms
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define INT_SWAP(x) ( \
|
||||
(x << 24) | \
|
||||
(((ulong)x) >> 24) | \
|
||||
((x & 0x0000ff00) << 8) | \
|
||||
((x & 0x00ff0000) >> 8) \
|
||||
)
|
||||
#else
|
||||
#define INT_SWAP(x) (x)
|
||||
#endif
|
||||
|
||||
FILE *fp_in = NULL;
|
||||
FILE *fp_out = NULL;
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 255
|
||||
#endif
|
||||
|
||||
char out_dir[MAX_PATH];
|
||||
|
||||
#define BLOCK_SIZE (1024*1024)
|
||||
|
||||
char tmp_data[BLOCK_SIZE]; // 1 MB
|
||||
|
||||
static int have_index = 0;
|
||||
static int have_header = 0;
|
||||
|
||||
#define ERR_NO_FP_IN 0
|
||||
#define ERR_NO_FP_OUT 1
|
||||
#define ERR_INVALID_VP 2
|
||||
#define ERR_NO_INDEX 3
|
||||
#define ERR_NO_HEADER 4
|
||||
#define ERR_PATH_TOO_LONG 5
|
||||
|
||||
typedef struct vp_header {
|
||||
char id[4]; // 'VPVP'
|
||||
int version;
|
||||
int index_offset; // offset where the file index starts, also a total file data size count
|
||||
int num_files; // number of files, including each step in the directory structure
|
||||
} vp_header;
|
||||
|
||||
vp_header VP_Header;
|
||||
|
||||
typedef struct vp_fileinfo {
|
||||
// stuff that is actually written to the VP
|
||||
int offset; // offset of where this file is in the VP
|
||||
int file_size; // size of file
|
||||
char file_name[CF_MAX_FILENAME_LENGTH]; // filename
|
||||
_fs_time_t write_time; // date/time in _fs_time_t type (a 32-bit version of time_t)
|
||||
|
||||
// not in the VP
|
||||
char file_path[CF_MAX_PATHNAME_LENGTH]; // file path, generated here and not actually in the VP on a per file basis
|
||||
|
||||
vp_fileinfo() {
|
||||
offset = 0;
|
||||
file_size = 0;
|
||||
file_name[0] = '\0';
|
||||
file_path[0] = '\0';
|
||||
write_time = 0;
|
||||
}
|
||||
|
||||
~vp_fileinfo() {}
|
||||
} vp_fileinfo;
|
||||
|
||||
SCP_vector<vp_fileinfo> VP_FileInfo;
|
||||
|
||||
// just like strlwr() but without actually including it here
|
||||
void lowercase(char *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
while (*s) {
|
||||
*s = tolower(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The useful stuff...
|
||||
//
|
||||
|
||||
void print_error(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case ERR_NO_FP_IN:
|
||||
printf("ERROR: The input file (fp_in) is NULL! Exiting...\n");
|
||||
break;
|
||||
case ERR_NO_FP_OUT:
|
||||
printf("ERROR: The output file (fp_out) is NULL! Exiting...\n");
|
||||
break;
|
||||
case ERR_INVALID_VP:
|
||||
printf("ERROR: The specified VP file is invalid! Exiting...\n");
|
||||
break;
|
||||
case ERR_NO_INDEX:
|
||||
printf("ERROR: No file index is available! Exiting...\n");
|
||||
break;
|
||||
case ERR_NO_HEADER:
|
||||
printf("ERROR: No file header is available! Exiting...\n");
|
||||
break;
|
||||
case ERR_PATH_TOO_LONG:
|
||||
printf("ERROR: Path to output directory is too long! Exiting...\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void read_header()
|
||||
{
|
||||
fseek(fp_in, 0, SEEK_SET);
|
||||
fread(&VP_Header.id, 1, 4, fp_in);
|
||||
fread(&VP_Header.version, 1, sizeof(int), fp_in);
|
||||
fread(&VP_Header.index_offset, 1, sizeof(int), fp_in);
|
||||
fread(&VP_Header.num_files, 1, sizeof(int), fp_in);
|
||||
|
||||
VP_Header.version = INT_SWAP(VP_Header.version);
|
||||
VP_Header.index_offset = INT_SWAP(VP_Header.index_offset);
|
||||
VP_Header.num_files = INT_SWAP(VP_Header.num_files);
|
||||
|
||||
// check for a valid id (VPVP)
|
||||
if ( (VP_Header.id[0] != 'V') && (VP_Header.id[1] != 'P') && (VP_Header.id[2] != 'V') && (VP_Header.id[3] != 'P') )
|
||||
print_error(ERR_INVALID_VP);
|
||||
|
||||
// the index_offset needs to be greater than the size of vp_header at the very least and there should be at least one file
|
||||
if ( !(VP_Header.index_offset > (int)sizeof(vp_header)) || !(VP_Header.num_files > 1) )
|
||||
print_error(ERR_INVALID_VP);
|
||||
|
||||
|
||||
have_header = 1;
|
||||
}
|
||||
|
||||
void read_index(int lc = 0)
|
||||
{
|
||||
if (fp_in == NULL)
|
||||
print_error(ERR_NO_FP_IN);
|
||||
else if (!have_header)
|
||||
print_error(ERR_NO_HEADER);
|
||||
|
||||
int i;
|
||||
char path[CF_MAX_PATHNAME_LENGTH];
|
||||
|
||||
fseek(fp_in, VP_Header.index_offset, SEEK_SET);
|
||||
|
||||
memset(path, 0, CF_MAX_PATHNAME_LENGTH);
|
||||
|
||||
for ( i = 0; i < VP_Header.num_files; i++) {
|
||||
vp_fileinfo vpinfo;
|
||||
|
||||
fread(&vpinfo.offset, 1, sizeof(int), fp_in);
|
||||
fread(&vpinfo.file_size, 1, sizeof(int), fp_in);
|
||||
fread(&vpinfo.file_name, 1, CF_MAX_FILENAME_LENGTH, fp_in);
|
||||
fread(&vpinfo.write_time, 1, sizeof(_fs_time_t), fp_in);
|
||||
|
||||
vpinfo.offset = INT_SWAP(vpinfo.offset);
|
||||
vpinfo.file_size = INT_SWAP(vpinfo.file_size);
|
||||
vpinfo.write_time = INT_SWAP(vpinfo.write_time);
|
||||
|
||||
// check if it's a directory and if so then create a path to use for files
|
||||
if (vpinfo.file_size == 0) {
|
||||
// if we get a ".." then drop down in the path
|
||||
if (!strcmp(vpinfo.file_name, "..")) {
|
||||
char *s = strrchr(path, DIR_SEPARATOR_CHAR);
|
||||
|
||||
if (s)
|
||||
*s = '\0';
|
||||
|
||||
// skip, we don't want to add the ".." to the path
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't add the very first directory separator character, easier to clean later
|
||||
if (path[0] != 0)
|
||||
strcat( path, DIR_SEPARATOR_STR );
|
||||
|
||||
// always make directory names lower case for ease of use
|
||||
lowercase( vpinfo.file_name );
|
||||
|
||||
strcat( path, vpinfo.file_name );
|
||||
} // it's a file then
|
||||
else {
|
||||
// lowercase the filename if wanted
|
||||
if (lc == 1)
|
||||
lowercase( vpinfo.file_name );
|
||||
|
||||
strcpy_s( vpinfo.file_path, path );
|
||||
VP_FileInfo.push_back(vpinfo);
|
||||
}
|
||||
}
|
||||
|
||||
have_index = 1;
|
||||
}
|
||||
|
||||
void extract_all_files(char *file)
|
||||
{
|
||||
if (fp_in == NULL)
|
||||
print_error(ERR_NO_FP_IN);
|
||||
else if (!have_header)
|
||||
print_error(ERR_NO_HEADER);
|
||||
else if (!have_index)
|
||||
print_error(ERR_NO_INDEX);
|
||||
|
||||
int status, m_error, nbytes, nbytes_remaining;
|
||||
char path[CF_MAX_PATHNAME_LENGTH+CF_MAX_FILENAME_LENGTH+1]; // path length + filename length + extra NULL
|
||||
char path2[CF_MAX_PATHNAME_LENGTH+CF_MAX_FILENAME_LENGTH+1]; // path length + filename length + extra NULL
|
||||
char *c;
|
||||
ubyte have_outdir = 0;
|
||||
|
||||
int out_len = strlen(out_dir);
|
||||
|
||||
if (out_len > 0)
|
||||
have_outdir = 1;
|
||||
|
||||
printf("VP file extractor - version 0.6\n");
|
||||
printf("\n");
|
||||
|
||||
if (have_outdir) {
|
||||
printf("Output directory: \"%s\"\n", out_dir);
|
||||
}
|
||||
|
||||
printf("Extracting: %s...\n", file);
|
||||
|
||||
for (size_t i = 0; i < VP_FileInfo.size(); i++) {
|
||||
// save the file path to a temp location and recursively make the needed directories
|
||||
if (have_outdir) {
|
||||
if ( (out_len + 1 + strlen(path)) > MAX_PATH-1 )
|
||||
print_error(ERR_PATH_TOO_LONG);
|
||||
|
||||
sprintf(path, "%s%s%s%s", out_dir, DIR_SEPARATOR_STR, VP_FileInfo[i].file_path, DIR_SEPARATOR_STR);
|
||||
} else {
|
||||
sprintf(path, "%s%s", VP_FileInfo[i].file_path, DIR_SEPARATOR_STR);
|
||||
}
|
||||
|
||||
c = &path[0];
|
||||
|
||||
while (c++) {
|
||||
c = strchr(c, DIR_SEPARATOR_CHAR);
|
||||
|
||||
if (c) {
|
||||
*c = '\0'; // NULL at DIR_SEP char
|
||||
|
||||
#ifdef _WIN32
|
||||
status = _mkdir(path);
|
||||
#else
|
||||
status = mkdir(path, 0777);
|
||||
#endif
|
||||
|
||||
m_error = errno;
|
||||
|
||||
if (status && (m_error != EEXIST) ) {
|
||||
printf("Cannot mkdir %s: %s\n", VP_FileInfo[i].file_path, strerror(m_error));
|
||||
continue;
|
||||
}
|
||||
|
||||
*c = DIR_SEPARATOR_CHAR; // replace DIR_SEP char
|
||||
}
|
||||
}
|
||||
|
||||
memset( path, 0, CF_MAX_PATHNAME_LENGTH+CF_MAX_FILENAME_LENGTH+1);
|
||||
|
||||
// start writing out the file
|
||||
fseek(fp_in, VP_FileInfo[i].offset, SEEK_SET);
|
||||
|
||||
sprintf(path, "%s%s%s", VP_FileInfo[i].file_path, DIR_SEPARATOR_STR, VP_FileInfo[i].file_name);
|
||||
|
||||
// this is cheap, I know.
|
||||
if (have_outdir) {
|
||||
if ( (out_len + 1 + strlen(path)) > MAX_PATH-1 )
|
||||
print_error(ERR_PATH_TOO_LONG);
|
||||
|
||||
sprintf(path2, "%s%s%s", out_dir, DIR_SEPARATOR_STR, path);
|
||||
} else {
|
||||
strcpy_s(path2, path);
|
||||
}
|
||||
|
||||
fp_out = fopen(path2, "wb");
|
||||
|
||||
printf(" %s ... ", path);
|
||||
|
||||
if (fp_out == NULL) {
|
||||
printf("can't create file!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
nbytes_remaining = VP_FileInfo[i].file_size;
|
||||
|
||||
while ( nbytes_remaining > 0 ) {
|
||||
nbytes = fread( tmp_data, 1, MIN(BLOCK_SIZE, nbytes_remaining), fp_in );
|
||||
|
||||
if (nbytes > 0) {
|
||||
fwrite( tmp_data, 1, nbytes, fp_out );
|
||||
nbytes_remaining -= nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
printf("done!\n");
|
||||
|
||||
fclose(fp_out);
|
||||
fp_out = NULL;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// TODO: the formatting of this is a bit loco but I don't care enough to make it better...
|
||||
void list_all_files(char *file)
|
||||
{
|
||||
char out_time[20];
|
||||
float one_k = 1024.0f;
|
||||
float one_m = 1048576.0f;
|
||||
char m;
|
||||
float div_by;
|
||||
time_t plat_time;
|
||||
|
||||
// if we don't have an index then bail
|
||||
if (!have_index)
|
||||
print_error(ERR_NO_INDEX);
|
||||
|
||||
|
||||
printf("VP file extractor - version 0.6\n");
|
||||
printf("\n");
|
||||
printf("%s:\n", file);
|
||||
printf("\n");
|
||||
|
||||
printf(" Name Size Offset Date/Time Path\n");
|
||||
printf("-------------------------------------------------------------------------------\n");
|
||||
for (size_t i = 0; i < VP_FileInfo.size(); i++) {
|
||||
plat_time = VP_FileInfo[i].write_time; // gets rid of some platform strangeness this way
|
||||
strftime(out_time, 32, "%F %H:%M", localtime(&plat_time)); // YYYY-mm-dd HH:mm (ISO 8601 date format, 24-hr time)
|
||||
|
||||
if (VP_FileInfo[i].file_size > (int)one_m) {
|
||||
m = 'M';
|
||||
div_by = one_m;
|
||||
} else {
|
||||
m = 'K';
|
||||
div_by = one_k;
|
||||
}
|
||||
|
||||
int len = strlen( VP_FileInfo[i].file_name );
|
||||
printf("%s %*.1f%c %10i %18s %3s%s\n", VP_FileInfo[i].file_name, 33 - len, (float)VP_FileInfo[i].file_size/div_by, m, VP_FileInfo[i].offset, out_time, DIR_SEPARATOR_STR, VP_FileInfo[i].file_path);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
// we use the vector size here since VP_Header.num_files would include each entry
|
||||
// in the directory tree as well as individual files and that artificially inflates
|
||||
// the number of files that we show or would extract
|
||||
printf("Total files: %i\n", (int)VP_FileInfo.size());
|
||||
|
||||
// yeah, I'm just that cheap
|
||||
if (VP_Header.index_offset > (int)one_m) {
|
||||
m = 'M';
|
||||
div_by = one_m;
|
||||
} else {
|
||||
m = 'K';
|
||||
div_by = one_k;
|
||||
}
|
||||
|
||||
printf("Total size: %.1f%c\n", (float)VP_Header.index_offset/div_by, m);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void help()
|
||||
{
|
||||
printf("VP file extractor - version 0.6\n");
|
||||
printf("\n");
|
||||
printf("Usage: cfileextractor [-x | -l] [-L] [-o <dir>] <vp_filename>\n");
|
||||
printf("\n");
|
||||
printf(" Commands (only one at the time):\n");
|
||||
printf(" -x | --extract Extract all files into current directory.\n");
|
||||
printf(" -l | --list List all files in VP archive.\n");
|
||||
printf(" -h | --help Show this help text.\n");
|
||||
printf("\n");
|
||||
printf(" Options:\n");
|
||||
printf(" -L | --lowercase Force all filenames to be lower case.\n");
|
||||
printf(" -o <dir> Extract files to <dir> instead of current directory.\n");
|
||||
printf(" NOTE: No spaces allowed, enclose path in \" \" if needed.\n");
|
||||
printf("\n");
|
||||
printf(" (No command specified will list all files in the VP archive.)\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// we end up #include'ing SDL.h which on Windows and Mac will redefine main() which is something
|
||||
// that we don't want since we don't actually link against SDL, this solves the problem...
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int extract = 0, lc = 0, list = 0;
|
||||
|
||||
if (argc < 2) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// the last option should always be the VP file that we want
|
||||
fp_in = fopen(argv[argc-1], "rb");
|
||||
|
||||
if (fp_in == NULL)
|
||||
print_error(ERR_NO_FP_IN);
|
||||
|
||||
// if the header is invalid then read_header() should exit us out
|
||||
read_header();
|
||||
|
||||
memset(out_dir, 0, MAX_PATH);
|
||||
|
||||
// TODO: add filter based extraction
|
||||
for (int i = 1; i < argc-1; i++) {
|
||||
if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--extract")) {
|
||||
if (list) {
|
||||
help();
|
||||
exit(0);
|
||||
}
|
||||
extract = 1;
|
||||
} else if (!strcmp(argv[i], "-L") || !strcmp(argv[i], "--lowercase")) {
|
||||
lc = 1;
|
||||
} else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--list")) {
|
||||
if (extract) {
|
||||
help();
|
||||
exit(0);
|
||||
}
|
||||
list = 1;
|
||||
} else if ( !strcmp(argv[i], "-o") && (i+1 < argc) && (argv[i+1][0] != '-') ) {
|
||||
strncpy(out_dir, argv[i+1], MAX_PATH-1);
|
||||
i++; // have to increment "i" past the output directory
|
||||
} else {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// read the file index, make all filenames lowercase if wanted
|
||||
read_index( lc );
|
||||
|
||||
if (extract) {
|
||||
extract_all_files( argv[argc-1] );
|
||||
return 0;
|
||||
} else if (list) {
|
||||
list_all_files( argv[argc-1] );
|
||||
return 0;
|
||||
} else {
|
||||
// if only -L is specified or no command is specified then just list files
|
||||
list_all_files( argv[argc-1] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FS_CMDLINE_HEADER_FILE
|
||||
#define FS_CMDLINE_HEADER_FILE
|
||||
|
||||
|
||||
int parse_cmdline(int argc, char *argv[]);
|
||||
|
||||
// COMMAND LINE SETTINGS
|
||||
// This section is for reference by all the *_init() functions. For example, the multiplayer init function
|
||||
// could check to see if (int Cmdline_multi_stream_chat_to_file) has been set by the command line parser.
|
||||
//
|
||||
// Add any extern definitions here and put the actual variables inside of cmdline.cpp for ease of use
|
||||
// Also, check to make sure anything you add doesn't break Fred or TestCode
|
||||
|
||||
|
||||
// RETAIL OPTIONS ----------------------------------------------
|
||||
extern char *Cmdline_connect_addr;
|
||||
extern char *Cmdline_game_name;
|
||||
extern char *Cmdline_game_password;
|
||||
extern char *Cmdline_rank_above;
|
||||
extern char *Cmdline_rank_below;
|
||||
extern int Cmdline_cd_check;
|
||||
extern int Cmdline_client_dodamage;
|
||||
extern int Cmdline_closed_game;
|
||||
extern int Cmdline_freespace_no_music;
|
||||
extern int Cmdline_freespace_no_sound;
|
||||
extern int Cmdline_gimme_all_medals;
|
||||
extern int Cmdline_mouse_coords;
|
||||
extern int Cmdline_multi_log;
|
||||
extern int Cmdline_multi_stream_chat_to_file;
|
||||
extern int Cmdline_network_port;
|
||||
extern int Cmdline_restricted_game;
|
||||
extern int Cmdline_spew_pof_info;
|
||||
extern int Cmdline_start_netgame;
|
||||
extern int Cmdline_timeout;
|
||||
extern int Cmdline_use_last_pilot;
|
||||
extern int Cmdline_window;
|
||||
extern int Cmdline_fullscreen_window;
|
||||
extern char *Cmdline_res;
|
||||
extern char *Cmdline_center_res;
|
||||
|
||||
|
||||
// FSO OPTIONS -------------------------------------------------
|
||||
|
||||
// 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_missile_lighting;
|
||||
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_no_batching;
|
||||
extern int Cmdline_shadow_quality;
|
||||
extern int Cmdline_no_deferred_lighting;
|
||||
|
||||
// Game Speed related
|
||||
extern int Cmdline_cache_bitmaps;
|
||||
extern int Cmdline_NoFPSCap;
|
||||
extern int Cmdline_no_vsync;
|
||||
|
||||
// HUD related
|
||||
extern int Cmdline_ballistic_gauge;
|
||||
extern int Cmdline_dualscanlines;
|
||||
extern int Cmdline_orb_radar;
|
||||
extern int Cmdline_rearm_timer;
|
||||
extern int Cmdline_targetinfo;
|
||||
|
||||
// Gameplay related
|
||||
extern int Cmdline_3dwarp;
|
||||
extern int Cmdline_ship_choice_3d;
|
||||
extern int Cmdline_weapon_choice_3d;
|
||||
extern int Cmdline_warp_flash;
|
||||
extern int Cmdline_autopilot_interruptable;
|
||||
extern int Cmdline_stretch_menu;
|
||||
|
||||
// Audio related
|
||||
extern int Cmdline_query_speech;
|
||||
extern int Cmdline_snd_preload;
|
||||
extern int Cmdline_voice_recognition;
|
||||
extern int Cmdline_no_enhanced_sound;
|
||||
|
||||
// MOD related
|
||||
extern char *Cmdline_mod; // DTP for mod support
|
||||
// Multiplayer/Network related
|
||||
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;
|
||||
|
||||
// Launcher related options
|
||||
extern bool Cmdline_portable_mode;
|
||||
|
||||
// Troubleshooting
|
||||
extern int Cmdline_load_all_weapons;
|
||||
extern int Cmdline_nomovies; // WMC Toggles movie playing support
|
||||
extern int Cmdline_no_set_gamma;
|
||||
extern int Cmdline_novbo;
|
||||
extern int Cmdline_no_fbo;
|
||||
extern int Cmdline_no_pbo;
|
||||
extern int Cmdline_noglsl;
|
||||
extern int Cmdline_mipmap;
|
||||
extern int Cmdline_ati_color_swap;
|
||||
extern int Cmdline_no_3d_sound;
|
||||
extern int Cmdline_drawelements;
|
||||
extern char* Cmdline_keyboard_layout;
|
||||
extern bool Cmdline_gl_finish;
|
||||
extern bool Cmdline_no_geo_sdr_effects;
|
||||
extern bool Cmdline_set_cpu_affinity;
|
||||
#ifdef WIN32
|
||||
extern bool Cmdline_alternate_registry_path;
|
||||
#endif
|
||||
|
||||
// Developer/Testing related
|
||||
extern char *Cmdline_start_mission;
|
||||
extern int Cmdline_old_collision_sys;
|
||||
extern int Cmdline_dis_collisions;
|
||||
extern int Cmdline_dis_weapons;
|
||||
extern int Cmdline_noparseerrors;
|
||||
#ifdef Allow_NoWarn
|
||||
extern int Cmdline_nowarn;
|
||||
#endif
|
||||
extern int Cmdline_extra_warn;
|
||||
extern int Cmdline_show_mem_usage;
|
||||
extern int Cmdline_show_pos;
|
||||
extern int Cmdline_show_stats;
|
||||
extern int Cmdline_save_render_targets;
|
||||
extern int Cmdline_verify_vps;
|
||||
extern int Cmdline_reparse_mainhall;
|
||||
extern bool Cmdline_frame_profile;
|
||||
extern bool Cmdline_profile_write_file;
|
||||
extern bool Cmdline_no_unfocus_pause;
|
||||
extern bool Cmdline_benchmark_mode;
|
||||
|
||||
#endif
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "cmeasure/cmeasure.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "hud/hud.h"
|
||||
#include "math/staticrand.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "network/multimsgs.h"
|
||||
#include "object/object.h"
|
||||
#include "ship/ship.h"
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
int Cmeasures_homing_check = 0;
|
||||
int Countermeasures_enabled = 1; // Debug, set to 0 means no one can fire countermeasures.
|
||||
const float CMEASURE_DETONATE_DISTANCE = 40.0f;
|
||||
|
||||
//Used to set a countermeasure velocity after being launched from a ship as a countermeasure
|
||||
//ie not as a primary or secondary.
|
||||
void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
|
||||
{
|
||||
vec3d vel, rand_vec;
|
||||
|
||||
//Get cmeasure rear velocity in world
|
||||
vm_vec_scale_add(&vel, &parent_objp->phys_info.vel, &parent_objp->orient.vec.fvec, -25.0f);
|
||||
|
||||
//Get random velocity vector
|
||||
static_randvec(arand+1, &rand_vec);
|
||||
|
||||
//Add it to the rear velocity
|
||||
vm_vec_scale_add2(&vel, &rand_vec, 2.0f);
|
||||
|
||||
objp->phys_info.vel = vel;
|
||||
|
||||
//Zero out this stuff so it isn't moving
|
||||
vm_vec_zero(&objp->phys_info.rotvel);
|
||||
vm_vec_zero(&objp->phys_info.max_vel);
|
||||
vm_vec_zero(&objp->phys_info.max_rotvel);
|
||||
|
||||
// blow out his reverse thrusters. Or drag, same thing.
|
||||
objp->phys_info.rotdamp = 10000.0f;
|
||||
objp->phys_info.side_slip_time_const = 10000.0f;
|
||||
|
||||
objp->phys_info.max_vel.xyz.z = -25.0f;
|
||||
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z );
|
||||
}
|
||||
|
||||
void cmeasure_select_next(ship *shipp)
|
||||
{
|
||||
Assert(shipp != NULL);
|
||||
int i, new_index;
|
||||
|
||||
for (i = 1; i < Num_weapon_types; i++)
|
||||
{
|
||||
new_index = (shipp->current_cmeasure + i) % Num_weapon_types;
|
||||
|
||||
if(Weapon_info[new_index].wi_flags & WIF_CMEASURE)
|
||||
{
|
||||
shipp->current_cmeasure = new_index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mprintf(("Countermeasure type set to %i in frame %i\n", shipp->current_cmeasure, Framecount));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief If this is a player countermeasure, let the player know they evaded a missile.
|
||||
* @param objp [description]
|
||||
*
|
||||
* During single player games, this function notifies the player that evasion has occurred.
|
||||
* Multiplayer games ensure that #send_countermeasure_success_packet() is called to notify the other player.
|
||||
*/
|
||||
|
||||
void cmeasure_maybe_alert_success(object *objp)
|
||||
{
|
||||
//Is this a countermeasure, and does it have a parent
|
||||
if ( objp->type != OBJ_WEAPON || objp->parent < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_CMEASURE);
|
||||
|
||||
if ( objp->parent == OBJ_INDEX(Player_obj) ) {
|
||||
hud_start_text_flash(XSTR("Evaded", 1430), 800);
|
||||
snd_play(&Snds[ship_get_sound(Player_obj, SND_MISSILE_EVADED_POPUP)]);
|
||||
} else if ( Objects[objp->parent].flags & OF_PLAYER_SHIP ) {
|
||||
send_countermeasure_success_packet( objp->parent );
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _CMEASURE_H
|
||||
#define _CMEASURE_H
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
|
||||
class object;
|
||||
|
||||
#define CMEASURE_WAIT 333 // delay in milliseconds between countermeasure firing.
|
||||
|
||||
// Maximum distance at which a countermeasure can be tracked
|
||||
// If this value is too large, missiles will always be tracking countermeasures.
|
||||
#define MAX_CMEASURE_TRACK_DIST 300.0f
|
||||
extern const float CMEASURE_DETONATE_DISTANCE;
|
||||
|
||||
extern int Cmeasures_homing_check;
|
||||
extern int Countermeasures_enabled;
|
||||
|
||||
extern void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand);
|
||||
extern void cmeasure_select_next(object *objp);
|
||||
extern void cmeasure_maybe_alert_success(object *objp);
|
||||
|
||||
#endif // _CMEASURE_H
|
||||
@@ -1,321 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CONTROLS_CONFIG_H
|
||||
#define CONTROLS_CONFIG_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#define CONTROL_CONFIG_XSTR 507
|
||||
|
||||
/*!
|
||||
* These are used to index a corresponding joystick axis value from an array.
|
||||
* Currently only used by ::Axis_map_to[] and ::Axis_map_to_defaults[]
|
||||
*/
|
||||
enum Joy_axis_index {
|
||||
JOY_X_AXIS =0,
|
||||
JOY_Y_AXIS,
|
||||
JOY_Z_AXIS,
|
||||
JOY_RX_AXIS,
|
||||
JOY_RY_AXIS,
|
||||
JOY_RZ_AXIS
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* These are used to index a corresponding (analog) action, namely controlling the orientation angles and throttle.
|
||||
*/
|
||||
enum Joy_axis_action_index {
|
||||
JOY_HEADING_AXIS =0,
|
||||
JOY_PITCH_AXIS,
|
||||
JOY_BANK_AXIS,
|
||||
JOY_ABS_THROTTLE_AXIS,
|
||||
JOY_REL_THROTTLE_AXIS,
|
||||
|
||||
/*!
|
||||
* This must always be below the last defined item
|
||||
*/
|
||||
NUM_JOY_AXIS_ACTIONS //!< The total number of actions an axis may map to
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* Control Configuration Types. Namely differ in how the control is activated
|
||||
*/
|
||||
enum CC_type {
|
||||
CC_TYPE_TRIGGER =0, //!< A normal, one-shot type control that is activated when a key is or button is pressed
|
||||
CC_TYPE_CONTINUOUS //!< A continous control that is activated as long as the key or button is held down
|
||||
};
|
||||
|
||||
/*!
|
||||
* Control configuration item type.
|
||||
*/
|
||||
typedef struct config_item {
|
||||
short key_default; //!< default key bound to action
|
||||
short joy_default; //!< default joystick button bound to action
|
||||
char tab; //!< what tab (category) it belongs in
|
||||
bool hasXSTR; //!< whether we should translate this with an XSTR
|
||||
char *text; //!< describes the action in the config screen
|
||||
char type; //!< manner control should be checked in
|
||||
short key_id; //!< actual key bound to action
|
||||
short joy_id; //!< joystick button bound to action
|
||||
int used; //!< has control been used yet in mission? If so, this is the timestamp
|
||||
bool disabled; //!< whether this action should be available at all
|
||||
bool continuous_ongoing;//!< whether this action is a continuous one and is currently ongoing
|
||||
} config_item;
|
||||
|
||||
/*!
|
||||
* All available actions
|
||||
* This is the value of the id field in config_item
|
||||
* The first group of items are ship targeting.
|
||||
*/
|
||||
enum IoActionId {
|
||||
TARGET_NEXT =0, //!< target next
|
||||
TARGET_PREV =1, //!< target previous
|
||||
TARGET_NEXT_CLOSEST_HOSTILE =2, //!< target the next hostile target
|
||||
TARGET_PREV_CLOSEST_HOSTILE =3, //!< target the previous closest hostile
|
||||
TOGGLE_AUTO_TARGETING =4, //!< toggle auto-targeting
|
||||
TARGET_NEXT_CLOSEST_FRIENDLY =5, //!< target the next friendly ship
|
||||
TARGET_PREV_CLOSEST_FRIENDLY =6, //!< target the closest friendly ship
|
||||
TARGET_SHIP_IN_RETICLE =7, //!< target ship closest to center of reticle
|
||||
TARGET_CLOSEST_SHIP_ATTACKING_TARGET =8, //!< target the closest ship attacking current target
|
||||
TARGET_LAST_TRANMISSION_SENDER =9, //!< TARGET_LAST_TRANMISSION_SENDER
|
||||
STOP_TARGETING_SHIP =10, //!< stop targeting ship
|
||||
|
||||
//!< @n
|
||||
//!< Targeting a Ship's Subsystem
|
||||
//!< ------------------------------
|
||||
TARGET_SUBOBJECT_IN_RETICLE =11, //!< target ships subsystem in reticle
|
||||
TARGET_NEXT_SUBOBJECT =12, //!< target next subsystem on current target
|
||||
TARGET_PREV_SUBOBJECT =13, //!< TARGET_PREV_SUBOBJECT
|
||||
STOP_TARGETING_SUBSYSTEM =14, //!< stop targeting subsystems on ship
|
||||
|
||||
//!< @n
|
||||
//!< Speed Matching
|
||||
//!< ----------------
|
||||
MATCH_TARGET_SPEED =15, //!< match target speed
|
||||
TOGGLE_AUTO_MATCH_TARGET_SPEED =16, //!< toggle auto-match target speed
|
||||
|
||||
//!< @n
|
||||
//!< Weapons
|
||||
//!< ---------
|
||||
FIRE_PRIMARY =17, //!< FIRE_PRIMARY
|
||||
FIRE_SECONDARY =18, //!< FIRE_SECONDARY
|
||||
CYCLE_NEXT_PRIMARY =19, //!< cycle to next primary weapon
|
||||
CYCLE_PREV_PRIMARY =20, //!< cycle to previous primary weapon
|
||||
CYCLE_SECONDARY =21, //!< cycle to next secondary weapon
|
||||
CYCLE_NUM_MISSLES =22, //!< cycle number of missiles fired from secondary bank
|
||||
LAUNCH_COUNTERMEASURE =23, //!< LAUNCH_COUNTERMEASURE
|
||||
|
||||
//!< @n
|
||||
//!< Controls
|
||||
//!< ----------
|
||||
FORWARD_THRUST =24, //!< FORWARD_THRUST
|
||||
REVERSE_THRUST =25, //!< REVERSE_THRUST
|
||||
BANK_LEFT =26, //!< BANK_LEFT
|
||||
BANK_RIGHT =27, //!< BANK_RIGHT
|
||||
PITCH_FORWARD =28, //!< PITCH_FORWARD
|
||||
PITCH_BACK =29, //!< PITCH_BACK
|
||||
YAW_LEFT =30, //!< YAW_LEFT
|
||||
YAW_RIGHT =31, //!< YAW_RIGHT
|
||||
|
||||
//!< @n
|
||||
//!< Throttle Control
|
||||
//!< ------------------
|
||||
ZERO_THROTTLE =32, //!< ZERO_THROTTLE
|
||||
MAX_THROTTLE =33, //!< MAX_THROTTLE
|
||||
ONE_THIRD_THROTTLE =34, //!< ONE_THIRD_THROTTLE
|
||||
TWO_THIRDS_THROTTLE =35, //!< TWO_THIRDS_THROTTLE
|
||||
PLUS_5_PERCENT_THROTTLE =36, //!< PLUS_5_PERCENT_THROTTLE
|
||||
MINUS_5_PERCENT_THROTTLE =37, //!< MINUS_5_PERCENT_THROTTLE
|
||||
|
||||
//!< @n
|
||||
//!< Squadmate Messaging Keys
|
||||
//!< --------------------------
|
||||
ATTACK_MESSAGE =38, //!< wingman message: attack current target
|
||||
DISARM_MESSAGE =39, //!< wingman message: disarm current target
|
||||
DISABLE_MESSAGE =40, //!< wingman message: disable current target
|
||||
ATTACK_SUBSYSTEM_MESSAGE =41, //!< wingman message: disable current target
|
||||
CAPTURE_MESSAGE =42, //!< wingman message: capture current target
|
||||
ENGAGE_MESSAGE =43, //!< wingman message: engage enemy
|
||||
FORM_MESSAGE =44, //!< wingman message: form on my wing
|
||||
IGNORE_MESSAGE =45, //!< IGNORE_MESSAGE
|
||||
PROTECT_MESSAGE =46, //!< wingman message: protect current target
|
||||
COVER_MESSAGE =47, //!< wingman message: cover me
|
||||
WARP_MESSAGE =48, //!< wingman message: warp out
|
||||
REARM_MESSAGE =49, //!< REARM_MESSAGE
|
||||
TARGET_CLOSEST_SHIP_ATTACKING_SELF =50, //!< target closest ship that is attacking player
|
||||
|
||||
//!< @n
|
||||
//!< Views
|
||||
//!< -------
|
||||
VIEW_CHASE =51, //!< VIEW_CHASE
|
||||
VIEW_EXTERNAL =52, //!< VIEW_EXTERNAL
|
||||
VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK =53, //!< VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK
|
||||
VIEW_SLEW =54, //!< VIEW_SLEW
|
||||
VIEW_OTHER_SHIP =55, //!< VIEW_OTHER_SHIP
|
||||
VIEW_DIST_INCREASE =56, //!< VIEW_DIST_INCREASE
|
||||
VIEW_DIST_DECREASE =57, //!< VIEW_DIST_DECREASE
|
||||
VIEW_CENTER =58, //!< VIEW_CENTER
|
||||
PADLOCK_UP =59, //!< PADLOCK_UP
|
||||
PADLOCK_DOWN =60, //!< PADLOCK_DOWN
|
||||
PADLOCK_LEFT =61, //!< PADLOCK_LEFT
|
||||
PADLOCK_RIGHT =62, //!< PADLOCK_RIGHT
|
||||
|
||||
//!< @n
|
||||
//!< Misc Controls 1
|
||||
//!< -----------------
|
||||
RADAR_RANGE_CYCLE =63, //!< cycle to next radar range
|
||||
SQUADMSG_MENU =64, //!< toggle the squadmate messaging menu
|
||||
SHOW_GOALS =65, //!< show the mission goals screen
|
||||
END_MISSION =66, //!< end the mission
|
||||
TARGET_TARGETS_TARGET =67, //!< target your target's target
|
||||
AFTERBURNER =68, //!< AFTERBURNER
|
||||
|
||||
//!< @n
|
||||
//!< ETS
|
||||
//!< -----
|
||||
INCREASE_WEAPON =69, //!< increase weapon recharge rate
|
||||
DECREASE_WEAPON =70, //!< decrease weapon recharge rate
|
||||
INCREASE_SHIELD =71, //!< increase shield recharge rate
|
||||
DECREASE_SHIELD =72, //!< decrease shield recharge rate
|
||||
INCREASE_ENGINE =73, //!< increase energy to engines
|
||||
DECREASE_ENGINE =74, //!< decrease energy to engines
|
||||
ETS_EQUALIZE =75, //!< equalize recharge rates
|
||||
SHIELD_EQUALIZE =76, //!< equalize shield energy to all quadrants
|
||||
SHIELD_XFER_TOP =77, //!< transfer shield energy to front
|
||||
SHIELD_XFER_BOTTOM =78, //!< transfer shield energy to rear
|
||||
SHIELD_XFER_LEFT =79, //!< transfer shield energy to left
|
||||
SHIELD_XFER_RIGHT =80, //!< transfer shield energy to right
|
||||
XFER_SHIELD =81, //!< transfer energy to shield from weapons
|
||||
XFER_LASER =82, //!< transfer energy to weapons from shield
|
||||
|
||||
//!< @n
|
||||
//!< Misc Controls 2
|
||||
//!< -----------------
|
||||
GLIDE_WHEN_PRESSED =83, //!< GLIDE_WHEN_PRESSED
|
||||
//!< @remark Backslash -- this was a convenient place for Glide When Pressed, since Show Damage Popup isn't used
|
||||
BANK_WHEN_PRESSED =84, //!< BANK_WHEN_PRESSED
|
||||
SHOW_NAVMAP =85, //!< SHOW_NAVMAP
|
||||
ADD_REMOVE_ESCORT =86, //!< ADD_REMOVE_ESCORT
|
||||
ESCORT_CLEAR =87, //!< ESCORT_CLEAR
|
||||
|
||||
TARGET_NEXT_ESCORT_SHIP =88, //!< TARGET_NEXT_ESCORT_SHIP
|
||||
TARGET_CLOSEST_REPAIR_SHIP =89, //!< target the closest repair ship
|
||||
TARGET_NEXT_UNINSPECTED_CARGO =90, //!< TARGET_NEXT_UNINSPECTED_CARGO
|
||||
TARGET_PREV_UNINSPECTED_CARGO =91, //!< TARGET_PREV_UNINSPECTED_CARGO
|
||||
TARGET_NEWEST_SHIP =92, //!< TARGET_NEWEST_SHIP
|
||||
|
||||
TARGET_NEXT_LIVE_TURRET =93, //!< TARGET_NEXT_LIVE_TURRET
|
||||
TARGET_PREV_LIVE_TURRET =94, //!< TARGET_PREV_LIVE_TURRET
|
||||
|
||||
TARGET_NEXT_BOMB =95, //!< TARGET_NEXT_BOMB
|
||||
TARGET_PREV_BOMB =96, //!< TARGET_PREV_BOMB
|
||||
|
||||
//!< @n
|
||||
//!< Multiplayer messaging keys
|
||||
//!< ----------------------------
|
||||
MULTI_MESSAGE_ALL =97, //!< message all netplayers
|
||||
MULTI_MESSAGE_FRIENDLY =98, //!< message all friendlies
|
||||
MULTI_MESSAGE_HOSTILE =99, //!< message all hostiles
|
||||
MULTI_MESSAGE_TARGET =100, //!< message targeted ship (if player)
|
||||
|
||||
//!< @n
|
||||
//!< Multiplayer misc keys
|
||||
//!< -----------------------
|
||||
MULTI_OBSERVER_ZOOM_TO =101, //!< if i'm an observer, zoom to my targeted object
|
||||
|
||||
TIME_SPEED_UP =102, //!< TIME_SPEED_UP
|
||||
TIME_SLOW_DOWN =103, //!< TIME_SLOW_DOWN
|
||||
|
||||
TOGGLE_HUD_CONTRAST =104, //!< toggle between high and low HUD contrast
|
||||
|
||||
MULTI_TOGGLE_NETINFO =105, //!< toggle network info
|
||||
|
||||
MULTI_SELF_DESTRUCT =106, //!< self destruct (multiplayer only)
|
||||
|
||||
//!< @n
|
||||
//!< Misc Controls 3
|
||||
//!< -----------------
|
||||
TOGGLE_HUD =107, //!< TOGGLE_HUD
|
||||
RIGHT_SLIDE_THRUST =108, //!< RIGHT_SLIDE_THRUST
|
||||
LEFT_SLIDE_THRUST =109, //!< LEFT_SLIDE_THRUST
|
||||
UP_SLIDE_THRUST =110, //!< UP_SLIDE_THRUST
|
||||
DOWN_SLIDE_THRUST =111, //!< DOWN_SLIDE_THRUST
|
||||
HUD_TARGETBOX_TOGGLE_WIREFRAME =112, //!< HUD_TARGETBOX_TOGGLE_WIREFRAME
|
||||
VIEW_TOPDOWN =113, //!< VIEW_TOPDOWN
|
||||
VIEW_TRACK_TARGET =114, //!< VIEW_TRACK_TARGET
|
||||
|
||||
//!< @n
|
||||
//!< AutoPilot - Kazan
|
||||
//!< -------------------
|
||||
AUTO_PILOT_TOGGLE =115, //!< Autopilot key control
|
||||
NAV_CYCLE =116, //!< NAV_CYCLE
|
||||
|
||||
//!< @n
|
||||
//!< Gliding
|
||||
//!< ---------
|
||||
TOGGLE_GLIDING =117, //!< TOGGLE_GLIDING
|
||||
|
||||
//!< @n
|
||||
//!< Additional weapon controls
|
||||
//!< ----------------------------
|
||||
CYCLE_PRIMARY_WEAPON_SEQUENCE =118, //!< cycle num primaries to fire at once
|
||||
|
||||
/*!
|
||||
* This must always be below the last defined item
|
||||
*/
|
||||
CCFG_MAX //!< The total number of defined control actions (or last define + 1)
|
||||
};
|
||||
|
||||
extern int Failed_key_index;
|
||||
extern int Invert_heading;
|
||||
extern int Invert_pitch;
|
||||
extern int Invert_roll;
|
||||
extern int Invert_thrust;
|
||||
extern int Disable_axis2;
|
||||
extern int Disable_axis3;
|
||||
|
||||
extern int Axis_map_to[];
|
||||
extern int Invert_axis[];
|
||||
extern int Invert_axis_defaults[];
|
||||
|
||||
extern int Control_config_overlay_id;
|
||||
|
||||
extern config_item Control_config[]; //!< Stores the keyboard configuration
|
||||
extern SCP_vector<config_item*> Control_config_presets; // tabled control presets; pointers to config_item arrays
|
||||
extern SCP_vector<SCP_string> Control_config_preset_names; // names for Control_config_presets (identical order of items)
|
||||
extern char **Scan_code_text;
|
||||
extern char **Joy_button_text;
|
||||
|
||||
void control_config_common_init(); //!< initialize common control config stuff - call at game startup after localization has been initialized
|
||||
void control_config_common_close(); //!< close common control config stuff - call at game shutdown
|
||||
|
||||
void control_config_init();
|
||||
void control_config_do_frame(float frametime);
|
||||
void control_config_close();
|
||||
|
||||
void control_config_cancel_exit();
|
||||
|
||||
void control_config_reset_defaults(int presetnum=-1);
|
||||
int translate_key_to_index(const char *key, bool find_override=true);
|
||||
char *translate_key(char *key);
|
||||
char *textify_scancode(int code);
|
||||
float check_control_timef(int id);
|
||||
int check_control(int id, int key = -1);
|
||||
void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr);
|
||||
void control_used(int id);
|
||||
void control_config_clear();
|
||||
void clear_key_binding(short key);
|
||||
void control_check_indicate();
|
||||
void control_config_clear_used_status();
|
||||
|
||||
#endif
|
||||
@@ -1,924 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "controlconfig/controlsconfig.h"
|
||||
#include "globalincs/def_files.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "io/joy.h"
|
||||
#include "io/key.h"
|
||||
#include "localization/localize.h"
|
||||
#include "parse/parselo.h"
|
||||
|
||||
// z64: These enumerations MUST equal to those in controlsconfig.cpp...
|
||||
// z64: Really need a better way than this.
|
||||
enum CC_tab {
|
||||
TARGET_TAB =0,
|
||||
SHIP_TAB =1,
|
||||
WEAPON_TAB =2,
|
||||
COMPUTER_TAB =3
|
||||
};
|
||||
|
||||
int Failed_key_index;
|
||||
|
||||
// assume control keys are used as modifiers until we find out
|
||||
int Shift_is_modifier;
|
||||
int Ctrl_is_modifier;
|
||||
int Alt_is_modifier;
|
||||
|
||||
int Axis_enabled[JOY_NUM_AXES] = { 1, 1, 1, 0, 0, 0 };
|
||||
int Axis_enabled_defaults[JOY_NUM_AXES] = { 1, 1, 1, 0, 0, 0 };
|
||||
int Invert_axis[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
|
||||
int Invert_axis_defaults[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
//! arrays which hold the key mappings. The array index represents a key-independent action.
|
||||
//! please use SPACES for aligning the fields of this array
|
||||
//XSTR:OFF
|
||||
config_item Control_config[CCFG_MAX + 1] = {
|
||||
// targeting a ship
|
||||
{ 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, 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, 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, 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, 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, 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, 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, true, "Target Closest Attacking Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
|
||||
// Views
|
||||
{ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 }
|
||||
};
|
||||
|
||||
char *Scan_code_text_german[] = {
|
||||
"", "Esc", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0", "Akzent '", "Eszett", "R\x81""cktaste", "Tab",
|
||||
"Q", "W", "E", "R", "T", "Z", "U", "I",
|
||||
"O", "P", "\x9A", "+", "Eingabe", "Strg Links", "A", "S",
|
||||
|
||||
"D", "F", "G", "H", "J", "K", "L", "\x99",
|
||||
"\x8E", "`", "Shift", "#", "Y", "X", "C", "V",
|
||||
"B", "N", "M", ",", ".", "-", "Shift", "Num *",
|
||||
"Alt", "Leertaste", "Hochstell", "F1", "F2", "F3", "F4", "F5",
|
||||
|
||||
"F6", "F7", "F8", "F9", "F10", "Pause", "Rollen", "Num 7",
|
||||
"Num 8", "Num 9", "Num -", "Num 4", "Num 5", "Num 6", "Num +", "Num 1",
|
||||
"Num 2", "Num 3", "Num 0", "Num ,", "", "", "", "F11",
|
||||
"F12", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "Num Eingabe", "Strg Rechts", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "Num /", "", "Druck",
|
||||
"Alt", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "Num Lock", "", "Pos 1",
|
||||
"Pfeil Hoch", "Bild Hoch", "", "Pfeil Links", "", "Pfeil Rechts", "", "Ende",
|
||||
"Pfeil Runter", "Bild Runter", "Einfg", "Entf", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
};
|
||||
|
||||
char *Joy_button_text_german[] = {
|
||||
"Knopf 1", "Knopf 2", "Knopf 3", "Knopf 4", "Knopf 5", "Knopf 6",
|
||||
"Knopf 7", "Knopf 8", "Knopf 9", "Knopf 10", "Knopf 11", "Knopf 12",
|
||||
"Knopf 13", "Knopf 14", "Knopf 15", "Knopf 16", "Knopf 17", "Knopf 18",
|
||||
"Knopf 19", "Knopf 20", "Knopf 21", "Knopf 22", "Knopf 23", "Knopf 24",
|
||||
"Knopf 25", "Knopf 26", "Knopf 27", "Knopf 28", "Knopf 29", "Knopf 30",
|
||||
"Knopf 31", "Knopf 32", "Hut Hinten", "Hut Vorne", "Hut Links", "Hut Rechts"
|
||||
};
|
||||
|
||||
char *Scan_code_text_french[] = {
|
||||
"", "\x90""chap", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0", "-", "=", "Fl\x82""che Ret.", "Tab",
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I",
|
||||
"O", "P", "[", "]", "Entr\x82""e", "Ctrl Gauche", "A", "S",
|
||||
|
||||
"D", "F", "G", "H", "J", "K", "L", ";",
|
||||
"'", "`", "Maj.", "\\", "Z", "X", "C", "V",
|
||||
"B", "N", "M", ",", ".", "/", "Maj.", "Pav\x82 *",
|
||||
"Alt", "Espace", "Verr. Maj.", "F1", "F2", "F3", "F4", "F5",
|
||||
|
||||
"F6", "F7", "F8", "F9", "F10", "Pause", "Arret defil", "Pav\x82 7",
|
||||
"Pav\x82 8", "Pav\x82 9", "Pav\x82 -", "Pav\x82 4", "Pav\x82 5", "Pav\x82 6", "Pav\x82 +", "Pav\x82 1",
|
||||
"Pav\x82 2", "Pav\x82 3", "Pav\x82 0", "Pav\x82 .", "", "", "", "F11",
|
||||
"F12", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "Pav\x82 Entr", "Ctrl Droite", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "Pav\x82 /", "", "Impr \x82""cran",
|
||||
"Alt", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "Verr num", "", "Orig.",
|
||||
"Fl\x82""che Haut", "Page Haut", "", "Fl\x82""che Gauche", "", "Fl\x82""che Droite", "", "Fin",
|
||||
"Fl\x82""che Bas", "Page Bas", "Inser", "Suppr", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
};
|
||||
|
||||
char *Joy_button_text_french[] = {
|
||||
"Bouton 1", "Bouton 2", "Bouton 3", "Bouton 4", "Bouton 5", "Bouton 6",
|
||||
"Bouton 7", "Bouton 8", "Bouton 9", "Bouton 10", "Bouton 11", "Bouton 12",
|
||||
"Bouton 13", "Bouton 14", "Bouton 15", "Bouton 16", "Bouton 17", "Bouton 18",
|
||||
"Bouton 19", "Bouton 20", "Bouton 21", "Bouton 22", "Bouton 23", "Bouton 24",
|
||||
"Bouton 25", "Bouton 26", "Bouton 27", "Bouton 28", "Bouton 29", "Bouton 30",
|
||||
"Bouton 31", "Bouton 32", "Chapeau Arri\x8Are", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
|
||||
};
|
||||
|
||||
char *Scan_code_text_polish[] = {
|
||||
"", "Esc", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0", "-", "=", "Backspace", "Tab",
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I",
|
||||
"O", "P", "[", "]", "Enter", "Lewy Ctrl", "A", "S",
|
||||
|
||||
"D", "F", "G", "H", "J", "K", "L", ";",
|
||||
"'", "`", "LShift", "\\", "Z", "X", "C", "V",
|
||||
"B", "N", "M", ",", ".", "/", "PShift", "Num *",
|
||||
"Alt", "Spacja", "CapsLock", "F1", "F2", "F3", "F4", "F5",
|
||||
|
||||
"F6", "F7", "F8", "F9", "F10", "Pause", "Scrlock", "Num 7",
|
||||
"Num 8", "Num 9", "Num -", "Num 4", "Num 5", "Num 6", "Num +", "Num 1",
|
||||
"Num 2", "Num 3", "Num 0", "Num .", "", "", "", "F11",
|
||||
"F12", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "Num Enter", "Prawy Ctrl", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "Num /", "", "PrntScr",
|
||||
"Alt", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "Num Lock", "", "Home",
|
||||
"Kursor G\xF3ra", "Page Up", "", "Kursor Lewo", "", "Kursor Prawo", "", "End",
|
||||
"Kursor D\xF3\xB3", "Page Down", "Insert", "Delete", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
};
|
||||
|
||||
char *Joy_button_text_polish[] = {
|
||||
"Przyc.1", "Przyc.2", "Przyc.3", "Przyc.4", "Przyc.5", "Przyc.6",
|
||||
"Przyc.7", "Przyc.8", "Przyc.9", "Przyc.10", "Przyc.11", "Przyc.12",
|
||||
"Przyc.13", "Przyc.14", "Przyc.15", "Przyc.16", "Przyc.17", "Przyc.18",
|
||||
"Przyc.19", "Przyc.20", "Przyc.21", "Przyc.22", "Przyc.23", "Przyc.24",
|
||||
"Przyc.25", "Przyc.26", "Przyc.27", "Przyc.28", "Przyc.29", "Przyc.30",
|
||||
"Przyc.31", "Przyc.32", "Hat Ty\xB3", "Hat Prz\xF3\x64", "Hat Lewo", "Hat Prawo"
|
||||
};
|
||||
|
||||
//! This is the text that is displayed on the screen for the keys a player selects
|
||||
char *Scan_code_text_english[] = {
|
||||
"", "Esc", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0", "-", "=", "Backspace", "Tab",
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I",
|
||||
"O", "P", "[", "]", "Enter", "Left Ctrl", "A", "S",
|
||||
|
||||
"D", "F", "G", "H", "J", "K", "L", ";",
|
||||
"'", "`", "Shift", "\\", "Z", "X", "C", "V",
|
||||
"B", "N", "M", ",", ".", "/", "Shift", "Pad *",
|
||||
"Alt", "Spacebar", "Caps Lock", "F1", "F2", "F3", "F4", "F5",
|
||||
|
||||
"F6", "F7", "F8", "F9", "F10", "Pause", "Scroll Lock", "Pad 7",
|
||||
"Pad 8", "Pad 9", "Pad -", "Pad 4", "Pad 5", "Pad 6", "Pad +", "Pad 1",
|
||||
"Pad 2", "Pad 3", "Pad 0", "Pad .", "", "", "", "F11",
|
||||
"F12", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "Pad Enter", "Right Ctrl", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "Pad /", "", "Print Scrn",
|
||||
"Alt", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "Num Lock", "", "Home",
|
||||
"Up Arrow", "Page Up", "", "Left Arrow", "", "Right Arrow", "", "End",
|
||||
"Down Arrow", "Page Down", "Insert", "Delete", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
};
|
||||
|
||||
char *Joy_button_text_english[] = {
|
||||
"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6",
|
||||
"Button 7", "Button 8", "Button 9", "Button 10", "Button 11", "Button 12",
|
||||
"Button 13", "Button 14", "Button 15", "Button 16", "Button 17", "Button 18",
|
||||
"Button 19", "Button 20", "Button 21", "Button 22", "Button 23", "Button 24",
|
||||
"Button 25", "Button 26", "Button 27", "Button 28", "Button 29", "Button 30",
|
||||
"Button 31", "Button 32", "Hat Back", "Hat Forward", "Hat Left", "Hat Right"
|
||||
};
|
||||
|
||||
char **Scan_code_text = Scan_code_text_english;
|
||||
char **Joy_button_text = Joy_button_text_english;
|
||||
|
||||
SCP_vector<config_item*> Control_config_presets;
|
||||
SCP_vector<SCP_string> Control_config_preset_names;
|
||||
|
||||
void set_modifier_status()
|
||||
{
|
||||
int i;
|
||||
|
||||
Alt_is_modifier = 0;
|
||||
Shift_is_modifier = 0;
|
||||
Ctrl_is_modifier = 0;
|
||||
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (Control_config[i].key_id < 0)
|
||||
continue;
|
||||
|
||||
if (Control_config[i].key_id & KEY_ALTED)
|
||||
Alt_is_modifier = 1;
|
||||
|
||||
if (Control_config[i].key_id & KEY_SHIFTED)
|
||||
Shift_is_modifier = 1;
|
||||
|
||||
if (Control_config[i].key_id & KEY_CTRLED) {
|
||||
Assert(0); // get Alan
|
||||
Ctrl_is_modifier = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If find_override is set to true, then this returns the index of the action
|
||||
// which has been bound to the given key. Otherwise, the index of the action
|
||||
// which has the given key as its default key will be returned.
|
||||
int translate_key_to_index(const char *key, bool find_override)
|
||||
{
|
||||
int i, index = -1, alt = 0, shift = 0, max_scan_codes;
|
||||
|
||||
max_scan_codes = sizeof(Scan_code_text_english) / sizeof(char *);
|
||||
|
||||
// look for modifiers
|
||||
Assert(key);
|
||||
if (!strnicmp(key, "Alt", 3)) {
|
||||
alt = 1;
|
||||
key += 3;
|
||||
if (*key)
|
||||
key++;
|
||||
}
|
||||
|
||||
if (!strnicmp(key, "Shift", 5)) {
|
||||
shift = 1;
|
||||
key += 5;
|
||||
if (*key)
|
||||
key++;
|
||||
}
|
||||
|
||||
// look up index for default key
|
||||
if (*key) {
|
||||
for (i=0; i<max_scan_codes; i++)
|
||||
if (!stricmp(key, Scan_code_text_english[i])) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == max_scan_codes)
|
||||
return -1;
|
||||
|
||||
if (shift)
|
||||
index |= KEY_SHIFTED;
|
||||
if (alt)
|
||||
index |= KEY_ALTED;
|
||||
|
||||
// convert scancode to Control_config index
|
||||
if (find_override) {
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (!Control_config[i].disabled && Control_config[i].key_id == index) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (!Control_config[i].disabled && Control_config[i].key_default == index) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == CCFG_MAX)
|
||||
return -1;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*! Given the system default key 'key', return the current key that is bound to that function.
|
||||
* Both are 'key' and the return value are descriptive strings that can be displayed
|
||||
* directly to the user. If 'key' isn't a real key, is not normally bound to anything,
|
||||
* or there is no key currently bound to the function, NULL is returned.
|
||||
*/
|
||||
char *translate_key(char *key)
|
||||
{
|
||||
int index = -1, key_code = -1, joy_code = -1;
|
||||
char *key_text = NULL;
|
||||
char *joy_text = NULL;
|
||||
|
||||
static char text[40] = {"None"};
|
||||
|
||||
index = translate_key_to_index(key, false);
|
||||
if (index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
key_code = Control_config[index].key_id;
|
||||
joy_code = Control_config[index].joy_id;
|
||||
|
||||
Failed_key_index = index;
|
||||
|
||||
if (key_code >= 0) {
|
||||
key_text = textify_scancode(key_code);
|
||||
}
|
||||
|
||||
if (joy_code >= 0) {
|
||||
joy_text = Joy_button_text[joy_code];
|
||||
}
|
||||
|
||||
// both key and joystick button are mapped to this control
|
||||
if ((key_code >= 0 ) && (joy_code >= 0) ) {
|
||||
strcpy_s(text, key_text);
|
||||
strcat_s(text, " or ");
|
||||
strcat_s(text, joy_text);
|
||||
}
|
||||
// if we only have one
|
||||
else if (key_code >= 0 ) {
|
||||
strcpy_s(text, key_text);
|
||||
}
|
||||
else if (joy_code >= 0) {
|
||||
strcpy_s(text, joy_text);
|
||||
}
|
||||
else {
|
||||
strcpy_s(text, "None");
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
char *textify_scancode(int code)
|
||||
{
|
||||
static char text[40];
|
||||
|
||||
if (code < 0)
|
||||
return "None";
|
||||
|
||||
int keycode = code & KEY_MASK;
|
||||
|
||||
*text = 0;
|
||||
if (code & KEY_ALTED && !(keycode == KEY_LALT || keycode == KEY_RALT)) {
|
||||
if(Lcl_gr){
|
||||
strcat_s(text, "Alt-");
|
||||
} else if(Lcl_fr){
|
||||
strcat_s(text, "Alt-");
|
||||
} else {
|
||||
strcat_s(text, "Alt-");
|
||||
}
|
||||
}
|
||||
|
||||
if (code & KEY_SHIFTED && !(keycode == KEY_LSHIFT || keycode == KEY_RSHIFT)) {
|
||||
if(Lcl_gr){
|
||||
strcat_s(text, "Shift-");
|
||||
} else if(Lcl_fr){
|
||||
strcat_s(text, "Maj.-");
|
||||
} else {
|
||||
strcat_s(text, "Shift-");
|
||||
}
|
||||
}
|
||||
|
||||
strcat_s(text, Scan_code_text[keycode]);
|
||||
return text;
|
||||
}
|
||||
//XSTR:ON
|
||||
|
||||
void control_config_common_load_overrides();
|
||||
|
||||
// initialize common control config stuff - call at game startup after localization has been initialized
|
||||
void control_config_common_init()
|
||||
{
|
||||
for (int i=0; i<CCFG_MAX; i++) {
|
||||
Control_config[i].disabled = false;
|
||||
Control_config[i].continuous_ongoing = false;
|
||||
}
|
||||
|
||||
control_config_common_load_overrides();
|
||||
if(Lcl_gr){
|
||||
Scan_code_text = Scan_code_text_german;
|
||||
Joy_button_text = Joy_button_text_german;
|
||||
} else if(Lcl_fr){
|
||||
Scan_code_text = Scan_code_text_french;
|
||||
Joy_button_text = Joy_button_text_french;
|
||||
} else if(Lcl_pl){
|
||||
Scan_code_text = Scan_code_text_polish;
|
||||
Joy_button_text = Joy_button_text_polish;
|
||||
} else {
|
||||
Scan_code_text = Scan_code_text_english;
|
||||
Joy_button_text = Joy_button_text_english;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief close any common control config stuff, called at game_shutdown()
|
||||
*/
|
||||
void control_config_common_close()
|
||||
{
|
||||
// only need to worry control presets for now
|
||||
for (auto ii = Control_config_presets.cbegin(); ii != Control_config_presets.cend(); ++ii) {
|
||||
delete[] * ii;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
SCP_map<SCP_string, int> mKeyNameToVal;
|
||||
SCP_map<SCP_string, CC_type> mCCTypeNameToVal;
|
||||
SCP_map<SCP_string, char> mCCTabNameToVal;
|
||||
|
||||
/*! Helper function to LoadEnumsIntoMaps(), Loads the Keyboard definitions/enumerations into mKeyNameToVal
|
||||
*/
|
||||
void LoadEnumsIntoKeyMap(void) {
|
||||
// Dirty macro hack :D
|
||||
#define ADD_ENUM_TO_KEY_MAP(Enum) mKeyNameToVal[#Enum] = (Enum);
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_SHIFTED)
|
||||
/*
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_ALTED)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_CTRLED)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_DEBUGGED)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_DEBUGGED1)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_MASK)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_DEBUG_KEY)
|
||||
*/
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_0)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_1)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_2)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_3)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_4)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_5)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_6)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_7)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_8)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_9)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_A)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_B)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_C)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_D)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_E)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_G)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_H)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_I)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_J)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_K)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_L)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_M)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_N)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_O)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_P)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_Q)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_R)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_S)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_T)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_U)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_V)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_W)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_X)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_Y)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_Z)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_MINUS)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_EQUAL)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_DIVIDE)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_SLASH)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_SLASH_UK)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_COMMA)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PERIOD)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_SEMICOL)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_LBRACKET)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_RBRACKET)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_RAPOSTRO)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_LAPOSTRO)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_ESC)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_ENTER)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_BACKSP)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_TAB)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_SPACEBAR)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_NUMLOCK)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_SCROLLOCK)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_CAPSLOCK)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_LSHIFT)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_RSHIFT)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_LALT)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_RALT)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_LCTRL)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_RCTRL)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F1)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F2)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F3)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F4)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F5)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F6)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F7)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F8)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F9)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F10)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F11)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_F12)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD0)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD1)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD2)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD3)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD4)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD5)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD6)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD7)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD8)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAD9)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PADMINUS)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PADPLUS)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PADPERIOD)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PADDIVIDE)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PADMULTIPLY)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PADENTER)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_INSERT)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_HOME)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAGEUP)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_DELETE)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_END)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAGEDOWN)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_UP)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_DOWN)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_LEFT)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_RIGHT)
|
||||
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PRINT_SCRN)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_PAUSE)
|
||||
ADD_ENUM_TO_KEY_MAP(KEY_BREAK)
|
||||
|
||||
#undef ADD_ENUM_TO_KEY_MAP
|
||||
}
|
||||
|
||||
/*! Helper function to LoadEnumsIntoMaps(), Loads the Control Types enumerations into mCCTypeNameToVal
|
||||
*/
|
||||
void LoadEnumsIntoCCTypeMap(void) {
|
||||
// Dirty macro hack :D
|
||||
#define ADD_ENUM_TO_CCTYPE_MAP(Enum) mCCTypeNameToVal[#Enum] = (Enum);
|
||||
|
||||
ADD_ENUM_TO_CCTYPE_MAP(CC_TYPE_TRIGGER)
|
||||
ADD_ENUM_TO_CCTYPE_MAP(CC_TYPE_CONTINUOUS)
|
||||
|
||||
#undef ADD_ENUM_TO_CCTYPE_MAP
|
||||
}
|
||||
|
||||
/*! Helper function to LoadEnumsIntoMaps(), Loads the Control Tabs enumerations into mCCTabNameToVal
|
||||
*/
|
||||
void LoadEnumsIntoCCTabMap(void) {
|
||||
// Dirty macro hack :D
|
||||
#define ADD_ENUM_TO_CCTAB_MAP(Enum) mCCTabNameToVal[#Enum] = (Enum);
|
||||
|
||||
ADD_ENUM_TO_CCTAB_MAP(TARGET_TAB)
|
||||
ADD_ENUM_TO_CCTAB_MAP(SHIP_TAB)
|
||||
ADD_ENUM_TO_CCTAB_MAP(WEAPON_TAB)
|
||||
ADD_ENUM_TO_CCTAB_MAP(COMPUTER_TAB)
|
||||
|
||||
#undef ADD_ENUM_TO_CCTAB_MAP
|
||||
}
|
||||
|
||||
/*! Loads the various control configuration maps to allow the parsing functions to appropriately map string tokns to
|
||||
* their associated enumerations. The string tokens in the controlconfigdefaults.tbl match directly to their names in
|
||||
* the C++ code, such as "KEY_5" in the .tbl mapping to the #define KEY_5 value
|
||||
*/
|
||||
void LoadEnumsIntoMaps() {
|
||||
LoadEnumsIntoKeyMap();
|
||||
LoadEnumsIntoCCTypeMap();
|
||||
LoadEnumsIntoCCTabMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parses controlconfigdefault.tbl, and overrides the default control configuration for each valid entry in the .tbl
|
||||
*/
|
||||
void control_config_common_load_overrides()
|
||||
{
|
||||
LoadEnumsIntoMaps();
|
||||
|
||||
if (cf_exists_full("controlconfigdefaults.tbl", CF_TYPE_TABLES)) {
|
||||
read_file_text("controlconfigdefaults.tbl", CF_TYPE_TABLES);
|
||||
} else {
|
||||
read_file_text_from_array(defaults_get_file("controlconfigdefaults.tbl"));
|
||||
}
|
||||
|
||||
reset_parse();
|
||||
|
||||
// start parsing
|
||||
// TODO: Split this out into more helps. Too many tabs!
|
||||
while(optional_string("#ControlConfigOverride")) {
|
||||
config_item *cfg_preset = new config_item[CCFG_MAX + 1];
|
||||
std::copy(Control_config, Control_config + CCFG_MAX + 1, cfg_preset);
|
||||
Control_config_presets.push_back(cfg_preset);
|
||||
|
||||
SCP_string preset_name;
|
||||
if (optional_string("$Name:")) {
|
||||
stuff_string_line(preset_name);
|
||||
} else {
|
||||
preset_name = "<unnamed preset>";
|
||||
}
|
||||
Control_config_preset_names.push_back(preset_name);
|
||||
|
||||
while (required_string_either("#End","$Bind Name:")) {
|
||||
const int iBufferLength = 64;
|
||||
char szTempBuffer[iBufferLength];
|
||||
|
||||
required_string("$Bind Name:");
|
||||
stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
|
||||
const size_t cCntrlAryLength = sizeof(Control_config) / sizeof(Control_config[0]);
|
||||
for (size_t i = 0; i < cCntrlAryLength; ++i) {
|
||||
config_item& r_ccConfig = cfg_preset[i];
|
||||
|
||||
if (!strcmp(szTempBuffer, r_ccConfig.text)) {
|
||||
/**
|
||||
* short key_default;
|
||||
* short joy_default;
|
||||
* char tab;
|
||||
* bool hasXSTR;
|
||||
* char type;
|
||||
*/
|
||||
|
||||
int iTemp;
|
||||
|
||||
if (optional_string("$Key Default:")) {
|
||||
if (optional_string("NONE")) {
|
||||
r_ccConfig.key_default = (short)-1;
|
||||
} else {
|
||||
stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
r_ccConfig.key_default = (short)mKeyNameToVal[szTempBuffer];
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Joy Default:")) {
|
||||
stuff_int(&iTemp);
|
||||
r_ccConfig.joy_default = (short)iTemp;
|
||||
}
|
||||
|
||||
if (optional_string("$Key Mod Shift:")) {
|
||||
stuff_int(&iTemp);
|
||||
r_ccConfig.key_default |= (iTemp == 1) ? KEY_SHIFTED : 0;
|
||||
}
|
||||
|
||||
if (optional_string("$Key Mod Alt:")) {
|
||||
stuff_int(&iTemp);
|
||||
r_ccConfig.key_default |= (iTemp == 1) ? KEY_ALTED : 0;
|
||||
}
|
||||
|
||||
if (optional_string("$Key Mod Ctrl:")) {
|
||||
stuff_int(&iTemp);
|
||||
r_ccConfig.key_default |= (iTemp == 1) ? KEY_CTRLED : 0;
|
||||
}
|
||||
|
||||
if (optional_string("$Category:")) {
|
||||
stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
r_ccConfig.tab = (char)mCCTabNameToVal[szTempBuffer];
|
||||
}
|
||||
|
||||
if (optional_string("$Has XStr:")) {
|
||||
stuff_int(&iTemp);
|
||||
r_ccConfig.hasXSTR = (iTemp == 1);
|
||||
}
|
||||
|
||||
if (optional_string("$Type:")) {
|
||||
stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
r_ccConfig.type = (char)mCCTypeNameToVal[szTempBuffer];
|
||||
}
|
||||
|
||||
if (optional_string("+Disable")) {
|
||||
r_ccConfig.disabled = true;
|
||||
}
|
||||
if (optional_string("$Disable:")) {
|
||||
stuff_boolean(&r_ccConfig.disabled);
|
||||
}
|
||||
|
||||
// Nerf the buffer now.
|
||||
szTempBuffer[0] = '\0';
|
||||
} else if ((i + 1) == cCntrlAryLength) {
|
||||
error_display(1, "Bind Name not found: %s\n", szTempBuffer);
|
||||
advance_to_eoln(NULL);
|
||||
ignore_white_space();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// Overwrite the control config with the first preset that was found
|
||||
if (Control_config_presets.size() > 0) {
|
||||
std::copy(Control_config_presets[0], Control_config_presets[0] + CCFG_MAX + 1, Control_config);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FREESPACE_CUTSCENES_SCREEN_HEADER_FILE
|
||||
#define _FREESPACE_CUTSCENES_SCREEN_HEADER_FILE
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
typedef struct cutscene_info {
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
char name[NAME_LENGTH];
|
||||
char *description;
|
||||
int cd;
|
||||
bool viewable;
|
||||
} cutscene_info;
|
||||
|
||||
extern SCP_vector<cutscene_info> Cutscenes;
|
||||
|
||||
// initializa table data
|
||||
void cutscene_init();
|
||||
int cutscene_get_cd_num(char *filename);
|
||||
|
||||
void cutscenes_screen_init();
|
||||
void cutscenes_screen_close();
|
||||
void cutscenes_screen_do_frame();
|
||||
|
||||
int cutscenes_validate_cd(char *mve_name, int prompt_for_cd = 1);
|
||||
void cutscene_mark_viewable(char *filename);
|
||||
|
||||
#endif
|
||||
@@ -1,570 +0,0 @@
|
||||
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
extern int g_width, g_height;
|
||||
extern void *g_vBackBuf1, *g_vBackBuf2;
|
||||
|
||||
/* 16 bit decoding routines */
|
||||
|
||||
static ushort *backBuf1, *backBuf2;
|
||||
static int lookup_initialized;
|
||||
|
||||
static void dispatchDecoder16(ushort **pFrame, ubyte codeType, ubyte **pData, ubyte **pOffData, int *pDataRemain, int *curXb, int *curYb);
|
||||
static void genLoopkupTable();
|
||||
|
||||
void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, unsigned char *pData, int dataRemain)
|
||||
{
|
||||
ubyte *pOrig, *pOffData, op;
|
||||
ushort offset;
|
||||
int length = 0, i, j, xb, yb;
|
||||
|
||||
if (!lookup_initialized) {
|
||||
genLoopkupTable();
|
||||
}
|
||||
|
||||
backBuf1 = (ushort *)g_vBackBuf1;
|
||||
backBuf2 = (ushort *)g_vBackBuf2;
|
||||
|
||||
xb = g_width >> 3;
|
||||
yb = g_height >> 3;
|
||||
|
||||
offset = pData[0]|(pData[1]<<8);
|
||||
|
||||
pOffData = pData + offset;
|
||||
|
||||
pData += 2;
|
||||
|
||||
pOrig = pData;
|
||||
length = offset - 2; /*dataRemain-2;*/
|
||||
|
||||
for (j=0; j<yb; j++) {
|
||||
for (i=0; i<xb/2; i++) {
|
||||
op = (*pMap) & 0xf;
|
||||
dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
|
||||
|
||||
op = ((*pMap) >> 4) & 0xf;
|
||||
dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
|
||||
|
||||
pMap++;
|
||||
mapRemain--;
|
||||
}
|
||||
|
||||
pFrame += 7*g_width*2;
|
||||
}
|
||||
|
||||
if ((length-(pData-pOrig)) != 0) {
|
||||
nprintf(("MVE", "DEBUG: junk left over: " PTRDIFF_T_ARG ",%d," PTRDIFF_T_ARG "\n",
|
||||
(pData-pOrig), length, (length-(pData-pOrig))));
|
||||
}
|
||||
}
|
||||
|
||||
static ushort GETPIXEL(unsigned char **buf, int off)
|
||||
{
|
||||
ushort val = (*buf)[0+off] | ((*buf)[1+off] << 8);
|
||||
return val;
|
||||
}
|
||||
|
||||
static ushort GETPIXELI(unsigned char **buf, int off)
|
||||
{
|
||||
ushort val = (*buf)[0+off] | ((*buf)[1+off] << 8);
|
||||
(*buf) += 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
static void relClose(int i, int *x, int *y)
|
||||
{
|
||||
int ma, mi;
|
||||
|
||||
ma = i >> 4;
|
||||
mi = i & 0xf;
|
||||
|
||||
*x = mi - 8;
|
||||
*y = ma - 8;
|
||||
}
|
||||
|
||||
static void relFar(int i, int sign, int *x, int *y)
|
||||
{
|
||||
if (i < 56) {
|
||||
*x = sign * (8 + (i % 7));
|
||||
*y = sign * (i / 7);
|
||||
} else {
|
||||
*x = sign * (-14 + (i - 56) % 29);
|
||||
*y = sign * (8 + (i - 56) / 29);
|
||||
}
|
||||
}
|
||||
|
||||
static int close_table[512];
|
||||
static int far_p_table[512];
|
||||
static int far_n_table[512];
|
||||
|
||||
static void genLoopkupTable()
|
||||
{
|
||||
int i;
|
||||
int x, y;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
relClose(i, &x, &y);
|
||||
|
||||
close_table[i*2+0] = x;
|
||||
close_table[i*2+1] = y;
|
||||
|
||||
relFar(i, 1, &x, &y);
|
||||
|
||||
far_p_table[i*2+0] = x;
|
||||
far_p_table[i*2+1] = y;
|
||||
|
||||
relFar(i, -1, &x, &y);
|
||||
|
||||
far_n_table[i*2+0] = x;
|
||||
far_n_table[i*2+1] = y;
|
||||
}
|
||||
|
||||
lookup_initialized = 1;
|
||||
}
|
||||
|
||||
static void copyFrame(ushort *pDest, ushort *pSrc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
memcpy(pDest, pSrc, 16);
|
||||
pDest += g_width;
|
||||
pSrc += g_width;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow4Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, ushort *p)
|
||||
{
|
||||
ushort mask=0x0003;
|
||||
ushort shift=0;
|
||||
ushort pattern = (pat1 << 8) | pat0;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pattern) >> shift];
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow4Pixels2(ushort *pFrame, unsigned char pat0, ushort *p)
|
||||
{
|
||||
unsigned char mask=0x03;
|
||||
unsigned char shift=0;
|
||||
ushort pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat0) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow4Pixels2x1(ushort *pFrame, unsigned char pat, ushort *p)
|
||||
{
|
||||
unsigned char mask=0x03;
|
||||
unsigned char shift=0;
|
||||
ushort pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternQuadrant4Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, unsigned char pat2, unsigned char pat3, ushort *p)
|
||||
{
|
||||
unsigned long mask = 0x00000003UL;
|
||||
int shift=0;
|
||||
int i;
|
||||
unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) >> shift];
|
||||
if ((i&3) == 3) {
|
||||
pFrame += g_width;
|
||||
}
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow2Pixels(ushort *pFrame, unsigned char pat, ushort *p)
|
||||
{
|
||||
unsigned char mask=0x01;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pat) ? 1 : 0];
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternRow2Pixels2(ushort *pFrame, unsigned char pat, ushort *p)
|
||||
{
|
||||
ushort pel;
|
||||
unsigned char mask=0x1;
|
||||
|
||||
while (mask != 0x10) {
|
||||
pel = p[(mask & pat) ? 1 : 0];
|
||||
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 1] = pel;
|
||||
pFrame += 2;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void patternQuadrant2Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, ushort *p)
|
||||
{
|
||||
ushort mask = 0x0001;
|
||||
int i;
|
||||
ushort pat = (pat1 << 8) | pat0;
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) ? 1 : 0];
|
||||
if ((i&3) == 3) {
|
||||
pFrame += g_width;
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb)
|
||||
{
|
||||
ushort p[4];
|
||||
unsigned char pat[16];
|
||||
int i, j, k;
|
||||
int x, y;
|
||||
ushort *pDstBak;
|
||||
|
||||
pDstBak = *pFrame;
|
||||
|
||||
switch(codeType) {
|
||||
case 0x0:
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1));
|
||||
break; // ADDED
|
||||
|
||||
case 0x1:
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
k = *(*pOffData)++;
|
||||
x = far_p_table[k*2+0];
|
||||
y = far_p_table[k*2+1];
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
k = *(*pOffData)++;
|
||||
x = far_n_table[k*2+0];
|
||||
y = far_n_table[k*2+1];
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
k = *(*pOffData)++;
|
||||
x = close_table[k*2+0];
|
||||
y = close_table[k*2+1];
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
x = (char)*(*pData)++;
|
||||
y = (char)*(*pData)++;
|
||||
copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
|
||||
*pDataRemain -= 2;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
nprintf(("MVE", "STUB: encoding 6 not tested\n"));
|
||||
for (i=0; i<2; i++) {
|
||||
*pFrame += 16;
|
||||
if (++*curXb == (g_width >> 3)) {
|
||||
*pFrame += 7*g_width;
|
||||
*curXb = 0;
|
||||
if (++*curYb == (g_height >> 3)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
if (!((p[0]/*|p[1]*/)&0x8000)) {
|
||||
for (i=0; i<8; i++) {
|
||||
patternRow2Pixels(*pFrame, *(*pData), p);
|
||||
(*pData)++;
|
||||
*pFrame += g_width;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<2; i++) {
|
||||
patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow2Pixels2(*pFrame, *(*pData) >> 4, p);
|
||||
(*pData)++;
|
||||
*pFrame += 2*g_width;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
(*pData) += 2;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p[2] = GETPIXEL(pData, 8);
|
||||
if (!(p[2]&0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
if ((i & 1) == 0) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
}
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<8; i++) {
|
||||
if ((i & 3) == 0) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
}
|
||||
patternRow2Pixels(*pFrame, *(*pData), p);
|
||||
(*pData)++;
|
||||
*pFrame += g_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
*pDataRemain -= 8;
|
||||
if (!(p[0] & 0x8000)) {
|
||||
if (!(p[2] & 0x8000)) {
|
||||
for (i=0; i<8; i++) {
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
(*pData) += 2;
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pDataRemain -= 16;
|
||||
} else {
|
||||
patternRow4Pixels2(*pFrame, (*pData)[0], p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow4Pixels2(*pFrame, (*pData)[1], p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow4Pixels2(*pFrame, (*pData)[2], p);
|
||||
*pFrame += 2*g_width;
|
||||
patternRow4Pixels2(*pFrame, (*pData)[3], p);
|
||||
(*pData) += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
} else {
|
||||
if (!(p[2] & 0x8000)) {
|
||||
for (i=0; i<8; i++) {
|
||||
pat[0] = (*pData)[0];
|
||||
(*pData) += 1;
|
||||
patternRow4Pixels2x1(*pFrame, pat[0], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pDataRemain -= 8;
|
||||
} else {
|
||||
for (i=0; i<4; i++) {
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
(*pData) += 2;
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
pat[2] = (*pData)[2];
|
||||
pat[3] = (*pData)[3];
|
||||
(*pData) += 4;
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p[0] = GETPIXEL(pData, 16);
|
||||
if (!(p[0] & 0x8000)) {
|
||||
for (i=0; i<4; i++) {
|
||||
if ((i&1) == 0) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
}
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
pat[2] = (*pData)[2];
|
||||
pat[3] = (*pData)[3];
|
||||
(*pData) += 4;
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
if (i & 1) {
|
||||
*pFrame -= (4*g_width - 4);
|
||||
} else {
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<8; i++) {
|
||||
if ((i&3) == 0) {
|
||||
p[0] = GETPIXELI(pData, 0);
|
||||
p[1] = GETPIXELI(pData, 0);
|
||||
p[2] = GETPIXELI(pData, 0);
|
||||
p[3] = GETPIXELI(pData, 0);
|
||||
}
|
||||
pat[0] = (*pData)[0];
|
||||
pat[1] = (*pData)[1];
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
(*pData) += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
for (i=0; i<8; i++) {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
ubyte frame_tmp[16];
|
||||
memcpy(&frame_tmp, *pData, 16);
|
||||
ushort *swap_tmp;
|
||||
for (j = 0; j < 16; j += 2) {
|
||||
swap_tmp = (ushort*)(frame_tmp + j);
|
||||
*swap_tmp = INTEL_SHORT(*swap_tmp);
|
||||
}
|
||||
memcpy(*pFrame, &frame_tmp, 16);
|
||||
#else
|
||||
memcpy(*pFrame, *pData, 16);
|
||||
#endif
|
||||
*pFrame += g_width;
|
||||
*pData += 16;
|
||||
*pDataRemain -= 16;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc:
|
||||
for (i=0; i<4; i++) {
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
p[1] = GETPIXEL(pData, 2);
|
||||
p[2] = GETPIXEL(pData, 4);
|
||||
p[3] = GETPIXEL(pData, 6);
|
||||
for (j=0; j<2; j++) {
|
||||
for (k=0; k<4; k++) {
|
||||
(*pFrame)[2*k] = p[k];
|
||||
(*pFrame)[2*k+1] = p[k];
|
||||
}
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pData += 8;
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xd:
|
||||
for (i=0; i<2; i++) {
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
p[1] = GETPIXEL(pData, 2);
|
||||
for (j=0; j<4; j++) {
|
||||
for (k=0; k<4; k++) {
|
||||
(*pFrame)[k*g_width+j] = p[0];
|
||||
(*pFrame)[k*g_width+j+4] = p[1];
|
||||
}
|
||||
}
|
||||
*pFrame += 4*g_width;
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
(*pFrame)[j] = p[0];
|
||||
}
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
break;
|
||||
|
||||
case 0xf:
|
||||
p[0] = GETPIXEL(pData, 0);
|
||||
p[1] = GETPIXEL(pData, 1);
|
||||
for (i=0; i<8; i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
(*pFrame)[j] = p[(i+j)&1];
|
||||
}
|
||||
*pFrame += g_width;
|
||||
}
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*pFrame = pDstBak+8;
|
||||
}
|
||||
@@ -1,533 +0,0 @@
|
||||
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
|
||||
extern int g_width, g_height;
|
||||
extern void *g_vBackBuf1, *g_vBackBuf2;
|
||||
|
||||
static void dispatchDecoder8(ubyte **pFrame, ubyte codeType, ubyte **pData, int *pDataRemain, int *curXb, int *curYb);
|
||||
|
||||
void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
|
||||
{
|
||||
int i, j;
|
||||
int xb, yb;
|
||||
|
||||
xb = g_width >> 3;
|
||||
yb = g_height >> 3;
|
||||
|
||||
for (j = 0; j < yb; j++) {
|
||||
for (i = 0; i < (xb / 2); i++) {
|
||||
dispatchDecoder8(&pFrame, (*pMap) & 0xf, &pData, &dataRemain, &i, &j);
|
||||
|
||||
dispatchDecoder8(&pFrame, (*pMap) >> 4, &pData, &dataRemain, &i, &j);
|
||||
|
||||
pMap++;
|
||||
mapRemain--;
|
||||
}
|
||||
|
||||
pFrame += 7*g_width;
|
||||
}
|
||||
}
|
||||
|
||||
static void relClose(int i, int *x, int *y)
|
||||
{
|
||||
int ma, mi;
|
||||
|
||||
ma = i >> 4;
|
||||
mi = i & 0xf;
|
||||
|
||||
*x = mi - 8;
|
||||
*y = ma - 8;
|
||||
}
|
||||
|
||||
static void relFar(int i, int sign, int *x, int *y)
|
||||
{
|
||||
if (i < 56) {
|
||||
*x = sign * (8 + (i % 7));
|
||||
*y = sign * (i / 7);
|
||||
} else {
|
||||
*x = sign * (-14 + (i - 56) % 29);
|
||||
*y = sign * (8 + (i - 56) / 29);
|
||||
}
|
||||
}
|
||||
|
||||
/* copies an 8x8 block from pSrc to pDest.
|
||||
pDest and pSrc are both g_width bytes wide */
|
||||
static void copyFrame(ubyte *pDest, ubyte *pSrc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
memcpy(pDest, pSrc, 8);
|
||||
pDest += g_width;
|
||||
pSrc += g_width;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next eight bytes with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0 and pat1
|
||||
static void patternRow4Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte *p)
|
||||
{
|
||||
ushort mask = 0x0003;
|
||||
ushort shift = 0;
|
||||
ushort pattern = (pat1 << 8) | pat0;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pattern) >> shift];
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next four 2x2 pixel blocks with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0.
|
||||
static void patternRow4Pixels2(ubyte *pFrame, ubyte pat0, ubyte *p)
|
||||
{
|
||||
ubyte mask = 0x03;
|
||||
ubyte shift = 0;
|
||||
ubyte pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat0) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame[g_width + 0] = pel;
|
||||
pFrame[g_width + 1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next four 2x1 pixel blocks with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat.
|
||||
static void patternRow4Pixels2x1(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte mask = 0x03;
|
||||
ubyte shift = 0;
|
||||
ubyte pel;
|
||||
|
||||
while (mask != 0) {
|
||||
pel = p[(mask & pat) >> shift];
|
||||
pFrame[0] = pel;
|
||||
pFrame[1] = pel;
|
||||
pFrame += 2;
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the next 4x4 pixel block with p[0], p[1], p[2], or p[3],
|
||||
// depending on the corresponding two-bit value in pat0, pat1, pat2, and pat3.
|
||||
static void patternQuadrant4Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte pat2, ubyte pat3, ubyte *p)
|
||||
{
|
||||
unsigned long mask = 0x00000003UL;
|
||||
int shift=0;
|
||||
int i;
|
||||
unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
pFrame[i&3] = p[(pat & mask) >> shift];
|
||||
|
||||
if ( (i & 3) == 3 )
|
||||
pFrame += g_width;
|
||||
|
||||
mask <<= 2;
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// fills the next 8 pixels with either p[0] or p[1], depending on pattern
|
||||
static void patternRow2Pixels(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte mask=0x01;
|
||||
|
||||
while (mask != 0) {
|
||||
*pFrame++ = p[(mask & pat) ? 1 : 0];
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// fills the next four 2 x 2 pixel boxes with either p[0] or p[1], depending on pattern
|
||||
static void patternRow2Pixels2(ubyte *pFrame, ubyte pat, ubyte *p)
|
||||
{
|
||||
ubyte pel;
|
||||
ubyte mask=0x1;
|
||||
|
||||
while (mask != 0x10) {
|
||||
pel = p[(mask & pat) ? 1 : 0];
|
||||
|
||||
pFrame[0] = pel; // upper-left
|
||||
pFrame[1] = pel; // upper-right
|
||||
pFrame[g_width + 0] = pel; // lower-left
|
||||
pFrame[g_width + 1] = pel; // lower-right
|
||||
pFrame += 2;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// fills pixels in the next 4 x 4 pixel boxes with either p[0] or p[1], depending on pat0 and pat1.
|
||||
static void patternQuadrant2Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte *p)
|
||||
{
|
||||
ubyte pel;
|
||||
ushort mask = 0x0001;
|
||||
int i, j;
|
||||
ushort pat = (pat1 << 8) | pat0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
pel = p[(pat & mask) ? 1 : 0];
|
||||
|
||||
pFrame[j + i * g_width] = pel;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dispatchDecoder8(ubyte **pFrame, ubyte codeType, ubyte **pData, int *pDataRemain, int *curXb, int *curYb)
|
||||
{
|
||||
ubyte p[4];
|
||||
ubyte pat[16];
|
||||
int i, j, k;
|
||||
int x, y;
|
||||
|
||||
switch(codeType) {
|
||||
case 0x0:
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1));
|
||||
*pFrame += 8;
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
*pFrame += 8;
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
relFar(*(*pData)++, 1, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
relFar(*(*pData)++, -1, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
relClose(*(*pData)++, &x, &y);
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1) + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
(*pDataRemain)--;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
x = (signed char)*(*pData)++;
|
||||
y = (signed char)*(*pData)++;
|
||||
copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1) + x + y*g_width);
|
||||
*pFrame += 8;
|
||||
*pDataRemain -= 2;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
for (i = 0; i < 2; i++) {
|
||||
*pFrame += 16;
|
||||
|
||||
if (++*curXb == (g_width >> 3)) {
|
||||
*pFrame += 7*g_width;
|
||||
*curXb = 0;
|
||||
|
||||
if (++*curYb == (g_height >> 3))
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
|
||||
if (p[0] <= p[1]) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
patternRow2Pixels(*pFrame, *(*pData)++, p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 2; i++) {
|
||||
patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow2Pixels2(*pFrame, *(*pData)++ >> 4, p);
|
||||
*pFrame += 2*g_width;
|
||||
}
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
// four quadrant case
|
||||
for (i = 0; i < 4; i++) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
// alternate between moving down and moving up and right
|
||||
if (i & 1)
|
||||
*pFrame += 4 - 4*g_width; // up and right
|
||||
else
|
||||
*pFrame += 4*g_width; // down
|
||||
}
|
||||
} else if ( (*pData)[6] <= (*pData)[7] ) {
|
||||
// split horizontal
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((i & 1) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
// split vertical
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((i & 3) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
}
|
||||
|
||||
patternRow2Pixels(*pFrame, *(*pData)++, p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
if ( (*pData)[2] <= (*pData)[3] ) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
} else {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame += 2*g_width;
|
||||
|
||||
patternRow4Pixels2(*pFrame, *(*pData)++, p);
|
||||
*pFrame -= (6*g_width - 8);
|
||||
}
|
||||
} else {
|
||||
if ( (*pData)[2] <= (*pData)[3] ) {
|
||||
// draw 2x1 strips
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels2x1(*pFrame, pat[0], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
} else {
|
||||
// draw 1x2 strips
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
if ( (*pData)[0] <= (*pData)[1] ) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
pat[2] = *(*pData)++;
|
||||
pat[3] = *(*pData)++;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
if ( (*pData)[12] <= (*pData)[13] ) {
|
||||
// split vertical
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((i&1) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
pat[2] = *(*pData)++;
|
||||
pat[3] = *(*pData)++;
|
||||
|
||||
patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
|
||||
|
||||
if (i & 1)
|
||||
*pFrame -= (4*g_width - 4);
|
||||
else
|
||||
*pFrame += 4*g_width;
|
||||
}
|
||||
} else {
|
||||
// split horizontal
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((i&3) == 0) {
|
||||
p[0] = *(*pData)++;
|
||||
p[1] = *(*pData)++;
|
||||
p[2] = *(*pData)++;
|
||||
p[3] = *(*pData)++;
|
||||
}
|
||||
|
||||
pat[0] = *(*pData)++;
|
||||
pat[1] = *(*pData)++;
|
||||
|
||||
patternRow4Pixels(*pFrame, pat[0], pat[1], p);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
for (i = 0; i < 8; i++) {
|
||||
memcpy(*pFrame, *pData, 8);
|
||||
*pFrame += g_width;
|
||||
*pData += 8;
|
||||
*pDataRemain -= 8;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xc:
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
(*pFrame)[2*k] = (*pData)[k];
|
||||
(*pFrame)[2*k+1] = (*pData)[k];
|
||||
}
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 4;
|
||||
*pDataRemain -= 4;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xd:
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
(*pFrame)[k*g_width+j] = (*pData)[0];
|
||||
(*pFrame)[k*g_width+j+4] = (*pData)[1];
|
||||
}
|
||||
}
|
||||
|
||||
*pFrame += 4*g_width;
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
}
|
||||
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xe:
|
||||
for (i = 0; i < 8; i++) {
|
||||
memset(*pFrame, **pData, 8);
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
(*pData)++;
|
||||
(*pDataRemain)--;
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
case 0xf:
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
(*pFrame)[j] = (*pData)[(i+j)&1];
|
||||
}
|
||||
|
||||
*pFrame += g_width;
|
||||
}
|
||||
|
||||
*pData += 2;
|
||||
*pDataRemain -= 2;
|
||||
*pFrame -= (8*g_width - 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "cutscene/cutscenes.h" // cutscene_mark_viewable()
|
||||
#include "cutscene/movie.h"
|
||||
#include "cutscene/mvelib.h"
|
||||
#include "cutscene/oggplayer.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "osapi/osapi.h"
|
||||
|
||||
extern int Game_mode;
|
||||
|
||||
const char *movie_ext_list[] = { ".ogg", ".mve" };
|
||||
const int NUM_MOVIE_EXT = sizeof(movie_ext_list) / sizeof(char*);
|
||||
|
||||
|
||||
#define MOVIE_NONE -1
|
||||
#define MOVIE_OGG 0
|
||||
#define MOVIE_MVE 1
|
||||
|
||||
// This module links freespace movie calls to the actual API calls the play the movie.
|
||||
// This module handles all the different requires of OS and gfx API and finding the file to play
|
||||
|
||||
|
||||
// filename - file to search for
|
||||
// out_name - output, full path to file
|
||||
// returns non-zero if file is found
|
||||
int movie_find(char *filename, char *out_name)
|
||||
{
|
||||
char full_path[MAX_PATH];
|
||||
char tmp_name[MAX_PATH];
|
||||
int size, offset = 0;
|
||||
|
||||
if (out_name == NULL)
|
||||
return MOVIE_NONE;
|
||||
|
||||
|
||||
memset( full_path, 0, sizeof(full_path) );
|
||||
memset( tmp_name, 0, sizeof(tmp_name) );
|
||||
|
||||
// remove extension
|
||||
strcpy_s( tmp_name, filename );
|
||||
char *p = strrchr(tmp_name, '.');
|
||||
if ( p ) *p = 0;
|
||||
|
||||
int rc = cf_find_file_location_ext(tmp_name, NUM_MOVIE_EXT, movie_ext_list, CF_TYPE_ANY, sizeof(full_path) - 1, full_path, &size, &offset, 0);
|
||||
|
||||
if (rc == MOVIE_NONE)
|
||||
return MOVIE_NONE;
|
||||
|
||||
strcpy( out_name, full_path );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Play one movie
|
||||
bool movie_play(char *name)
|
||||
{
|
||||
// mark the movie as viewable to the player when in a campaign
|
||||
// do this before anything else so that we're sure the movie is available
|
||||
// to the player even if it's not going to play right now
|
||||
if (Game_mode & GM_CAMPAIGN_MODE) {
|
||||
cutscene_mark_viewable(name);
|
||||
}
|
||||
|
||||
extern int Is_standalone;
|
||||
|
||||
if (Cmdline_nomovies || Is_standalone)
|
||||
return false;
|
||||
|
||||
|
||||
char full_name[MAX_PATH];
|
||||
int rc = 0;
|
||||
|
||||
memset(full_name, 0, sizeof(full_name));
|
||||
|
||||
rc = movie_find(name, full_name);
|
||||
|
||||
if (rc == MOVIE_NONE) {
|
||||
strcpy_s(full_name, name);
|
||||
char *p = strrchr(full_name, '.');
|
||||
if ( p ) *p = 0;
|
||||
|
||||
mprintf(("Movie Error: Unable to open '%s' movie in any supported format.\n", full_name));
|
||||
return false;
|
||||
}
|
||||
|
||||
// clear the screen and hide the mouse cursor
|
||||
io::mouse::CursorManager::get()->pushStatus();
|
||||
io::mouse::CursorManager::get()->showCursor(false);
|
||||
gr_reset_clip();
|
||||
gr_set_color(255, 255, 255);
|
||||
gr_set_clear_color(0, 0, 0);
|
||||
gr_zbuffer_clear(0);
|
||||
// clear first buffer
|
||||
gr_clear();
|
||||
gr_flip();
|
||||
// clear second buffer (may not be one, but that's ok)
|
||||
gr_clear();
|
||||
gr_flip();
|
||||
// clear third buffer (may not be one, but that's ok)
|
||||
gr_clear();
|
||||
|
||||
if (rc == MOVIE_OGG) {
|
||||
THEORAFILE *movie_ogg = theora_open(name);
|
||||
|
||||
if (movie_ogg) {
|
||||
// start playing ...
|
||||
theora_play(movie_ogg);
|
||||
|
||||
// ... done playing, close the movie
|
||||
theora_close(movie_ogg);
|
||||
} else {
|
||||
// uh-oh, movie is invalid... Abory, Retry, Fail?
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
io::mouse::CursorManager::get()->popStatus();
|
||||
return false;
|
||||
}
|
||||
} else if (rc == MOVIE_MVE) {
|
||||
MVESTREAM *movie_mve = mve_open(name);
|
||||
|
||||
if (movie_mve) {
|
||||
// start playing ...
|
||||
mve_init(movie_mve);
|
||||
mve_play(movie_mve);
|
||||
|
||||
// ... done playing, close the movie
|
||||
mve_shutdown();
|
||||
mve_close(movie_mve);
|
||||
} else {
|
||||
// uh-oh, movie is invalid... Abory, Retry, Fail?
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
io::mouse::CursorManager::get()->popStatus();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// show the mouse cursor again
|
||||
io::mouse::CursorManager::get()->popStatus();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void movie_play_two(char *name1, char *name2)
|
||||
{
|
||||
if ( movie_play(name1) )
|
||||
movie_play(name2);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _MOVIE_HEADER_FILE
|
||||
#define _MOVIE_HEADER_FILE
|
||||
|
||||
extern const char *movie_ext_list[];
|
||||
extern const int NUM_MOVIE_EXT;
|
||||
|
||||
bool movie_play(char *name);
|
||||
void movie_play_two(char *name1, char *name2);
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
|
||||
|
||||
static int audio_exp_table[256] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47, 51, 56, 61,
|
||||
66, 72, 79, 86, 94, 102, 112, 122, 133, 145, 158, 173, 189, 206, 225, 245,
|
||||
267, 292, 318, 348, 379, 414, 452, 493, 538, 587, 640, 699, 763, 832, 908, 991,
|
||||
1081, 1180, 1288, 1405, 1534, 1673, 1826, 1993, 2175, 2373, 2590, 2826, 3084, 3365, 3672, 4008,
|
||||
4373, 4772, 5208, 5683, 6202, 6767, 7385, 8059, 8794, 9597, 10472, 11428, 12471, 13609, 14851, 16206,
|
||||
17685, 19298, 21060, 22981, 25078, 27367, 29864, 32589, -29973, -26728, -23186, -19322, -15105, -10503, -5481, -1,
|
||||
1, 1, 5481, 10503, 15105, 19322, 23186, 26728, 29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
|
||||
-17685, -16206, -14851, -13609, -12471, -11428, -10472, -9597, -8794, -8059, -7385, -6767, -6202, -5683, -5208, -4772,
|
||||
-4373, -4008, -3672, -3365, -3084, -2826, -2590, -2373, -2175, -1993, -1826, -1673, -1534, -1405, -1288, -1180,
|
||||
-1081, -991, -908, -832, -763, -699, -640, -587, -538, -493, -452, -414, -379, -348, -318, -292,
|
||||
-267, -245, -225, -206, -189, -173, -158, -145, -133, -122, -112, -102, -94, -86, -79, -72,
|
||||
-66, -61, -56, -51, -47, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33,
|
||||
-32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17,
|
||||
-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1
|
||||
};
|
||||
|
||||
static int getWord(unsigned char **fin)
|
||||
{
|
||||
int value = ((*fin)[1] << 8) | (*fin)[0];
|
||||
*fin += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
static void sendWord(short **fout, int nOffset)
|
||||
{
|
||||
*(*fout)++ = (short)nOffset;
|
||||
}
|
||||
|
||||
static void processSwath(short *fout, unsigned char *data, int swath, int *offsets)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<swath; i++) {
|
||||
offsets[i&1] += audio_exp_table[data[i]];
|
||||
sendWord(&fout, offsets[i&1]);
|
||||
}
|
||||
}
|
||||
|
||||
void mveaudio_uncompress(short *buffer, unsigned char *data)
|
||||
{
|
||||
int nCurOffsets[2];
|
||||
int swath;
|
||||
|
||||
data += 4;
|
||||
swath = getWord(&data) / 2;
|
||||
nCurOffsets[0] = getWord(&data);
|
||||
nCurOffsets[1] = getWord(&data);
|
||||
sendWord(&buffer, nCurOffsets[0]);
|
||||
sendWord(&buffer, nCurOffsets[1]);
|
||||
processSwath(buffer, data, swath, nCurOffsets);
|
||||
}
|
||||
@@ -1,371 +0,0 @@
|
||||
|
||||
|
||||
#include "cfile/cfile.h"
|
||||
#include "cutscene/mvelib.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
|
||||
static const char MVE_HEADER[] = "Interplay MVE File\x1A";
|
||||
static const short MVE_HDRCONST1 = 0x001A;
|
||||
static const short MVE_HDRCONST2 = 0x0100;
|
||||
static const short MVE_HDRCONST3 = 0x1133;
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// public MVEFILE functions
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// utility functions for mvefile and mveplayer
|
||||
short mve_get_short(ubyte *data)
|
||||
{
|
||||
short value;
|
||||
value = data[0] | (data[1] << 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
ushort mve_get_ushort(ubyte *data)
|
||||
{
|
||||
ushort value;
|
||||
value = data[0] | (data[1] << 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
int mve_get_int(ubyte *data)
|
||||
{
|
||||
int value;
|
||||
value = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
|
||||
return value;
|
||||
}
|
||||
|
||||
// open an MVE file
|
||||
MVEFILE *mvefile_open(char *filename)
|
||||
{
|
||||
int cf_opened = 0;
|
||||
int mve_valid = 1;
|
||||
char lower_name[MAX_FILENAME_LEN];
|
||||
char buffer[20];
|
||||
MVEFILE *file;
|
||||
|
||||
// create the file
|
||||
file = (MVEFILE *)vm_malloc(sizeof(MVEFILE));
|
||||
|
||||
// set defaults
|
||||
file->stream = NULL;
|
||||
file->cur_chunk = NULL;
|
||||
file->buf_size = 0;
|
||||
file->cur_fill = 0;
|
||||
file->next_segment = 0;
|
||||
|
||||
// lower case filename for checking
|
||||
strncpy(lower_name, filename, strlen(filename)+1);
|
||||
strlwr(lower_name);
|
||||
|
||||
char *p = strchr( lower_name, '.' );
|
||||
if ( p ) *p = 0;
|
||||
|
||||
strcat_s( lower_name, ".mve" );
|
||||
|
||||
// NOTE: CF_TYPE *must* be ANY to get movies off of the CDs
|
||||
// assume lower case filename for *nix
|
||||
file->stream = cfopen(lower_name, "rb", CFILE_NORMAL, CF_TYPE_ANY);
|
||||
if ( file->stream ) {
|
||||
cf_opened = 1;
|
||||
}
|
||||
|
||||
if (!cf_opened) {
|
||||
mvefile_close(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// initialize the buffer
|
||||
file->cur_chunk = (ubyte *)vm_malloc(100 + 1024);
|
||||
file->buf_size = 100 + 1024;
|
||||
|
||||
// verify the file's header
|
||||
cfread_string(buffer, 20, file->stream);
|
||||
|
||||
if (strcmp(buffer, MVE_HEADER))
|
||||
mve_valid = 0;
|
||||
|
||||
if (cfread_short(file->stream) != MVE_HDRCONST1)
|
||||
mve_valid = 0;
|
||||
|
||||
if (cfread_short(file->stream) != MVE_HDRCONST2)
|
||||
mve_valid = 0;
|
||||
|
||||
if (cfread_short(file->stream) != MVE_HDRCONST3)
|
||||
mve_valid = 0;
|
||||
|
||||
if (!mve_valid) {
|
||||
mvefile_close(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// now, prefetch the next chunk
|
||||
mvefile_fetch_next_chunk(file);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
// close a MVE file
|
||||
void mvefile_close(MVEFILE *file)
|
||||
{
|
||||
// free the stream
|
||||
if (file->stream)
|
||||
cfclose(file->stream);
|
||||
|
||||
file->stream = NULL;
|
||||
|
||||
// free the buffer
|
||||
if (file->cur_chunk)
|
||||
vm_free(file->cur_chunk);
|
||||
|
||||
file->cur_chunk = NULL;
|
||||
|
||||
// not strictly necessary
|
||||
file->buf_size = 0;
|
||||
file->cur_fill = 0;
|
||||
file->next_segment = 0;
|
||||
|
||||
// free the struct
|
||||
vm_free(file);
|
||||
}
|
||||
|
||||
// get the size of the next segment
|
||||
int mvefile_get_next_segment_size(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return -1;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return -1;
|
||||
|
||||
// otherwise, get the data length
|
||||
return mve_get_short(file->cur_chunk + file->next_segment);
|
||||
}
|
||||
|
||||
// get type of next segment in chunk (0xff if no more segments in chunk)
|
||||
ubyte mvefile_get_next_segment_major(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return 0xff;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return 0xff;
|
||||
|
||||
// otherwise, get the data length
|
||||
return file->cur_chunk[file->next_segment + 2];
|
||||
}
|
||||
|
||||
// get subtype (version) of next segment in chunk (0xff if no more segments in chunk)
|
||||
ubyte mvefile_get_next_segment_minor(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return 0xff;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return 0xff;
|
||||
|
||||
// otherwise, get the data length
|
||||
return file->cur_chunk[file->next_segment + 3];
|
||||
}
|
||||
|
||||
// see next segment (return NULL if no next segment)
|
||||
ubyte *mvefile_get_next_segment(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return NULL;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return NULL;
|
||||
|
||||
// otherwise, get the data length
|
||||
return file->cur_chunk + file->next_segment + 4;
|
||||
}
|
||||
|
||||
// advance to next segment
|
||||
void mvefile_advance_segment(MVEFILE *file)
|
||||
{
|
||||
// if nothing is cached, fail
|
||||
if (file->cur_chunk == NULL || file->next_segment >= file->cur_fill)
|
||||
return;
|
||||
|
||||
// if we don't have enough data to get a segment, fail
|
||||
if (file->cur_fill - file->next_segment < 4)
|
||||
return;
|
||||
|
||||
// else, advance to next segment
|
||||
file->next_segment += (4 + mve_get_ushort(file->cur_chunk + file->next_segment));
|
||||
}
|
||||
|
||||
// fetch the next chunk (return 0 if at end of stream)
|
||||
int mvefile_fetch_next_chunk(MVEFILE *file)
|
||||
{
|
||||
ubyte buffer[4];
|
||||
ubyte *new_buffer;
|
||||
ushort length;
|
||||
|
||||
// fail if not open
|
||||
if (file->stream == NULL)
|
||||
return 0;
|
||||
|
||||
// fail if we can't read the next segment descriptor
|
||||
if (cfread(buffer, 1, 4, file->stream) < 4)
|
||||
return 0;
|
||||
|
||||
// pull out the next length
|
||||
length = mve_get_short(buffer);
|
||||
|
||||
// setup a new buffer if needed --
|
||||
// only allocate new buffer is old one is too small
|
||||
if (length > file->buf_size) {
|
||||
// allocate new buffer
|
||||
new_buffer = (ubyte *)vm_malloc(100 + length);
|
||||
|
||||
// copy old data
|
||||
if (file->cur_chunk && file->cur_fill)
|
||||
memcpy(new_buffer, file->cur_chunk, file->cur_fill);
|
||||
|
||||
// free old buffer
|
||||
if (file->cur_chunk) {
|
||||
vm_free(file->cur_chunk);
|
||||
file->cur_chunk = NULL;
|
||||
}
|
||||
|
||||
// install new buffer
|
||||
file->cur_chunk = new_buffer;
|
||||
file->buf_size = 100 + length;
|
||||
}
|
||||
|
||||
// read the chunk
|
||||
if (length > 0) {
|
||||
if (cfread(file->cur_chunk, 1, length, file->stream) < length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
file->cur_fill = length;
|
||||
file->next_segment = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// public MVESTREAM functions
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// open an MVE stream
|
||||
MVESTREAM *mve_open(char *filename)
|
||||
{
|
||||
MVESTREAM *stream;
|
||||
|
||||
// allocate
|
||||
stream = (MVESTREAM *)vm_malloc(sizeof(MVESTREAM));
|
||||
|
||||
// defaults
|
||||
stream->movie = NULL;
|
||||
|
||||
// open
|
||||
stream->movie = mvefile_open(filename);
|
||||
|
||||
if (stream->movie == NULL) {
|
||||
mve_close(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
// close an MVE stream
|
||||
void mve_close(MVESTREAM *stream)
|
||||
{
|
||||
// close MVEFILE
|
||||
if (stream->movie)
|
||||
mvefile_close(stream->movie);
|
||||
|
||||
stream->movie = NULL;
|
||||
|
||||
vm_free(stream);
|
||||
}
|
||||
|
||||
// play next chunk
|
||||
int mve_play_next_chunk(MVESTREAM *stream)
|
||||
{
|
||||
ubyte major, minor;
|
||||
ubyte *data;
|
||||
int len;
|
||||
|
||||
// loop over segments
|
||||
major = mvefile_get_next_segment_major(stream->movie);
|
||||
while (major != 0xff) {
|
||||
// check whether to handle the segment
|
||||
if (major < 32) {
|
||||
minor = mvefile_get_next_segment_minor(stream->movie);
|
||||
len = mvefile_get_next_segment_size(stream->movie);
|
||||
data = mvefile_get_next_segment(stream->movie);
|
||||
|
||||
switch (major) {
|
||||
case 0x00:
|
||||
mve_end_movie();
|
||||
break;
|
||||
case 0x01:
|
||||
mve_end_chunk();
|
||||
break;
|
||||
case 0x02:
|
||||
mve_timer_create(data);
|
||||
break;
|
||||
case 0x03:
|
||||
mve_audio_createbuf(minor, data);
|
||||
break;
|
||||
case 0x04:
|
||||
mve_audio_play();
|
||||
break;
|
||||
case 0x05:
|
||||
if (!mve_video_createbuf(minor, data))
|
||||
return 0;
|
||||
break;
|
||||
case 0x07:
|
||||
mve_video_display();
|
||||
break;
|
||||
case 0x08:
|
||||
mve_audio_data(major, data);
|
||||
break;
|
||||
case 0x09:
|
||||
mve_audio_data(major, data);
|
||||
break;
|
||||
case 0x0a:
|
||||
if (!mve_video_init(data))
|
||||
return 0;
|
||||
break;
|
||||
case 0x0c:
|
||||
mve_video_palette(data);
|
||||
break;
|
||||
case 0x0f:
|
||||
mve_video_codemap(data, len);
|
||||
break;
|
||||
case 0x11:
|
||||
mve_video_data(data, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// advance to next segment
|
||||
mvefile_advance_segment(stream->movie);
|
||||
major = mvefile_get_next_segment_major(stream->movie);
|
||||
}
|
||||
|
||||
if (!mvefile_fetch_next_chunk(stream->movie))
|
||||
return 0;
|
||||
|
||||
// return status
|
||||
return 1;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
|
||||
|
||||
#ifndef INCLUDED_MVELIB_H
|
||||
#define INCLUDED_MVELIB_H
|
||||
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
struct CFILE;
|
||||
|
||||
// structure for maintaining info on a MVEFILE stream
|
||||
typedef struct MVEFILE
|
||||
{
|
||||
CFILE *stream;
|
||||
ubyte *cur_chunk;
|
||||
int buf_size;
|
||||
int cur_fill;
|
||||
int next_segment;
|
||||
} MVEFILE;
|
||||
|
||||
// open a .MVE file
|
||||
MVEFILE *mvefile_open(char *filename);
|
||||
|
||||
// close a .MVE file
|
||||
void mvefile_close(MVEFILE *movie);
|
||||
|
||||
// get size of next segment in chunk (-1 if no more segments in chunk)
|
||||
int mvefile_get_next_segment_size(MVEFILE *movie);
|
||||
|
||||
// get type of next segment in chunk (0xff if no more segments in chunk)
|
||||
ubyte mvefile_get_next_segment_major(MVEFILE *movie);
|
||||
|
||||
// get subtype (version) of next segment in chunk (0xff if no more segments in chunk)
|
||||
ubyte mvefile_get_next_segment_minor(MVEFILE *movie);
|
||||
|
||||
// see next segment (return NULL if no next segment)
|
||||
ubyte *mvefile_get_next_segment(MVEFILE *movie);
|
||||
|
||||
// advance to next segment
|
||||
void mvefile_advance_segment(MVEFILE *movie);
|
||||
|
||||
// fetch the next chunk (return 0 if at end of stream)
|
||||
int mvefile_fetch_next_chunk(MVEFILE *movie);
|
||||
|
||||
// structure for maintaining an MVE stream
|
||||
typedef struct MVESTREAM
|
||||
{
|
||||
MVEFILE *movie;
|
||||
} MVESTREAM;
|
||||
|
||||
// open an MVE stream
|
||||
MVESTREAM *mve_open(char *filename);
|
||||
|
||||
// close an MVE stream
|
||||
void mve_close(MVESTREAM *movie);
|
||||
|
||||
// play next chunk
|
||||
int mve_play_next_chunk(MVESTREAM *movie);
|
||||
|
||||
// basic movie playing functions
|
||||
void mve_init(MVESTREAM *mve);
|
||||
void mve_play(MVESTREAM *mve);
|
||||
void mve_shutdown();
|
||||
|
||||
// utility functions
|
||||
short mve_get_short(ubyte *data);
|
||||
ushort mve_get_ushort(ubyte *data);
|
||||
int mve_get_int(ubyte *data);
|
||||
|
||||
// callbacks for data handling
|
||||
// audio
|
||||
void mve_audio_createbuf(ubyte minor, ubyte *data);
|
||||
int mve_audio_data(ubyte major, ubyte *data);
|
||||
void mve_audio_play();
|
||||
// video
|
||||
int mve_video_createbuf(ubyte minor, ubyte *data);
|
||||
int mve_video_init(ubyte *data);
|
||||
void mve_video_palette(ubyte *data);
|
||||
void mve_video_data(ubyte *data, int len);
|
||||
void mve_video_codemap(ubyte *data, int len);
|
||||
void mve_video_display();
|
||||
// misc
|
||||
void mve_end_movie();
|
||||
void mve_end_chunk();
|
||||
int mve_timer_create(ubyte *data);
|
||||
|
||||
typedef short mves;
|
||||
|
||||
#endif /* INCLUDED_MVELIB_H */
|
||||
@@ -1,811 +0,0 @@
|
||||
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "cutscene/movie.h"
|
||||
#include "cutscene/mvelib.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropengldraw.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropenglstate.h"
|
||||
#include "graphics/gropenglshader.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
|
||||
#include "io/key.h"
|
||||
#include "io/timer.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "sound/openal.h"
|
||||
#include "sound/sound.h"
|
||||
|
||||
|
||||
extern int Cmdline_noscalevid;
|
||||
|
||||
static int mve_playing;
|
||||
|
||||
// timer variables
|
||||
static int micro_frame_delay = 0;
|
||||
static int timer_started = 0;
|
||||
#ifdef SCP_UNIX
|
||||
static struct timeval timer_expire = { 0, 0 };
|
||||
#else
|
||||
static int timer_expire;
|
||||
#endif
|
||||
|
||||
// audio variables
|
||||
#define MVE_AUDIO_BUFFERS 64 // total buffers to interact with stream
|
||||
static int mve_audio_buffer_tail = 0;
|
||||
static int mve_audio_playing = 0;
|
||||
static int mve_audio_canplay = 0;
|
||||
static int mve_audio_compressed = 0;
|
||||
static int audiobuf_created;
|
||||
|
||||
// struct for the audio stream information
|
||||
typedef struct MVE_AUDIO_T {
|
||||
ALenum format;
|
||||
int sample_rate;
|
||||
int bytes_per_sec;
|
||||
int channels;
|
||||
int bitsize;
|
||||
ALuint source_id;
|
||||
ALuint audio_buffer[MVE_AUDIO_BUFFERS];
|
||||
} mve_audio_t;
|
||||
|
||||
mve_audio_t *mas; // mve_audio_stream
|
||||
|
||||
// audio decompressor
|
||||
extern void mveaudio_uncompress(short *buffer, unsigned char *data);
|
||||
|
||||
// video variables
|
||||
int g_width, g_height;
|
||||
void *g_vBuffers = NULL;
|
||||
void *g_vBackBuf1, *g_vBackBuf2;
|
||||
ushort *pixelbuf = NULL;
|
||||
static GLuint GLtex = 0;
|
||||
static GLfloat gl_screenYH = 0;
|
||||
static GLfloat gl_screenXW = 0;
|
||||
static GLfloat gl_screenU = 0;
|
||||
static GLfloat gl_screenV = 0;
|
||||
static GLfloat glVertices[4][4] = {{0}};
|
||||
static int g_screenWidth, g_screenHeight;
|
||||
static float g_screenX, g_screenY;
|
||||
static int g_truecolor = 0;
|
||||
static ubyte g_palette[768];
|
||||
static ubyte *g_pCurMap = NULL;
|
||||
static int g_nMapLength = 0;
|
||||
static int videobuf_created, video_inited;
|
||||
static int hp2, wp2;
|
||||
static uint mve_video_skiptimer = 0;
|
||||
static int mve_scale_video = 0;
|
||||
|
||||
// video externs from API graphics functions
|
||||
extern void opengl_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out);
|
||||
extern GLenum GL_previous_texture_target;
|
||||
|
||||
// the decoders
|
||||
extern void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain);
|
||||
extern void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain);
|
||||
|
||||
|
||||
/*************************
|
||||
* general handlers
|
||||
*************************/
|
||||
void mve_end_movie()
|
||||
{
|
||||
mve_playing = 0;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* timer handlers
|
||||
*************************/
|
||||
|
||||
int mve_timer_create(ubyte *data)
|
||||
{
|
||||
int rate = mve_get_int(data);
|
||||
int subd = mve_get_short(data+4);
|
||||
|
||||
micro_frame_delay = rate * subd;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void mve_timer_start(void)
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
int nsec = 0;
|
||||
|
||||
gettimeofday(&timer_expire, NULL);
|
||||
|
||||
timer_expire.tv_usec += micro_frame_delay;
|
||||
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
#else
|
||||
timer_expire = timer_get_microseconds();
|
||||
timer_expire += micro_frame_delay;
|
||||
#endif
|
||||
|
||||
timer_started = 1;
|
||||
}
|
||||
|
||||
static int mve_do_timer_wait(void)
|
||||
{
|
||||
if (!timer_started) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
int nsec = 0;
|
||||
struct timespec ts, tsRem;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (tv.tv_sec > timer_expire.tv_sec) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ( (tv.tv_sec == timer_expire.tv_sec) && (tv.tv_usec >= timer_expire.tv_usec) ) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ts.tv_sec = timer_expire.tv_sec - tv.tv_sec;
|
||||
ts.tv_nsec = 1000 * (timer_expire.tv_usec - tv.tv_usec);
|
||||
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_nsec += 1000000000UL;
|
||||
--ts.tv_sec;
|
||||
}
|
||||
|
||||
if ( (nanosleep(&ts, &tsRem) == -1) && (errno == EINTR) ) {
|
||||
// so we got an error that was a signal interupt, try to sleep again with remainder of time
|
||||
if ( (nanosleep(&tsRem, NULL) == -1) && (errno == EINTR) ) {
|
||||
mprintf(("MVE: Timer error! Aborting movie playback!\n"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
timer_expire.tv_usec += micro_frame_delay;
|
||||
|
||||
if (timer_expire.tv_usec > 1000000) {
|
||||
nsec = timer_expire.tv_usec / 1000000;
|
||||
timer_expire.tv_sec += nsec;
|
||||
timer_expire.tv_usec -= nsec * 1000000;
|
||||
}
|
||||
#else
|
||||
int tv, ts, ts2;
|
||||
|
||||
tv = timer_get_microseconds();
|
||||
|
||||
if (tv > timer_expire) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ts = timer_expire - tv;
|
||||
ts2 = ts/1000;
|
||||
Sleep(ts2);
|
||||
|
||||
end:
|
||||
timer_expire += micro_frame_delay;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mve_timer_stop()
|
||||
{
|
||||
#ifdef SCP_UNIX
|
||||
timer_expire.tv_sec = 0;
|
||||
timer_expire.tv_usec = 0;
|
||||
#else
|
||||
timer_expire = 0;
|
||||
#endif
|
||||
timer_started = 0;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* audio handlers
|
||||
*************************/
|
||||
|
||||
// setup the audio information from the data stream
|
||||
void mve_audio_createbuf(ubyte minor, ubyte *data)
|
||||
{
|
||||
if (audiobuf_created) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if game sound disabled don't try and play movie audio
|
||||
if (!Sound_enabled) {
|
||||
mve_audio_canplay = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int flags, sample_rate;
|
||||
|
||||
mas = (mve_audio_t *) vm_malloc ( sizeof(mve_audio_t) );
|
||||
memset(mas, 0, sizeof(mve_audio_t));
|
||||
|
||||
mas->format = AL_INVALID;
|
||||
|
||||
flags = mve_get_ushort(data + 2);
|
||||
sample_rate = mve_get_ushort(data + 4);
|
||||
|
||||
mas->channels = (flags & 0x0001) ? 2 : 1;
|
||||
mas->bitsize = (flags & 0x0002) ? 16 : 8;
|
||||
|
||||
mas->sample_rate = sample_rate;
|
||||
|
||||
if (minor > 0) {
|
||||
mve_audio_compressed = flags & 0x0004 ? 1 : 0;
|
||||
} else {
|
||||
mve_audio_compressed = 0;
|
||||
}
|
||||
|
||||
if (mas->bitsize == 16) {
|
||||
if (mas->channels == 2) {
|
||||
mas->format = AL_FORMAT_STEREO16;
|
||||
} else if (mas->channels == 1) {
|
||||
mas->format = AL_FORMAT_MONO16;
|
||||
}
|
||||
} else if (mas->bitsize == 8) {
|
||||
if (mas->channels == 2) {
|
||||
mas->format = AL_FORMAT_STEREO8;
|
||||
} else if (mas->channels == 1) {
|
||||
mas->format = AL_FORMAT_MONO8;
|
||||
}
|
||||
}
|
||||
|
||||
// somethings wrong, bail now
|
||||
if (mas->format == AL_INVALID) {
|
||||
mve_audio_canplay = 0;
|
||||
audiobuf_created = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGenSources(1, &mas->source_id), { mve_audio_canplay = 0; return; } );
|
||||
|
||||
mve_audio_canplay = 1;
|
||||
|
||||
OpenAL_ErrorPrint( alSourcef(mas->source_id, AL_GAIN, 1.0f) );
|
||||
|
||||
memset(mas->audio_buffer, 0, MVE_AUDIO_BUFFERS * sizeof(ALuint));
|
||||
|
||||
mve_audio_buffer_tail = 0;
|
||||
|
||||
audiobuf_created = 1;
|
||||
}
|
||||
|
||||
// play and stream the audio
|
||||
void mve_audio_play()
|
||||
{
|
||||
if (mve_audio_canplay) {
|
||||
ALint status, bqueued;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return );
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return );
|
||||
|
||||
mve_audio_playing = 1;
|
||||
|
||||
if (status != AL_PLAYING && bqueued > 0) {
|
||||
OpenAL_ErrorPrint( alSourcePlay(mas->source_id) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call this in shutdown to stop and close audio
|
||||
static void mve_audio_stop()
|
||||
{
|
||||
if (!audiobuf_created || mas == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALint p = 0;
|
||||
|
||||
mve_audio_playing = 0;
|
||||
|
||||
OpenAL_ErrorPrint( alSourceStop(mas->source_id) );
|
||||
OpenAL_ErrorPrint( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &p) );
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(mas->source_id, p, mas->audio_buffer) );
|
||||
OpenAL_ErrorPrint( alDeleteSources(1, &mas->source_id) );
|
||||
|
||||
for (int i = 0; i < MVE_AUDIO_BUFFERS; i++) {
|
||||
// make sure that the buffer is real before trying to delete, it could crash for some otherwise
|
||||
if ( (mas->audio_buffer[i] != 0) && alIsBuffer(mas->audio_buffer[i]) ) {
|
||||
OpenAL_ErrorPrint( alDeleteBuffers(1, &mas->audio_buffer[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
if (mas != NULL) {
|
||||
vm_free(mas);
|
||||
mas = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int mve_audio_data(ubyte major, ubyte *data)
|
||||
{
|
||||
static const int selected_chan=1;
|
||||
int chan;
|
||||
int nsamp;
|
||||
|
||||
if (mve_audio_canplay) {
|
||||
chan = mve_get_ushort(data + 2);
|
||||
nsamp = mve_get_ushort(data + 4);
|
||||
|
||||
if (chan & selected_chan) {
|
||||
ALint bprocessed, bqueued, status;
|
||||
ALuint bid;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &bprocessed), return 0 );
|
||||
|
||||
while (bprocessed-- > 2) {
|
||||
OpenAL_ErrorPrint( alSourceUnqueueBuffers(mas->source_id, 1, &bid) );
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return 0 );
|
||||
|
||||
if (bqueued == 0) {
|
||||
mprintf(("MVE: Buffer underun (First is normal)\n"));
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return 0 );
|
||||
|
||||
if ( (mve_audio_playing) && (status != AL_PLAYING) && (bqueued > 0) ) {
|
||||
OpenAL_ErrorCheck( alSourcePlay(mas->source_id), return 0 );
|
||||
}
|
||||
|
||||
if (bqueued < MVE_AUDIO_BUFFERS) {
|
||||
short *buf = NULL;
|
||||
|
||||
/* HACK: +4 mveaudio_uncompress adds 4 more bytes */
|
||||
if (major == 8) {
|
||||
if (mve_audio_compressed) {
|
||||
nsamp += 4;
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
mveaudio_uncompress(buf, data); /* XXX */
|
||||
} else {
|
||||
nsamp -= 8;
|
||||
data += 8;
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
memcpy(buf, data, nsamp);
|
||||
}
|
||||
} else {
|
||||
buf = (short *)vm_malloc(nsamp);
|
||||
memset(buf, 0, nsamp); /* XXX */
|
||||
}
|
||||
|
||||
if (!mas->audio_buffer[mve_audio_buffer_tail]) {
|
||||
OpenAL_ErrorCheck( alGenBuffers(1,&mas->audio_buffer[mve_audio_buffer_tail]), { vm_free(buf); return 0; } );
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alBufferData(mas->audio_buffer[mve_audio_buffer_tail], mas->format, buf, nsamp, mas->sample_rate), { vm_free(buf); return 0; } );
|
||||
|
||||
OpenAL_ErrorCheck( alSourceQueueBuffers(mas->source_id, 1, &mas->audio_buffer[mve_audio_buffer_tail]), { vm_free(buf); return 0;} );
|
||||
|
||||
//fprintf(stderr,"Queued buffer %d(%d)\n", mve_audio_buftail, mas->audio_buffer[mve_audio_buftail]);
|
||||
|
||||
if (++mve_audio_buffer_tail == MVE_AUDIO_BUFFERS) {
|
||||
mve_audio_buffer_tail = 0;
|
||||
}
|
||||
|
||||
bqueued++;
|
||||
vm_free(buf);
|
||||
} else {
|
||||
mprintf(("MVE: Buffer overrun: Queue full\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* video handlers
|
||||
*************************/
|
||||
|
||||
int mve_video_createbuf(ubyte minor, ubyte *data)
|
||||
{
|
||||
if (videobuf_created) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
short w, h;
|
||||
short truecolor;
|
||||
w = mve_get_short(data);
|
||||
h = mve_get_short(data+2);
|
||||
|
||||
if (minor > 1) {
|
||||
truecolor = mve_get_short(data+6);
|
||||
} else {
|
||||
truecolor = 0;
|
||||
}
|
||||
|
||||
g_width = w << 3;
|
||||
g_height = h << 3;
|
||||
|
||||
g_vBackBuf1 = g_vBuffers = vm_malloc(g_width * g_height * 4);
|
||||
|
||||
if (g_vBackBuf1 == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate video buffer"));
|
||||
videobuf_created = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (truecolor) {
|
||||
g_vBackBuf2 = (ushort *)g_vBackBuf1 + (g_width * g_height);
|
||||
} else {
|
||||
g_vBackBuf2 = (ubyte *)g_vBackBuf1 + (g_width * g_height);
|
||||
}
|
||||
memset(g_vBackBuf1, 0, g_width * g_height * 4);
|
||||
|
||||
g_truecolor = truecolor;
|
||||
videobuf_created = 1;
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
GLfloat scale_by = 1.0f;
|
||||
|
||||
float screen_ratio = (float)gr_screen.center_w / (float)gr_screen.center_h;
|
||||
float movie_ratio = (float)g_width / (float)g_height;
|
||||
|
||||
if (screen_ratio > movie_ratio) {
|
||||
scale_by = (float)gr_screen.center_h / (float)g_height;
|
||||
} else {
|
||||
scale_by = (float)gr_screen.center_w / (float)g_width;
|
||||
}
|
||||
|
||||
// don't bother setting anything if we aren't going to need it
|
||||
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glScalef( scale_by, scale_by, 1.0f );
|
||||
mve_scale_video = 1;
|
||||
}
|
||||
|
||||
if (mve_scale_video) {
|
||||
g_screenX = ((ceil((gr_screen.center_w / scale_by) - 0.5f) - g_width) / 2) + ceil((gr_screen.center_offset_x / scale_by) - 0.5f);
|
||||
g_screenY = ((ceil((gr_screen.center_h / scale_by) - 0.5f) - g_height) / 2) + ceil((gr_screen.center_offset_y / scale_by) - 0.5f);
|
||||
} else {
|
||||
// centers on 1024x768, fills on 640x480
|
||||
g_screenX = ((float)(gr_screen.center_w - g_width) / 2.0f) + gr_screen.center_offset_x;
|
||||
g_screenY = ((float)(gr_screen.center_h - g_height) / 2.0f) + gr_screen.center_offset_y;
|
||||
}
|
||||
|
||||
// set additional values for screen width/height and UV coords
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
gl_screenYH = g_screenY + g_height;
|
||||
gl_screenXW = g_screenX + g_width;
|
||||
|
||||
gl_screenU = i2fl(g_width) / i2fl(wp2);
|
||||
gl_screenV = i2fl(g_height) / i2fl(hp2);
|
||||
}
|
||||
|
||||
glVertices[0][0] = g_screenX;
|
||||
glVertices[0][1] = g_screenY;
|
||||
glVertices[0][2] = 0;
|
||||
glVertices[0][3] = 0;
|
||||
|
||||
glVertices[1][0] = g_screenX;
|
||||
glVertices[1][1] = gl_screenYH;
|
||||
glVertices[1][2] = 0;
|
||||
glVertices[1][3] = gl_screenV;
|
||||
|
||||
glVertices[2][0] = gl_screenXW;
|
||||
glVertices[2][1] = g_screenY;
|
||||
glVertices[2][2] = gl_screenU;
|
||||
glVertices[2][3] = 0;
|
||||
|
||||
glVertices[3][0] = gl_screenXW;
|
||||
glVertices[3][1] = gl_screenYH;
|
||||
glVertices[3][2] = gl_screenU;
|
||||
glVertices[3][3] = gl_screenV;
|
||||
|
||||
GL_state.Array.BindArrayBuffer(0);
|
||||
|
||||
vertex_layout vertex_def;
|
||||
|
||||
vertex_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
|
||||
vertex_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
|
||||
|
||||
opengl_bind_vertex_layout(vertex_def);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void mve_convert_and_draw()
|
||||
{
|
||||
ushort *pDests;
|
||||
ushort *pSrcs = NULL;
|
||||
ushort *pixels = (ushort *)g_vBackBuf1;
|
||||
int x, y;
|
||||
|
||||
ubyte *pSrcs8 = NULL;
|
||||
ubyte *pixels8 = (ubyte *)g_vBackBuf1;
|
||||
ubyte r, g, b;
|
||||
ushort bit_16;
|
||||
|
||||
if (g_truecolor) {
|
||||
pSrcs = pixels;
|
||||
} else {
|
||||
pSrcs8 = pixels8;
|
||||
}
|
||||
pDests = pixelbuf;
|
||||
|
||||
if (gr_screen.mode != GR_OPENGL) {
|
||||
if (g_screenWidth > g_width) {
|
||||
pDests += ((g_screenWidth - g_width) / 2) / 2;
|
||||
}
|
||||
if (g_screenHeight > g_height) {
|
||||
pDests += ((g_screenHeight - g_height) / 2) * g_screenWidth;
|
||||
}
|
||||
}
|
||||
|
||||
for (y=0; y<g_height; y++) {
|
||||
for (x = 0; x < g_width; x++) {
|
||||
if (g_truecolor) {
|
||||
Assert( pSrcs != NULL );
|
||||
pDests[x] = (1<<15)|*pSrcs;
|
||||
pSrcs++;
|
||||
} else {
|
||||
Assert( pSrcs8 != NULL );
|
||||
|
||||
// grab rgb color
|
||||
r = (g_palette[(*pSrcs8)*3] / 2);
|
||||
g = (g_palette[(*pSrcs8)*3 + 1] / 2);
|
||||
b = (g_palette[(*pSrcs8)*3 + 2] / 2);
|
||||
|
||||
// stuff the color
|
||||
bit_16 = (ushort)(r << Gr_t_red.shift);
|
||||
bit_16 |= (ushort)(g << Gr_t_green.shift);
|
||||
bit_16 |= (ushort)(b << Gr_t_blue.shift);
|
||||
bit_16 |= (ushort)(Gr_t_alpha.mask);
|
||||
|
||||
// stuff the pixel
|
||||
pDests[x] = (1<<15)|bit_16;
|
||||
|
||||
pSrcs8++;
|
||||
}
|
||||
}
|
||||
|
||||
pDests += g_screenWidth;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mve_video_display()
|
||||
{
|
||||
fix t1 = timer_get_fixed_seconds();
|
||||
|
||||
mve_convert_and_draw();
|
||||
|
||||
// this thing is basically stupid but I don't care
|
||||
// micro_frame_delay is divided by 10 to match mve_video_skiptimer overflow catch
|
||||
if ( mve_video_skiptimer > (uint)(micro_frame_delay/10) ) {
|
||||
// we are running slow so subtract desired time from actual and skip this frame
|
||||
mve_video_skiptimer -= (micro_frame_delay/10);
|
||||
return;
|
||||
} else {
|
||||
// zero out so we can get a new count
|
||||
mve_video_skiptimer = 0;
|
||||
}
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_width, g_height, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixelbuf);
|
||||
|
||||
opengl_shader_set_passthrough(true);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
} else {
|
||||
// DDOI - This is probably really fricking slow
|
||||
int bitmap = bm_create (16, g_screenWidth, g_screenHeight, pixelbuf, 0);
|
||||
gr_set_bitmap (bitmap);
|
||||
gr_bitmap ((int)g_screenX, (int)g_screenY, GR_RESIZE_FULL);
|
||||
bm_release (bitmap);
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
os_poll();
|
||||
|
||||
fix t2 = timer_get_fixed_seconds();
|
||||
|
||||
// only get a new count if we are definitely through with old count
|
||||
if ( mve_video_skiptimer == 0 ) {
|
||||
// for a more accurate count convert the frame rate to a float and multiply
|
||||
// by one-hundred-thousand before converting to an uint.
|
||||
mve_video_skiptimer = (uint)(f2fl(t2-t1) * 100000);
|
||||
}
|
||||
|
||||
int k = key_inkey();
|
||||
switch (k) {
|
||||
case KEY_ESC:
|
||||
case KEY_ENTER:
|
||||
case KEY_SPACEBAR:
|
||||
mve_playing = 0;
|
||||
}
|
||||
|
||||
//mprintf(("mve frame took this long: %.6f\n", f2fl(t2-t1) / 1000.0f));
|
||||
}
|
||||
|
||||
int mve_video_init(ubyte *data)
|
||||
{
|
||||
if (video_inited) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
short width, height;
|
||||
|
||||
width = mve_get_short(data);
|
||||
height = mve_get_short(data+2);
|
||||
|
||||
g_screenWidth = width;
|
||||
g_screenHeight = height;
|
||||
|
||||
// DDOI - Allocate RGB565 pixel buffer
|
||||
pixelbuf = (ushort *)vm_malloc(g_screenWidth * g_screenHeight * 2);
|
||||
|
||||
if (pixelbuf == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
|
||||
video_inited = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(pixelbuf, 0, g_screenWidth * g_screenHeight * 2);
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
opengl_set_texture_target(GL_TEXTURE_2D);
|
||||
opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
|
||||
|
||||
glGenTextures(1, &GLtex);
|
||||
|
||||
Assert( GLtex != 0 );
|
||||
|
||||
if ( GLtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gr_set_lighting(false, false);
|
||||
GL_state.Texture.DisableAll();
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(GLtex);
|
||||
|
||||
GL_state.SetTextureSource(TEXTURE_SOURCE_DECAL);
|
||||
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
|
||||
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
|
||||
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB5_A1, wp2, hp2, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
|
||||
|
||||
// set our color so that we can make sure that it's correct
|
||||
GL_state.Color(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
memset(g_palette, 0, 768);
|
||||
video_inited = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mve_video_palette(ubyte *data)
|
||||
{
|
||||
short start, count;
|
||||
start = mve_get_short(data);
|
||||
count = mve_get_short(data+2);
|
||||
memcpy(g_palette + 3*start, data+4, 3*count);
|
||||
}
|
||||
|
||||
void mve_video_codemap(ubyte *data, int len)
|
||||
{
|
||||
g_pCurMap = data;
|
||||
g_nMapLength = len;
|
||||
}
|
||||
|
||||
void mve_video_data(ubyte *data, int len)
|
||||
{
|
||||
ushort nFlags;
|
||||
ubyte *temp;
|
||||
|
||||
nFlags = mve_get_ushort(data+12);
|
||||
|
||||
if (nFlags & 1) {
|
||||
temp = (ubyte *)g_vBackBuf1;
|
||||
g_vBackBuf1 = g_vBackBuf2;
|
||||
g_vBackBuf2 = temp;
|
||||
}
|
||||
|
||||
if (g_truecolor) {
|
||||
decodeFrame16((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
} else {
|
||||
decodeFrame8((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
|
||||
}
|
||||
}
|
||||
|
||||
void mve_end_chunk()
|
||||
{
|
||||
g_pCurMap = NULL;
|
||||
}
|
||||
|
||||
void mve_init(MVESTREAM *mve)
|
||||
{
|
||||
// reset to default values
|
||||
mve_audio_buffer_tail = 0;
|
||||
mve_audio_playing = 0;
|
||||
mve_audio_canplay = 0;
|
||||
mve_audio_compressed = 0;
|
||||
audiobuf_created = 0;
|
||||
|
||||
videobuf_created = 0;
|
||||
video_inited = 0;
|
||||
mve_scale_video = 0;
|
||||
|
||||
mve_playing = 1;
|
||||
}
|
||||
|
||||
void mve_play(MVESTREAM *mve)
|
||||
{
|
||||
int init_timer = 0, timer_error = 0;
|
||||
int cont = 1;
|
||||
|
||||
if (!timer_started) {
|
||||
mve_timer_start();
|
||||
}
|
||||
|
||||
while (cont && mve_playing && !timer_error) {
|
||||
cont = mve_play_next_chunk(mve);
|
||||
|
||||
if (micro_frame_delay && !init_timer) {
|
||||
mve_timer_start();
|
||||
init_timer = 1;
|
||||
}
|
||||
|
||||
timer_error = mve_do_timer_wait();
|
||||
}
|
||||
}
|
||||
|
||||
void mve_shutdown()
|
||||
{
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
if (mve_scale_video) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
GL_state.Texture.Disable();
|
||||
GL_state.Texture.Delete(GLtex);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
GLtex = 0;
|
||||
}
|
||||
|
||||
if (pixelbuf != NULL) {
|
||||
vm_free(pixelbuf);
|
||||
pixelbuf = NULL;
|
||||
}
|
||||
|
||||
if (g_vBuffers != NULL) {
|
||||
vm_free(g_vBuffers);
|
||||
g_vBuffers = NULL;
|
||||
}
|
||||
|
||||
mve_audio_stop();
|
||||
mve_timer_stop();
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,40 +0,0 @@
|
||||
|
||||
|
||||
#ifndef _OGGPLAYER_H
|
||||
#define _OGGPLAYER_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include "theora/theora.h"
|
||||
#include "vorbis/codec.h"
|
||||
|
||||
struct CFILE;
|
||||
|
||||
// structure for maintaining info on a THEORAFILE stream
|
||||
typedef struct THEORAFILE
|
||||
{
|
||||
CFILE *cfp;
|
||||
ubyte theora_p;
|
||||
ubyte vorbis_p;
|
||||
|
||||
ogg_sync_state osyncstate;
|
||||
ogg_page opage;
|
||||
ogg_packet opacket;
|
||||
ogg_stream_state v_osstate;
|
||||
ogg_stream_state t_osstate;
|
||||
|
||||
theora_info tinfo;
|
||||
theora_comment tcomment;
|
||||
theora_state tstate;
|
||||
|
||||
vorbis_info vinfo;
|
||||
vorbis_dsp_state vstate;
|
||||
vorbis_block vblock;
|
||||
vorbis_comment vcomment;
|
||||
} THEORAFILE;
|
||||
|
||||
void theora_play(THEORAFILE *movie);
|
||||
THEORAFILE *theora_open(char *filename);
|
||||
void theora_close(THEORAFILE *movie);
|
||||
|
||||
#endif
|
||||
@@ -1,498 +0,0 @@
|
||||
|
||||
#include "ddsutils/ddsutils.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "osapi/osregistry.h"
|
||||
|
||||
|
||||
/* Currently supported formats:
|
||||
* DXT1a (compressed)
|
||||
* DXT1c (compressed)
|
||||
* DXT3 (compressed)
|
||||
* DXT5 (compressed)
|
||||
* uncompressed 1555 (16-bit, 1-bit being alpha)
|
||||
* uncompressed 8888 (32-bit)
|
||||
* uncompressed 888 (24-bit, no alpha)
|
||||
* paletted 8-bit (256 colors)
|
||||
*/
|
||||
|
||||
|
||||
int Texture_compression_available = 0;
|
||||
int Use_compressed_textures = 0;
|
||||
|
||||
// power of two check, to verify that a given DDS will always be usable since
|
||||
// some may not be power-of-2
|
||||
static inline int is_power_of_two(int w, int h)
|
||||
{
|
||||
return ( (w && !(w & (w-1))) && (h && !(h & (h-1))) );
|
||||
}
|
||||
|
||||
|
||||
int dds_read_header(const char *filename, CFILE *img_cfp, int *width, int *height, int *bpp, int *compression_type, int *levels, int *size, ubyte *palette)
|
||||
{
|
||||
DDSURFACEDESC2 dds_header;
|
||||
int code = 0;
|
||||
CFILE *ddsfile;
|
||||
char real_name[MAX_FILENAME_LEN];
|
||||
int retval = DDS_ERROR_NONE;
|
||||
int ct = DDS_UNCOMPRESSED;
|
||||
int bits = 0;
|
||||
int i, is_cubemap = 0;
|
||||
int d_width = 0, d_height = 0, d_depth = 0, d_size = 0;
|
||||
|
||||
|
||||
if (img_cfp == NULL) {
|
||||
// this better not happen.. ever
|
||||
Assert(filename != NULL);
|
||||
|
||||
// make sure there is an extension
|
||||
strcpy_s(real_name, filename);
|
||||
char *p = strchr(real_name, '.');
|
||||
if (p) { *p=0; }
|
||||
strcat_s(real_name, ".dds");
|
||||
|
||||
// try to open the file
|
||||
ddsfile = cfopen(real_name, "rb");
|
||||
|
||||
// file not found
|
||||
if (ddsfile == NULL)
|
||||
return DDS_ERROR_INVALID_FILENAME;
|
||||
} else {
|
||||
ddsfile = img_cfp;
|
||||
}
|
||||
|
||||
// read the code
|
||||
code = cfread_int(ddsfile);
|
||||
|
||||
// check it
|
||||
if (code != DDS_FILECODE) {
|
||||
retval = DDS_ERROR_BAD_HEADER;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// read header variables
|
||||
dds_header.dwSize = cfread_uint(ddsfile);
|
||||
dds_header.dwFlags = cfread_uint(ddsfile);
|
||||
dds_header.dwHeight = cfread_uint(ddsfile);
|
||||
dds_header.dwWidth = cfread_uint(ddsfile);
|
||||
dds_header.dwPitchOrLinearSize = cfread_uint(ddsfile);
|
||||
dds_header.dwDepth = cfread_uint(ddsfile);
|
||||
dds_header.dwMipMapCount = cfread_uint(ddsfile);
|
||||
|
||||
// skip over the crap we don't care about
|
||||
for (i = 0; i < 11; i++)
|
||||
cfread_uint(ddsfile);
|
||||
|
||||
dds_header.ddpfPixelFormat.dwSize = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwFlags = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwFourCC = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwRGBBitCount = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwRBitMask = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwGBitMask = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwBBitMask = cfread_uint(ddsfile);
|
||||
dds_header.ddpfPixelFormat.dwRGBAlphaBitMask = cfread_uint(ddsfile);
|
||||
|
||||
dds_header.ddsCaps.dwCaps1 = cfread_uint(ddsfile);
|
||||
dds_header.ddsCaps.dwCaps2 = cfread_uint(ddsfile);
|
||||
|
||||
// sanity
|
||||
if (dds_header.dwDepth == 0)
|
||||
dds_header.dwDepth = 1;
|
||||
|
||||
if (dds_header.dwMipMapCount < 1)
|
||||
dds_header.dwMipMapCount = 1;
|
||||
|
||||
d_width = dds_header.dwWidth;
|
||||
d_height = dds_header.dwHeight;
|
||||
d_depth = dds_header.dwDepth;
|
||||
|
||||
// calculate the type and size of the data
|
||||
if (dds_header.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
|
||||
// did I mention lately that I hate Microsoft?
|
||||
// this is here to fix the situation where Microsoft doesn't follow their own docs
|
||||
if ( dds_header.dwPitchOrLinearSize <= 0 ) {
|
||||
// calculate the block size, mult by 8 for DXT1, 16 for DXT3 & 5
|
||||
d_size = ((dds_header.dwWidth + 3)/4) * ((dds_header.dwHeight + 3)/4) * ((dds_header.dwDepth + 3)/4) * ((dds_header.ddpfPixelFormat.dwFourCC == FOURCC_DXT1) ? 8 : 16);
|
||||
} else {
|
||||
d_size = dds_header.dwPitchOrLinearSize;
|
||||
}
|
||||
|
||||
// if we have mipmaps then compute them into the final size too
|
||||
for (i = 1; i < (int)dds_header.dwMipMapCount; i++) {
|
||||
// reduce size by half for the next pass
|
||||
d_width /= 2;
|
||||
d_height /= 2;
|
||||
|
||||
if (d_width <= 0)
|
||||
d_width = 1;
|
||||
|
||||
if (d_height <= 0)
|
||||
d_height = 1;
|
||||
|
||||
// size of data block (4x4)
|
||||
d_size += ((d_width + 3) / 4) * ((d_height + 3) / 4) * ((dds_header.ddpfPixelFormat.dwFourCC == FOURCC_DXT1) ? 8 : 16);
|
||||
}
|
||||
|
||||
if ( dds_header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP ) {
|
||||
if ( !(dds_header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) ) {
|
||||
retval = DDS_ERROR_CUBEMAP_FACES;
|
||||
ct = DDS_DXT_INVALID;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// it's a valid cubemap, probably
|
||||
is_cubemap = 1;
|
||||
|
||||
// the previously computed size is just per face, mult by 6 for full size
|
||||
d_size *= 6;
|
||||
}
|
||||
|
||||
Assert( d_size > 0 );
|
||||
*size = d_size;
|
||||
|
||||
switch (dds_header.ddpfPixelFormat.dwFourCC) {
|
||||
case FOURCC_DXT1:
|
||||
bits = 24;
|
||||
ct = (is_cubemap) ? DDS_CUBEMAP_DXT1 : DDS_DXT1;
|
||||
break;
|
||||
|
||||
case FOURCC_DXT3:
|
||||
bits = 32;
|
||||
ct = (is_cubemap) ? DDS_CUBEMAP_DXT3 : DDS_DXT3;
|
||||
break;
|
||||
|
||||
case FOURCC_DXT5:
|
||||
bits = 32;
|
||||
ct = (is_cubemap) ? DDS_CUBEMAP_DXT5 : DDS_DXT5;
|
||||
break;
|
||||
|
||||
// dxt2 and dxt4 aren't supported
|
||||
case FOURCC_DXT2:
|
||||
case FOURCC_DXT4:
|
||||
retval = DDS_ERROR_UNSUPPORTED;
|
||||
ct = DDS_DXT_INVALID;
|
||||
goto Done;
|
||||
break;
|
||||
|
||||
// none of the above
|
||||
default:
|
||||
retval = DDS_ERROR_INVALID_FORMAT;
|
||||
ct = DDS_DXT_INVALID;
|
||||
goto Done;
|
||||
break;
|
||||
}
|
||||
} else if ( dds_header.ddpfPixelFormat.dwFlags & (DDPF_RGB | DDPF_PALETTEINDEXED8) ) {
|
||||
d_size += d_width * d_height * d_depth * (dds_header.ddpfPixelFormat.dwRGBBitCount / 8);
|
||||
|
||||
// calculate full data size for all mipmap levels
|
||||
for (i = 1; i < (int)dds_header.dwMipMapCount; i++) {
|
||||
d_width /= 2;
|
||||
d_height /= 2;
|
||||
d_depth /= 2;
|
||||
|
||||
if (d_width < 1)
|
||||
d_width = 1;
|
||||
|
||||
if (d_height < 1)
|
||||
d_height = 1;
|
||||
|
||||
if (d_depth < 1)
|
||||
d_depth = 1;
|
||||
|
||||
d_size += d_width * d_height * d_depth * (dds_header.ddpfPixelFormat.dwRGBBitCount / 8);
|
||||
}
|
||||
|
||||
Assert( d_size > 0 );
|
||||
|
||||
if ( dds_header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP ) {
|
||||
if ( !(dds_header.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) ) {
|
||||
retval = DDS_ERROR_CUBEMAP_FACES;
|
||||
ct = DDS_DXT_INVALID;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// it's a valid cubemap, probably
|
||||
is_cubemap = 1;
|
||||
|
||||
// the previously computed size is just per face, mult by 6 for full size
|
||||
d_size *= 6;
|
||||
}
|
||||
|
||||
*size = d_size;
|
||||
|
||||
bits = dds_header.ddpfPixelFormat.dwRGBBitCount;
|
||||
ct = (is_cubemap) ? DDS_CUBEMAP_UNCOMPRESSED : DDS_UNCOMPRESSED;
|
||||
} else {
|
||||
// it's not a readable format
|
||||
retval = DDS_ERROR_INVALID_FORMAT;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// we don't support compressed, non-power-of-2 images
|
||||
if ( (ct != DDS_UNCOMPRESSED) && (!is_power_of_two(dds_header.dwWidth, dds_header.dwHeight)) ) {
|
||||
retval = DDS_ERROR_NON_POWER_OF_2;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// make sure that the video card can handle compressed textures before using them
|
||||
if ( !Use_compressed_textures && (ct != DDS_UNCOMPRESSED) && (ct != DDS_DXT_INVALID) ) {
|
||||
retval = DDS_ERROR_NO_COMPRESSION;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// stuff important info
|
||||
if (bpp)
|
||||
*bpp = bits;
|
||||
|
||||
if (compression_type)
|
||||
*compression_type = ct;
|
||||
|
||||
if (width)
|
||||
*width = dds_header.dwWidth;
|
||||
|
||||
if (height)
|
||||
*height = dds_header.dwHeight;
|
||||
|
||||
if (levels)
|
||||
*levels = dds_header.dwMipMapCount;
|
||||
|
||||
if (palette && (bits == 8)) {
|
||||
cfseek(ddsfile, DDS_OFFSET, CF_SEEK_SET);
|
||||
cfread(palette, 1, 1024, ddsfile);
|
||||
}
|
||||
|
||||
|
||||
Done:
|
||||
if (img_cfp == NULL) {
|
||||
// close file and return
|
||||
cfclose(ddsfile);
|
||||
ddsfile = NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
//reads pixel info from a dds file
|
||||
int dds_read_bitmap(const char *filename, ubyte *data, ubyte *bpp, int cf_type)
|
||||
{
|
||||
int retval;
|
||||
int w,h,ct,lvl;
|
||||
int size = 0, bits = 0;
|
||||
CFILE *cfp;
|
||||
char real_name[MAX_FILENAME_LEN];
|
||||
|
||||
// this better not happen.. ever
|
||||
Assert(filename != NULL);
|
||||
|
||||
// make sure there is an extension
|
||||
strcpy_s(real_name, filename);
|
||||
char *p = strchr(real_name, '.');
|
||||
if (p) { *p = 0; }
|
||||
strcat_s(real_name, ".dds");
|
||||
|
||||
// open it up and go to the data section
|
||||
cfp = cfopen(real_name, "rb", CFILE_NORMAL, cf_type);
|
||||
|
||||
// just in case
|
||||
if (cfp == NULL)
|
||||
return DDS_ERROR_INVALID_FILENAME;
|
||||
|
||||
// read the header -- if its at this stage, it should be legal.
|
||||
retval = dds_read_header(real_name, cfp, &w, &h, &bits, &ct, &lvl, &size);
|
||||
Assert(retval == DDS_ERROR_NONE);
|
||||
|
||||
// this really shouldn't be needed but better safe than sorry
|
||||
if (retval != DDS_ERROR_NONE) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
cfseek(cfp, DDS_OFFSET, CF_SEEK_SET);
|
||||
|
||||
// read in the data
|
||||
cfread(data, 1, size, cfp);
|
||||
|
||||
if (bpp)
|
||||
*bpp = (ubyte)bits;
|
||||
|
||||
// we look done here
|
||||
cfclose(cfp);
|
||||
|
||||
return DDS_ERROR_NONE;
|
||||
}
|
||||
|
||||
// save some image data as a DDS image
|
||||
// NOTE: we only support, uncompressed, 24-bit RGB and 32-bit RGBA images here!!
|
||||
void dds_save_image(int width, int height, int bpp, int num_mipmaps, ubyte *data, int cubemap, const char *filename)
|
||||
{
|
||||
DDSURFACEDESC2 dds_header;
|
||||
char real_filename[MAX_FILENAME_LEN];
|
||||
|
||||
if (data == NULL) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
// header size check
|
||||
if (sizeof(DDSURFACEDESC2) != 124) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// not that that's out of the way we can get down to business, constructing a sane filename
|
||||
memset( &real_filename, 0, sizeof(real_filename) );
|
||||
|
||||
int count = os_config_read_uint(NULL, "ImageExportNum", 0);
|
||||
|
||||
if (count > 999)
|
||||
count = 0;
|
||||
|
||||
if (filename == NULL) {
|
||||
if (cubemap) {
|
||||
sprintf(real_filename, "cubemap%.3d.dds", count++);
|
||||
} else {
|
||||
sprintf(real_filename, "image%.3d.dds", count++);
|
||||
}
|
||||
os_config_write_uint(NULL, "ImageExportNum", count);
|
||||
} else {
|
||||
Assert( strlen(filename) < MAX_FILENAME_LEN-5 );
|
||||
|
||||
strcpy_s(real_filename, filename);
|
||||
|
||||
char *p = strchr(real_filename, '.');
|
||||
if (p) { *p = 0; }
|
||||
|
||||
strcat_s(real_filename, ".dds");
|
||||
}
|
||||
|
||||
CFILE *image = cfopen( real_filename, "wb", CFILE_NORMAL, CF_TYPE_CACHE );
|
||||
|
||||
if (image == NULL) {
|
||||
mprintf(("Unable to open DDS image for saving!!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (num_mipmaps < 1)
|
||||
num_mipmaps = 1;
|
||||
|
||||
// we have a filename and file handle, so now lets create our DDS header...
|
||||
memset( &dds_header, 0, sizeof(DDSURFACEDESC2) );
|
||||
|
||||
uint flags = (DDSD_CAPS | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT);
|
||||
uint pixel_flags = DDPF_RGB;
|
||||
uint caps1 = DDSCAPS_TEXTURE;
|
||||
uint caps2 = 0;
|
||||
|
||||
if (bpp == 32) {
|
||||
pixel_flags |= DDPF_ALPHAPIXELS;
|
||||
}
|
||||
|
||||
if (num_mipmaps > 1) {
|
||||
flags |= DDSD_MIPMAPCOUNT;
|
||||
caps1 |= (DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
|
||||
}
|
||||
|
||||
if (cubemap) {
|
||||
caps1 |= DDSCAPS_COMPLEX;
|
||||
caps2 |= (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES);
|
||||
}
|
||||
|
||||
dds_header.dwSize = 124;
|
||||
dds_header.dwFlags = flags;
|
||||
dds_header.dwHeight = height;
|
||||
dds_header.dwWidth = width;
|
||||
dds_header.dwPitchOrLinearSize = (width * (bpp >> 3));
|
||||
dds_header.dwDepth = 0;
|
||||
dds_header.dwMipMapCount = num_mipmaps;
|
||||
|
||||
dds_header.ddpfPixelFormat.dwSize = 32;
|
||||
dds_header.ddpfPixelFormat.dwFlags = pixel_flags;
|
||||
dds_header.ddpfPixelFormat.dwFourCC = 0;
|
||||
dds_header.ddpfPixelFormat.dwRGBBitCount = bpp;
|
||||
dds_header.ddpfPixelFormat.dwRBitMask = 0x00ff0000;
|
||||
dds_header.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
|
||||
dds_header.ddpfPixelFormat.dwBBitMask = 0x000000ff;
|
||||
dds_header.ddpfPixelFormat.dwRGBAlphaBitMask = (bpp == 32) ? 0xff000000 : 0x00000000;
|
||||
|
||||
dds_header.ddsCaps.dwCaps1 = caps1;
|
||||
dds_header.ddsCaps.dwCaps2 = caps2;
|
||||
|
||||
// now save it all...
|
||||
uint dds_id = DDS_FILECODE;
|
||||
cfwrite(&dds_id, 1, 4, image);
|
||||
cfwrite(&dds_header, 1, sizeof(DDSURFACEDESC2), image);
|
||||
|
||||
int faces = (cubemap) ? 6 : 1;
|
||||
int f_width = width;
|
||||
int f_height = height;
|
||||
int f_size = 0, f_offset = 0;
|
||||
|
||||
// cubemaps are written:
|
||||
// face 1
|
||||
// all face 1 mipmaps
|
||||
// face 2
|
||||
// all face 2 mipmaps
|
||||
// ... etc.
|
||||
|
||||
for (int i = 0; i < faces; i++) {
|
||||
for (int j = 0; j < num_mipmaps; j++) {
|
||||
f_size = (f_width * f_height * (bpp >> 3));
|
||||
|
||||
cfwrite(data + f_offset, 1, f_size, image);
|
||||
|
||||
// increase offset for next mipmap level
|
||||
f_offset += f_size;
|
||||
|
||||
// half width and height for next mipmap level
|
||||
f_width /= 2;
|
||||
f_height /= 2;
|
||||
|
||||
if (f_width < 1)
|
||||
f_width = 1;
|
||||
|
||||
if (f_height < 1)
|
||||
f_height = 1;
|
||||
}
|
||||
|
||||
// reset width and height to original values for the next face
|
||||
f_width = width;
|
||||
f_height = height;
|
||||
}
|
||||
|
||||
// done! now lets go get something to eat...
|
||||
cfclose(image);
|
||||
}
|
||||
|
||||
|
||||
// returns string representation of DDS_** error code
|
||||
const char *dds_error_string(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case DDS_ERROR_NONE:
|
||||
return "No error";
|
||||
|
||||
case DDS_ERROR_INVALID_FILENAME:
|
||||
return "File not found";
|
||||
|
||||
case DDS_ERROR_BAD_HEADER:
|
||||
return "Filecode did not equal \"DDS \"";
|
||||
|
||||
case DDS_ERROR_INVALID_FORMAT:
|
||||
return "DDS was in an unsupported/unknown format";
|
||||
|
||||
case DDS_ERROR_UNSUPPORTED:
|
||||
return "DDS format was known but is not supported (ie. DXT2/DXT4)";
|
||||
|
||||
case DDS_ERROR_NO_COMPRESSION:
|
||||
return "DDS is compressed but compression support is not enabled";
|
||||
|
||||
case DDS_ERROR_NON_POWER_OF_2:
|
||||
return "Cannot load DDS if not power-of-2";
|
||||
|
||||
case DDS_ERROR_CUBEMAP_FACES:
|
||||
return "Cubemaps must have all 6 faces";
|
||||
|
||||
default:
|
||||
return "Abort, retry, fail?";
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
//header file to load .dds files
|
||||
//these use dxtc texture compression
|
||||
|
||||
#ifndef __DDS_H
|
||||
#define __DDS_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cfile/cfile.h"
|
||||
|
||||
|
||||
#define DDS_ERROR_NONE 0 // everything went fine
|
||||
#define DDS_ERROR_INVALID_FILENAME 1 // bad or missing file
|
||||
#define DDS_ERROR_UNSUPPORTED 2 // a known format but one we don't support
|
||||
#define DDS_ERROR_INVALID_FORMAT 3 // format that's not supported
|
||||
#define DDS_ERROR_BAD_HEADER 4 // header was not "DDS "
|
||||
#define DDS_ERROR_NO_COMPRESSION 5 // file is compressed, compression isn't supported
|
||||
#define DDS_ERROR_NON_POWER_OF_2 6 // file is not a power of 2 in dimensions
|
||||
#define DDS_ERROR_CUBEMAP_FACES 7 // file is a cubemap, but doesn't have all six faces
|
||||
|
||||
|
||||
#define DDS_DXT_INVALID -1
|
||||
#define DDS_UNCOMPRESSED 0
|
||||
#define DDS_DXT1 1
|
||||
#define DDS_DXT3 3
|
||||
#define DDS_DXT5 5
|
||||
#define DDS_CUBEMAP_UNCOMPRESSED 10
|
||||
#define DDS_CUBEMAP_DXT1 11
|
||||
#define DDS_CUBEMAP_DXT3 13
|
||||
#define DDS_CUBEMAP_DXT5 15
|
||||
|
||||
#ifndef MAKEFOURCC
|
||||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||
((uint)(ubyte)(ch0) | ((uint)(ubyte)(ch1) << 8) | \
|
||||
((uint)(ubyte)(ch2) << 16) | ((uint)(ubyte)(ch3) << 24 ))
|
||||
#endif //defined(MAKEFOURCC)
|
||||
|
||||
// FOURCC codes for DX compressed-texture pixel formats
|
||||
#define FOURCC_DXT1 (MAKEFOURCC('D','X','T','1'))
|
||||
#define FOURCC_DXT2 (MAKEFOURCC('D','X','T','2'))
|
||||
#define FOURCC_DXT3 (MAKEFOURCC('D','X','T','3'))
|
||||
#define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4'))
|
||||
#define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5'))
|
||||
|
||||
#define DDS_FILECODE 0x20534444 // "DDS " in file
|
||||
|
||||
// DDS format stuff ...
|
||||
#define DDSD_LINEARSIZE 0x00080000
|
||||
#define DDSD_PITCH 0x00000008
|
||||
#define DDPF_ALPHAPIXELS 0x00000001
|
||||
#define DDPF_FOURCC 0x00000004
|
||||
#define DDPF_PALETTEINDEXED4 0x00000008
|
||||
#define DDPF_PALETTEINDEXEDTO8 0x00000010
|
||||
#define DDPF_PALETTEINDEXED8 0x00000020
|
||||
#define DDPF_RGB 0x00000040
|
||||
#define DDSD_PIXELFORMAT 0x00001000
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_CAPS 0x00000001
|
||||
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||
|
||||
#define DDSCAPS_COMPLEX 0x00000008
|
||||
#define DDSCAPS_PRIMARYSURFACE 0x00000200
|
||||
#define DDSCAPS_MIPMAP 0x00400000
|
||||
#define DDSCAPS_TEXTURE 0x00001000
|
||||
|
||||
#define DDSCAPS2_CUBEMAP 0x00000200
|
||||
#define DDSCAPS2_VOLUME 0x00200000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
|
||||
|
||||
#define DDSCAPS2_CUBEMAP_ALLFACES ( DDSCAPS2_CUBEMAP_POSITIVEX | \
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEX | \
|
||||
DDSCAPS2_CUBEMAP_POSITIVEY | \
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEY | \
|
||||
DDSCAPS2_CUBEMAP_POSITIVEZ | \
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEZ )
|
||||
|
||||
#pragma pack(1)
|
||||
// these structures are the headers for a dds file
|
||||
/*typedef struct _DDPIXELFORMAT {
|
||||
uint dwSize;
|
||||
uint dwFlags;
|
||||
uint dwFourCC;
|
||||
uint dwRGBBitCount;
|
||||
uint dwRBitMask;
|
||||
uint dwGBitMask;
|
||||
uint dwBBitMask;
|
||||
uint dwRGBAlphaBitMask;
|
||||
} DDPIXELFORMAT;
|
||||
|
||||
typedef struct _DDSCAPS2
|
||||
{
|
||||
uint dwCaps1;
|
||||
uint dwCaps2;
|
||||
uint Reserved[2];
|
||||
} DDSCAPS2;*/
|
||||
|
||||
typedef struct _DDSURFACEDESC2
|
||||
{
|
||||
uint dwSize; // size of the DDSURFACEDESC structure
|
||||
uint dwFlags; // determines what fields are valid
|
||||
uint dwHeight; // height of surface to be created
|
||||
uint dwWidth; // width of input surface
|
||||
uint dwPitchOrLinearSize;
|
||||
uint dwDepth;
|
||||
uint dwMipMapCount;
|
||||
uint dwReserved1[11];
|
||||
|
||||
struct {
|
||||
uint dwSize;
|
||||
uint dwFlags;
|
||||
uint dwFourCC;
|
||||
uint dwRGBBitCount;
|
||||
uint dwRBitMask;
|
||||
uint dwGBitMask;
|
||||
uint dwBBitMask;
|
||||
uint dwRGBAlphaBitMask;
|
||||
} ddpfPixelFormat;
|
||||
|
||||
struct {
|
||||
uint dwCaps1;
|
||||
uint dwCaps2;
|
||||
uint Reserved[2];
|
||||
} ddsCaps;
|
||||
|
||||
// DDPIXELFORMAT ddpfPixelFormat;
|
||||
// DDSCAPS2 ddsCaps; // direct draw surface capabilities
|
||||
uint dwReserved2;
|
||||
} DDSURFACEDESC2;
|
||||
#pragma pack()
|
||||
|
||||
#define DDS_OFFSET 4+sizeof(DDSURFACEDESC2) //place where the data starts -- should be 128
|
||||
|
||||
//reads a dds header
|
||||
//returns one of the error values
|
||||
//'compression_type' comes back as one of the DDS_DXTC* defines
|
||||
int dds_read_header(const char *filename, CFILE *img_cfp = NULL, int *width = 0, int *height = 0, int *bpp = 0, int *compression_type = 0, int *levels = 0, int *size = 0, ubyte *palette = NULL);
|
||||
|
||||
//reads bitmap
|
||||
//size of the data it stored in size
|
||||
int dds_read_bitmap(const char *filename, ubyte *data, ubyte *bpp = NULL, int cf_type = CF_TYPE_ANY);
|
||||
|
||||
// writes a DDS file using given data
|
||||
void dds_save_image(int width, int height, int bpp, int num_mipmaps, ubyte *data = NULL, int cubemap = 0, const char *filename = NULL);
|
||||
|
||||
//returns a string from a DDS error code
|
||||
const char *dds_error_string(int code);
|
||||
|
||||
extern int Texture_compression_available;
|
||||
extern int Use_compressed_textures;
|
||||
|
||||
#endif //__DDS_H
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _DEBRIS_H
|
||||
#define _DEBRIS_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
class object;
|
||||
struct CFILE;
|
||||
class draw_list;
|
||||
|
||||
#define MAX_DEBRIS_ARCS 8 // Must be less than MAX_ARC_EFFECTS in model.h
|
||||
|
||||
typedef struct debris {
|
||||
debris *next, *prev; // used for a linked list of the hull debris chunks
|
||||
int flags; // See DEBRIS_??? defines
|
||||
int source_objnum; // What object this came from
|
||||
int source_sig; // Signature of the source object
|
||||
int damage_type_idx; // Damage type of this debris
|
||||
int ship_info_index; // Ship info index of the ship type debris came from
|
||||
int team; // Team of the ship where the debris came from
|
||||
int objnum; // What object this is linked to
|
||||
float lifeleft; // When 0 or less object dies
|
||||
int must_survive_until; //WMC - timestamp of earliest point that it can be murthered.
|
||||
int model_num; // What model this uses
|
||||
int submodel_num; // What submodel this uses
|
||||
int next_fireball; // When to start a fireball
|
||||
int is_hull; // indicates a large hull chunk of debris
|
||||
int species; // What species this is from. -1 if don't care.
|
||||
int fire_timeout; // timestamp that holds time for fireballs to stop appearing
|
||||
int sound_delay; // timestamp to signal when sound should start
|
||||
fix time_started; // time when debris was created
|
||||
int next_distance_check; // timestamp to determine whether to delete this piece of debris.
|
||||
|
||||
vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
|
||||
int arc_timestamp[MAX_DEBRIS_ARCS]; // When this times out, the spark goes away. -1 is not used
|
||||
int arc_frequency; // Starts at 0, gets bigger
|
||||
int parent_alt_name;
|
||||
float damage_mult;
|
||||
|
||||
} debris;
|
||||
|
||||
|
||||
// flags for debris pieces
|
||||
#define DEBRIS_USED (1<<0)
|
||||
#define DEBRIS_EXPIRE (1<<1) // debris can expire (ie hull chunks from small ships)
|
||||
|
||||
#define MAX_DEBRIS_PIECES 64
|
||||
|
||||
extern debris Debris[MAX_DEBRIS_PIECES];
|
||||
|
||||
extern int Num_debris_pieces;
|
||||
|
||||
struct collision_info_struct;
|
||||
|
||||
void debris_init();
|
||||
void debris_render(object * obj, draw_list *scene);
|
||||
void debris_delete( object * obj );
|
||||
void debris_process_post( object * obj, float frame_time);
|
||||
object *debris_create( object * source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force );
|
||||
int debris_check_collision( object * obj, object * other_obj, vec3d * hitpos, collision_info_struct *debris_hit_info=NULL );
|
||||
void debris_hit( object * debris_obj, object * other_obj, vec3d * hitpos, float damage );
|
||||
int debris_get_team(object *objp);
|
||||
void debris_clear_expired_flag(debris *db);
|
||||
|
||||
#endif // _DEBRIS_H
|
||||
@@ -1,612 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "debugconsole/console.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "globalincs/version.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "graphics/font.h"
|
||||
#include "io/key.h"
|
||||
#include "io/timer.h"
|
||||
#include "osapi/osapi.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
// ========================= GLOBALS =========================
|
||||
bool Dc_debug_on; //!< Flag used to print console and command debugging strings
|
||||
|
||||
// Commands and History
|
||||
SCP_string dc_command_str; //!< The entered command line, arguments and all.
|
||||
//!< Is progressively culled from the left as commands, arguments are parsed in DCF's
|
||||
|
||||
// Misc
|
||||
bool debug_inited = FALSE;
|
||||
uint lastline = 0; // Number of lines written to the console since the last command was processed
|
||||
|
||||
|
||||
// ========================= LOCALS ==========================
|
||||
// Text Buffer
|
||||
uint DBROWS = 80; // # of buffer rows
|
||||
uint DBCOLS = 80; // # of buffer columns
|
||||
uint lastwhite = 0; // Last whitespace character encountered, used by putc for 'true' word wrapping
|
||||
ubyte DTABS = 4; //!< Tab size in spaces
|
||||
|
||||
/**
|
||||
* Human readable versions of the dc_token's. Primarily used in error diagnosis
|
||||
*/
|
||||
static
|
||||
const char *token_str[DCT_MAX_ITEMS] =
|
||||
{
|
||||
"nothing",
|
||||
"string",
|
||||
"float",
|
||||
"integer",
|
||||
"unsigned integer",
|
||||
"byte",
|
||||
"unsigned byte",
|
||||
"boolean"
|
||||
};
|
||||
|
||||
SCP_deque<SCP_string> dc_buffer;
|
||||
|
||||
// Display Window
|
||||
uint DROWS = 25;
|
||||
uint DCOLS = 80;
|
||||
const uint DROWS_MIN = 25;
|
||||
const uint DCOLS_MIN = 80;
|
||||
uint dc_scroll_x; // X scroll position (Leftmost character)
|
||||
uint dc_scroll_y; // Y scroll position (Topmost character)
|
||||
int row_height; // Row/Line height, in pixels
|
||||
int col_width; // Col/Character width, in pixels
|
||||
int dc_font = FONT1;
|
||||
|
||||
SCP_string dc_title;
|
||||
|
||||
#define SCROLL_X_MAX (DBCOLS - DCOLS)
|
||||
#define SCROLL_Y_MAX (DBROWS - DROWS)
|
||||
|
||||
// Commands and History
|
||||
uint DCMDS = 40; // Max number of commands to remember
|
||||
|
||||
SCP_deque<SCP_string> dc_history;
|
||||
SCP_deque<SCP_string>::iterator last_oldcommand; // Iterator to the last old command. Is reset to the start every new command push.
|
||||
|
||||
const char dc_prompt[]= "> "; // The prompt c_str
|
||||
SCP_string dc_command_buf; // The command line as shown in the console. Essentially an input buffer for dc_command_str
|
||||
|
||||
// Local functions
|
||||
/**
|
||||
* @brief Initializes the debug console.
|
||||
*/
|
||||
void dc_init(void);
|
||||
|
||||
/**
|
||||
* @brief Process the entered command string
|
||||
*/
|
||||
void dc_do_command(SCP_string *cmd_str);
|
||||
|
||||
/**
|
||||
* @brief Draws the in-game console.
|
||||
*/
|
||||
void dc_draw(bool show_prompt);
|
||||
|
||||
/**
|
||||
* Draws the cursor
|
||||
* @param [in] cmd_string The formatted command string displayed by dc_draw_window
|
||||
* @param [in] x The x screen position of the command string
|
||||
* @param [in] y The y screen position of the command string
|
||||
*/
|
||||
void dc_draw_cursor( SCP_string &cmd_string, int x, int y );
|
||||
|
||||
/**
|
||||
* Draws the window text
|
||||
*/
|
||||
void dc_draw_window(bool show_prompt);
|
||||
|
||||
/**
|
||||
* @brief Stuffs the given character into the output buffer.
|
||||
* @details Also handles tab alignment, newlines, and maintains the target.
|
||||
*/
|
||||
void dc_putc(char c);
|
||||
|
||||
/**
|
||||
* @brief Predicate function used to sort debug_commands
|
||||
*/
|
||||
bool dcmd_less(debug_command *first, debug_command *second);
|
||||
|
||||
// ============================== IMPLEMENTATIONS =============================
|
||||
void dc_do_command(SCP_string *cmd_str)
|
||||
{
|
||||
/**
|
||||
* Grab the first word from the cmd_str
|
||||
* If it is not a literal, ignore it "Invalid keyword: %s"
|
||||
* Search for the command...
|
||||
* Compare the word against valid commands
|
||||
* If command not found, ignore it "Invalid or unknown command: %s"\
|
||||
* Process the command...
|
||||
* Call the function to process the command (the rest of the command line is in the parser)
|
||||
* Function takes care of long_help and status depending on the mode.
|
||||
*/
|
||||
int i;
|
||||
SCP_string command;
|
||||
extern debug_command* dc_commands[]; // z64: I don't like this extern here, at all. Nope nope nope.
|
||||
|
||||
if (cmd_str->empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
dc_parse_init(*cmd_str);
|
||||
|
||||
dc_stuff_string_white(command); // Grab the first token, presumably this is a command
|
||||
|
||||
for (i = 0; i < dc_commands_size; ++i) {
|
||||
|
||||
if (stricmp(dc_commands[i]->name, command.c_str()) == 0) {
|
||||
break;
|
||||
} // Else, continue
|
||||
}
|
||||
|
||||
if (i == dc_commands_size) {
|
||||
dc_printf("Command not found: '%s'\n", command.c_str());
|
||||
return;
|
||||
} // Else, we found our command
|
||||
|
||||
try {
|
||||
dc_commands[i]->func(); // Run the command!
|
||||
|
||||
} catch (errParseString err) {
|
||||
dc_printf("Require string(s) not found: \n");
|
||||
for (uint j = 0; j < err.expected_tokens.size(); ++j) {
|
||||
dc_printf("%i: %s\n", j, err.expected_tokens[j].c_str());
|
||||
}
|
||||
|
||||
dc_printf("Found '%s' instead\n", err.found_token.c_str());
|
||||
|
||||
} catch (errParse err) {
|
||||
dc_printf("Invalid argument. Expected %s, found '%s'\n", token_str[err.expected_type], err.found_token.c_str());
|
||||
|
||||
}
|
||||
|
||||
// dc_maybe_stuff_string is vulnerable to overflow. Once the errParseOverflow throw class (or w/e) gets
|
||||
// implemented, this last command should be put into its own try{} catch{} block.
|
||||
if (dc_maybe_stuff_string(command)) {
|
||||
dc_printf( "Ignoring the unused command line tail '%s'\n", command.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
void dc_draw(bool show_prompt = FALSE)
|
||||
{
|
||||
gr_clear();
|
||||
gr_set_font(dc_font);
|
||||
gr_set_color_fast( &Color_bright );
|
||||
gr_string( 0x8000, gr_screen.center_offset_y + 3, dc_title.c_str(), GR_RESIZE_NONE );
|
||||
|
||||
gr_set_color_fast( &Color_normal );
|
||||
|
||||
dc_draw_window(show_prompt);
|
||||
|
||||
gr_flip();
|
||||
}
|
||||
|
||||
void dc_draw_cursor( SCP_string &cmd_string, int x, int y )
|
||||
{
|
||||
int t;
|
||||
int w, h; // gr_string width and height
|
||||
|
||||
t = timer_get_fixed_seconds() / (F1_0/3);
|
||||
if ( t & 1 ) {
|
||||
gr_get_string_size( &w, &h, cmd_string.c_str() );
|
||||
|
||||
w %= (DCOLS * Current_font->w);
|
||||
//gr_string( w, debug_y*16, "_" );
|
||||
gr_rect(gr_screen.center_offset_x + (x + (w + 1)), gr_screen.center_offset_y + (y + (h + 1)), 2, Current_font->h, GR_RESIZE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
void dc_draw_window(bool show_prompt)
|
||||
{
|
||||
uint cmd_lines; // Number of lines for the command string
|
||||
uint buffer_lines; // Number of lines from the buffer to draw
|
||||
uint i; // The current row we're drawing
|
||||
uint j; // The current row of the command string we're drawing
|
||||
SCP_string out_str; // The command string + prompt character
|
||||
SCP_string::iterator str_it; // Iterator to out_str
|
||||
|
||||
out_str = dc_prompt + dc_command_buf;
|
||||
cmd_lines = (out_str.size() / DCOLS) + 1;
|
||||
if (show_prompt) {
|
||||
buffer_lines = DROWS - cmd_lines;
|
||||
} else {
|
||||
buffer_lines = DROWS;
|
||||
}
|
||||
|
||||
// Ensure the window is not bigger than the buffer
|
||||
CLAMP(DROWS, DROWS_MIN, DBROWS);
|
||||
CLAMP(DCOLS, DCOLS_MIN, DBCOLS);
|
||||
|
||||
// Ensure we don't scroll too far
|
||||
dc_scroll_x = MIN(dc_scroll_x, (DBCOLS - DCOLS));
|
||||
if (dc_buffer.size() >= buffer_lines) {
|
||||
dc_scroll_y = MIN(dc_scroll_y, (dc_buffer.size() - buffer_lines));
|
||||
} else {
|
||||
dc_scroll_y = 0; // Disallow vscroll until the buffer is larger than the window
|
||||
}
|
||||
|
||||
// Draw the buffer strings
|
||||
for (i = 0; i < buffer_lines; ++i) {
|
||||
if ((i + dc_scroll_y) < dc_buffer.size()) {
|
||||
gr_string(gr_screen.center_offset_x, gr_screen.center_offset_y + ((i * row_height) + row_height), dc_buffer[i + dc_scroll_y].substr(dc_scroll_x).c_str(), GR_RESIZE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the command string w/ padding only if the prompt is active.
|
||||
if (show_prompt) {
|
||||
i += 1; // 1 line between the output and the input text
|
||||
j = 0;
|
||||
gr_set_color_fast(&Color_bright);
|
||||
for (str_it = out_str.begin(); str_it < out_str.end(); ++str_it) {
|
||||
if (j == (DCOLS - 1)) {
|
||||
// Insert a newline char at every place the string needs to return the 'carriage'
|
||||
str_it = out_str.insert(str_it, '\n');
|
||||
j = 0;
|
||||
} else {
|
||||
++j;
|
||||
}
|
||||
}
|
||||
gr_string(gr_screen.center_offset_x, gr_screen.center_offset_y + ((i * row_height) + row_height), out_str.c_str(), GR_RESIZE_NONE);
|
||||
|
||||
dc_draw_cursor(out_str, 0, ((i * row_height)));
|
||||
gr_set_color_fast(&Color_normal);
|
||||
}
|
||||
}
|
||||
|
||||
void dc_init(void)
|
||||
{
|
||||
if (debug_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
debug_inited = TRUE;
|
||||
|
||||
// Init window settings
|
||||
dc_font = FONT1;
|
||||
row_height = ((Current_font->h) * 3) / 2; // Row/Line height, in pixels
|
||||
col_width = Current_font->w; // Col/Character width, in pixels
|
||||
dc_scroll_x = 0;
|
||||
dc_scroll_y = 0;
|
||||
DCOLS = (gr_screen.center_w / col_width) - 1; // Subtract as needed. Windowed mode has some quirks with the resolution
|
||||
DROWS = (gr_screen.center_h / row_height) - 2;
|
||||
DBCOLS = DCOLS;
|
||||
DBROWS = 2 * DROWS;
|
||||
|
||||
// Init History
|
||||
dc_history.clear();
|
||||
dc_history.push_back("");
|
||||
last_oldcommand = dc_history.begin();
|
||||
|
||||
// Init buffers
|
||||
dc_buffer.clear();
|
||||
dc_buffer.push_back("");
|
||||
|
||||
dc_command_buf.reserve(MAX_CLI_LEN);
|
||||
dc_command_buf.clear();
|
||||
|
||||
sprintf(dc_title, "FreeSpace Open v%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD);
|
||||
dc_printf("Debug console started.\n" );
|
||||
}
|
||||
|
||||
bool dc_pause_output(void)
|
||||
{
|
||||
dc_printf("More to follow. Press any key to continue. ESC halts output...");
|
||||
|
||||
int key;
|
||||
bool loop;
|
||||
do {
|
||||
loop = true;
|
||||
|
||||
os_poll();
|
||||
|
||||
dc_draw(FALSE);
|
||||
|
||||
key = key_inkey();
|
||||
switch (key) {
|
||||
case KEY_ESC:
|
||||
return true;
|
||||
break;
|
||||
|
||||
case KEY_PAGEUP:
|
||||
if (dc_scroll_y > 1) {
|
||||
dc_scroll_y--;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_PAGEDOWN:
|
||||
if (dc_scroll_y < DBROWS) {
|
||||
dc_scroll_y++;
|
||||
} else {
|
||||
dc_scroll_y = DBROWS;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_LEFT:
|
||||
// TODO: Scroll Left
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
// TODO: Scroll Right
|
||||
break;
|
||||
case 0:
|
||||
// No key pressed
|
||||
break;
|
||||
default:
|
||||
// Non-control key pressed, break.
|
||||
loop = false;
|
||||
}
|
||||
} while (loop);
|
||||
|
||||
dc_printf("\n");
|
||||
return false;
|
||||
};
|
||||
|
||||
void dc_printf(const char *format, ...)
|
||||
{
|
||||
SCP_string tmp;
|
||||
va_list args;
|
||||
SCP_string::iterator tmp_it;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(tmp, format, args);
|
||||
va_end(args);
|
||||
|
||||
for (tmp_it = tmp.begin(); tmp_it != tmp.end(); ++tmp_it) {
|
||||
dc_putc(*tmp_it);
|
||||
}
|
||||
}
|
||||
|
||||
void dc_putc(char c)
|
||||
{
|
||||
SCP_string* line_str = &(dc_buffer.back());
|
||||
SCP_string temp_str;
|
||||
int i;
|
||||
int w;
|
||||
|
||||
if (c == ' ') {
|
||||
/**
|
||||
* Push c onto the temp_str and get its gr_string width
|
||||
*
|
||||
* If we run out of room on the line, or
|
||||
* If we run out of room on the screen, change c to a '\n' and let subsequent block handle it,
|
||||
* Else, push the space onto the line and bail
|
||||
*/
|
||||
temp_str = *line_str;
|
||||
temp_str.push_back(c);
|
||||
gr_get_string_size(&w, NULL, temp_str.c_str());
|
||||
|
||||
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.center_w)) {
|
||||
c = '\n';
|
||||
|
||||
} else {
|
||||
lastwhite = temp_str.size();
|
||||
*line_str = temp_str;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\t') {
|
||||
/**
|
||||
* Calculate how many spaces to put in to align tabs,
|
||||
* Append temp_str with the spaces and get its gr_string width
|
||||
*
|
||||
* If we run out of room on the line, or
|
||||
* If we run out of room on the screen, change c to a '\n' and let subsequent block handle it,
|
||||
* Else, copy temp_str onto the line, update the lastwhite index, and bail
|
||||
*/
|
||||
i = DTABS - (line_str->size() % DTABS);
|
||||
temp_str = *line_str;
|
||||
temp_str.append(i, ' ');
|
||||
gr_get_string_size(&w, NULL, temp_str.c_str());
|
||||
|
||||
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.center_w)) {
|
||||
c = '\n';
|
||||
|
||||
} else {
|
||||
lastwhite = temp_str.size();
|
||||
*line_str = temp_str;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n') {
|
||||
/**
|
||||
* Trash whatever char happens to be past (DBCOLS - 1),
|
||||
* Push a blank line onto the dc_buffer from the bottom,
|
||||
* Increment the scroller, if needed,
|
||||
* Trash the topmost line(s) in the buffer,
|
||||
* Reset the lastwhite index,
|
||||
* Increment the lastline counter, and finally
|
||||
* bail
|
||||
*/
|
||||
if (line_str->size() > DBCOLS) {
|
||||
line_str->resize(DBCOLS);
|
||||
}
|
||||
dc_buffer.push_back("");
|
||||
|
||||
if ((dc_buffer.size() > DROWS) && (dc_scroll_y < SCROLL_Y_MAX)) {
|
||||
dc_scroll_y++;
|
||||
}
|
||||
|
||||
while (dc_buffer.size() > DBROWS) {
|
||||
dc_buffer.pop_front();
|
||||
}
|
||||
|
||||
lastwhite = 0;
|
||||
lastline++;
|
||||
return;
|
||||
}
|
||||
|
||||
// By this point, c is probably a writable character
|
||||
temp_str = *line_str;
|
||||
temp_str.push_back(c);
|
||||
gr_get_string_size(&w, NULL, temp_str.c_str());
|
||||
|
||||
if ((temp_str.size() >= DBCOLS) || (w > gr_screen.center_w)) {
|
||||
/**
|
||||
* Word wrapping
|
||||
* Save the word, clear the line of the word, push new line with the word on it
|
||||
* Update scroll_y, if needed,
|
||||
* Pop off old lines, and finally
|
||||
* Push new character onto the new line
|
||||
*/
|
||||
temp_str = line_str->substr(lastwhite);
|
||||
line_str->resize(lastwhite);
|
||||
dc_buffer.push_back(temp_str);
|
||||
line_str = &dc_buffer.back();
|
||||
|
||||
if ((dc_buffer.size() > DROWS) && (dc_scroll_y < SCROLL_Y_MAX)) {
|
||||
dc_scroll_y++;
|
||||
}
|
||||
|
||||
while (dc_buffer.size() > DBROWS) {
|
||||
dc_buffer.pop_front();
|
||||
}
|
||||
|
||||
lastwhite = 0;
|
||||
lastline++;
|
||||
line_str->push_back(c);
|
||||
return;
|
||||
}
|
||||
|
||||
// Else, just push the char onto the line
|
||||
line_str->push_back(c);
|
||||
}
|
||||
|
||||
bool dcmd_less(debug_command *first, debug_command *second)
|
||||
{
|
||||
return (strcmp(first->name, second->name) < 0);
|
||||
}
|
||||
|
||||
void debug_console(void (*_func)(void))
|
||||
{
|
||||
int done = 0;
|
||||
|
||||
while( key_inkey() ) {
|
||||
os_poll();
|
||||
}
|
||||
|
||||
if ( !debug_inited ) {
|
||||
dc_init();
|
||||
}
|
||||
|
||||
dc_draw(TRUE);
|
||||
|
||||
while (!done) {
|
||||
// poll the os
|
||||
os_poll();
|
||||
|
||||
int k = key_inkey();
|
||||
switch( k ) {
|
||||
|
||||
case KEY_SHIFTED+KEY_ENTER:
|
||||
case KEY_ESC:
|
||||
done = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_BACKSP:
|
||||
if (!dc_command_buf.empty()) {
|
||||
dc_command_buf.erase(dc_command_buf.size() - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_F3:
|
||||
case KEY_UP:
|
||||
if (last_oldcommand < (dc_history.end() - 1)) {
|
||||
++last_oldcommand;
|
||||
}
|
||||
|
||||
dc_command_buf = *last_oldcommand;
|
||||
break;
|
||||
|
||||
case KEY_DOWN:
|
||||
if (last_oldcommand > dc_history.begin()) {
|
||||
--last_oldcommand;
|
||||
}
|
||||
|
||||
dc_command_buf = *last_oldcommand;
|
||||
break;
|
||||
|
||||
case KEY_PAGEUP:
|
||||
if (dc_scroll_y > 1) {
|
||||
dc_scroll_y--;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_PAGEDOWN:
|
||||
if (dc_scroll_y < (DBROWS - DROWS)) {
|
||||
dc_scroll_y++;
|
||||
} else {
|
||||
dc_scroll_y = (DBROWS - DROWS);
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
dc_scroll_y = (DBROWS - DROWS); // Set the scroll to look at the bottom
|
||||
last_oldcommand = dc_history.begin(); // Reset the last oldcommand
|
||||
lastline = 0; // Reset the line counter
|
||||
|
||||
// Clear the command line on the window, but don't print the prompt until the command has processed
|
||||
// Stuff a copy of the command line onto the history
|
||||
// Search for the command
|
||||
// If not found:
|
||||
// abort,
|
||||
// dc_printf("Error: Invalid or Missing command %s", cmd.c_str()), and
|
||||
// dc_printf(dc_prompt) when ready for input
|
||||
// Call the function for that command, and strip the cmd token from the command line string
|
||||
if (dc_command_buf.empty()) {
|
||||
dc_printf("No command given.\n");
|
||||
break;
|
||||
} // Else, continue to process the cmd_line
|
||||
|
||||
// z64: Thread Note: Maybe lock a mutex here to allow a previous DCF to finish/abort before starting a new one
|
||||
// z64: We'll just assume we won't be here unless a command has finished...
|
||||
dc_history.push_front(dc_command_buf); // Push the command onto the history queue
|
||||
last_oldcommand = dc_history.begin(); // Reset oldcommand
|
||||
|
||||
while (dc_history.size() > DCMDS) {
|
||||
dc_history.pop_back(); // Keep the commands less than or equal to DCMDS
|
||||
}
|
||||
|
||||
dc_command_str = dc_command_buf; // Xfer to the command string for processing
|
||||
dc_command_buf.resize(0); // Nullify the buffer
|
||||
dc_printf("%s%s\n", dc_prompt, dc_command_str.c_str()); // Print the command w/ prompt.
|
||||
dc_draw(FALSE); // Redraw the console without the command line.
|
||||
dc_do_command(&dc_command_str); // Try to do the command
|
||||
break;
|
||||
|
||||
default:
|
||||
// Not any of the control key codes, so it's probably a letter or number.
|
||||
ubyte c = (ubyte)key_to_ascii(k);
|
||||
if ((c != 255) && (dc_command_buf.size() < MAX_CLI_LEN)) {
|
||||
dc_command_buf.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
// Do the passed function
|
||||
if ( _func ) {
|
||||
_func();
|
||||
}
|
||||
|
||||
// All done, and ready for new entry
|
||||
dc_draw(TRUE);
|
||||
}
|
||||
|
||||
while( key_inkey() ) {
|
||||
os_poll();
|
||||
}
|
||||
}
|
||||
@@ -1,279 +0,0 @@
|
||||
#ifndef _CONSOLE_H
|
||||
#define _CONSOLE_H
|
||||
/*
|
||||
* z64555's debug console, created for the FreeSpace Source Code project
|
||||
*
|
||||
* Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
|
||||
* commercially exploit the source or things you created based on the source.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file console.h
|
||||
* @brief An overhauled/updated debug console to allow monitoring, testing, and general debugging of new features.
|
||||
*
|
||||
* @details
|
||||
* Of key interest is Volition's DCF macro, which adds the function argument to the available command list in the
|
||||
* debug console. These functions may be defined in the .cpp file that they are related to, but it is recommended
|
||||
* that they be in their own .cpp if they have multiple sub-arguments (ex: Git has its sub-arguments delimited by
|
||||
* a pair of -'s, or --)
|
||||
*/
|
||||
|
||||
#include "debugconsole/consoleparse.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/vmallocator.h"
|
||||
|
||||
#define DC_MAX_COMMANDS 300
|
||||
|
||||
class debug_command;
|
||||
|
||||
/**
|
||||
* @def DCF
|
||||
*
|
||||
* @brief The potent DCF macro, used to define new debug commands for the console.
|
||||
*
|
||||
* @param function_name[in] The name of the function, as shown in the debug console
|
||||
* @param help_txt[in] The short-help text, as shown as listed from the 'help' command
|
||||
*
|
||||
* @details
|
||||
* Each DCF is responsible for getting data from the debug console's command line. The parsing functions for the
|
||||
* command line have been set up to have similar syntax and usage as the parselo commands. (see consoleparse.h)
|
||||
* Most, if not all, argument and subcommand strings should be parsed by the dc_optional_string functions.
|
||||
* Usage example:
|
||||
* DCF(toggle_it, "description")
|
||||
* {
|
||||
* if (dc_optional_string_either("help", "--help")) {
|
||||
* dc_printf("Usage: sample. Toggles This_var on/off\n");
|
||||
*
|
||||
* } else if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
|
||||
* dc_printf("This_var is %s\n", (This_var ? "ON" : "OFF"));
|
||||
*
|
||||
* } else {
|
||||
* This_var = !This_var;
|
||||
*
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* In the console, the command would be listed as 'toggle_it', and dcf_help would display it as:
|
||||
* toggle_it - Usage: sample. Toggles This_var on/off.
|
||||
* Note: The only allowed function type is a void fn( void )
|
||||
*/
|
||||
#define DCF(function_name, help_text) \
|
||||
void dcf_##function_name(); \
|
||||
debug_command dcmd_##function_name(#function_name, help_text, dcf_##function_name); \
|
||||
void dcf_##function_name()
|
||||
|
||||
/**
|
||||
* @def Shortcut for debug commands that toggle a bool, such as Show_lightning
|
||||
*
|
||||
* @param [in] function_name Name of the function, as shown in the debug console
|
||||
* @param [in] bool_variable Name of the variable to allow toggling.
|
||||
*/
|
||||
#define DCF_BOOL(function_name, bool_variable) \
|
||||
void dcf_##function_name(); \
|
||||
debug_command dcmd_##function_name(#function_name, "Sets or toggles the boolean: "#bool_variable, dcf_##function_name ); \
|
||||
void dcf_##function_name() { \
|
||||
bool bool_tmp = bool_variable != 0; \
|
||||
if (dc_optional_string_either("help", "--help")) { \
|
||||
dc_printf( "Usage: %s [bool]\nSets %s to true or false. If nothing passed, then toggles it.\n", #function_name, #bool_variable ); \
|
||||
return; \
|
||||
} \
|
||||
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
|
||||
dc_printf("%s = %s\n", #bool_variable, (bool_variable ? "TRUE" : "FALSE")); \
|
||||
return; \
|
||||
} \
|
||||
if (!dc_maybe_stuff_boolean(&bool_tmp)) { \
|
||||
if (bool_variable != 0) \
|
||||
bool_variable = 0; \
|
||||
else \
|
||||
bool_variable = 1; \
|
||||
} else { \
|
||||
if (bool_tmp) \
|
||||
bool_variable = 1; \
|
||||
else \
|
||||
bool_variable = 0; \
|
||||
} \
|
||||
dc_printf("%s set to %s\n", #bool_variable, (bool_variable != 0 ? "TRUE" : "FALSE")); \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @def Same as DCF_BOOL, but with custom help strings
|
||||
*
|
||||
* @param [in] function_name Name of the function, as shown in the debug console
|
||||
* @param [in] bool_variable Name of the variable to allow toggling.
|
||||
*/
|
||||
#define DCF_BOOL2(function_name, bool_variable, short_help, long_help) \
|
||||
void dcf_##function_name(); \
|
||||
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
|
||||
void dcf_##function_name() { \
|
||||
if (dc_optional_string_either("help", "--help")) { \
|
||||
dc_printf( #long_help ); \
|
||||
return; \
|
||||
} \
|
||||
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
|
||||
dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE")); \
|
||||
return; \
|
||||
} \
|
||||
if (!dc_maybe_stuff_boolean(&bool_variable)) { \
|
||||
bool_variable = !bool_variable; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @def Shortcut for single-variable setters/monitors
|
||||
*
|
||||
* @param [in] function_name
|
||||
* @param [in] float_variable
|
||||
* @param [in] short_help
|
||||
*/
|
||||
#define DCF_FLOAT(function_name, float_variable, short_help) \
|
||||
void dcf_##function_name(); \
|
||||
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
|
||||
void dcf_##function_name() { \
|
||||
float value; \
|
||||
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
|
||||
dc_printf("%s = %f\n", #float_variable, float_variable); \
|
||||
return; \
|
||||
} \
|
||||
dc_stuff_float(&value); \
|
||||
float_variable = value; \
|
||||
dc_printf("%s set to %f\n", #float_variable, float_variable); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
|
||||
*
|
||||
* @param [in] function_name
|
||||
* @param [in] float_variable
|
||||
* @param [in] lower_bounds
|
||||
* @param [in] upper_bounds
|
||||
* @param [in] short_help
|
||||
*/
|
||||
#define DCF_FLOAT2(function_name, float_variable, lower_bounds, upper_bounds, short_help) \
|
||||
void dcf_##function_name(); \
|
||||
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
|
||||
void dcf_##function_name() { \
|
||||
float value; \
|
||||
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
|
||||
dc_printf("%s = %f\n", #float_variable, float_variable); \
|
||||
return; \
|
||||
} \
|
||||
dc_stuff_float(&value); \
|
||||
CLAMP(float_variable, lower_bounds, upper_bounds); \
|
||||
float_variable = value; \
|
||||
dc_printf("%s set to %f\n", #float_variable, float_variable); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @def Shortcut for single-variable setters/monitors
|
||||
*
|
||||
* @param [in] function_name
|
||||
* @param [in] int_variable
|
||||
* @param [in] short_help
|
||||
*/
|
||||
#define DCF_INT(function_name, int_variable, short_help) \
|
||||
void dcf_##function_name(); \
|
||||
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
|
||||
void dcf_##function_name() { \
|
||||
int value; \
|
||||
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
|
||||
dc_printf("%s = %i\n", #int_variable, int_variable); \
|
||||
return; \
|
||||
} \
|
||||
dc_stuff_int(&value); \
|
||||
int_variable = value; \
|
||||
dc_printf("%s set to %i\n", #int_variable, int_variable); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
|
||||
*
|
||||
* @param [in] function_name
|
||||
* @param [in] int_variable
|
||||
* @param [in] lower_bounds
|
||||
* @param [in] upper_bounds
|
||||
* @param [in] short_help
|
||||
*/
|
||||
#define DCF_INT2(function_name, int_variable, lower_bounds, upper_bounds, short_help) \
|
||||
void dcf_##function_name(); \
|
||||
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
|
||||
void dcf_##function_name() { \
|
||||
int value; \
|
||||
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
|
||||
dc_printf("%s = %i\n", #int_variable, int_variable); \
|
||||
return; \
|
||||
} \
|
||||
dc_stuff_int(&value); \
|
||||
CLAMP(int_variable, lower_bounds, upper_bounds); \
|
||||
int_variable = value; \
|
||||
dc_printf("%s set to %i\n", #int_variable, int_variable); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @class debug_command
|
||||
* @brief Class to aggregate a debug command with its name (as shown in the console) and short help.
|
||||
*
|
||||
* @details
|
||||
* Note: Long help, as evoked by '<command> help', should be handled by the function itself. It is recommended
|
||||
* that arguments that have sub-arguments be in their own function, so as to aide in organization and to keep the
|
||||
* size of the command function down.
|
||||
*/
|
||||
class debug_command {
|
||||
public:
|
||||
const char *name; //!< The name of the command, as shown in the debug console
|
||||
const char *help; //!< The short help string, as shown by 'help <command>'
|
||||
void (*func)(); //!< Pointer to the function that to run when this command is evoked
|
||||
|
||||
debug_command();
|
||||
|
||||
/**
|
||||
* @brief Adds a debug command to the debug_commands map, if it isn't in there already.
|
||||
*
|
||||
* @details The DCF macro more or less guarantees that a command won't be duplicated on compile time. But no harm in
|
||||
* some extra caution.
|
||||
*/
|
||||
debug_command(const char *name, const char *help, void (*func)());
|
||||
};
|
||||
|
||||
/**
|
||||
* @class is_dcmd
|
||||
* @brief Predicate class used to search for a dcmd by name
|
||||
*/
|
||||
class is_dcmd {
|
||||
public:
|
||||
const char *name;
|
||||
|
||||
is_dcmd(const char *_name) : name(_name) {}
|
||||
|
||||
bool operator() (debug_command* dcmd)
|
||||
{
|
||||
return (strcmp(name, dcmd->name) == 0);
|
||||
}
|
||||
};
|
||||
|
||||
extern bool Dc_debug_on;
|
||||
extern int dc_commands_size;
|
||||
extern uint lastline;
|
||||
extern SCP_string dc_command_str; // The rest of the command line, from the end of the last processed arg on.
|
||||
|
||||
/**
|
||||
* @brief Pauses the output of a command and allows user to scroll through the output history.
|
||||
*
|
||||
* @details Returns true if user has pressed Esc, returns false otherwise. Use this in your function to (safely?) break
|
||||
* out of the loop it's presumably in.
|
||||
*/
|
||||
bool dc_pause_output(void);
|
||||
|
||||
/**
|
||||
* @brief Prints the given char string to the debug console
|
||||
* @details See the doc for std::printf() for formating and more details
|
||||
*/
|
||||
void dc_printf(const char *format, ...);
|
||||
|
||||
/**
|
||||
* @brief Opens and processes the debug console. (Blocking call)
|
||||
* @details TODO: Make this a non-blocking call so that the game can still run while the debug console is open.
|
||||
*/
|
||||
void debug_console(void (*func)(void) = NULL);
|
||||
|
||||
#endif // _CONSOLE_H
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* z64555's debug console
|
||||
* Created for the FreeSpace Source Code project
|
||||
*
|
||||
* Portions of this source code are based on works by Volition, Inc. circa
|
||||
* 1999. You may not sell or otherwise commercially exploit the source or things you
|
||||
* created based on the source
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file consolecmds.cpp
|
||||
*
|
||||
* @brief This file contains the "built-in" commands for the debug console, and is listed by the 'help' and '?' commands
|
||||
*
|
||||
* @details
|
||||
* All other debug commands should be in their respective files and added to the console with the DCF macro. For
|
||||
* further documentation, please see console.h
|
||||
*/
|
||||
|
||||
#include "debugconsole/console.h"
|
||||
#include "debugconsole/consoleparse.h"
|
||||
#include "io/key.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// ========================= GLOBALS =========================
|
||||
debug_command *dc_commands[DC_MAX_COMMANDS];
|
||||
int dc_commands_size = 0;
|
||||
|
||||
// ========================= LOCALS ==========================
|
||||
// dcf_shell commands
|
||||
void dc_shell_font( void );
|
||||
void dc_shell_resize( void );
|
||||
void dc_shell_resize_buf( void );
|
||||
|
||||
// =================== class debug_command ===================
|
||||
debug_command::debug_command()
|
||||
: name(""), help(""), func(NULL) {
|
||||
};
|
||||
|
||||
debug_command::debug_command(const char *_name, const char *_help, void(*_func)())
|
||||
: name(_name), help(_help), func(_func) {
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (dc_commands_size >= DC_MAX_COMMANDS) {
|
||||
Error(LOCATION, "Too many debug console commands! Please inform a coder to increase DC_MAX_COMMANDS.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Start the insertion sort by finding where to stick the debug command
|
||||
for (; i < dc_commands_size; ++i) {
|
||||
ret = stricmp(dc_commands[i]->name, _name);
|
||||
|
||||
if (ret == 0) {
|
||||
Error(LOCATION, "Debug Command %s already exists! Please inform a coder immediately.", _name);
|
||||
return;
|
||||
} else if (ret > 0) {
|
||||
// Insert the command here
|
||||
break;
|
||||
} // Else, do nothing
|
||||
}
|
||||
|
||||
// Then, do the insertion
|
||||
if (i < dc_commands_size) {
|
||||
for (int j = dc_commands_size; j > i; --j) {
|
||||
dc_commands[j] = dc_commands[j - 1];
|
||||
}
|
||||
dc_commands[i] = this;
|
||||
dc_commands_size++;
|
||||
} else {
|
||||
dc_commands[dc_commands_size] = this;
|
||||
dc_commands_size++;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================== IMPLEMENTATIONS =============================
|
||||
|
||||
DCF(debug, "Runs a command in debug mode.")
|
||||
{
|
||||
int i;
|
||||
SCP_string command = "";
|
||||
|
||||
Dc_debug_on = true;
|
||||
|
||||
dc_stuff_string_white(command);
|
||||
|
||||
if (command == "") {
|
||||
dc_printf("<debug> No command given\n");
|
||||
return;
|
||||
} // Else, command is present.
|
||||
|
||||
for (i = 0; i < dc_commands_size; ++i) {
|
||||
if (stricmp(dc_commands[i]->name, command.c_str()) == 0) {
|
||||
break;
|
||||
} // Else, continue
|
||||
}
|
||||
|
||||
if (i == dc_commands_size) {
|
||||
dc_printf("<debug> Command not found: '%s'\n", command.c_str());
|
||||
return;
|
||||
} // Else, we found our command
|
||||
|
||||
dc_printf("<debug> Executing command: '%s'\n", command.c_str());
|
||||
// try {
|
||||
dc_commands[i]->func();
|
||||
// } catch {
|
||||
// }
|
||||
|
||||
Dc_debug_on = false;
|
||||
}
|
||||
|
||||
DCF(help, "Displays the help list." )
|
||||
{
|
||||
extern uint DROWS;
|
||||
|
||||
int i;
|
||||
SCP_string command = "";
|
||||
|
||||
dc_maybe_stuff_string_white(command);
|
||||
if ((command == "help") || (command == "man"))
|
||||
{
|
||||
// Moron filter :D
|
||||
dc_printf("GTVA Command: Sorry pilot. You're on your own.\n");
|
||||
return;
|
||||
|
||||
} else if (command != "") {
|
||||
for (i = 0; i < dc_commands_size; ++i) {
|
||||
if (stricmp(dc_commands[i]->name, command.c_str()) == 0) {
|
||||
break;
|
||||
} // Else, continue
|
||||
}
|
||||
|
||||
if (i == dc_commands_size) {
|
||||
dc_printf("Command not found: '%s'\n", command.c_str());
|
||||
return;
|
||||
} // Else, we found our command
|
||||
|
||||
dc_printf("%s\n", dc_commands[i]->help);
|
||||
return;
|
||||
} // Else, command line is empty, print out the help list
|
||||
|
||||
dc_printf("FreeSpace Open Debug Console\n");
|
||||
dc_printf(" These commands are defined internally.\n");
|
||||
dc_printf(" Typing 'help function_name' will give the short help on the function.\n");
|
||||
dc_printf(" Some functions may have detailed help, try passing \"help\" or \"--help\" to them.");
|
||||
dc_printf(" F3 selects last command line. Up and Down arrow keys scroll through the command history\n");
|
||||
dc_printf("\n");
|
||||
|
||||
dc_printf(" Available commands:\n");
|
||||
for (i = 0; i < dc_commands_size; ++i) {
|
||||
if (((lastline % DROWS) == 0) && (lastline != 0)) {
|
||||
dc_pause_output();
|
||||
}
|
||||
|
||||
dc_printf(" %s - %s\n", dc_commands[i]->name, dc_commands[i]->help);
|
||||
}
|
||||
}
|
||||
|
||||
debug_command dc_man("man", "Also displays the help list", dcf_help);
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,460 +0,0 @@
|
||||
#ifndef _CONSOLEPARSE_H
|
||||
#define _CONSOLEPARSE_H
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Command-line parsing functions for z64555's debug console, created for the FreeSpace Source Code project
|
||||
//
|
||||
// Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
|
||||
// commercially exploit the source or things you created based on the source.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @file consoleparse.h
|
||||
* @brief Parsing functions for the command line. Previously known as the command line scanner
|
||||
*
|
||||
* @details A lot of functions here are blatently copied from parselo.h :D
|
||||
*/
|
||||
|
||||
#include "debugconsole/console.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
#define MAX_CLI_LEN 512
|
||||
#define MAX_TOKEN_LENGTH 255
|
||||
|
||||
enum dc_token {
|
||||
DCT_NONE = 0, //!< No token
|
||||
DCT_STRING, //!< String
|
||||
DCT_FLOAT, //!< Floating point
|
||||
DCT_INT, //!< Integral
|
||||
DCT_UINT, //!< Unsigned Integral
|
||||
DCT_BYTE, //!< Integral with values between -128 and 127
|
||||
DCT_UBYTE, //!< Integral with values between 0 and 255
|
||||
DCT_BOOL, //!< Integral or string evaluated as a boolean
|
||||
|
||||
DCT_MAX_ITEMS //!< Maximum number of dc_token elements. Primarily used as an end value in loops
|
||||
};
|
||||
|
||||
/**
|
||||
* @class errParse
|
||||
*
|
||||
* @brief Class thrown when a required token is not found
|
||||
*
|
||||
* @details This is a basic parser error, it contains the token (a single word) that was found, and the expected token
|
||||
* type. Some DCT's, such as the DCT_STRING's, have their own specific requirements for error handling, and as
|
||||
* such get their own class derived from errParse. The catching routines should be able to catch the derived error
|
||||
* objects, but if not, they can be caught by a routine looking for the base class and then be casted to their
|
||||
* proper type.
|
||||
*/
|
||||
class errParse {
|
||||
public:
|
||||
SCP_string found_token;
|
||||
dc_token expected_type;
|
||||
|
||||
/**
|
||||
* @brief Invalid/Unexpected token constructor
|
||||
* @param [in] found_str The token that was found
|
||||
* @param [in] expected_dct The token type that was expected
|
||||
*/
|
||||
errParse(const char *found_str, dc_token expected_dct)
|
||||
: found_token(found_str), expected_type(expected_dct)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @class errParseString
|
||||
*
|
||||
* @brief Class thrown when an expected string was not found. Can/should contain all of the expected strings.
|
||||
*/
|
||||
class errParseString : public errParse
|
||||
{
|
||||
public:
|
||||
SCP_vector<SCP_string> expected_tokens;
|
||||
|
||||
/**
|
||||
* @brief Invalid/Unexpected token constructor.
|
||||
*
|
||||
* @param [in] found_str The string that was found
|
||||
* @param [in] str The token that was expected
|
||||
*/
|
||||
errParseString(const char *found_str, char *str)
|
||||
: errParse(found_str, DCT_STRING)
|
||||
{
|
||||
expected_tokens.push_back(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Invalid/Unexpected token constructor.
|
||||
*
|
||||
* @param [in] found_str The string that was found
|
||||
* @param [in] str1 The first token that was expected
|
||||
* @param [in] str2 The second token that was expected
|
||||
*/
|
||||
errParseString(const char *found_str, char *str1, char *str2)
|
||||
: errParse(found_str, DCT_STRING)
|
||||
{
|
||||
expected_tokens.push_back(str1);
|
||||
expected_tokens.push_back(str2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Invalid/Unexpected token constructor.
|
||||
*
|
||||
* @param [in] found_str The string that was found
|
||||
* @param [in] strings The strings that were expected
|
||||
*/
|
||||
errParseString(const char *found_str, SCP_vector<SCP_string> &strings)
|
||||
: errParse(found_str, DCT_STRING), expected_tokens(strings)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @class errParseOverflow
|
||||
*
|
||||
* @brief Class thrown when the parsed string or token could not be stuffed into the smaller destination container
|
||||
*
|
||||
* @var found_str Contains the first 'len' valid characters.
|
||||
*/
|
||||
class errParseOverflow : public errParse
|
||||
{
|
||||
public:
|
||||
size_t len; //!< The size of the destination container
|
||||
|
||||
errParseOverflow(const char *found_str, size_t _len)
|
||||
: errParse(found_str, DCT_STRING), len(_len)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initializes the DC command line parser
|
||||
*/
|
||||
void dc_parse_init(SCP_string &str);
|
||||
|
||||
/**
|
||||
* @brief Advances the parser past whitespace characters
|
||||
*/
|
||||
void dc_ignore_white_space(void);
|
||||
|
||||
/**
|
||||
* @brief Advances the parser past grayspace characters
|
||||
*/
|
||||
void dc_ignore_gray_space(void);
|
||||
|
||||
// Required/Optional Token
|
||||
/**
|
||||
* @brief Searches for a specified required string, throwing an errParse if not found.
|
||||
*
|
||||
* @param[in] pstr The string to search for
|
||||
*
|
||||
* @throws errParseString with the required string
|
||||
*/
|
||||
void dc_required_string(char *pstr);
|
||||
|
||||
/**
|
||||
* @brief Searchs for either of the specified required strings, throwing an errParse if neither are found
|
||||
*
|
||||
* @param[in] str1 The first string to search for
|
||||
* @param[in] str2 The second string to search for
|
||||
*
|
||||
* @retval 0 if str1 was found, or
|
||||
* @retval 1 if str2 was found
|
||||
*
|
||||
* @throws errParseString with the required strings
|
||||
*/
|
||||
int dc_required_string_either(char *str1, char *str2);
|
||||
|
||||
/**
|
||||
* @brief Searches for specified required strings
|
||||
*
|
||||
* @param[in] n The number of char[] or c_str's given
|
||||
* @param[in] ... A comma delimited list of one or more required strings.
|
||||
*
|
||||
* @returns The index of the specified required strings (as if they were an array)
|
||||
*
|
||||
* @throws errParseString with the required strings
|
||||
*/
|
||||
uint dc_required_string_any(const uint n, ...);
|
||||
|
||||
/**
|
||||
* @brief Searches for an optional string
|
||||
*
|
||||
* @param[in] pstr The char[] to look for
|
||||
*
|
||||
* @retval true if the string was found,
|
||||
* @retval false otherwise
|
||||
*/
|
||||
bool dc_optional_string(const char *pstr);
|
||||
|
||||
/**
|
||||
* @brief Searches for an optional string and it's alias
|
||||
*
|
||||
* @param[in] str1 The char[] to look for
|
||||
* @param[in] str2 The alternative char[] to look for
|
||||
*
|
||||
* @retval true if the string was found,
|
||||
* @retval false otherwise
|
||||
*/
|
||||
bool dc_optional_string_either(const char *str1, const char *str2);
|
||||
|
||||
|
||||
// ==========================
|
||||
// Stuffers
|
||||
// ==========================
|
||||
|
||||
/**
|
||||
* @brief Stuffs a float to the given variable.
|
||||
*
|
||||
* @param[in] f The float variable to stuff to
|
||||
*
|
||||
* @throws errParse if an unexpected or otherwise malformed float string is found.
|
||||
* @throws errParse if nothing was found
|
||||
*/
|
||||
void dc_stuff_float(float *f);
|
||||
|
||||
/**
|
||||
* @brief Stuffs an int to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
|
||||
*
|
||||
* @param[in] i The int variable to stuff to
|
||||
*
|
||||
* @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
|
||||
* Ex: "0xDEADBEEF" would be parsed properly while "DEADBEEF" would throw an error
|
||||
*
|
||||
* @throws errParse if an unexpected or otherwise malformed float string is found.
|
||||
* @throws errParse if nothing was found
|
||||
*/
|
||||
void dc_stuff_int(int *i);
|
||||
|
||||
/**
|
||||
* @brief Stuffs an unsigned int to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
|
||||
*
|
||||
* @param[in] i The unsigned int variable to stuff to
|
||||
*
|
||||
* @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
|
||||
* Ex: "0xDEADBEEF" would be parsed properly while "DEADBEEF" would throw an error
|
||||
*
|
||||
* @throws errParse if an unexpected or otherwise malformed float string is found.
|
||||
* @throws errParse if nothing was found
|
||||
*/
|
||||
void dc_stuff_uint(uint *i);
|
||||
|
||||
/**
|
||||
* @brief Stuffs an unsigned byte to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
|
||||
*
|
||||
* @param[in] i The ubyte variable to stuff to
|
||||
*
|
||||
* @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
|
||||
* Ex: "0x0F" would be parsed properly while "0F" would throw an error
|
||||
*
|
||||
* @throws errParse if an unexpected or otherwise malformed float string is found.
|
||||
* @throws errParse if nothing was found
|
||||
*/
|
||||
void dc_stuff_ubyte(ubyte *i);
|
||||
|
||||
/**
|
||||
* @brief stuffs a boolean evaluated integer or string into the given variable.
|
||||
*
|
||||
* @param[in] b The bool variable to stuff to
|
||||
*
|
||||
* @details Supports a number of literal strings as true and false, including "true", "false", "yes", "no" and the
|
||||
* yes/no equivalents in other languages supported in localization.
|
||||
* TODO: Make a static string map to handle this instead of being hard-coded
|
||||
*
|
||||
* @throws errParse if an unexpected or otherwise malformed float string is found.
|
||||
* @throws errParse if nothing was found
|
||||
*/
|
||||
void dc_stuff_boolean(bool *b);
|
||||
|
||||
/**
|
||||
* @brief stuffs a boolean evaluated integer or string into the given variable.
|
||||
*
|
||||
* @param[in] i The int variable to stuff to. 0 is false, 1 is true
|
||||
*
|
||||
* @details Supports a number of literal strings as true and false, including "true", "false", "yes", "no" and the
|
||||
* yes/no equivalents in other languages supported in localization.
|
||||
* TODO: Make a static string map to handle this instead of being hard-coded
|
||||
*
|
||||
* @throws errParse if an unexpected or otherwise malformed float string is found.
|
||||
* @throws errParse if nothing was found
|
||||
*/
|
||||
void dc_stuff_boolean(int *i);
|
||||
|
||||
/**
|
||||
* @brief Stuffs a string to out_str from the command line, stopping at the end of the command line
|
||||
*
|
||||
* @param[out] str Destination string
|
||||
* @param[in] maxlen Maximum length to copy. (maxlen <= sizeof(str)) && (maxlen <= MAX_TOKEN_LENGTH)
|
||||
*
|
||||
* @throws errParse when nothing left was found on the command line
|
||||
* @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
|
||||
*/
|
||||
void dc_stuff_string(char *str, size_t maxlen);
|
||||
|
||||
/**
|
||||
* @brief Stuffs a string to out_str from the command line, stopping at the end of the command line
|
||||
*
|
||||
* @param[out] str Destination string
|
||||
*
|
||||
* @throws errParse when nothing left was found on the command line
|
||||
*/
|
||||
void dc_stuff_string(SCP_string &str);
|
||||
|
||||
/**
|
||||
* @brief Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the command line
|
||||
*
|
||||
* @param[out] str Destination string
|
||||
* @param[in] len Maximum length to copy. (len <= sizeof(str)) && (len <= MAX_TOKEN_LENGTH)
|
||||
*
|
||||
* @throws errParse when nothing left was found on the command line
|
||||
* @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
|
||||
*/
|
||||
void dc_stuff_string_white(char *str, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the command line
|
||||
*
|
||||
* @param[out] str Destination string
|
||||
*
|
||||
* @throws errParse when nothing left was found on the command line
|
||||
*/
|
||||
void dc_stuff_string_white(SCP_string &str);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff a float from the Command_string.
|
||||
*
|
||||
* @param[in] f The float variable to maybe stuff.
|
||||
*
|
||||
* @details
|
||||
* If there's nothing on the command line, *f = 0 and false is returned
|
||||
*
|
||||
* If there's something on the command line, and we're able to convert it, *f = the converted value, true is
|
||||
* returned, and the parser is advanced past the token
|
||||
*
|
||||
* If there's something on command line, but we can't convert it, an errParse is thrown
|
||||
*/
|
||||
bool dc_maybe_stuff_float(float *f);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff an int from the Command_string.
|
||||
*
|
||||
* @param[in] i The int variable to maybe stuff.
|
||||
*
|
||||
* @details
|
||||
* If there's nothing on the command line, *i = 0 and false is returned
|
||||
*
|
||||
* If there's something on the command line, and we're able to convert it, *i = the converted value, true is
|
||||
* returned, and the parser is advanced past the token
|
||||
*
|
||||
* If there's something on command line, but we can't convert it, an errParse is thrown
|
||||
*/
|
||||
bool dc_maybe_stuff_int(int *i);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff an uint from the Command_string.
|
||||
*
|
||||
* @param[in] i The uint variable to maybe stuff.
|
||||
*
|
||||
* @details
|
||||
* If there's nothing on the command line, *i = 0 and false is returned
|
||||
*
|
||||
* If there's something on the command line, and we're able to convert it, *i = the converted value, true is
|
||||
* returned, and the parser is advanced past the token
|
||||
*
|
||||
* If there's something on command line, but we can't convert it, an errParse is thrown
|
||||
*/
|
||||
bool dc_maybe_stuff_uint(uint *i);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff an ubyte from the Command_string.
|
||||
*
|
||||
* @param[in] i The ubyte variable to maybe stuff.
|
||||
*
|
||||
* @details
|
||||
* If there's nothing on the command line, *i = 0 and false is returned
|
||||
*
|
||||
* If there's something on the command line, and we're able to convert it, *i = the converted value, true is
|
||||
* returned, and the parser is advanced past the token
|
||||
*
|
||||
* If there's something on command line, but we can't convert it, an errParse is thrown
|
||||
*/
|
||||
bool dc_maybe_stuff_ubyte(ubyte *i);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff a bool from the Command_string.
|
||||
*
|
||||
* @param[in] b The bool variable to maybe stuff.
|
||||
*
|
||||
* @details
|
||||
* If there's nothing on the command line, *b = false and false is returned
|
||||
*
|
||||
* If there's something on the command line, and we're able to convert it, *b = the converted value, true is
|
||||
* returned, and the parser is advanced past the token
|
||||
*
|
||||
* If there's something on command line, but we can't convert it, an errParse is thrown
|
||||
*/
|
||||
bool dc_maybe_stuff_boolean(bool *b);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff an int with a bool value from the Command_string.
|
||||
*
|
||||
* @param[in] i The int variable to maybe stuff.
|
||||
*
|
||||
* @details
|
||||
* If there's nothing on the command line, *i = 0 and false is returned
|
||||
*
|
||||
* If there's something on the command line, and we're able to convert it, *i = the converted value, true is
|
||||
* returned, and the parser is advanced past the token
|
||||
*
|
||||
* If there's something on command line, but we can't convert it, an errParse is thrown
|
||||
*/
|
||||
bool dc_maybe_stuff_boolean(int *i);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff a string to out_str from the command line, stopping at the end of the command line
|
||||
*
|
||||
* @param[out] str Destination string. If nothing was found, str = ""
|
||||
* @param[in] len Maximum length to copy. (len <= sizeof(str)) && (len <= MAX_TOKEN_LENGTH)
|
||||
*
|
||||
* @retval true if the operation was successful,
|
||||
* @retval false otherwise
|
||||
*
|
||||
* @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
|
||||
*/
|
||||
bool dc_maybe_stuff_string(char *str, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff a string to out_str from the command line, stopping at the end of the command line
|
||||
*
|
||||
* @param[out] str Destination string. If nothing was found, str = ""
|
||||
*
|
||||
* @retval true if the operation was successful,
|
||||
* @retval false otherwise
|
||||
*/
|
||||
bool dc_maybe_stuff_string(SCP_string &str);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff a whitespace delimited string to out_str from the command line, stopping at the end of the command line
|
||||
*
|
||||
* @param[out] str Destination string. If nothing was found, str = ""
|
||||
* @param[in] len Maximum length to copy. (maxlen <= sizeof(str)) && (maxlen <= MAX_TOKEN_LENGTH)
|
||||
*
|
||||
* @retval true if the operation was successful,
|
||||
* @retval false otherwise
|
||||
*
|
||||
* @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
|
||||
*/
|
||||
bool dc_maybe_stuff_string_white(char *str, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Tries to stuff a whitespace delimited string to out_str from the command line, stopping at the end of the command line
|
||||
*
|
||||
* @param[out] str Destination string. If nothing was found, str = ""
|
||||
*
|
||||
* @retval true if the operation was successful,
|
||||
* @retval false otherwise
|
||||
*/
|
||||
bool dc_maybe_stuff_string_white(SCP_string &str);
|
||||
|
||||
#endif // _CONSOLEPARSE_H
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,93 +0,0 @@
|
||||
#ifndef EXTERNALCODE_H_INCLUDED_
|
||||
#define EXTERNALCODE_H_INCLUDED_
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include "SDL_loadso.h"
|
||||
|
||||
/* This class loads external libraries for FSO use.
|
||||
* Uses SDL to do the actual loading so this should be supported on most platforms
|
||||
*/
|
||||
class SCP_ExternalCode
|
||||
{
|
||||
public:
|
||||
SCP_ExternalCode() : m_dll(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SCP_ExternalCode()
|
||||
{
|
||||
if (m_dll)
|
||||
SDL_UnloadObject(m_dll);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool LoadExternal(const char* externlib)
|
||||
{
|
||||
if (!externlib)
|
||||
return false;
|
||||
|
||||
m_dll = SDL_LoadObject(externlib);
|
||||
|
||||
if (m_dll)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void* LoadFunction(const char* functionname)
|
||||
{
|
||||
if (m_dll != NULL && functionname != NULL)
|
||||
return SDL_LoadFunction(m_dll, functionname);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
private:
|
||||
void* m_dll;
|
||||
};
|
||||
|
||||
/* These are available if you're compiling an external DLL
|
||||
* So far we have trackir, and speech is on the way
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
# define SCP_EXT_CALLCONV __cdecl
|
||||
# ifdef SCPDLL_EXTERNAL_LIB
|
||||
# define SCPDLL_EXTERNAL __declspec( dllexport )
|
||||
# else
|
||||
# define SCPDLL_EXTERNAL __declspec( dllimport )
|
||||
# endif
|
||||
/* Must be in a CPP file in your DLL code
|
||||
* If you want to write your own, you shouldn't.
|
||||
*/
|
||||
# define SCPDLL_DLLMAIN( ) \
|
||||
SCP_EXTERN_C BOOL APIENTRY DllMain( HANDLE, DWORD, LPVOID ) { return TRUE; }
|
||||
#else
|
||||
# define SCP_EXT_CALLCONV
|
||||
# define SCPDLL_EXTERNAL
|
||||
# define SCPDLL_DLLMAIN( )
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define SCP_EXTERN_C extern "C"
|
||||
#else
|
||||
# define SCP_EXTERN_C
|
||||
#endif
|
||||
|
||||
/* Version information */
|
||||
typedef struct _SCPDLL_Version
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
} SCPDLL_Version;
|
||||
|
||||
typedef int (SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version*);
|
||||
|
||||
/* Must be in a CPP file in your DLL code */
|
||||
#define SCPDLL_VERSION_FUNCTION( Major, Minor, Patch ) \
|
||||
SCP_EXTERN_C int SCPDLL_EXTERNAL SCPDLL_GetVersion( SCPDLL_Version* v ) { \
|
||||
if ( !v ) return -1;\
|
||||
v->major = Major; v->minor = Minor; v->patch = Patch;\
|
||||
return 0; }
|
||||
|
||||
#endif /* EXTERNALCODE_H_INCLUDED_ */
|
||||
@@ -1,4 +0,0 @@
|
||||
#include "trackirpublic.h"
|
||||
|
||||
/* The TrackIR Interface */
|
||||
TrackIRDLL gTirDll_TrackIR;
|
||||
@@ -1,191 +0,0 @@
|
||||
#ifndef TRACKIRPUBLIC_H_INCLUDED_
|
||||
#define TRACKIRPUBLIC_H_INCLUDED_
|
||||
|
||||
#ifdef WIN32
|
||||
# include "SDL_syswm.h" // For SDL_SysWMinfo
|
||||
#endif
|
||||
|
||||
#include "external_dll/externalcode.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "osapi/osapi.h"
|
||||
|
||||
#define TRACKIRBRIDGEDLLNAME "scptrackir.dll"
|
||||
|
||||
#define SCP_INITRESULT_SUCCESS 0
|
||||
#define SCP_INITRESULT_BADKEY 1
|
||||
#define SCP_INITRESULT_BADPATH 2
|
||||
#define SCP_INITRESULT_PATHTOOLONG 3
|
||||
#define SCP_INITRESULT_NODLL 4
|
||||
#define SCP_INITRESULT_BADSIGNATURE 5
|
||||
#define SCP_INITRESULT_UNABLETOREGISTER 6
|
||||
#define SCP_INITRESULT_BADDATAFIELDS 7
|
||||
#define SCP_INITRESULT_BADREGISTRATION 8
|
||||
#define SCP_INITRESULT_BADTRANSMISSION 9
|
||||
|
||||
/* Exported functions */
|
||||
/* HWND comes from externalcode.h */
|
||||
/* These are function pointer prototypes provided for library loading */
|
||||
|
||||
/* Only one function doesn't return an int or a float */
|
||||
typedef int ( SCP_EXT_CALLCONV *SCPTRACKIR_PFINIT )( HWND );
|
||||
|
||||
/* All other trackir functions return an int or a float
|
||||
* and take no parameters
|
||||
*/
|
||||
typedef int ( SCP_EXT_CALLCONV *SCPTRACKIR_PFINTVOID )( );
|
||||
typedef float ( SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID )( );
|
||||
|
||||
class TrackIRDLL : public SCP_ExternalCode
|
||||
{
|
||||
public:
|
||||
TrackIRDLL( )
|
||||
{
|
||||
/* Load the DLL and functions
|
||||
* If this is done globally, we'll be found by MSPDBDEBUGGING :)
|
||||
*/
|
||||
|
||||
Reset( );
|
||||
|
||||
if ( !LoadExternal( TRACKIRBRIDGEDLLNAME ) )
|
||||
return;
|
||||
|
||||
m_Init = (SCPTRACKIR_PFINIT)LoadFunction( "SCPTIR_Init" );
|
||||
m_Close = (SCPTRACKIR_PFINTVOID)LoadFunction( "SCPTIR_Close" );
|
||||
m_Query = (SCPTRACKIR_PFINTVOID)LoadFunction( "SCPTIR_Query" );
|
||||
|
||||
m_GetX = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetX" );
|
||||
m_GetY = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetY" );
|
||||
m_GetZ = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetZ" );
|
||||
m_GetRoll = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetRoll" );
|
||||
m_GetPitch = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetPitch" );
|
||||
m_GetYaw = (SCPTRACKIR_PFFLOATVOID)LoadFunction( "SCPTIR_GetYaw" );
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
bool Enabled( )
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
virtual ~TrackIRDLL( )
|
||||
{
|
||||
/* Prevent further use of the DLL */
|
||||
Reset( );
|
||||
}
|
||||
|
||||
void Reset( )
|
||||
{
|
||||
m_Init = NULL;
|
||||
m_Close = NULL;
|
||||
m_Query = NULL;
|
||||
m_GetX = NULL;
|
||||
m_GetY = NULL;
|
||||
m_GetZ = NULL;
|
||||
m_GetPitch = NULL;
|
||||
m_GetRoll = NULL;
|
||||
m_GetYaw = NULL;
|
||||
m_enabled = false;
|
||||
}
|
||||
|
||||
/* Returns 0 on success */
|
||||
int Init( SDL_Window* window )
|
||||
{
|
||||
// This is only supported on windows
|
||||
#ifdef WIN32
|
||||
if (m_Init)
|
||||
{
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version); // initialize info structure with SDL version info
|
||||
|
||||
if (SDL_GetWindowWMInfo(os_get_window(), &info)) { // the call returns true on success
|
||||
// success
|
||||
return m_Init(info.info.win.window);
|
||||
}
|
||||
else {
|
||||
// call failed
|
||||
mprintf(("TrackIR: Couldn't get window information: %s\n", SDL_GetError()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Close( )
|
||||
{
|
||||
if ( m_Close )
|
||||
return m_Close( );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Query( )
|
||||
{
|
||||
if ( m_Query )
|
||||
return m_Query( );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
float GetX( )
|
||||
{
|
||||
if ( m_GetX )
|
||||
return m_GetX( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetY( )
|
||||
{
|
||||
if ( m_GetY )
|
||||
return m_GetY( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetZ( )
|
||||
{
|
||||
if ( m_GetZ )
|
||||
return m_GetZ( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetPitch( )
|
||||
{
|
||||
if ( m_GetPitch )
|
||||
return m_GetPitch( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetRoll( )
|
||||
{
|
||||
if ( m_GetRoll )
|
||||
return m_GetRoll( );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float GetYaw( )
|
||||
{
|
||||
if ( m_GetYaw )
|
||||
return m_GetYaw( );
|
||||
return 0.0f;
|
||||
}
|
||||
private:
|
||||
/* Functions */
|
||||
SCPTRACKIR_PFINIT m_Init;
|
||||
SCPTRACKIR_PFINTVOID m_Close;
|
||||
SCPTRACKIR_PFINTVOID m_Query;
|
||||
|
||||
SCPTRACKIR_PFFLOATVOID m_GetX;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetY;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetZ;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetPitch;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetRoll;
|
||||
SCPTRACKIR_PFFLOATVOID m_GetYaw;
|
||||
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
/* Added to trackirpublic.h */
|
||||
#ifndef SCPDLL_EXTERNAL_LIB
|
||||
extern TrackIRDLL gTirDll_TrackIR;
|
||||
#endif
|
||||
|
||||
#endif /* TRACKIRPUBLIC_H_INCLUDED_ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _FIREBALLS_H
|
||||
#define _FIREBALLS_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "model/modelrender.h"
|
||||
|
||||
class object;
|
||||
class ship_info;
|
||||
class asteroid_info;
|
||||
|
||||
// values correspond to the fireball render types
|
||||
#define FIREBALL_MEDIUM_EXPLOSION 0
|
||||
#define FIREBALL_LARGE_EXPLOSION 1
|
||||
#define FIREBALL_WARP_EFFECT 2
|
||||
|
||||
// these values correspond to the fireball.tbl default entries
|
||||
#define FIREBALL_EXPLOSION_MEDIUM 0 // Used for the 4 little explosions before a ship explodes
|
||||
#define FIREBALL_WARP 1 // Used for the warp in / warp out effect
|
||||
#define FIREBALL_KNOSSOS 2 // Used for the KNOSSOS warp in / warp out effect
|
||||
#define FIREBALL_ASTEROID 3
|
||||
#define FIREBALL_EXPLOSION_LARGE1 4 // Used for the big explosion when a ship breaks into pieces
|
||||
#define FIREBALL_EXPLOSION_LARGE2 5 // Used for the big explosion when a ship breaks into pieces
|
||||
|
||||
#define MAX_FIREBALL_TYPES 32 // The maximum number of fireballs that can be defined
|
||||
#define NUM_DEFAULT_FIREBALLS 6
|
||||
|
||||
#define FIREBALL_NUM_LARGE_EXPLOSIONS 2
|
||||
|
||||
extern int fireball_used[MAX_FIREBALL_TYPES];
|
||||
extern int Num_fireball_types;
|
||||
|
||||
// all this moved here by Goober5000 because it makes more sense in the H file
|
||||
typedef struct fireball_lod {
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
int bitmap_id;
|
||||
int num_frames;
|
||||
int fps;
|
||||
} fireball_lod;
|
||||
|
||||
typedef struct fireball_info {
|
||||
int lod_count;
|
||||
float exp_color[3];
|
||||
fireball_lod lod[4];
|
||||
} fireball_info;
|
||||
|
||||
// flag values for fireball struct flags member
|
||||
#define FBF_WARP_CLOSE_SOUND_PLAYED (1<<0)
|
||||
#define FBF_WARP_CAPITAL_SIZE (1<<1)
|
||||
#define FBF_WARP_CRUISER_SIZE (1<<2)
|
||||
#define FBF_WARP_3D (1<<3) // Goober5000
|
||||
#define FBF_WARP_VIA_SEXP (1<<4) // Goober5000
|
||||
|
||||
typedef struct fireball {
|
||||
int objnum; // If -1 this object is unused
|
||||
int fireball_info_index; // Index into Fireball_info array
|
||||
int fireball_render_type;
|
||||
int current_bitmap;
|
||||
int orient; // For fireballs, which orientation. For warps, 0 is warpin, 1 is warpout
|
||||
int flags; // see #define FBF_*
|
||||
char lod; // current LOD
|
||||
float time_elapsed; // in seconds
|
||||
float total_time; // total lifetime of animation in seconds
|
||||
int warp_open_sound_index; // for warp-effect - Goober5000
|
||||
int warp_close_sound_index; // for warp-effect - Goober5000
|
||||
} fireball;
|
||||
// end move
|
||||
|
||||
void fireball_init();
|
||||
void fireball_render(object* obj, draw_list *scene);
|
||||
void fireball_delete( object * obj );
|
||||
void fireball_process_post(object * obj, float frame_time);
|
||||
|
||||
// reversed is for warp_in/out effects
|
||||
// Velocity: If not NULL, the fireball will move at a constant velocity.
|
||||
// warp_lifetime: If warp_lifetime > 0.0f then makes the explosion loop so it lasts this long. Only works for warp effect
|
||||
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reversed=0, vec3d *velocity=NULL, float warp_lifetime=0.0f, int ship_class=-1, matrix *orient=NULL, int low_res=0, int extra_flags=0, int warp_open_sound=-1, int warp_close_sound=-1);
|
||||
void fireball_render_plane(int plane);
|
||||
void fireball_close();
|
||||
|
||||
// Returns 1 if you can remove this fireball
|
||||
int fireball_is_perishable(object * obj);
|
||||
|
||||
// Returns 1 if this fireball is a warp
|
||||
int fireball_is_warp(object * obj);
|
||||
|
||||
// Returns life left of a fireball in seconds
|
||||
float fireball_lifeleft( object *obj );
|
||||
|
||||
// Returns life left of a fireball in percent
|
||||
float fireball_lifeleft_percent( object *obj );
|
||||
|
||||
// returns the lighting color (in [0...1] range) to use for explosion
|
||||
void fireball_get_color(int idx, float *red, float *green, float *blue);
|
||||
|
||||
// returns the index of the fireball bitmap for this ship. -1 if there is none.
|
||||
int fireball_ship_explosion_type(ship_info *sip);
|
||||
|
||||
// returns the index of the fireball bitmap for this asteroid. -1 if there is none.
|
||||
int fireball_asteroid_explosion_type(asteroid_info *aip);
|
||||
|
||||
// returns the intensity of a wormhole
|
||||
float fireball_wormhole_intensity( object *obj );
|
||||
|
||||
// internal function to draw warp grid.
|
||||
extern void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d = 0 );
|
||||
|
||||
extern void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d);
|
||||
|
||||
extern int Warp_model;
|
||||
|
||||
// Goober5000
|
||||
extern int Knossos_warp_ani_used;
|
||||
|
||||
#endif /* _FIREBALLS_H */
|
||||
@@ -1,339 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/tmapper.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "model/model.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "render/3d.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
extern int Warp_model;
|
||||
extern int Warp_glow_bitmap;
|
||||
extern int Warp_ball_bitmap;
|
||||
|
||||
|
||||
void draw_face( vertex *v1, vertex *v2, vertex *v3 )
|
||||
{
|
||||
vec3d norm;
|
||||
vertex *vertlist[3];
|
||||
|
||||
vm_vec_perp(&norm,&v1->world, &v2->world, &v3->world);
|
||||
if ( vm_vec_dot(&norm, &v1->world ) >= 0.0 ) {
|
||||
vertlist[0] = v3;
|
||||
vertlist[1] = v2;
|
||||
vertlist[2] = v1;
|
||||
} else {
|
||||
vertlist[0] = v1;
|
||||
vertlist[1] = v2;
|
||||
vertlist[2] = v3;
|
||||
}
|
||||
|
||||
g3_draw_poly( 3, vertlist, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
||||
|
||||
}
|
||||
|
||||
void warpin_batch_draw_face( int texture, vertex *v1, vertex *v2, vertex *v3 )
|
||||
{
|
||||
vec3d norm;
|
||||
vertex vertlist[3];
|
||||
|
||||
vm_vec_perp(&norm,&v1->world, &v2->world, &v3->world);
|
||||
if ( vm_vec_dot(&norm, &v1->world ) >= 0.0 ) {
|
||||
vertlist[0] = *v3;
|
||||
vertlist[1] = *v2;
|
||||
vertlist[2] = *v1;
|
||||
} else {
|
||||
vertlist[0] = *v1;
|
||||
vertlist[1] = *v2;
|
||||
vertlist[2] = *v3;
|
||||
}
|
||||
|
||||
batch_add_tri(texture, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE, vertlist, 1.0f);
|
||||
}
|
||||
|
||||
void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
|
||||
{
|
||||
vec3d center;
|
||||
vec3d vecs[5];
|
||||
vertex verts[5];
|
||||
int saved_gr_zbuffering = gr_zbuffer_get();
|
||||
|
||||
gr_zbuffer_set(GR_ZBUFF_READ);
|
||||
|
||||
vm_vec_scale_add( ¢er, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
|
||||
|
||||
memset(verts, 0, sizeof(verts));
|
||||
|
||||
if (Warp_glow_bitmap >= 0) {
|
||||
float r = radius;
|
||||
bool render_it = true;
|
||||
|
||||
#define OUT_PERCENT1 0.80f
|
||||
#define OUT_PERCENT2 0.90f
|
||||
|
||||
#define IN_PERCENT1 0.10f
|
||||
#define IN_PERCENT2 0.20f
|
||||
|
||||
if (Cmdline_warp_flash)
|
||||
{
|
||||
if ( (life_percent >= IN_PERCENT1) && (life_percent < IN_PERCENT2) ) {
|
||||
r *= (life_percent - IN_PERCENT1) / (IN_PERCENT2 - IN_PERCENT1);
|
||||
//render_it = true;
|
||||
} else if ( (life_percent >= OUT_PERCENT1) && (life_percent < OUT_PERCENT2) ) {
|
||||
r *= (OUT_PERCENT2 - life_percent) / (OUT_PERCENT2 - OUT_PERCENT1);
|
||||
//render_it = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (render_it) {
|
||||
// Add in noise
|
||||
int noise_frame = fl2i(Missiontime/15.0f) % NOISE_NUM_FRAMES;
|
||||
|
||||
r *= (0.40f + Noise[noise_frame] * 0.30f);
|
||||
|
||||
// Bobboau's warp thingie, toggled by cmdline
|
||||
if (Cmdline_warp_flash) {
|
||||
r += powf((2.0f * life_percent) - 1.0f, 24.0f) * max_radius * 1.5f;
|
||||
}
|
||||
|
||||
vecs[4] = center;
|
||||
verts[4].texture_position.u = 0.5f; verts[4].texture_position.v = 0.5f;
|
||||
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
|
||||
float alpha = (The_mission.flags & MISSION_FLAG_FULLNEB) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
|
||||
gr_set_bitmap( Warp_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha );
|
||||
|
||||
g3_draw_bitmap( &verts[4], 0, r, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
||||
}
|
||||
}
|
||||
|
||||
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
model_render_params render_info;
|
||||
|
||||
vec3d scale;
|
||||
scale.xyz.z = scale.xyz.y = scale.xyz.x = radius / 25.0f;
|
||||
render_info.set_warp_params(texture_bitmap_num, radius/max_radius, scale);
|
||||
|
||||
float dist = vm_vec_dist_quick( pos, &Eye_position );
|
||||
render_info.set_detail_level_lock((int)(dist / (radius * 10.0f)));
|
||||
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL | MR_NO_BATCH);
|
||||
|
||||
model_render_immediate( &render_info, Warp_model, orient, pos );
|
||||
} else {
|
||||
float Grid_depth = radius/2.5f;
|
||||
|
||||
gr_set_bitmap( texture_bitmap_num, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
|
||||
|
||||
vm_vec_scale_add( &vecs[0], ¢er, &orient->vec.uvec, radius );
|
||||
vm_vec_scale_add2( &vecs[0], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[0], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[1], ¢er, &orient->vec.uvec, radius );
|
||||
vm_vec_scale_add2( &vecs[1], &orient->vec.rvec, radius );
|
||||
vm_vec_scale_add2( &vecs[1], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[2], ¢er, &orient->vec.uvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[2], &orient->vec.rvec, radius );
|
||||
vm_vec_scale_add2( &vecs[2], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[3], ¢er, &orient->vec.uvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
|
||||
vecs[4] = center;
|
||||
|
||||
verts[0].texture_position.u = 0.01f;
|
||||
verts[0].texture_position.v = 0.01f;
|
||||
|
||||
verts[1].texture_position.u = 0.99f;
|
||||
verts[1].texture_position.v = 0.01f;
|
||||
|
||||
verts[2].texture_position.u = 0.99f;
|
||||
verts[2].texture_position.v = 0.99f;
|
||||
|
||||
verts[3].texture_position.u = 0.01f;
|
||||
verts[3].texture_position.v = 0.99f;
|
||||
|
||||
verts[4].texture_position.u = 0.5f;
|
||||
verts[4].texture_position.v = 0.5f;
|
||||
|
||||
g3_transfer_vertex( &verts[0], &vecs[0] );
|
||||
g3_transfer_vertex( &verts[1], &vecs[1] );
|
||||
g3_transfer_vertex( &verts[2], &vecs[2] );
|
||||
g3_transfer_vertex( &verts[3], &vecs[3] );
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
|
||||
int cull = gr_set_cull(0); // fixes rendering problem in D3D - taylor
|
||||
draw_face( &verts[0], &verts[4], &verts[1] );
|
||||
draw_face( &verts[1], &verts[4], &verts[2] );
|
||||
draw_face( &verts[4], &verts[3], &verts[2] );
|
||||
draw_face( &verts[0], &verts[3], &verts[4] );
|
||||
gr_set_cull(cull);
|
||||
}
|
||||
|
||||
if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
|
||||
flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
|
||||
float adg = (2.0f * life_percent) - 1.0f;
|
||||
float pct = (powf(adg, 4.0f) - powf(adg, 128.0f)) * 4.0f;
|
||||
|
||||
if (pct > 0.00001f) {
|
||||
g3_start_instance_matrix(pos, orient, true);
|
||||
|
||||
gr_set_bitmap(Warp_ball_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
|
||||
|
||||
warp_ball.render(max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
|
||||
|
||||
g3_done_instance(true);
|
||||
}
|
||||
}
|
||||
|
||||
gr_zbuffer_set( saved_gr_zbuffering );
|
||||
}
|
||||
|
||||
void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
|
||||
{
|
||||
vec3d center;
|
||||
vec3d vecs[5];
|
||||
vertex verts[5];
|
||||
|
||||
vm_vec_scale_add( ¢er, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
|
||||
|
||||
|
||||
if (Warp_glow_bitmap >= 0) {
|
||||
float r = radius;
|
||||
bool render_it = true;
|
||||
|
||||
#define OUT_PERCENT1 0.80f
|
||||
#define OUT_PERCENT2 0.90f
|
||||
|
||||
#define IN_PERCENT1 0.10f
|
||||
#define IN_PERCENT2 0.20f
|
||||
|
||||
if (Cmdline_warp_flash)
|
||||
{
|
||||
if ( (life_percent >= IN_PERCENT1) && (life_percent < IN_PERCENT2) ) {
|
||||
r *= (life_percent - IN_PERCENT1) / (IN_PERCENT2 - IN_PERCENT1);
|
||||
//render_it = true;
|
||||
} else if ( (life_percent >= OUT_PERCENT1) && (life_percent < OUT_PERCENT2) ) {
|
||||
r *= (OUT_PERCENT2 - life_percent) / (OUT_PERCENT2 - OUT_PERCENT1);
|
||||
//render_it = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (render_it) {
|
||||
// Add in noise
|
||||
int noise_frame = fl2i(Missiontime/15.0f) % NOISE_NUM_FRAMES;
|
||||
|
||||
r *= (0.40f + Noise[noise_frame] * 0.30f);
|
||||
|
||||
// Bobboau's warp thingie, toggled by cmdline
|
||||
if (Cmdline_warp_flash) {
|
||||
r += powf((2.0f * life_percent) - 1.0f, 24.0f) * max_radius * 1.5f;
|
||||
}
|
||||
|
||||
vecs[4] = center;
|
||||
verts[4].texture_position.u = 0.5f; verts[4].texture_position.v = 0.5f;
|
||||
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
|
||||
float alpha = (The_mission.flags & MISSION_FLAG_FULLNEB) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
|
||||
|
||||
batch_add_bitmap(Warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE , &verts[4], 0, r, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
model_render_params render_info;
|
||||
|
||||
float scale = radius / 25.0f;
|
||||
|
||||
vec3d warp_scale;
|
||||
|
||||
warp_scale.xyz.x = warp_scale.xyz.y = warp_scale.xyz.z = scale;
|
||||
|
||||
float dist = vm_vec_dist_quick( pos, &Eye_position );
|
||||
|
||||
render_info.set_warp_params(texture_bitmap_num, radius/max_radius, warp_scale);
|
||||
render_info.set_detail_level_lock((int)(dist / (radius * 10.0f)));
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL | MR_NO_BATCH);
|
||||
|
||||
model_render_queue( &render_info, scene, Warp_model, orient, pos);
|
||||
} else {
|
||||
float Grid_depth = radius/2.5f;
|
||||
|
||||
// gr_set_bitmap( texture_bitmap_num, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
|
||||
|
||||
vm_vec_scale_add( &vecs[0], ¢er, &orient->vec.uvec, radius );
|
||||
vm_vec_scale_add2( &vecs[0], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[0], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[1], ¢er, &orient->vec.uvec, radius );
|
||||
vm_vec_scale_add2( &vecs[1], &orient->vec.rvec, radius );
|
||||
vm_vec_scale_add2( &vecs[1], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[2], ¢er, &orient->vec.uvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[2], &orient->vec.rvec, radius );
|
||||
vm_vec_scale_add2( &vecs[2], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[3], ¢er, &orient->vec.uvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
|
||||
vecs[4] = center;
|
||||
|
||||
verts[0].texture_position.u = 0.01f;
|
||||
verts[0].texture_position.v = 0.01f;
|
||||
|
||||
verts[1].texture_position.u = 0.99f;
|
||||
verts[1].texture_position.v = 0.01f;
|
||||
|
||||
verts[2].texture_position.u = 0.99f;
|
||||
verts[2].texture_position.v = 0.99f;
|
||||
|
||||
verts[3].texture_position.u = 0.01f;
|
||||
verts[3].texture_position.v = 0.99f;
|
||||
|
||||
verts[4].texture_position.u = 0.5f;
|
||||
verts[4].texture_position.v = 0.5f;
|
||||
|
||||
g3_transfer_vertex( &verts[0], &vecs[0] );
|
||||
g3_transfer_vertex( &verts[1], &vecs[1] );
|
||||
g3_transfer_vertex( &verts[2], &vecs[2] );
|
||||
g3_transfer_vertex( &verts[3], &vecs[3] );
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[0], &verts[4], &verts[1] );
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[1], &verts[4], &verts[2] );
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[4], &verts[3], &verts[2] );
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[0], &verts[3], &verts[4] );
|
||||
}
|
||||
|
||||
if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
|
||||
//flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
|
||||
flash_ball warp_ball(20, .1f,.25f, &orient->vec.fvec, pos, 4.0f, 0.5f);
|
||||
|
||||
float adg = (2.0f * life_percent) - 1.0f;
|
||||
float pct = (powf(adg, 4.0f) - powf(adg, 128.0f)) * 4.0f;
|
||||
|
||||
if (pct > 0.00001f) {
|
||||
warp_ball.render(Warp_ball_bitmap, max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,406 +0,0 @@
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
// AltShipClassDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "AltShipClassDlg.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
|
||||
AltShipClassDlg::AltShipClassDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(AltShipClassDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AltShipClassDlg)
|
||||
m_selected_variable = -1;
|
||||
m_selected_class = -1;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
multi_edit = false;
|
||||
player_ships_only = true;
|
||||
num_string_variables = 0;
|
||||
|
||||
memset(string_variable_indices, -1, sizeof (int)*MAX_SEXP_VARIABLES);
|
||||
memset(ship_class_indices, -1, sizeof (int)*MAX_SHIP_CLASSES);
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AltShipClassDlg)
|
||||
DDX_Control(pDX, IDC_DEFAULT_TO_CLASS, m_default_to_class);
|
||||
DDX_Control(pDX, IDC_ALT_CLASS_LIST, m_alt_class_list);
|
||||
DDX_Control(pDX, IDC_SET_FROM_SHIP_CLASS, m_set_from_ship_class);
|
||||
DDX_Control(pDX, IDC_SET_FROM_VARIABLES, m_set_from_variables);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_VARIABLES, m_selected_variable);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_SHIP_CLASS, m_selected_class);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AltShipClassDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(AltShipClassDlg)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_ADD, OnAltClassAdd)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_INSERT, OnAltClassInsert)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DELETE, OnAltClassDelete)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_UP, OnMoveUp)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DOWN, OnMoveDown)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_SHIP_CLASS, OnSelendokSetFromShipClass)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_VARIABLES, OnSelendokSetFromVariables)
|
||||
ON_LBN_SELCHANGE(IDC_ALT_CLASS_LIST, OnSelchangeAltClassList)
|
||||
ON_BN_CLICKED(IDC_DEFAULT_TO_CLASS, OnDefaultToClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg message handlers
|
||||
|
||||
|
||||
BOOL AltShipClassDlg::OnInitDialog()
|
||||
{
|
||||
int i, count;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// have we got multiple selected ships?
|
||||
num_selected_ships = 0;
|
||||
object *objp;
|
||||
|
||||
objp = GET_FIRST(&obj_used_list);
|
||||
while (objp != END_OF_LIST(&obj_used_list)) {
|
||||
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
|
||||
if (objp->flags & OF_MARKED) {
|
||||
m_selected_ships[num_selected_ships++] = objp->instance;
|
||||
}
|
||||
}
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
Assert (num_selected_ships > 0);
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
|
||||
if (num_selected_ships > 1)
|
||||
{
|
||||
multi_edit = true;
|
||||
}
|
||||
|
||||
// Fill the variable combo box
|
||||
m_set_from_variables.ResetContent();
|
||||
m_set_from_variables.AddString("Set From Ship Class");
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[i].variable_name, Sexp_variables[i].text);
|
||||
m_set_from_variables.AddString(buff);
|
||||
string_variable_indices[num_string_variables++] = i;
|
||||
}
|
||||
}
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
if (!num_string_variables) {
|
||||
m_set_from_variables.EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
// Fill the ship classes combo box
|
||||
m_set_from_ship_class.ResetContent();
|
||||
// Add the default entry if we need one followed by all the ship classes
|
||||
if (num_string_variables) {
|
||||
m_set_from_ship_class.AddString("Set From Variable");
|
||||
}
|
||||
count = 0;
|
||||
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
|
||||
{
|
||||
if (player_ships_only && !(it->flags & SIF_PLAYER_SHIP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ship_class_indices[count++] = std::distance(Ship_info.cbegin(), it);
|
||||
m_set_from_ship_class.AddString(it->name);
|
||||
}
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables?1:0); // Set to the first ship class
|
||||
|
||||
// Set up the actual list of alt classes
|
||||
alt_class_pool.clear();
|
||||
alt_class_pool = Ships[Objects[cur_object_index].instance].s_alt_classes;
|
||||
alt_class_list_rebuild();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild()
|
||||
{
|
||||
int i, j;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
j = m_alt_class_list.GetCount();
|
||||
for ( i=0; i < j ; i++) {
|
||||
m_alt_class_list.DeleteString(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)alt_class_pool.size() ; i++) {
|
||||
// Default classes should be at the end of the list
|
||||
if(alt_class_pool[i].default_to_this_class && (i < (int)alt_class_pool.size() - 1) ) {
|
||||
// Int3();
|
||||
// TO DO : we should fix this.
|
||||
}
|
||||
|
||||
if (alt_class_pool[i].variable_index != -1) {
|
||||
Assert (alt_class_pool[i].variable_index > -1 && alt_class_pool[i].variable_index < MAX_SEXP_VARIABLES);
|
||||
Assert (Sexp_variables[alt_class_pool[i].variable_index].type & SEXP_VARIABLE_STRING);
|
||||
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[alt_class_pool[i].variable_index].variable_name, Sexp_variables[alt_class_pool[i].variable_index].text);
|
||||
|
||||
// add it to the list
|
||||
m_alt_class_list.AddString(buff);
|
||||
}
|
||||
else {
|
||||
if (alt_class_pool[i].ship_class >= 0 && alt_class_pool[i].ship_class < MAX_SHIP_CLASSES) {
|
||||
m_alt_class_list.AddString(Ship_info[alt_class_pool[i].ship_class].name);
|
||||
}
|
||||
else {
|
||||
m_alt_class_list.AddString("Invalid Ship Class");
|
||||
Int3();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
|
||||
for (int i=0; i < num_selected_ships; i++) {
|
||||
Ships[m_selected_ships[i]].s_alt_classes = alt_class_pool;
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassAdd()
|
||||
{
|
||||
alt_class new_list_item;
|
||||
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassInsert()
|
||||
{
|
||||
int index;
|
||||
alt_class new_list_item;
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// If nothing is selected just add it
|
||||
if ( index == -1) {
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
}
|
||||
// Stick it in front of the current selection
|
||||
else {
|
||||
alt_class_pool.insert(alt_class_pool.begin() + index, new_list_item );
|
||||
}
|
||||
|
||||
alt_class_list_rebuild();
|
||||
|
||||
// If we inserted the user will probably want to edit the selection
|
||||
if (index > -1) {
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the currently selected list entry
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item)
|
||||
{
|
||||
int index;
|
||||
|
||||
// Add a string variable to the list
|
||||
if (num_string_variables && m_set_from_variables.GetCurSel() > 0) {
|
||||
index = string_variable_indices[m_set_from_variables.GetCurSel() -1];
|
||||
|
||||
Assert (index >= 0);
|
||||
list_item.variable_index = index;
|
||||
list_item.ship_class = ship_info_lookup(Sexp_variables[index].text);
|
||||
}
|
||||
// Add a ship class to the list
|
||||
else {
|
||||
index = m_set_from_ship_class.GetCurSel();
|
||||
|
||||
// Correct the index if the first entry isn't actually a ship class
|
||||
if (num_string_variables) {
|
||||
Assert (index > 0);
|
||||
index--;
|
||||
}
|
||||
|
||||
list_item.variable_index = -1;
|
||||
list_item.ship_class = ship_class_indices[index];
|
||||
}
|
||||
|
||||
// check the default tickbox
|
||||
list_item.default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassDelete()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert (index < (int) alt_class_pool.size());
|
||||
alt_class_pool.erase(alt_class_pool.begin()+index);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveUp()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected or already at the top
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[index-1]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index-1);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveDown()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
int inext = index + 1;
|
||||
|
||||
// Nothing selected or already at the bottom
|
||||
if (index == -1 || (index >= m_alt_class_list.GetCount() - 1) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[inext]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromShipClass()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_ship_class.GetCurSel() == 0 && num_string_variables) {
|
||||
m_set_from_variables.SetCurSel(1);
|
||||
}
|
||||
else {
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromVariables()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_variables.GetCurSel() == 0) {
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
m_set_from_ship_class.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelchangeAltClassList()
|
||||
{
|
||||
int i;
|
||||
int variable_selection = 0;
|
||||
int ship_selection = 0;
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Selected nothing
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have a variable selected
|
||||
if (alt_class_pool[index].variable_index != -1) {
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (string_variable_indices[i] == alt_class_pool[index].variable_index) {
|
||||
variable_selection = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ship selected
|
||||
else {
|
||||
for (i=0; i < MAX_SHIP_CLASSES; i++) {
|
||||
if (ship_class_indices[i] == alt_class_pool[index].ship_class) {
|
||||
ship_selection = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have string variables in the mission the first entry on the list won't be a ship
|
||||
if (num_string_variables) {
|
||||
ship_selection++;
|
||||
}
|
||||
}
|
||||
|
||||
m_set_from_variables.SetCurSel(variable_selection);
|
||||
m_set_from_ship_class.SetCurSel(ship_selection);
|
||||
m_default_to_class.SetCheck(alt_class_pool[index].default_to_this_class ? 1:0);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnDefaultToClass()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
alt_class_pool[index].default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
#define AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AltShipClassDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
class AltShipClassDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
AltShipClassDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(AltShipClassDlg)
|
||||
enum { IDD = IDD_ALT_SHIP_CLASS };
|
||||
CButton m_default_to_class;
|
||||
CListBox m_alt_class_list;
|
||||
CComboBox m_set_from_ship_class;
|
||||
CComboBox m_set_from_variables;
|
||||
int m_selected_variable;
|
||||
int m_selected_class;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(AltShipClassDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(AltShipClassDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnCancel();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnAltClassAdd();
|
||||
afx_msg void OnAltClassInsert();
|
||||
afx_msg void OnAltClassDelete();
|
||||
afx_msg void OnMoveUp();
|
||||
afx_msg void OnMoveDown();
|
||||
afx_msg void OnSelendokSetFromShipClass();
|
||||
afx_msg void OnSelendokSetFromVariables();
|
||||
afx_msg void OnSelchangeAltClassList();
|
||||
afx_msg void OnDefaultToClass();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
|
||||
bool player_ships_only; // Whether we only add player ships to the alt classes or if we can add any ship
|
||||
|
||||
SCP_vector<alt_class> alt_class_pool;
|
||||
int num_string_variables; // Number of string variables in the mission
|
||||
int string_variable_indices[MAX_SEXP_VARIABLES]; // maps string variables to their index in Sexp_variables
|
||||
int ship_class_indices[MAX_SHIP_CLASSES]; // maps ships in the ships combobox to their index in Ship_info
|
||||
|
||||
|
||||
// variables to handle selection of multiple ships
|
||||
bool multi_edit;
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild();
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item);
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
@@ -1,144 +0,0 @@
|
||||
// FictionViewerDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "FictionViewerDlg.h"
|
||||
#include "missionui/fictionviewer.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
|
||||
FictionViewerDlg::FictionViewerDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(FictionViewerDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(FictionViewerDlg)
|
||||
m_story_file = _T("");
|
||||
m_font_file = _T("");
|
||||
m_voice_file = _T("");
|
||||
m_fiction_music = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void FictionViewerDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(FictionViewerDlg)
|
||||
DDX_Text(pDX, IDC_STORY_FILE, m_story_file);
|
||||
DDX_Text(pDX, IDC_FONT_FILE, m_font_file);
|
||||
DDX_Text(pDX, IDC_VOICE_FILE, m_voice_file);
|
||||
DDX_CBIndex(pDX, IDC_FICTION_MUSIC, m_fiction_music);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(FictionViewerDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(FictionViewerDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg message handlers
|
||||
|
||||
BOOL FictionViewerDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
CComboBox *box;
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_FICTION_MUSIC);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++){
|
||||
box->AddString(Spooled_music[i].name);
|
||||
}
|
||||
|
||||
// make sure we have at least one stage
|
||||
if (Fiction_viewer_stages.empty())
|
||||
{
|
||||
fiction_viewer_stage stage;
|
||||
memset(&stage, 0, sizeof(fiction_viewer_stage));
|
||||
stage.formula = Locked_sexp_true;
|
||||
|
||||
Fiction_viewer_stages.push_back(stage);
|
||||
}
|
||||
else if (Fiction_viewer_stages.size() > 1)
|
||||
{
|
||||
MessageBox("You have multiple fiction viewer stages defined for this mission. At present, FRED will only allow you to edit the first stage.");
|
||||
}
|
||||
|
||||
// init fields based on first fiction viewer stage
|
||||
fiction_viewer_stage *stagep = &Fiction_viewer_stages.at(0);
|
||||
m_story_file = _T(stagep->story_filename);
|
||||
m_font_file = _T(stagep->font_filename);
|
||||
m_voice_file = _T(stagep->voice_filename);
|
||||
|
||||
// music is managed through the mission
|
||||
m_fiction_music = Mission_music[SCORE_FICTION_VIEWER] + 1;
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
// store the fields in the data structure
|
||||
fiction_viewer_stage *stagep = &Fiction_viewer_stages.at(0);
|
||||
strcpy_s(stagep->story_filename, (LPCSTR)m_story_file);
|
||||
strcpy_s(stagep->font_filename, (LPCSTR)m_font_file);
|
||||
strcpy_s(stagep->voice_filename, (LPCSTR)m_voice_file);
|
||||
|
||||
// if we don't have a story file, remove this stage (stage 0)
|
||||
if (strlen(stagep->story_filename) == 0)
|
||||
Fiction_viewer_stages.erase(Fiction_viewer_stages.begin());
|
||||
|
||||
// set music
|
||||
Mission_music[SCORE_FICTION_VIEWER] = m_fiction_music - 1;
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnClose()
|
||||
{
|
||||
int z;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
if (query_modified()) {
|
||||
z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
|
||||
if (z == IDCANCEL){
|
||||
return;
|
||||
}
|
||||
|
||||
if (z == IDYES) {
|
||||
OnOK();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
int FictionViewerDlg::query_modified()
|
||||
{
|
||||
fiction_viewer_stage *stagep = &Fiction_viewer_stages.at(0);
|
||||
|
||||
return strcmp(m_story_file, stagep->story_filename) || strcmp(m_font_file, stagep->font_filename) ||
|
||||
strcmp(m_voice_file, stagep->voice_filename) || m_fiction_music != (Mission_music[SCORE_FICTION_VIEWER] + 1);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
#if !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
#define AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// FictionViewerDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
class FictionViewerDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
FictionViewerDlg(CWnd* pParent = NULL); // standard constructor
|
||||
int query_modified();
|
||||
void OnOK();
|
||||
void OnCancel();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(FictionViewerDlg)
|
||||
enum { IDD = IDD_FICTION_VIEWER };
|
||||
CString m_fiction_background_640;
|
||||
CString m_fiction_background_1024;
|
||||
int m_fiction_ui;
|
||||
CString m_story_file;
|
||||
CString m_font_file;
|
||||
CString m_voice_file;
|
||||
int m_fiction_music;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(FictionViewerDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(FictionViewerDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
@@ -1,287 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
// AddVariableDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "FRED.h"
|
||||
#include "AddVariableDlg.h"
|
||||
#include "parse/sexp.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
#define NO_RESET_FOCUS 0
|
||||
#define RESET_FOCUS 1
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAddVariableDlg dialog
|
||||
|
||||
|
||||
CAddVariableDlg::CAddVariableDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CAddVariableDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAddVariableDlg)
|
||||
m_default_value = _T("");
|
||||
m_variable_name = _T("");
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CAddVariableDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAddVariableDlg)
|
||||
DDX_Text(pDX, IDC_ADD_VARIABLE_DEFAULT_VALUE, m_default_value);
|
||||
DDV_MaxChars(pDX, m_default_value, 31);
|
||||
DDX_Text(pDX, IDC_ADD_VARIABLE_NAME, m_variable_name);
|
||||
DDV_MaxChars(pDX, m_variable_name, 31);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAddVariableDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CAddVariableDlg)
|
||||
ON_BN_CLICKED(IDC_TYPE_NUMBER, OnTypeNumber)
|
||||
ON_BN_CLICKED(IDC_TYPE_STRING, OnTypeString)
|
||||
ON_BN_CLICKED(IDC_TYPE_CAMPAIGN_PERSISTENT, OnTypeCampaignPersistent)
|
||||
ON_BN_CLICKED(IDC_TYPE_PLAYER_PERSISTENT, OnTypePlayerPersistent)
|
||||
ON_BN_CLICKED(IDC_TYPE_NETWORK_VARIABLE, OnTypeNetworkVariable)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAddVariableDlg message handlers
|
||||
|
||||
void CAddVariableDlg::OnOK()
|
||||
{
|
||||
// validation name
|
||||
validate_variable_name(RESET_FOCUS);
|
||||
|
||||
// validate data
|
||||
if ( m_name_validated ) {
|
||||
validate_data(RESET_FOCUS);
|
||||
}
|
||||
|
||||
// both ok, then store results
|
||||
if ( m_name_validated && m_data_validated ) {
|
||||
// int sexp_add_variable(char *text, char*, int type);
|
||||
// char temp_name[32];
|
||||
// char temp_value[32];
|
||||
// strcpy_s(temp_name, m_variable_name);
|
||||
// strcpy_s(temp_value, m_default_value);
|
||||
// SEXP_VARIABLE_NUMBER SEXP_VARIABLE_STRING
|
||||
// int type;
|
||||
//
|
||||
// if (m_type_number) {
|
||||
// type = SEXP_VARIABLE_NUMBER;
|
||||
// } else {
|
||||
// type = SEXP_VARIABLE_STRING;
|
||||
// }
|
||||
//
|
||||
// // Goober5000
|
||||
// if (m_type_player_persistent) {
|
||||
// type |= SEXP_VARIABLE_PLAYER_PERSISTENT;
|
||||
// } else if (m_type_campaign_persistent) {
|
||||
// type |= SEXP_VARIABLE_CAMPAIGN_PERSISTENT;
|
||||
// }
|
||||
//
|
||||
// m_sexp_var_index = sexp_add_variable(temp_value, temp_name, type);
|
||||
// this get done for free CDialog::OnOk() UpdateData(TRUE);
|
||||
m_create = true;
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CAddVariableDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// TODO: Add extra initialization here
|
||||
m_variable_name = "<Variable Name>";
|
||||
m_default_value = "<Default Value>";
|
||||
|
||||
// Set variable type to number
|
||||
m_type_number = true;
|
||||
m_type_campaign_persistent = false;
|
||||
m_type_player_persistent = false;
|
||||
m_type_network_variable = false;
|
||||
set_variable_type();
|
||||
|
||||
m_name_validated = false;
|
||||
m_data_validated = false;
|
||||
m_create = false;
|
||||
|
||||
// Send default name and values into dialog box
|
||||
UpdateData(FALSE);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
bool is_sexp_variable_name(const char* temp_name)
|
||||
{
|
||||
for (int i=0; i<MAX_SEXP_VARIABLES; i++) {
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_SET) {
|
||||
if ( !strcmp(Sexp_variables[i].text, temp_name) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// name not found
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Check variable name (1) changed (2) > 0 length (3) does not already exist
|
||||
void CAddVariableDlg::validate_variable_name(int set_focus)
|
||||
{
|
||||
CString temp_name;
|
||||
|
||||
CEdit *edit = (CEdit *) GetDlgItem(IDC_ADD_VARIABLE_NAME);
|
||||
edit->GetWindowText(temp_name);
|
||||
|
||||
// Check if any change and not already in list
|
||||
if ( stricmp(temp_name, "<Variable Name>") ) {
|
||||
if ( (strlen(temp_name) > 0) && (get_index_sexp_variable_name(LPCTSTR(temp_name)) == -1) ) { //not already in list and length > 0 { //-V805
|
||||
// Goober5000 - replace spaces with hyphens
|
||||
if (strchr(temp_name, ' ') != NULL)
|
||||
{
|
||||
// display msg
|
||||
MessageBox("Variable names cannot contain spaces. Replacing with hyphens.");
|
||||
|
||||
// replace chars
|
||||
//Modified to make the code build. - Thunderbird
|
||||
temp_name.Replace((TCHAR) ' ', (TCHAR) '-');
|
||||
//temp_name.Replace((TCHAR) ' ', (TCHAR) '-'));
|
||||
|
||||
// fix what's displayed
|
||||
edit->SetFocus();
|
||||
edit->SetWindowText(temp_name);
|
||||
edit->SetSel(0, -1);
|
||||
}
|
||||
|
||||
m_name_validated = true;
|
||||
} else {
|
||||
// conflicting variable name
|
||||
if (strlen(temp_name) == 0) { //-V805
|
||||
edit->SetWindowText("<Variable Name>");
|
||||
}
|
||||
m_name_validated = false;
|
||||
if (set_focus == RESET_FOCUS) {
|
||||
MessageBox("Conflicting variable name");
|
||||
edit->SetFocus();
|
||||
edit->SetSel(0, -1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// name unchanged from default
|
||||
m_name_validated = false;
|
||||
if (set_focus == RESET_FOCUS) {
|
||||
MessageBox("Invalid variable name");
|
||||
edit->SetFocus();
|
||||
edit->SetSel(0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CAddVariableDlg::validate_data(int set_focus)
|
||||
{
|
||||
CString temp_data;
|
||||
|
||||
CEdit *edit = (CEdit *) GetDlgItem(IDC_ADD_VARIABLE_DEFAULT_VALUE);
|
||||
edit->GetWindowText(temp_data);
|
||||
|
||||
// check for 0 string length
|
||||
if (strlen(temp_data) == 0) { //-V805
|
||||
m_data_validated = false;
|
||||
} else {
|
||||
if (m_type_number) {
|
||||
// verify valid number
|
||||
int temp_num = atoi(temp_data);
|
||||
char buf[TOKEN_LENGTH];
|
||||
sprintf(buf, "%d", temp_num);
|
||||
|
||||
if ( stricmp(buf, temp_data) ) {
|
||||
m_data_validated = false;
|
||||
} else {
|
||||
m_data_validated = true;
|
||||
}
|
||||
} else {
|
||||
m_data_validated = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Display message and reset focus
|
||||
if ( (!m_data_validated) && (set_focus == RESET_FOCUS) ) {
|
||||
MessageBox("Invalid Default Value.");
|
||||
edit->SetFocus();
|
||||
edit->SetSel(0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Set type to number
|
||||
void CAddVariableDlg::OnTypeNumber()
|
||||
{
|
||||
m_type_number = true;
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
// Set type to string
|
||||
void CAddVariableDlg::OnTypeString()
|
||||
{
|
||||
m_type_number = false;
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
void CAddVariableDlg::OnTypePlayerPersistent()
|
||||
{
|
||||
m_type_player_persistent = ((CButton *) GetDlgItem(IDC_TYPE_PLAYER_PERSISTENT))->GetCheck() ? true : false;
|
||||
|
||||
if (m_type_player_persistent)
|
||||
m_type_campaign_persistent = false;
|
||||
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
void CAddVariableDlg::OnTypeCampaignPersistent()
|
||||
{
|
||||
m_type_campaign_persistent = ((CButton *) GetDlgItem(IDC_TYPE_CAMPAIGN_PERSISTENT))->GetCheck() ? true : false;
|
||||
|
||||
if (m_type_campaign_persistent)
|
||||
m_type_player_persistent = false;
|
||||
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
void CAddVariableDlg::OnTypeNetworkVariable()
|
||||
{
|
||||
m_type_network_variable = ((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->GetCheck() ? true : false;
|
||||
set_variable_type();
|
||||
}
|
||||
|
||||
// Set type check boxes
|
||||
void CAddVariableDlg::set_variable_type()
|
||||
{
|
||||
|
||||
CButton *button_string = (CButton *) GetDlgItem(IDC_TYPE_STRING);
|
||||
CButton *button_number = (CButton *) GetDlgItem(IDC_TYPE_NUMBER);
|
||||
|
||||
button_number->SetCheck( m_type_number);
|
||||
button_string->SetCheck(!m_type_number);
|
||||
|
||||
((CButton *) GetDlgItem(IDC_TYPE_CAMPAIGN_PERSISTENT))->SetCheck(m_type_campaign_persistent);
|
||||
((CButton *) GetDlgItem(IDC_TYPE_PLAYER_PERSISTENT))->SetCheck(m_type_player_persistent);
|
||||
((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->SetCheck(m_type_network_variable);
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(AFX_ADDVARIABLEDLG_H__0F668CB5_AAEE_11D2_A899_0060088FAE88__INCLUDED_)
|
||||
#define AFX_ADDVARIABLEDLG_H__0F668CB5_AAEE_11D2_A899_0060088FAE88__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AddVariableDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAddVariableDlg dialog
|
||||
|
||||
class CAddVariableDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CAddVariableDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAddVariableDlg)
|
||||
enum { IDD = IDD_ADD_VARIABLE };
|
||||
CString m_default_value;
|
||||
CString m_variable_name;
|
||||
bool m_name_validated;
|
||||
bool m_data_validated;
|
||||
bool m_type_number;
|
||||
bool m_type_campaign_persistent;
|
||||
bool m_type_player_persistent;
|
||||
bool m_type_network_variable;
|
||||
bool m_create;
|
||||
int m_sexp_var_index;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAddVariableDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CAddVariableDlg)
|
||||
virtual void OnOK();
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void validate_variable_name(int set_focus);
|
||||
afx_msg void validate_data(int set_focus);
|
||||
afx_msg void OnTypeNumber();
|
||||
afx_msg void OnTypeString();
|
||||
afx_msg void OnTypePlayerPersistent();
|
||||
afx_msg void OnTypeCampaignPersistent();
|
||||
afx_msg void OnTypeNetworkVariable();
|
||||
afx_msg void set_variable_type();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ADDVARIABLEDLG_H__0F668CB5_AAEE_11D2_A899_0060088FAE88__INCLUDED_)
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "FRED.h"
|
||||
#include "AdjustGridDlg.h"
|
||||
#include "mission/missiongrid.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// adjust_grid_dlg dialog
|
||||
|
||||
adjust_grid_dlg::adjust_grid_dlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(adjust_grid_dlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(adjust_grid_dlg)
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_z = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
void adjust_grid_dlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(adjust_grid_dlg)
|
||||
DDX_Control(pDX, IDC_SPIN_Z, m_spinz);
|
||||
DDX_Control(pDX, IDC_SPIN_Y, m_spiny);
|
||||
DDX_Control(pDX, IDC_SPIN_X, m_spinx);
|
||||
DDX_Text(pDX, IDC_EDIT_X, m_x);
|
||||
DDX_Text(pDX, IDC_EDIT_Y, m_y);
|
||||
DDX_Text(pDX, IDC_EDIT_Z, m_z);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(adjust_grid_dlg, CDialog)
|
||||
//{{AFX_MSG_MAP(adjust_grid_dlg)
|
||||
ON_BN_CLICKED(IDC_XY_PLANE, OnXyPlane)
|
||||
ON_BN_CLICKED(IDC_XZ_PLANE, OnXzPlane)
|
||||
ON_BN_CLICKED(IDC_YZ_PLANE, OnYzPlane)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// adjust_grid_dlg message handlers
|
||||
|
||||
BOOL adjust_grid_dlg::OnInitDialog()
|
||||
{
|
||||
m_x = (int) The_grid->center.xyz.x;
|
||||
m_y = (int) The_grid->center.xyz.y;
|
||||
m_z = (int) The_grid->center.xyz.z;
|
||||
CDialog::OnInitDialog();
|
||||
if (The_grid->gmatrix.vec.uvec.xyz.y) {
|
||||
((CButton *) GetDlgItem(IDC_XZ_PLANE))->SetCheck(TRUE);
|
||||
GetDlgItem(IDC_EDIT_X)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_EDIT_Z)->EnableWindow(FALSE);
|
||||
|
||||
} else if (The_grid->gmatrix.vec.uvec.xyz.z) {
|
||||
((CButton *) GetDlgItem(IDC_XY_PLANE))->SetCheck(TRUE);
|
||||
GetDlgItem(IDC_EDIT_X)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_EDIT_Y)->EnableWindow(FALSE);
|
||||
|
||||
} else {
|
||||
((CButton *) GetDlgItem(IDC_YZ_PLANE))->SetCheck(TRUE);
|
||||
GetDlgItem(IDC_EDIT_Y)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_EDIT_Z)->EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
m_spinx.SetRange(SHRT_MIN, SHRT_MAX);
|
||||
m_spiny.SetRange(SHRT_MIN, SHRT_MAX);
|
||||
m_spinz.SetRange(SHRT_MIN, SHRT_MAX);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void adjust_grid_dlg::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
The_grid->center.xyz.x = (float) m_x;
|
||||
The_grid->center.xyz.y = (float) m_y;
|
||||
The_grid->center.xyz.z = (float) m_z;
|
||||
|
||||
if (((CButton *) GetDlgItem(IDC_XY_PLANE)) -> GetCheck()) {
|
||||
The_grid->gmatrix.vec.fvec = vmd_x_vector;
|
||||
The_grid->gmatrix.vec.rvec = vmd_y_vector;
|
||||
|
||||
} else if (((CButton *) GetDlgItem(IDC_YZ_PLANE)) -> GetCheck()) {
|
||||
The_grid->gmatrix.vec.fvec = vmd_y_vector;
|
||||
The_grid->gmatrix.vec.rvec = vmd_z_vector;
|
||||
|
||||
} else { // XZ plane
|
||||
The_grid->gmatrix.vec.fvec = vmd_x_vector;
|
||||
The_grid->gmatrix.vec.rvec = vmd_z_vector;
|
||||
}
|
||||
|
||||
modify_grid(The_grid);
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void adjust_grid_dlg::OnXyPlane()
|
||||
{
|
||||
GetDlgItem(IDC_EDIT_X)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SPIN_X)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_EDIT_Y)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SPIN_Y)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_EDIT_Z)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SPIN_Z)->EnableWindow(TRUE);
|
||||
}
|
||||
|
||||
void adjust_grid_dlg::OnXzPlane()
|
||||
{
|
||||
GetDlgItem(IDC_EDIT_X)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SPIN_X)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_EDIT_Y)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SPIN_Y)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_EDIT_Z)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SPIN_Z)->EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
void adjust_grid_dlg::OnYzPlane()
|
||||
{
|
||||
GetDlgItem(IDC_EDIT_X)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SPIN_X)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_EDIT_Y)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SPIN_Y)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_EDIT_Z)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SPIN_Z)->EnableWindow(FALSE);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// adjust_grid_dlg dialog
|
||||
|
||||
class adjust_grid_dlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
void OnOK();
|
||||
adjust_grid_dlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(adjust_grid_dlg)
|
||||
enum { IDD = IDD_ADJUST_GRID };
|
||||
CSpinButtonCtrl m_spinz;
|
||||
CSpinButtonCtrl m_spiny;
|
||||
CSpinButtonCtrl m_spinx;
|
||||
int m_x;
|
||||
int m_y;
|
||||
int m_z;
|
||||
//}}AFX_DATA
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(adjust_grid_dlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(adjust_grid_dlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnXyPlane();
|
||||
afx_msg void OnXzPlane();
|
||||
afx_msg void OnYzPlane();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
@@ -1,679 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
// AsteroidEditorDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "FRED.h"
|
||||
#include "AsteroidEditorDlg.h"
|
||||
#include "starfield/starfield.h"
|
||||
#include "FREDDoc.h"
|
||||
#include "debris/debris.h" // Asteroid stuff.
|
||||
#include "species_defs/species_defs.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
#define ID_FIELD_MENU 9000
|
||||
|
||||
// helps in looping over combo boxes
|
||||
int Dlg_id[MAX_ACTIVE_DEBRIS_TYPES] = {IDC_SHIP_DEBRIS1, IDC_SHIP_DEBRIS2, IDC_SHIP_DEBRIS3};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// asteroid_editor dialog
|
||||
|
||||
asteroid_editor::asteroid_editor(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(asteroid_editor::IDD, pParent)
|
||||
{
|
||||
int i;
|
||||
|
||||
//{{AFX_DATA_INIT(asteroid_editor)
|
||||
m_avg_speed = 0;
|
||||
m_density = 0;
|
||||
m_enable_asteroids = FALSE;
|
||||
m_max_x = _T("");
|
||||
m_max_y = _T("");
|
||||
m_max_z = _T("");
|
||||
m_min_x = _T("");
|
||||
m_min_y = _T("");
|
||||
m_min_z = _T("");
|
||||
m_enable_inner_bounds = FALSE;
|
||||
m_field_type = FT_ACTIVE;
|
||||
m_box_max_x = _T("");
|
||||
m_box_max_y = _T("");
|
||||
m_box_max_z = _T("");
|
||||
m_box_min_x = _T("");
|
||||
m_box_min_y = _T("");
|
||||
m_box_min_z = _T("");
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
last_field = -1;
|
||||
i=0;
|
||||
// for (i=0; i<MAX_ASTEROID_FIELDS; i++)
|
||||
a_field[i] = Asteroid_field; // Only supporting one field per mission.
|
||||
}
|
||||
|
||||
void asteroid_editor::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(asteroid_editor)
|
||||
DDX_Control(pDX, IDC_DENSITY_SPIN, m_density_spin);
|
||||
DDX_Text(pDX, IDC_AVG_SPEED, m_avg_speed);
|
||||
DDX_Text(pDX, IDC_DENSITY, m_density);
|
||||
DDX_Check(pDX, IDC_ENABLE_ASTEROIDS, m_enable_asteroids);
|
||||
DDX_Text(pDX, IDC_MAX_X, m_max_x);
|
||||
DDX_Text(pDX, IDC_MAX_Y, m_max_y);
|
||||
DDX_Text(pDX, IDC_MAX_Z, m_max_z);
|
||||
DDX_Text(pDX, IDC_MIN_X, m_min_x);
|
||||
DDX_Text(pDX, IDC_MIN_Y, m_min_y);
|
||||
DDX_Text(pDX, IDC_MIN_Z, m_min_z);
|
||||
DDX_Check(pDX, IDC_ENABLE_INNER_BOX, m_enable_inner_bounds);
|
||||
DDX_Text(pDX, IDC_INNER_MAX_X, m_box_max_x);
|
||||
DDX_Text(pDX, IDC_INNER_MAX_Y, m_box_max_y);
|
||||
DDX_Text(pDX, IDC_INNER_MAX_Z, m_box_max_z);
|
||||
DDX_Text(pDX, IDC_INNER_MIN_X, m_box_min_x);
|
||||
DDX_Text(pDX, IDC_INNER_MIN_Y, m_box_min_y);
|
||||
DDX_Text(pDX, IDC_INNER_MIN_Z, m_box_min_z);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(asteroid_editor, CDialog)
|
||||
//{{AFX_MSG_MAP(asteroid_editor)
|
||||
ON_WM_INITMENU()
|
||||
ON_BN_CLICKED(IDC_ENABLE_ASTEROIDS, OnEnableAsteroids)
|
||||
ON_WM_CLOSE()
|
||||
ON_BN_CLICKED(IDC_ENABLE_INNER_BOX, OnEnableInnerBox)
|
||||
ON_BN_CLICKED(IDC_PASSIVE_FIELD, OnPassiveField)
|
||||
ON_BN_CLICKED(IDC_FIELD_SHIP, OnFieldShip)
|
||||
ON_BN_CLICKED(IDC_ACTIVE_FIELD, OnActiveField)
|
||||
ON_BN_CLICKED(IDC_FIELD_ASTEROID, OnFieldAsteroid)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// asteroid_editor message handlers
|
||||
|
||||
void asteroid_editor::OnInitMenu(CMenu* pMenu)
|
||||
{
|
||||
int i;
|
||||
CString str;
|
||||
CMenu *m;
|
||||
|
||||
m = pMenu->GetSubMenu(0);
|
||||
clear_menu(m);
|
||||
i = 0; //for (i=0; i<MAX_ASTEROID_FIELDS; i++) {
|
||||
str.Format("Asteroid Field %d", i);
|
||||
m->AppendMenu(MF_ENABLED | MF_STRING, ID_FIELD_MENU + i, str);
|
||||
//}
|
||||
|
||||
m->DeleteMenu(ID_PLACEHOLDER, MF_BYCOMMAND);
|
||||
if (cur_field != -1)
|
||||
m->CheckMenuItem(ID_FIELD_MENU + cur_field, MF_BYCOMMAND | MF_CHECKED);
|
||||
|
||||
CDialog::OnInitMenu(pMenu);
|
||||
}
|
||||
|
||||
BOOL asteroid_editor::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int id;
|
||||
|
||||
id = LOWORD(wParam);
|
||||
if (id >= ID_FIELD_MENU && id < ID_FIELD_MENU + 1) { //MAX_ASTEROID_FIELDS) {
|
||||
cur_field = id - ID_FIELD_MENU;
|
||||
update_init();
|
||||
}
|
||||
|
||||
return CDialog::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
int asteroid_editor::query_modified()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<1 /*MAX_ASTEROID_FIELDS*/; i++) {
|
||||
if (a_field[i].num_initial_asteroids != Asteroid_field.num_initial_asteroids)
|
||||
return 1;
|
||||
if (vm_vec_dist_quick(&a_field[i].vel, &Asteroid_field.vel) == 0.0f)
|
||||
return 1;
|
||||
if (a_field[i].min_bound.xyz.x != Asteroid_field.min_bound.xyz.x)
|
||||
return 1;
|
||||
if (a_field[i].min_bound.xyz.y != Asteroid_field.min_bound.xyz.y)
|
||||
return 1;
|
||||
if (a_field[i].min_bound.xyz.z != Asteroid_field.min_bound.xyz.z)
|
||||
return 1;
|
||||
if (a_field[i].max_bound.xyz.x != Asteroid_field.max_bound.xyz.x)
|
||||
return 1;
|
||||
if (a_field[i].max_bound.xyz.y != Asteroid_field.max_bound.xyz.y)
|
||||
return 1;
|
||||
if (a_field[i].max_bound.xyz.z != Asteroid_field.max_bound.xyz.z)
|
||||
return 1;
|
||||
|
||||
|
||||
if (a_field[i].has_inner_bound != Asteroid_field.has_inner_bound)
|
||||
return 1;
|
||||
|
||||
if (a_field[i].field_type != Asteroid_field.field_type)
|
||||
return 1;
|
||||
|
||||
if (a_field[i].has_inner_bound) {
|
||||
if (a_field[i].inner_max_bound.xyz.x != Asteroid_field.inner_max_bound.xyz.x)
|
||||
return 1;
|
||||
|
||||
if (a_field[i].inner_max_bound.xyz.y != Asteroid_field.inner_max_bound.xyz.y)
|
||||
return 1;
|
||||
|
||||
if (a_field[i].inner_max_bound.xyz.z != Asteroid_field.inner_max_bound.xyz.z)
|
||||
return 1;
|
||||
|
||||
if (a_field[i].inner_min_bound.xyz.x != Asteroid_field.inner_min_bound.xyz.x)
|
||||
return 1;
|
||||
|
||||
if (a_field[i].inner_min_bound.xyz.y != Asteroid_field.inner_min_bound.xyz.y)
|
||||
return 1;
|
||||
|
||||
if (a_field[i].inner_min_bound.xyz.z != Asteroid_field.inner_min_bound.xyz.z)
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MIN_BOX_THICKNESS 400
|
||||
int asteroid_editor::validate_data()
|
||||
{
|
||||
if (!m_enable_asteroids) {
|
||||
return 1;
|
||||
} else {
|
||||
// check x
|
||||
if (a_field[0].max_bound.xyz.x < a_field[0].min_bound.xyz.x) {
|
||||
MessageBox("Asteroid x min is greater than max");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check y
|
||||
if (a_field[0].max_bound.xyz.y < a_field[0].min_bound.xyz.y) {
|
||||
MessageBox("Asteroid y min is greater than max");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check z
|
||||
if (a_field[0].max_bound.xyz.z < a_field[0].min_bound.xyz.z) {
|
||||
MessageBox("Asteroid z min is greater than max");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check if inner bounds enabled
|
||||
if (a_field[0].has_inner_bound) {
|
||||
if (a_field[0].inner_max_bound.xyz.x < a_field[0].inner_min_bound.xyz.x) {
|
||||
MessageBox("Asteroid x inner min is greater than inner max");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a_field[0].inner_max_bound.xyz.y < a_field[0].inner_min_bound.xyz.y) {
|
||||
MessageBox("Asteroid y inner min is greater than inner max");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a_field[0].inner_max_bound.xyz.z < a_field[0].inner_min_bound.xyz.z) {
|
||||
MessageBox("Asteroid z inner min is greater than inner max");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check x thickness
|
||||
if (a_field[0].inner_min_bound.xyz.x - MIN_BOX_THICKNESS < a_field[0].min_bound.xyz.x) {
|
||||
MessageBox("Asteroid x thickness from outer box to inner box must be > 400");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a_field[0].inner_max_bound.xyz.x + MIN_BOX_THICKNESS > a_field[0].max_bound.xyz.x) {
|
||||
MessageBox("Asteroid x thickness from outer box to inner box must be > 400");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check y thickness
|
||||
if (a_field[0].inner_min_bound.xyz.y - MIN_BOX_THICKNESS < a_field[0].min_bound.xyz.y) {
|
||||
MessageBox("Asteroid y thickness from outer box to inner box must be > 400");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a_field[0].inner_max_bound.xyz.y + MIN_BOX_THICKNESS > a_field[0].max_bound.xyz.y) {
|
||||
MessageBox("Asteroid y thickness from outer box to inner box must be > 400");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check z thickness
|
||||
if (a_field[0].inner_min_bound.xyz.z - MIN_BOX_THICKNESS < a_field[0].min_bound.xyz.z) {
|
||||
MessageBox("Asteroid z thickness from outer box to inner box must be > 400");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a_field[0].inner_max_bound.xyz.z + MIN_BOX_THICKNESS > a_field[0].max_bound.xyz.z) {
|
||||
MessageBox("Asteroid z thickness from outer box to inner box must be > 400");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// check if passive, ship debris field, at least one speceis selected
|
||||
if (a_field[0].field_type == FT_PASSIVE) {
|
||||
if (a_field[0].debris_genre == DG_SHIP) {
|
||||
if ( (a_field[0].field_debris_type[0] == -1) && (a_field[0].field_debris_type[1] == -1) && (a_field[0].field_debris_type[2] == -1) ) {
|
||||
MessageBox("You must choose one or more types of ship debris");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check at least one asteroid subtype is selected
|
||||
if (a_field[0].debris_genre == DG_ASTEROID) {
|
||||
if ( (a_field[0].field_debris_type[0] == -1) && (a_field[0].field_debris_type[1] == -1) && (a_field[0].field_debris_type[2] == -1) ) {
|
||||
MessageBox("You must choose one or more asteroid subtypes");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void asteroid_editor::OnOK()
|
||||
{
|
||||
int i;
|
||||
|
||||
update_init();
|
||||
if (!validate_data()) {
|
||||
return;
|
||||
}
|
||||
for (i=0; i<1 /*MAX_ASTEROID_FIELDS*/; i++)
|
||||
Asteroid_field = a_field[i];
|
||||
|
||||
update_map_window();
|
||||
theApp.record_window_data(&Asteroid_wnd_data, this);
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
BOOL asteroid_editor::OnInitDialog()
|
||||
{
|
||||
|
||||
|
||||
cur_field = 0;
|
||||
CDialog::OnInitDialog();
|
||||
update_init();
|
||||
theApp.init_window(&Asteroid_wnd_data, this);
|
||||
|
||||
m_density_spin.SetRange(1, MAX_ASTEROIDS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void asteroid_editor::update_init()
|
||||
{
|
||||
int num_asteroids, idx, cur_choice;
|
||||
|
||||
UpdateData(TRUE);
|
||||
if (last_field >= 0) {
|
||||
// store into temp asteroid field
|
||||
num_asteroids = a_field[last_field].num_initial_asteroids;
|
||||
a_field[last_field].num_initial_asteroids = m_enable_asteroids ? m_density : 0;
|
||||
if (a_field[last_field].num_initial_asteroids < 0)
|
||||
a_field[last_field].num_initial_asteroids = 0;
|
||||
|
||||
if (a_field[last_field].num_initial_asteroids > MAX_ASTEROIDS)
|
||||
a_field[last_field].num_initial_asteroids = MAX_ASTEROIDS;
|
||||
|
||||
if (num_asteroids != a_field[last_field].num_initial_asteroids)
|
||||
set_modified();
|
||||
|
||||
vec3d vel_vec = {1.0f, 0.0f, 0.0f};
|
||||
vm_vec_scale(&vel_vec, (float) m_avg_speed);
|
||||
|
||||
MODIFY(a_field[last_field].vel.xyz.x, vel_vec.xyz.x);
|
||||
MODIFY(a_field[last_field].vel.xyz.y, vel_vec.xyz.y);
|
||||
MODIFY(a_field[last_field].vel.xyz.z, vel_vec.xyz.z);
|
||||
|
||||
MODIFY(a_field[last_field].min_bound.xyz.x, (float) atof(m_min_x));
|
||||
MODIFY(a_field[last_field].min_bound.xyz.y, (float) atof(m_min_y));
|
||||
MODIFY(a_field[last_field].min_bound.xyz.z, (float) atof(m_min_z));
|
||||
MODIFY(a_field[last_field].max_bound.xyz.x, (float) atof(m_max_x));
|
||||
MODIFY(a_field[last_field].max_bound.xyz.y, (float) atof(m_max_y));
|
||||
MODIFY(a_field[last_field].max_bound.xyz.z, (float) atof(m_max_z));
|
||||
|
||||
// type of field
|
||||
MODIFY(a_field[last_field].field_type, m_field_type);
|
||||
MODIFY(a_field[last_field].debris_genre, m_debris_genre);
|
||||
if ( (m_field_type == FT_PASSIVE) && (m_debris_genre == DG_SHIP) ) {
|
||||
// we should have ship debris
|
||||
for (idx=0; idx<MAX_ACTIVE_DEBRIS_TYPES; idx++) {
|
||||
// loop over combo boxes, store the item data of the cur selection, -1 in no cur selection
|
||||
int cur_sel = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetCurSel();
|
||||
if (cur_sel != CB_ERR) {
|
||||
cur_choice = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetItemData(cur_sel);
|
||||
} else {
|
||||
cur_choice = -1;
|
||||
}
|
||||
MODIFY(a_field[cur_field].field_debris_type[idx], cur_choice);
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_debris_genre == DG_ASTEROID ) {
|
||||
if ( ((CButton *)GetDlgItem(IDC_SUBTYPE1))->GetCheck() == 1) {
|
||||
cur_choice = 1;
|
||||
} else {
|
||||
cur_choice = -1;
|
||||
}
|
||||
MODIFY(a_field[cur_field].field_debris_type[0], cur_choice);
|
||||
|
||||
|
||||
if ( ((CButton *)GetDlgItem(IDC_SUBTYPE2))->GetCheck() == 1) {
|
||||
cur_choice = 1;
|
||||
} else {
|
||||
cur_choice = -1;
|
||||
}
|
||||
MODIFY(a_field[cur_field].field_debris_type[1], cur_choice);
|
||||
|
||||
|
||||
if ( ((CButton *)GetDlgItem(IDC_SUBTYPE3))->GetCheck() == 1) {
|
||||
cur_choice = 1;
|
||||
} else {
|
||||
cur_choice = -1;
|
||||
}
|
||||
MODIFY(a_field[cur_field].field_debris_type[2], cur_choice);
|
||||
}
|
||||
|
||||
MODIFY(a_field[last_field].has_inner_bound, m_enable_inner_bounds);
|
||||
|
||||
MODIFY(a_field[last_field].inner_min_bound.xyz.x, (float) atof(m_box_min_x));
|
||||
MODIFY(a_field[last_field].inner_min_bound.xyz.y, (float) atof(m_box_min_y));
|
||||
MODIFY(a_field[last_field].inner_min_bound.xyz.z, (float) atof(m_box_min_z));
|
||||
MODIFY(a_field[last_field].inner_max_bound.xyz.x, (float) atof(m_box_max_x));
|
||||
MODIFY(a_field[last_field].inner_max_bound.xyz.y, (float) atof(m_box_max_y));
|
||||
MODIFY(a_field[last_field].inner_max_bound.xyz.z, (float) atof(m_box_max_z));
|
||||
}
|
||||
|
||||
Assert(cur_field >= 0);
|
||||
// get from temp asteroid field into class
|
||||
m_enable_asteroids = a_field[cur_field].num_initial_asteroids ? TRUE : FALSE;
|
||||
m_enable_inner_bounds = a_field[cur_field].has_inner_bound ? TRUE : FALSE;
|
||||
m_density = a_field[cur_field].num_initial_asteroids;
|
||||
if (!m_enable_asteroids)
|
||||
m_density = 10;
|
||||
|
||||
// set field type
|
||||
m_field_type = a_field[cur_field].field_type;
|
||||
m_debris_genre = a_field[cur_field].debris_genre;
|
||||
// m_debris_species = a_field[cur_field].debris_species;
|
||||
|
||||
m_avg_speed = (int) vm_vec_mag(&a_field[cur_field].vel);
|
||||
m_min_x.Format("%.1f", a_field[cur_field].min_bound.xyz.x);
|
||||
m_min_y.Format("%.1f", a_field[cur_field].min_bound.xyz.y);
|
||||
m_min_z.Format("%.1f", a_field[cur_field].min_bound.xyz.z);
|
||||
m_max_x.Format("%.1f", a_field[cur_field].max_bound.xyz.x);
|
||||
m_max_y.Format("%.1f", a_field[cur_field].max_bound.xyz.y);
|
||||
m_max_z.Format("%.1f", a_field[cur_field].max_bound.xyz.z);
|
||||
|
||||
m_box_min_x.Format("%.1f", a_field[cur_field].inner_min_bound.xyz.x);
|
||||
m_box_min_y.Format("%.1f", a_field[cur_field].inner_min_bound.xyz.y);
|
||||
m_box_min_z.Format("%.1f", a_field[cur_field].inner_min_bound.xyz.z);
|
||||
m_box_max_x.Format("%.1f", a_field[cur_field].inner_max_bound.xyz.x);
|
||||
m_box_max_y.Format("%.1f", a_field[cur_field].inner_max_bound.xyz.y);
|
||||
m_box_max_z.Format("%.1f", a_field[cur_field].inner_max_bound.xyz.z);
|
||||
|
||||
// set up combo boxes
|
||||
uint i;
|
||||
int j, k, index, box_index;
|
||||
|
||||
// add "None" to each box
|
||||
for (k = 0; k < MAX_ACTIVE_DEBRIS_TYPES; k++)
|
||||
{
|
||||
box_index = ((CComboBox*)GetDlgItem(Dlg_id[k]))->AddString("None");
|
||||
((CComboBox*)GetDlgItem(Dlg_id[k]))->SetItemData(box_index, static_cast<DWORD_PTR>(-1));
|
||||
}
|
||||
|
||||
// now add each kind of debris to each box
|
||||
CString name;
|
||||
char *debris_size[NUM_DEBRIS_SIZES] = { "Small", "Medium", "Large" };
|
||||
|
||||
// each species
|
||||
for (i = 0; i < Species_info.size(); i++)
|
||||
{
|
||||
// each size
|
||||
for (j = 0; j < NUM_DEBRIS_SIZES; j++)
|
||||
{
|
||||
name = CString(Species_info[i].species_name) + " " + debris_size[j];
|
||||
index = NUM_DEBRIS_SIZES + ((i * NUM_DEBRIS_SIZES) + j);
|
||||
|
||||
// each box
|
||||
for (k = 0; k < MAX_ACTIVE_DEBRIS_TYPES; k++)
|
||||
{
|
||||
box_index = ((CComboBox*)GetDlgItem(Dlg_id[k]))->AddString(name);
|
||||
((CComboBox*)GetDlgItem(Dlg_id[k]))->SetItemData(box_index, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set active debris type for each combo box
|
||||
int box_count, cur_box_data;
|
||||
for (idx=0;idx<MAX_ACTIVE_DEBRIS_TYPES; idx++) {
|
||||
// Only set selection if not "None"
|
||||
if (a_field[cur_field].field_debris_type[idx] != -1) {
|
||||
box_count = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetCount();
|
||||
for (box_index=0; box_index<box_count; box_index++) {
|
||||
cur_box_data = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetItemData(box_index);
|
||||
if (cur_box_data == a_field[cur_field].field_debris_type[idx]) {
|
||||
// set cur sel
|
||||
((CComboBox*)GetDlgItem(Dlg_id[idx]))->SetCurSel(box_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set up asteroid subtype checkboxes
|
||||
((CButton*)GetDlgItem(IDC_SUBTYPE1))->SetCheck(a_field[cur_field].field_debris_type[0] == 1);
|
||||
((CButton*)GetDlgItem(IDC_SUBTYPE2))->SetCheck(a_field[cur_field].field_debris_type[1] == 1);
|
||||
((CButton*)GetDlgItem(IDC_SUBTYPE3))->SetCheck(a_field[cur_field].field_debris_type[2] == 1);
|
||||
|
||||
|
||||
UpdateData(FALSE);
|
||||
OnEnableAsteroids();
|
||||
|
||||
last_field = cur_field;
|
||||
}
|
||||
|
||||
void asteroid_editor::OnEnableAsteroids()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
GetDlgItem(IDC_DENSITY)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_DENSITY_SPIN)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_AVG_SPEED)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_MIN_X)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_MIN_Y)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_MIN_Z)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_MAX_X)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_MAX_Y)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_MAX_Z)->EnableWindow(m_enable_asteroids);
|
||||
|
||||
GetDlgItem(IDC_ENABLE_INNER_BOX)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_PASSIVE_FIELD)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_ACTIVE_FIELD)->EnableWindow(m_enable_asteroids);
|
||||
|
||||
GetDlgItem(IDC_FIELD_SHIP)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_FIELD_ASTEROID)->EnableWindow(m_enable_asteroids);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_SHIP));
|
||||
GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_SHIP));
|
||||
GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_SHIP));
|
||||
GetDlgItem(IDC_SUBTYPE1)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_ASTEROID));
|
||||
GetDlgItem(IDC_SUBTYPE2)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_ASTEROID));
|
||||
GetDlgItem(IDC_SUBTYPE3)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_ASTEROID));
|
||||
|
||||
OnEnableInnerBox();
|
||||
OnEnableField();
|
||||
}
|
||||
|
||||
void asteroid_editor::OnCancel()
|
||||
{
|
||||
theApp.record_window_data(&Asteroid_wnd_data, this);
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void asteroid_editor::OnClose()
|
||||
{
|
||||
int z;
|
||||
|
||||
update_init();
|
||||
if (query_modified()) {
|
||||
z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
|
||||
if (z == IDCANCEL)
|
||||
return;
|
||||
|
||||
if (z == IDYES) {
|
||||
OnOK();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
// enable inner box (asteroid free zone)
|
||||
// only allowed for active debris field
|
||||
void asteroid_editor::OnEnableInnerBox()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
GetDlgItem(IDC_INNER_MIN_X)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
|
||||
GetDlgItem(IDC_INNER_MAX_X)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
|
||||
GetDlgItem(IDC_INNER_MIN_Y)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
|
||||
GetDlgItem(IDC_INNER_MAX_Y)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
|
||||
GetDlgItem(IDC_INNER_MIN_Z)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
|
||||
GetDlgItem(IDC_INNER_MAX_Z)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
|
||||
}
|
||||
|
||||
//
|
||||
void asteroid_editor::OnEnableField()
|
||||
{
|
||||
// set check in active
|
||||
if (m_enable_asteroids) {
|
||||
if (m_field_type == FT_ACTIVE) {
|
||||
OnActiveField();
|
||||
} else {
|
||||
OnPassiveField();
|
||||
}
|
||||
}
|
||||
|
||||
// maybe enable species
|
||||
if ( m_enable_asteroids && (m_field_type == FT_PASSIVE) && (m_debris_genre == DG_SHIP) ) {
|
||||
OnFieldShip();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void asteroid_editor::OnActiveField()
|
||||
{
|
||||
// set field type
|
||||
m_field_type = FT_ACTIVE;
|
||||
m_debris_genre = DG_ASTEROID;
|
||||
|
||||
// gray out ship and species
|
||||
GetDlgItem(IDC_FIELD_SHIP)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SUBTYPE1)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SUBTYPE2)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SUBTYPE3)->EnableWindow(TRUE);
|
||||
|
||||
// force check of asteroid
|
||||
((CButton*)GetDlgItem(IDC_FIELD_ASTEROID))->SetCheck(1);
|
||||
((CButton*)GetDlgItem(IDC_FIELD_SHIP))->SetCheck(0);
|
||||
|
||||
// force check of active field
|
||||
((CButton*)GetDlgItem(IDC_ACTIVE_FIELD))->SetCheck(1);
|
||||
((CButton*)GetDlgItem(IDC_PASSIVE_FIELD))->SetCheck(0);
|
||||
|
||||
// enable inner box
|
||||
GetDlgItem(IDC_ENABLE_INNER_BOX)->EnableWindow(TRUE);
|
||||
}
|
||||
|
||||
void asteroid_editor::OnPassiveField()
|
||||
{
|
||||
// set field type
|
||||
m_field_type = FT_PASSIVE;
|
||||
|
||||
// acivate ship
|
||||
GetDlgItem(IDC_FIELD_SHIP)->EnableWindow(TRUE);
|
||||
|
||||
// maybe activate species
|
||||
GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(m_debris_genre == DG_SHIP);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(m_debris_genre == DG_SHIP);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(m_debris_genre == DG_SHIP);
|
||||
|
||||
// maybe activate asteroid subtype
|
||||
GetDlgItem(IDC_SUBTYPE1)->EnableWindow(m_debris_genre == DG_ASTEROID);
|
||||
GetDlgItem(IDC_SUBTYPE2)->EnableWindow(m_debris_genre == DG_ASTEROID);
|
||||
GetDlgItem(IDC_SUBTYPE3)->EnableWindow(m_debris_genre == DG_ASTEROID);
|
||||
|
||||
|
||||
// force check of current debris type
|
||||
((CButton*)GetDlgItem(IDC_FIELD_ASTEROID))->SetCheck(m_debris_genre == DG_ASTEROID);
|
||||
((CButton*)GetDlgItem(IDC_FIELD_SHIP))->SetCheck(m_debris_genre == DG_SHIP);
|
||||
|
||||
// force check of passive field
|
||||
((CButton*)GetDlgItem(IDC_ACTIVE_FIELD))->SetCheck(0);
|
||||
((CButton*)GetDlgItem(IDC_PASSIVE_FIELD))->SetCheck(1);
|
||||
|
||||
// disable inner box
|
||||
GetDlgItem(IDC_ENABLE_INNER_BOX)->EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
void asteroid_editor::OnFieldShip()
|
||||
{
|
||||
// set debris type
|
||||
m_debris_genre = DG_SHIP;
|
||||
|
||||
GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(TRUE);
|
||||
|
||||
GetDlgItem(IDC_SUBTYPE1)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SUBTYPE2)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SUBTYPE3)->EnableWindow(FALSE);
|
||||
|
||||
// force check of ship
|
||||
((CButton*)GetDlgItem(IDC_FIELD_ASTEROID))->SetCheck(0);
|
||||
((CButton*)GetDlgItem(IDC_FIELD_SHIP))->SetCheck(1);
|
||||
|
||||
}
|
||||
|
||||
void asteroid_editor::OnFieldAsteroid()
|
||||
{
|
||||
// set debris type
|
||||
m_debris_genre = DG_ASTEROID;
|
||||
|
||||
GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(FALSE);
|
||||
|
||||
|
||||
GetDlgItem(IDC_SUBTYPE1)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SUBTYPE2)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SUBTYPE3)->EnableWindow(TRUE);
|
||||
|
||||
// force check of asteroid
|
||||
((CButton*)GetDlgItem(IDC_FIELD_ASTEROID))->SetCheck(1);
|
||||
((CButton*)GetDlgItem(IDC_FIELD_SHIP))->SetCheck(0);
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
// AsteroidEditorDlg.h : header file
|
||||
//
|
||||
|
||||
#include "starfield/starfield.h"
|
||||
#include "asteroid/asteroid.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// asteroid_editor dialog
|
||||
|
||||
class asteroid_editor : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
void update_init();
|
||||
int query_modified();
|
||||
void OnCancel();
|
||||
void OnOK();
|
||||
void OnEnableField();
|
||||
int validate_data();
|
||||
|
||||
asteroid_editor(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(asteroid_editor)
|
||||
enum { IDD = IDD_ASTEROID_EDITOR };
|
||||
CSpinButtonCtrl m_density_spin;
|
||||
int m_avg_speed;
|
||||
int m_density;
|
||||
BOOL m_enable_asteroids;
|
||||
CString m_max_x;
|
||||
CString m_max_y;
|
||||
CString m_max_z;
|
||||
CString m_min_x;
|
||||
CString m_min_y;
|
||||
CString m_min_z;
|
||||
BOOL m_enable_inner_bounds;
|
||||
field_type_t m_field_type; // active or passive
|
||||
debris_genre_t m_debris_genre; // ship or asteroid
|
||||
int m_field_debris_type[3]; // species and size of ship debris
|
||||
CString m_box_max_x;
|
||||
CString m_box_max_y;
|
||||
CString m_box_max_z;
|
||||
CString m_box_min_x;
|
||||
CString m_box_min_y;
|
||||
CString m_box_min_z;
|
||||
//}}AFX_DATA
|
||||
|
||||
int cur_field, last_field;
|
||||
asteroid_field a_field[1 /*MAX_ASTEROID_FIELDS*/];
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(asteroid_editor)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(asteroid_editor)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnInitMenu(CMenu* pMenu);
|
||||
afx_msg void OnEnableAsteroids();
|
||||
afx_msg void OnClose();
|
||||
afx_msg void OnEnableInnerBox();
|
||||
afx_msg void OnPassiveField();
|
||||
afx_msg void OnFieldShip();
|
||||
afx_msg void OnActiveField();
|
||||
afx_msg void OnFieldAsteroid();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
// BackgroundChooser.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "BackgroundChooser.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// BackgroundChooser dialog
|
||||
|
||||
|
||||
BackgroundChooser::BackgroundChooser(int numBackgrounds)
|
||||
: CDialog(BackgroundChooser::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(BackgroundChooser)
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
m_numBackgrounds = numBackgrounds;
|
||||
m_chosenBackground = -1;
|
||||
}
|
||||
|
||||
|
||||
void BackgroundChooser::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(BackgroundChooser)
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(BackgroundChooser, CDialog)
|
||||
//{{AFX_MSG_MAP(BackgroundChooser)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// BackgroundChooser message handlers
|
||||
|
||||
BOOL BackgroundChooser::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < m_numBackgrounds; i++)
|
||||
{
|
||||
char temp[NAME_LENGTH];
|
||||
sprintf(temp, "Background %d", i + 1);
|
||||
|
||||
((CComboBox*) GetDlgItem(IDC_BACKGROUND))->AddString(temp);
|
||||
}
|
||||
((CComboBox*) GetDlgItem(IDC_BACKGROUND))->SetCurSel(0);
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void BackgroundChooser::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
m_chosenBackground = ((CComboBox*) GetDlgItem(IDC_BACKGROUND))->GetCurSel();
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void BackgroundChooser::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void BackgroundChooser::OnClose()
|
||||
{
|
||||
OnCancel();
|
||||
}
|
||||
|
||||
int BackgroundChooser::GetChosenBackground()
|
||||
{
|
||||
return m_chosenBackground;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#if !defined(_BACKGROUND_CHOOSER_H_)
|
||||
#define _BACKGROUND_CHOOSER_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// BackgroundChooser.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// BackgroundChooser dialog
|
||||
|
||||
class BackgroundChooser : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
BackgroundChooser(int numBackgrounds); // standard constructor
|
||||
void OnOK();
|
||||
void OnCancel();
|
||||
|
||||
int GetChosenBackground();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(BackgroundChooser)
|
||||
enum { IDD = IDD_BACKGROUND_CHOOSER};
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(BackgroundChooser)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
int m_numBackgrounds;
|
||||
int m_chosenBackground;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(BackgroundChooser)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(_BACKGROUND_CHOOSER_H_)
|
||||
Loaded 100 of 1669 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user