Compare commits

..
Author SHA1 Message Date
Goober5000 17b01fa8eb Merge pull request #1906 from plieblang/LabShipMenuImprovement
Show ship directly when clicking on it in the F3 lab
2018-10-23 22:41:16 -04:00
Goober5000 45ea62a9a2 Merge pull request #1907 from plieblang/ShipInvisibleAutoTargeting
ship-invisible doesn't turn off autotargeting
2018-10-23 22:41:02 -04:00
plieblang 979a4b0924 Flip default param value 2018-10-22 14:42:42 -05:00
Goober5000 e1db71fb69 Merge pull request #1910 from wookieejedi/FixOnShipDepart
Fix to "On Ship Depart" to incorporate Goober's feedback
2018-10-22 14:27:03 -04:00
niffiwan c33d406942 Merge pull request #1909 from asarium/build/travis_windows
Test Windows compilation with Travis CI
2018-10-22 22:03:25 +10:00
plieblang 30baac39a9 Combine cease_targeting functions 2018-10-21 13:13:08 -05:00
wookieejedi 50dbbc4687 Incorporates Goober's feedback
Moved new "On Ship Depart" hook exectuion to ship_cleanup.
2018-10-21 01:11:16 -04:00
niffiwan e19a6f9e01 Merge pull request #1905 from wookieejedi/OnDepartHook
Add '$On Ship Depart' Conditional Hook
2018-10-21 08:52:53 +10:00
niffiwan d9184545f7 Merge pull request #1902 from plieblang/BriefingVoiceUnpause
Play simulated speech if mission is launched while briefing is paused
2018-10-21 08:52:18 +10:00
asarium 5c07d181ad Test Windows compilation with Travis CI
Travis CI recently added support for running builds in Windows. This
adds support for testing compilation on Windows using that feature.

The newer version of Visual Studio and MinGW required some code changes
and an update of Google Test which is included in this commit.
2018-10-20 23:44:10 +02:00
wookieejedi 140fed2812 Added "Method" hook variable to "On Ship Depart" 2018-10-20 16:41:59 -04:00
plieblang dd2fd3ee5c Address feedback 2018-10-20 10:45:51 -05:00
plieblang dd7c36e43d ship-invisible doesn't turn off autotargeting 2018-10-19 18:49:53 -05:00
plieblang 409c7da2d7 Clicking on a ship in the lab shows it directly 2018-10-19 15:00:07 -05:00
wookieejedi 791e22bc1d Add On Ship Depart Conditional Hook 2018-10-18 17:50:22 -04:00
plieblang 6a93715c9b Clarify fsspeech_pause call 2018-10-18 11:28:45 -05:00
Goober5000 8fee9804df Merge pull request #1903 from plieblang/LabUpdatePOFName
Update displayed POF name in the F3 lab when new ship is selected
2018-10-17 23:32:53 -04:00
plieblang 2dc6d64c37 Update POF name when new ship is selected 2018-10-17 19:31:37 -05:00
plieblang a8142b8f80 Solution that actually compiles 2018-10-17 15:56:12 -05:00
plieblang 53f98cda99 Play simulated speech if mission is launched while briefing is paused 2018-10-17 01:03:39 -05:00
m!m 115d06a051 Merge pull request #1899 from Artyrm/Fix_missing_HUD
Fix missing HUD bug
2018-10-14 19:22:37 +02:00
m!m 485af1bad3 Merge pull request #1895 from Artyrm/Adapt_barracks_interface
Barracks stats adaptation for longer Unicode strings.
2018-10-14 19:22:27 +02:00
Goober5000 0ca5ade5ef Merge pull request #1894 from Artyrm/master
More friendly assert if used font misses a glyph.
2018-10-14 13:22:05 -04:00
Artyrm ff601db6fc Switched to hud_config_as_player() 2018-10-14 18:15:18 +03:00
Artyrm 686bc35cff Moved variables, gave mean. names and descr. 2018-10-14 16:07:59 +03:00
Artyrm ffe9a085b6 Improved readability. 2018-10-14 15:39:48 +03:00
Artyrm 33df766edf #ifdefed debug parts. 2018-10-14 15:25:17 +03:00
Artyrm 9a6227e7b0 Fixed grammar. 2018-10-14 14:58:53 +03:00
m!m c664eac1ee Merge pull request #1898 from ngld/enhance/betterBmErrors
If an icon can't be loaded, display an error instead of asserting.
2018-10-14 12:31:03 +02:00
Artyrm a7a9514fd1 Little cleanups. 2018-10-13 19:37:17 +03:00
Artyrm b402d9158c Use .is_observer flag. Add HUD restore in DEBRIEF state. 2018-10-13 18:56:21 +03:00
Artyrm c1b055a685 Start using hud_config_restore(). 2018-10-13 16:58:17 +03:00
ngld 412197d3e9 Gracefully handle missing briefing icons. 2018-10-13 06:16:16 +02:00
Artyrm 98f1d690f6 Fix Clang warnings. 2018-10-12 19:18:24 +03:00
Goober5000 842dbb1b75 Merge pull request #1888 from plieblang/AIProfileABFlag
Add "$free afterburner use" flag to ai_profiles.tbl
2018-10-12 12:12:26 -04:00
Artyrm df8e85f22e String width adapts, orig. behaviour is intact. 2018-10-12 17:57:44 +03:00
Goober5000 73482a6d62 Merge pull request #1896 from wookieejedi/FixOnArriveforDockWings
Fixes missing "On Ship Arrive" with Docked Wings
2018-10-11 22:38:04 -04:00
wookieejedi afa7976018 Removed redundant syntax 2018-10-11 18:36:05 -04:00
wookieejedi 0d355982d4 Update code/mission/missionparse.cpp 2018-10-11 11:43:40 -04:00
wookieejedi 7f9021cbdb Fixed missing "=" 2018-10-11 11:41:53 -04:00
wookieejedi 1450c71e2e Improve dock check with bool
Uses boolean value to determine if wing is docked, incoroprates that bool into if block for setting On Ship Arrive hook.
2018-10-11 11:39:16 -04:00
wookieejedi d80e6d0f71 Fixed missing "_" 2018-10-10 18:05:48 -04:00
wookieejedi f6dd3b09ab Remove incorrect placement 2018-10-10 17:05:22 -04:00
wookieejedi bc5ef0b28d Fixed anchor call and null bug 2018-10-10 13:12:18 -04:00
wookieejedi 8e618ffaec Add HV to Docked Wings
Fixs bug by adding the conditional hook call "On Ship Arrive" to docked wings that arrive.
2018-10-10 12:24:30 -04:00
Artyrm 889474688c Barracks stats adaptation for longer Unicode strings. 2018-10-10 18:01:06 +03:00
Artyrm d56cb8fc62 Even mor specific, gcc syntax. 2018-10-09 19:29:00 +03:00
Artyrm 98f196ee48 Compiler-specific fallthrough. 2018-10-09 19:13:36 +03:00
Artyrm 9f4ad9d1eb #ifdefed print for Release. Tried the strictest fallthrough comment 2018-10-09 18:29:00 +03:00
Artyrm a69e1d7308 Proper args handling. Extern C is also back. 2018-10-09 17:48:42 +03:00
Artyrm 34d1bf03f9 Got rid of unnes. #ifded. 2018-10-09 17:28:03 +03:00
wookieejedi 9fcd96ff97 Adds Accept Mission Outcome as new Conditional Hook (#1893)
* Adds Accept Mission Outcome Event to Game Events

Adds Accept Mission Outcome Event to Game Events, so scritps and other things can be called only when a campaign mission is accepted.

* Fixed double entry

* Define CHA_CMISSIONACCEPT

Adds line to define new conditional hook, CHA_CMISSIONACCEPT

* Add flag_def_list for On Campaign Mission Accept

Adds the proper flag_def_list for "On Campaign Mission Accept" CHA_CMISSIONACCEPT

* Runs New Conditional Hook

Runs the new conditional hook for "On Campaign Mission Accept"

* Reverts event changes

* Reverts state changese

* Reverts post_event change
2018-10-08 18:13:02 +02:00
Artyrm 2b77721c79 Tweaked function type a little for compilers. 2018-10-08 12:45:14 +03:00
Artyrm 95fafa50c4 Changed printf function. Explicit fallthrough. 2018-10-08 12:01:55 +03:00
Artyrm cac07391ca More user-friendly assert on missed glyph in font. 2018-10-07 23:44:27 +03:00
Goober5000 9daeb7f417 Merge pull request #1891 from Artyrm/master
Switch communication messages to use SCP_string
2018-10-07 11:11:06 -04:00
Artyrm f0ba0265fd New version of stb_truetype.h, just in case. 2018-10-07 15:35:12 +03:00
Artyrm 5b77cad5ac Merge branch 'ComMsg_Unicode_fix' 2018-10-07 14:57:16 +03:00
Artyrm 3f024cb324 And FRED fix as well. 2018-10-07 14:56:50 +03:00
m!m 1d60d25cf5 Merge pull request #1890 from wookieejedi/HyperspaceSounds
Fix missing Warpin sounds from Hyperspace Warpin Effect
2018-10-07 09:36:16 +02:00
Artyrm be5c98c7e2 Merge branch 'ComMsg_Unicode_fix' 2018-10-06 19:57:36 +03:00
Artyrm 6212ad29f1 One dependency in qtfred. Fixed. 2018-10-06 19:57:06 +03:00
wookieejedi 5ec30bdaee Update code/ship/shipfx.cpp 2018-10-06 11:37:50 -04:00
wookieejedi b9b74a3201 Fixed sound variable error
Pos variable not used, so removed it.
2018-10-06 09:45:36 -04:00
wookieejedi 09c24313d7 Added sounds to WE Hyperspace
Allows warpin enter and exit sounds to be properly used with the Hyperspace warpin effect.
2018-10-06 08:35:28 -04:00
Artyrm afdaa3a3ee Merge branch 'ComMsg_Unicode_fix' 2018-10-06 13:32:20 +03:00
Artyrm 68dcef639d Clean-up commented variants. 2018-10-06 13:31:21 +03:00
wookieejedi 91f351b990 Update code/ship/shipfx.cpp 2018-10-06 01:35:52 -04:00
wookieejedi dd1def4f4c Update code/ship/shipfx.cpp 2018-10-06 00:36:23 -04:00
wookieejedi 8b770792fb Update code/ship/shipfx.cpp 2018-10-05 22:17:30 -04:00
plieblang 23f9cfc815 Add free-afterburner-use flag to ai_profiles.tbl 2018-10-02 14:10:27 -05:00
niffiwan 11f9175425 Merge pull request #1887 from TRBlount/feature/mod_play_warp_settings
Make player warpout settings customizable
2018-10-01 11:08:14 +10:00
Artyrm 4fb9c27e71 Comm_orders assign fix. MsgItems to SCP_string too. 2018-09-30 23:51:47 +03:00
TRBlount 4c7b7a0fef Make player warpout settings customizable 2018-09-30 11:31:41 -06:00
Artyrm 3dc1689936 Switched to SCP_string in HUDSquadMsg 2018-09-30 17:23:23 +03:00
niffiwan 94df2777e0 Merge pull request #1884 from niffiwan/fix/setetsvalues_doco
Fix set-ets-values sexp documentation bug
2018-09-30 12:52:38 +10:00
niffiwan c9ebc33d98 apply similar to get-ets-values 2018-09-30 10:12:18 +10:00
niffiwan 9bd459d549 further enhance doco (per feedback) 2018-09-30 09:27:10 +10:00
m!m d9db8bdb71 Merge pull request #1883 from asarium/fix/linuxRelease
Fix linux release building
2018-09-29 16:30:46 +02:00
niffiwan f3cdfcc229 Fix set-ets-values sexp documentation bug
Found by Asteroth - thanks!
2018-09-29 19:16:06 +10:00
asarium 44e3f1f9b5 Fix linux release building
I removed too much code when disabling qtFRED deployment...
2018-09-29 10:30:15 +02:00
niffiwan da5e7f1510 Merge pull request #1882 from asarium/build/disableLinuxQtFred
Disable Linux qtFRED building again
2018-09-29 10:51:55 +10:00
asarium d830a01381 Disable Linux qtFRED building again
There are still some unresolved issues and the file size is pretty large
due to some issues with how the AppImage is built.
2018-09-28 23:13:20 +02:00
m!m d24d536731 Merge pull request #1862 from asarium/feature/libRocket
Add scripting features for barracks libRocket UI
2018-09-28 10:27:01 +02:00
Goober5000 6d0e166dea Merge pull request #1875 from asarium/opengl/shadowFboFix
Remove duplicate shadow FBO creation
2018-09-27 16:34:33 -04:00
m!m e0301da596 Merge pull request #1879 from Goober5000/fred_choose_dock_leader
always choose a dock leader in FRED
2018-09-27 11:46:55 +02:00
asarium a815c0247c Add scripting features for barracks libRocket UI
This mostly adds the scripting features required for accessing the
various internal variables required for the barracks screen.
2018-09-27 11:45:09 +02:00
m!m f42eaf9637 Merge pull request #1817 from asarium/cleanup/luaVarargs
Convert scripting interaction function to variadic templates
2018-09-27 11:44:22 +02:00
Goober5000 01fb2c1243 Merge pull request #1878 from Goober5000/fireball_warp_type
allow custom fireballs to be used as ship warp effects
2018-09-26 17:21:29 -04:00
Goober5000 408f259368 always choose a dock leader in FRED
In FRED, if all docked ships had their arrival cue set to false, none of them would be loaded
in the mission because there was no dock leader to bring in the entire group.  This PR fixes that
by choosing an arbitrary ship (the biggest ship according to ship_class_compare) to be the
dock leader.  This consequently fixes issue #1877 because the wing is able to find its ship.
2018-09-26 15:35:23 -04:00
Goober5000 a9b8e5c043 address clang-tidy complaints 2018-09-26 14:17:39 -04:00
asarium cfb9540e2c Fix issues with ignoring parameters 2018-09-26 19:15:42 +02:00
asarium 88115c7703 Fix clang-tidy issues 2018-09-26 19:15:42 +02:00
asarium 8dba6770ae Convert ade argument setting to variadic templates
Same as with argument getting, this preserves the type information and
makes the system generally much safer.
2018-09-26 19:15:42 +02:00
asarium 8f4d51b14a Convert ade_get_args to variadic template based solution
This maintains the type information which can be used for enforce
const-correctness and also for implementing more advanced ways of
handling the type information.
2018-09-26 19:15:42 +02:00
asarium 185aece470 Remove duplicate shadow FBO creation
This appears to be a leftover from the development of the shadow
rendering code. The shadow FBO was allocated twice but only one was
used. This removed the unused code and also ports the improved error
handling of that code over to the actual shadow FBO creation code.
2018-09-26 14:10:35 +02:00
m!m 0e962e269b Merge pull request #1876 from plieblang/MemUsageFlagRemoval
Don't show nonexistent memory usage flag
2018-09-26 09:02:20 +02:00
Goober5000 095a2efc56 allow custom fireballs to be used as ship warp effects
This allows the WE_Default warp type to be used with any warp fireball in fireball.tbl.  The fireball can be used by specifying its unique ID for the existing $Warpin type and $Warpout type options in ships.tbl.  The warp type is managed by bitwise-OR'ing a flag to the fireball's index.
2018-09-26 00:19:17 -04:00
plieblang 944a254551 Don't show nonexistent memory usage flag 2018-09-25 16:37:21 -05:00
Goober5000 f628999ef9 Merge pull request #1872 from asarium/fix/libRocketTTF
Disable libRocket unless unicode mode is active
2018-09-24 12:02:33 -04:00
Goober5000 e2fb4d84d7 Merge pull request #1871 from asarium/fix/linuxBuildTransferSh
Remove release build uploading to transfer.sh
2018-09-23 19:59:38 -04:00
asarium ff952298a2 Disable libRocket unless unicode mode is active
Since libRocket requires unicode mode this doesn't change anything but
it fixes an error when a mod uses TrueType fonts without unicode mode.
2018-09-23 14:18:35 +02:00
m!m 66b3fdfed8 Merge pull request #1870 from Goober5000/issue_1869
fix issue #1869
2018-09-23 12:19:41 +02:00
asarium 451c03f76a Remove release build uploading to transfer.sh
I think I used that for debugging some things but now it's causing
issues.
2018-09-23 12:16:12 +02:00
Goober5000 da30c5a38e fix issue 1869 2018-09-22 18:33:00 -04:00
m!m 5206aaabdf Merge pull request #1866 from Goober5000/custom_warpglow
Custom warp glows, balls, and models
2018-09-20 23:20:34 +02:00
Goober5000 f6ed93f7a9 address Travis complaint 2018-09-20 15:29:05 -04:00
Goober5000 4f0e2ae9f1 additional small fixes 2018-09-20 00:25:42 -04:00
Goober5000 c3f595ba0e tweaks 2018-09-19 22:51:57 -04:00
Goober5000 d02d98681a apply new warp attributes for remodularized fireball.tbl 2018-09-19 20:08:19 -04:00
Goober5000 98e37b2570 Merge pull request #1865 from Goober5000/remodularize_fireball_tbl
Remodularize fireball.tbl
2018-09-19 19:50:18 -04:00
Goober5000 3c8b87c958 address PR feedback 2018-09-19 13:00:05 -04:00
niffiwan 8d44946b2b Merge pull request #1863 from asarium/fix/jsonPilotModConversion
Use the correct location flags for enumerating pilots
2018-09-19 21:24:08 +10:00
Goober5000 98b9d5c899 a few more corrections 2018-09-18 19:43:11 -04:00
Goober5000 2f5079fcd1 populate the fireball entry IDs when fred2 starts up
fix various issues with both strings and positive numbers being accepted as sexp arguments
2018-09-18 17:33:45 -04:00
asarium 59a8a347a1 Use the correct location flags for enumerating pilots
This was an oversight in the JSON changes since those were made long
before the CFile location flags were a thing. This uses the correct
location flags for enumerating pilots for conversion.
2018-09-18 22:33:51 +02:00
niffiwan e04f1b4ca4 Merge pull request #1861 from Artyrm/master
Training messages fix.
2018-09-18 20:08:19 +10:00
Fabian Woltermann 7da41c32e3 Merge pull request #1267 from asarium/feature/jsonPilotReading
Add JSON pilot reading implementation
2018-09-18 10:26:07 +02:00
Goober5000 73770845b6 use enhanced fireball.tbl to create OPF_FIREBALL for use in explosion-effect and warp-effect 2018-09-18 00:56:38 -04:00
Goober5000 5828d7f634 generate a unique ID for each fireball, if one isn't specified 2018-09-17 23:06:04 -04:00
Goober5000 45f6cdc687 make fireball modular tables simpler, without using the confusing lod_checker logic, and also add an optional unique id 2018-09-17 22:49:23 -04:00
Artyrm 13fe34a3c7 Merge branch 'training_messages_fix' 2018-09-17 22:26:33 +03:00
asarium da64f285bc Fix issue with file location flags 2018-09-17 20:12:38 +02:00
asarium 45f9ea2ea4 Suppress false-positives in valgrind tests 2018-09-17 19:47:40 +02:00
asarium eb73328c14 Add std::ostream operator to ID class
This will print the internal valie to the stream which can be useful for
debugging.
2018-09-17 19:24:20 +02:00
asarium 380ca12b0d Fix clang-tidy issues 2018-09-17 19:24:11 +02:00
asarium c7e66e26fb Delete old pilot files as well when deleting a pilot 2018-09-17 19:23:18 +02:00
asarium ff911e666d More fixes
This finally fixes the seemingly non-deterministic failure of the
unit-tests (among other things).
2018-09-17 19:23:12 +02:00
asarium c8619ddd0d Fix uninitialized variable error detected by valgrind 2018-09-17 19:23:05 +02:00
asarium 721b2da37b Fix copy-paste error
This caused the continuous conversion of old binary pilots to the JSON
format which reset all the changes made to the JSON data.
2018-09-17 19:22:59 +02:00
asarium e9f4c1618e Add unit tests for validating pilot loading 2018-09-17 19:22:50 +02:00
asarium 4eef54c10b Add JSON reading implementation
This changes the pilot reading code to always use JSON files for storing
the pilot data. Old pilots are converted to the new format when FSO
starts and after that point only JSON pilots will be used.
2018-09-17 19:22:43 +02:00
Artyrm f5ba1e470c Training messages fix. Their delay could be too small with voices volume ste to 0. 2018-09-17 20:12:58 +03:00
asarium 94a00ca6ee Add reading code to FileHandler
Currently only implemented for the BinaryFileHandler
2018-09-17 19:06:50 +02:00
Goober5000 3a8c10bec5 Merge pull request #1858 from Goober5000/enhanced_warp_effect
add additional parameters to warp-effect
2018-09-17 13:00:28 -04:00
niffiwan e92cc5161e Merge pull request #1859 from asarium/feature/loopingParticles
Add support for looping particles
2018-09-17 19:47:26 +10:00
asarium ea73ea33ca Add support for looping particles
This introduces support for keeping particles around forever and letting
them be controlled by a Lua script.
2018-09-17 09:26:20 +02:00
Goober5000 8fe7dc4a1b Merge pull request #1860 from Goober5000/friendlier_warning
rewrite the mod warning dialog a bit
2018-09-16 19:33:58 -04:00
Goober5000 f5bbb21199 rewrite the mod warning dialog a bit 2018-09-16 14:16:57 -04:00
Goober5000 c2761a6142 address clang-tidy complaints 2018-09-16 13:44:38 -04:00
Fabian Woltermann 88b0dba208 Merge pull request #1466 from asarium/feature/libRocket
Add new libRocket UI system
2018-09-16 15:20:34 +02:00
asarium 7173299ca7 Add new libRocket UI system
This new system allows to create a user interface that goes beyond the
existing UI system.
2018-09-16 13:55:29 +02:00
Fabian Woltermann e35fc10530 Merge pull request #1856 from Goober5000/sexp_reset_post_effects
add reset-post-effects sexp
2018-09-16 10:43:39 +02:00
Goober5000 46e8e735b6 more complaining by clang-tidy 2018-09-16 00:31:58 -04:00
Goober5000 e3e40ee576 fix build warning 2018-09-15 23:42:29 -04:00
Goober5000 f0b99e24ff add additional parameters to warp-effect
The warp-effect SEXP can now specify other animations from fireball.tbl that are not necessarily the standard or Knossos animations.  Additionally, the SEXP can now specify the duration for the opening and closing of the warp effect.
2018-09-15 23:30:17 -04:00
Goober5000 e0f76e0cfa tweak sexp documentation as well 2018-09-14 21:59:05 -04:00
Goober5000 5303440dfb add reset-post-effects sexp
Nobody ever thought to add a reset-post-effects SEXP to complement set-post-effects, so this remedies that.  Also, a few minor edits were made to the scripting documentation.
2018-09-14 21:54:35 -04:00
Fabian Woltermann 138a1d01d4 Merge pull request #1854 from TRBlount/fix/share_fire_dir
Fix share_fire_direction logic
2018-09-11 08:04:40 +02:00
TRBlount 0814bf0ae1 Fix share_fire_direction logic 2018-09-10 16:40:36 -06:00
niffiwan 39a0cfecbb Merge pull request #1853 from asarium/feature/sdlVersionDebugLog
Write SDL version to debug log
2018-09-10 23:31:03 +10:00
asarium b78d940136 Write SDL version to debug log
This adds the runtime and compile version of the used SDL library to the
start of the debug log. This was requested by ngld and should make
diagnosing some errors easier.
2018-09-10 09:36:24 +02:00
Goober5000 bc03442a3c Merge pull request #1850 from asarium/fix/1722
Handle DIRECTIVE_WING_ZERO in is-destroyed SEXPs correctly
2018-09-07 12:33:43 -04:00
asarium 8ce1a6f490 Handle DIRECTIVE_WING_ZERO in is-destroyed SEXPs correctly
The special value DIRECTIVE_WING_ZERO (defined to be -999) is used to
signify to the directives system that an is-destroyed SEXP was found
which specified an empty wing. However, if a second is-destroyed-delay
SEXP is present in the same directive then the count of the parameters
is added to -999 which makes means that the directives system then
displays it on the HUD as a negative number.

This fixes that by resetting the counter to 0 if a second SEXP
encounters the special value which fixes the issue in the supplied test
mission. There are probably other edge cases when using multiple
is-destroyed SEXPs in a directive so I added a warning to the SEXP help
which lets the mission designer know that it is preferable to specify
multiple parameters instead of using multiple is-destroyed SEXPs.

This fixes #1722.
2018-09-07 13:38:10 +02:00
Fabian Woltermann 18d2ef8580 Merge pull request #1849 from asarium/fix/1655
Apply clipping offsets when using the line draw list
2018-09-06 12:29:17 +02:00
asarium 4a86b70a69 Apply clipping offsets when using the line draw list
This should make the line draw list class behave identically to the old
line rendering functions. This caused a few issues where the lines were
drawn outside the scissor area which made them invisible.

This fixes #1655.
2018-09-04 15:04:57 +02:00
m!m f717c41083 Merge pull request #1846 from asarium/fix/nebulaBackground
Fix nebula background rendering
2018-09-02 22:59:59 +02:00
asarium 92aacc8479 Fix nebula background rendering
This makes the deferred fog rendering code use the nebula background
instead of the single fog color for the background.

This is not an ideal solution since objects fade to the fog color
instead of the color of the background but it's better than rendering no
background.
2018-09-02 19:07:48 +02:00
Fabian Woltermann 2ae7990c61 Merge pull request #1845 from asarium/fix/1828
Disable movie looping for MVE cutscenes
2018-09-02 15:53:38 +02:00
asarium 4e8ebedfa0 Disable movie looping for MVE cutscenes
This changes the FFmpeg code to not use av_seek_frame anymore if looping
is not required. This fixes an issue when playing MVE movies since that
format does not support seeking.

This fixes #1828.
2018-08-30 23:10:22 +02:00
m!m 01f418f2fb Merge pull request #1844 from The-E/fix/hdr_spec_maps
HDR color space conversion for spec maps is not applied correctly
2018-08-30 15:52:03 +02:00
Fabian Woltermann 0ed47de357 Update main-f.sdr 2018-08-30 13:53:20 +02:00
Fabian Woltermann f5f1c97c0f HDR color space conversion for spec maps only happened in one code path, not all of them. This fixes that. 2018-08-29 21:19:48 +02:00
Goober5000 b0d3957df7 Merge pull request #1841 from niffiwan/feature/per_ship_scan_range
add per-ship-class scanning range feature
2018-08-28 12:59:07 -04:00
niffiwan 332bd01f0f address feedback
remove static keyword & add comment for new constant variable
switch to using #define values for the default scan ranges
2018-08-28 21:51:06 +10:00
niffiwan eb8717f051 add per-ship-class scanning range feature
Requested for FotG - allow dedicated scanning ship options
e.g. Y-wing Longprobe & TIE/rc
2018-08-28 21:13:50 +10:00
m!m af8ae03d9e Merge pull request #1839 from Goober5000/ignore_multiplayer_campaigns
ignore multiplayer as well as singleplayer campaigns
2018-08-24 18:41:53 +02:00
Goober5000 0ca7299bbc ignore multiplayer as well as singleplayer campaigns 2018-08-24 10:58:11 -04:00
Fabian Woltermann 98234c3bc2 Merge pull request #1834 from The-E/fix/team_color_srgb
The team color process is only valid for srgb color space
2018-08-23 18:53:36 +02:00
niffiwan 50691c41da Merge pull request #1837 from niffiwan/feature/autoaim_frame
add feature: change reticle when autoaim is active
2018-08-22 08:42:08 +10:00
m!m 4a66cb190a Merge pull request #1824 from The-E/fix/vm_vec_random_cone_params
vm_vec_random_cone needs to be called with the smaller angle first.
2018-08-21 15:04:39 +02:00
niffiwan 9ba3a0ccf9 clang-tidy: remove FALSE & NULL 2018-08-21 22:53:31 +10:00
niffiwan b625f51645 add feature: change reticle when autoaim is active
Optionally play a sound when autoaim becomes active, and another sound
when autoaim becomes inactive
Credit to zookeeper - I'm just pushing this into master!
2018-08-21 20:56:58 +10:00
Fabian Woltermann c2c8acbf13 REdo properly 2018-08-20 17:12:38 +02:00
Fabian Woltermann ac58950ac5 Revert "vm_vec_random_cone needs to be called with the smaller angle first."
This reverts commit 5b01036723.
2018-08-20 17:10:31 +02:00
Fabian Woltermann 8a84fffe12 Small copy/paste error fix 2018-08-19 20:18:31 +02:00
Fabian Woltermann 0c216ede98 The team color process is only valid for srgb color space, so we need to convert everything into it when we do the thing 2018-08-19 20:14:15 +02:00
m!m 3e543729fc Merge pull request #1832 from Goober5000/ignored_missions
add game_settings feature to ignore single missions
2018-08-19 16:39:49 +02:00
Goober5000 6385bf73be we should not only match without regard to file extension but also without regard to letter case -- and do this for campaigns as well 2018-08-18 15:20:04 -04:00
Goober5000 b7a32329db Merge pull request #1831 from Goober5000/make_getmissionfilename_consistent
make sure getMissionFilename never has a .fs2 extension
2018-08-18 15:05:06 -04:00
m!m b363bda60d Merge pull request #1833 from Goober5000/fix_insufficient_loadout_crash
fix bug introduced in pr #1736
2018-08-18 09:08:23 +02:00
Goober5000 0b547d971e make sure getMissionFilename never has a .fs2 extension 2018-08-18 01:52:48 -04:00
Goober5000 9ac04b9349 fix bug introduced in pr #1736 2018-08-18 01:35:16 -04:00
Goober5000 453b1ca619 address clang-tidy complaint 2018-08-17 23:16:48 -04:00
Goober5000 e6f1332980 add game_settings feature to ignore single missions 2018-08-17 18:32:58 -04:00
Goober5000 5840ca84d6 make sure getMissionFilename has a .fs2 extension 2018-08-17 16:47:51 -04:00
m!m aa0e1c755f Merge pull request #1825 from niffiwan/feature/qtfred_asteroid
qtfred asteroid editor
2018-08-17 13:37:26 +02:00
niffiwan 97469d65ef Merge pull request #1820 from asarium/build/updatedFFmpeg
Update prebuilt FFmpeg libraries to version 3.4.4
2018-08-17 19:24:11 +10:00
niffiwan 5834c01ca9 use UNREACHABLE macro in switch default:
addresses review feedback from m!m
2018-08-14 19:50:08 +10:00
niffiwan 13076364d6 Merge pull request #1714 from asarium/qtfred2_/linuxqtdeploy
Enable qtFRED for all deployments
2018-08-13 23:38:07 +10:00
niffiwan e2905e76ca fix clang-tidy (3): const auto & (!) ;) 2018-08-13 19:09:47 +10:00
niffiwan accea7bb4d fix clang-tidy warnings (2): const auto 2018-08-12 22:39:52 +10:00
niffiwan 733b67ada3 fix clang-tidy warnings
change CLAMP macro to use boolean rather than implicit conversion int
2018-08-12 21:42:11 +10:00
niffiwan de06d1e36f fix clang-tidy warnings (1)
add override to functions
convert to range based for loops
set default dtor
2018-08-12 21:40:47 +10:00
Fabian Woltermann 5b01036723 vm_vec_random_cone needs to be called with the smaller angle first.
This also adds a check to that function to swap the values around should that not be the case
2018-08-10 17:26:42 +02:00
asarium a737c7a373 Update prebuilt FFmpeg libraries to version 3.4.4
This should fix an issue with the playback speed of APNG files which is
present in the current builds. This does not include the Mac libraries
since I cannot compile the libraries for that platform.
2018-07-31 15:43:52 +02:00
asarium 7e399681cd Enable qtFRED for all deployments
This enabled qtFRED building for all deployments (releases, nightlies
and test builds). qtFRED is relatively stable now and should be
available for wider testing which may be provided by nightly builds.

This also adds AppImage support fot qtFRED although I still couldn't get
it to work entirely since there is some sort of libpng issue which
prevents icons from showing up correctly.
2018-04-24 14:57:52 +02:00
291 changed files with 14724 additions and 11846 deletions

No files matched your search

+1
View File
@@ -10,6 +10,7 @@ misc-*,\
-misc-macro-parentheses,\
-misc-misplaced-widening-cast,\
-misc-static-assert,\
-modernize-make-unique,\
"
WarningsAsErrors: ''
HeaderFilterRegex: 'code/.*$|freespace2/.*$|qtfred/.*$|test/src/.*$|build/.*$'
-3
View File
@@ -26,9 +26,6 @@
*.unsuccessfulbuild
ipch/
[Oo]bj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad
*.VC.db
*.VC.VC.opendb
+3
View File
@@ -1,3 +1,6 @@
[submodule "cmake/external/rpavlik-cmake-modules"]
path = cmake/external/rpavlik-cmake-modules
url = https://github.com/asarium/cmake-modules.git
[submodule "lib/libRocket"]
path = lib/libRocket
url = https://github.com/asarium/libRocket.git
+164 -140
View File
@@ -1,157 +1,181 @@
language: generic
language: bash
sudo: required
dist: trusty
cache:
directories:
directories:
- $HOME/cmake-3.8
- $HOME/.ccache
addons:
apt:
packages: &global_deps
- ninja-build
- libopenal-dev
- libreadline6-dev
- libpng12-dev
- libjpeg62-dev
- liblua5.1-0-dev
- libjansson-dev
- libsdl2-dev
- valgrind
- qt57base
coverity_scan:
project:
name: "scp-fs2open/fs2open.github.com"
notification_email: niffiwan.scp@gmail.com
build_command: "ci/travis/script.sh"
# must match TRAVIS_BRANCH check below
branch_pattern: coverity_scan
apt:
packages: &global_deps
- ninja-build
- libopenal-dev
- libreadline6-dev
- libpng12-dev
- libjpeg62-dev
- liblua5.1-0-dev
- libjansson-dev
- libsdl2-dev
- libfreetype6-dev
- valgrind
- qt57base
coverity_scan:
project:
name: "scp-fs2open/fs2open.github.com"
notification_email: [email protected]
build_command: "ci/travis/script.sh"
# must match TRAVIS_BRANCH check below
branch_pattern: coverity_scan
env:
global:
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
# also note that fork's don't get access to secure keys
# you have to test using a branch in the main repo
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
# These declarations set INDIEGAMES_USER and INDIEGAMES_PASSWORD for uploading nightly builds to the indiegames server
- secure: "lUuRu8XIi8MKNf1ebOfyC4iVEpPyASojJIDWXRo2bNqEF4ILAljXdkVeXeN6H5yKCHD52cxCNTtyePIG/o3p3QEuGSVud9bDS3D7LaQicLETGGrsw3l07U49gF2OKHXGopg0MzBbZUU9QmhoFTAe8t6PV9NDuEayYCheqvTqjZg="
- secure: "E/DHLYcPK/hBUqxBYYlUqp5sjgvIqY5A0qRHyQ4bmjsB+WB/Xx71bGCSiF7hk6lTxar1ZI1i5RAXXh9AIvNVaYAIdEOlCP+q3gvwCYuc5naZEKmkxlUCf0oEL4O9Fye93A/3VkFHuBdC1TGPYYf69m4W5r4367wWO9dPRIdWpJA="
# These declarations set FS2DOWNLOADS_USER and FS2DOWNLOADS_PASSWORD
- secure: "h6GbMX2jLsW1bS9fCM9fthOSJ1nfQQIRWi6EUH2p8u4NFLD5Bfi/C8JhQPKHUzyo3wvKkSHl+PsW7bgr1oXLusRwAur/dtv2N3imqvtbfIz305b00hZlsvbcYmQmUzQFSAdOGShK57JJ5aKQKccaUBP25KqB7Q+JaqBRdaMBS54="
- secure: "fUDAPAUUaaYZy8I4zU3SJ0JcK7aw4eb6eTdaEr7LyNyTMSfPgwY6P1MrbSQC0lJNQIUQ5ffjdxE5g7D7OYpoJF9L14ni4UY8t2QASt7kmpgcYihmjeuYy8FQXgmFG8CTxiWBPKTybZJ7voQcvIvRaNG7b2wM9PMfc5lRIondB6c="
global:
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
# also note that fork's don't get access to secure keys
# you have to test using a branch in the main repo
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
# These declarations set INDIEGAMES_USER and INDIEGAMES_PASSWORD for uploading nightly builds to the indiegames server
- secure: "lUuRu8XIi8MKNf1ebOfyC4iVEpPyASojJIDWXRo2bNqEF4ILAljXdkVeXeN6H5yKCHD52cxCNTtyePIG/o3p3QEuGSVud9bDS3D7LaQicLETGGrsw3l07U49gF2OKHXGopg0MzBbZUU9QmhoFTAe8t6PV9NDuEayYCheqvTqjZg="
- secure: "E/DHLYcPK/hBUqxBYYlUqp5sjgvIqY5A0qRHyQ4bmjsB+WB/Xx71bGCSiF7hk6lTxar1ZI1i5RAXXh9AIvNVaYAIdEOlCP+q3gvwCYuc5naZEKmkxlUCf0oEL4O9Fye93A/3VkFHuBdC1TGPYYf69m4W5r4367wWO9dPRIdWpJA="
# These declarations set FS2DOWNLOADS_USER and FS2DOWNLOADS_PASSWORD
- secure: "h6GbMX2jLsW1bS9fCM9fthOSJ1nfQQIRWi6EUH2p8u4NFLD5Bfi/C8JhQPKHUzyo3wvKkSHl+PsW7bgr1oXLusRwAur/dtv2N3imqvtbfIz305b00hZlsvbcYmQmUzQFSAdOGShK57JJ5aKQKccaUBP25KqB7Q+JaqBRdaMBS54="
- secure: "fUDAPAUUaaYZy8I4zU3SJ0JcK7aw4eb6eTdaEr7LyNyTMSfPgwY6P1MrbSQC0lJNQIUQ5ffjdxE5g7D7OYpoJF9L14ni4UY8t2QASt7kmpgcYihmjeuYy8FQXgmFG8CTxiWBPKTybZJ7voQcvIvRaNG7b2wM9PMfc5lRIondB6c="
deploy:
- provider: releases
api_key:
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
skip_cleanup: true
file_glob: true
file: "/tmp/builds/*"
on:
condition: '"$RELEASE_BUILD" == true'
tags: true
- provider: releases
api_key:
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
skip_cleanup: true
file_glob: true
file: "/tmp/builds/*"
on:
condition: '"$RELEASE_BUILD" == true'
tags: true
- provider: script
script: bash ci/travis/ftp_deploy.sh
on:
condition: '"$NIGHTLY_BUILD" == true'
tags: true
- provider: script
script: bash ci/travis/ftp_deploy.sh
on:
condition: '"$NIGHTLY_BUILD" == true'
tags: true
- provider: script
skip_cleanup: true
script: bash ci/travis/ftp_deploy.sh
on:
condition: $TEST_BUILD = true
all_branches: true
- provider: script
skip_cleanup: true
script: bash ci/travis/ftp_deploy.sh
on:
condition: $TEST_BUILD = true
all_branches: true
matrix:
include:
# note that gcc Debug MUST be 1st for Coverity
- os: linux
env: CONFIGURATION="Debug" CC=gcc-5 CXX=g++-5
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- g++-5
- os: linux
env: CONFIGURATION="Debug" CC=gcc-8 CXX=g++-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- g++-8
- *global_deps
- os: linux
env: CONFIGURATION="Debug" CC=clang-4.0 CXX=clang++-4.0 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- clang-4.0
- clang-tidy-4.0
- libc++-dev
script:
- ./ci/travis/script.sh
- ./ci/travis/clang_tidy.sh
- os: osx
env: CONFIGURATION="Debug"
include:
# note that gcc Debug MUST be 1st for Coverity
- os: linux
env: CONFIGURATION="Debug" CC=gcc-5 CXX=g++-5
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- g++-5
- os: linux
env: CONFIGURATION="Debug" CC=gcc-8 CXX=g++-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- g++-8
- *global_deps
- os: linux
env: CONFIGURATION="Debug" CC=clang-4.0 CXX=clang++-4.0 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- clang-4.0
- clang-tidy-4.0
- libc++-dev
script:
- ./ci/travis/script.sh
- ./ci/travis/clang_tidy.sh
- os: osx
env: CONFIGURATION="Debug"
- os: windows
env: CONFIGURATION="Debug" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
- os: linux
env: CONFIGURATION="Release" CC=gcc-5 CXX=g++-5
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- g++-5
- os: linux
env: CONFIGURATION="Release" CC=gcc-8 CXX=g++-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- g++-8
- *global_deps
- os: linux
env: CONFIGURATION="Release" CC=clang-4.0 CXX=clang++-4.0
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- clang-4.0
- libc++-dev
- os: osx
env: CONFIGURATION="Release"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
# As long as Windows is still experimental on Travis CI, allow failures
allow_failures:
- os: windows
env: CONFIGURATION="Debug" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
fast_finish: true
- os: linux
env: CONFIGURATION="Release" CC=gcc-5 CXX=g++-5
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- g++-5
- os: linux
env: CONFIGURATION="Release" CC=gcc-8 CXX=g++-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- g++-8
- *global_deps
- os: linux
env: CONFIGURATION="Release" CC=clang-4.0 CXX=clang++-4.0
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- sourceline: 'ppa:beineri/opt-qt571-trusty'
packages:
- *global_deps
- clang-4.0
- libc++-dev
- os: osx
env: CONFIGURATION="Release"
before_install:
# ugly hack; if running a coverity scan abort all except the 1st build
# see note re gcc compiler above needing to be 1st
# also note that branch_pattern & the TRAVIS_BRANCH check must match
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
# build process
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
- source "./ci/travis/check_release.sh"
- "./ci/travis/before_install.sh"
# ugly hack; if running a coverity scan abort all except the 1st build
# see note re gcc compiler above needing to be 1st
# also note that branch_pattern & the TRAVIS_BRANCH check must match
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
# build process
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
- source "./ci/travis/check_release.sh"
- "./ci/travis/before_install.sh"
install:
- "./ci/travis/install.sh"
- export PATH=$HOME/cmake-3.6/bin:$PATH
- if [ "$TRAVIS_OS_NAME" = "windows" ]; then export PATH="/c/Program Files/CMake/bin":$PATH; fi
- "./ci/travis/install.sh"
- export PATH=$HOME/cmake-3.6/bin:$PATH
before_script:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then QT_ENV_SCRIPT=$(find /opt -name 'qt*-env.sh'); source $QT_ENV_SCRIPT; fi
- "./ci/travis/before_script.sh"
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then QT_ENV_SCRIPT=$(find /opt -name 'qt*-env.sh'); source $QT_ENV_SCRIPT; fi
- "./ci/travis/before_script.sh"
script:
- if [ "$BUILD_DEPLOYMENT" = true ] ; then ./ci/travis/release.sh ; else ./ci/travis/script.sh ; fi
- if [ "$BUILD_DEPLOYMENT" = true ] ; then ./ci/travis/release.sh ; else ./ci/travis/script.sh ; fi
-1
View File
@@ -84,7 +84,6 @@ IF (WIN32)
OPTION(FSO_BUILD_FRED2 "Build FRED2 binary" ON)
elseif(UNIX)
option(FSO_BUILD_APPIMAGE "Build an AppImage package" OFF)
set(APPIMAGE_ASSISTANT "" CACHE STRING "The root directory of an AppImage clone.")
ENDIF(WIN32)
OPTION(FSO_BUILD_TOOLS "Build tools related to FSO" OFF)
+1
View File
@@ -133,6 +133,7 @@ if ($DeployBuild) {
cmake -DCMAKE_INSTALL_PREFIX="$env:APPVEYOR_BUILD_FOLDER/../install" -DFSO_USE_SPEECH="ON" `
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$($buildConfig.SimdType)" `
-DQT5_INSTALL_ROOT="$($buildConfig.QtDir)" -DFSO_BUILD_QTFRED=ON `
-G "$($buildConfig.Generator)" -T "$($buildConfig.Toolset)" ..
$Configs = @("Release", "FastDebug")
+3
View File
@@ -8,4 +8,7 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
# Nothing to do here
:
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
# Nothing to do here
:
fi
+18 -7
View File
@@ -2,15 +2,19 @@
set -ex
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
mkdir -p /tmp/builds
if [ "$RELEASE_BUILD" = true ]; then
# Package the source code in release builds
PARENT_DIR="$(basename "$PWD")"
(cd .. && tar -czvf /tmp/builds/$PACKAGE_NAME-source-Unix.tar.gz --exclude-vcs "$PARENT_DIR")
fi
fi
mkdir -p build
cd build
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ "$RELEASE_BUILD" = true ]; then
PARENT_DIR="$(basename $PWD)"
(cd .. && tar -czvf /tmp/builds/$PACKAGE_NAME-source-Unix.tar.gz --exclude-vcs "$PARENT_DIR")
fi
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
@@ -27,8 +31,7 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
mkdir -p $config
cd $config
eval $CMAKE -DFSO_INSTALL_DEBUG_FILES=ON -DCMAKE_BUILD_TYPE=$config -DCMAKE_INSTALL_PREFIX="/tmp/release/$config" \
-DFSO_BUILD_APPIMAGE=ON -DAPPIMAGE_ASSISTANT="$HOME/AppImageAssistant" \
-DFSO_BUILD_INCLUDED_LIBS=ON -DFFMPEG_USE_PRECOMPILED=ON ../..
-DFSO_BUILD_APPIMAGE=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_QTFRED=OFF ../..
cd ..
done
else
@@ -40,4 +43,12 @@ elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
else
cmake -G "Xcode" $CMAKE_OPTIONS ..
fi
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
if [ "$CMAKE_GENERATOR" = "Ninja" ]; then
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
-DFSO_BUILD_FRED2="OFF" -G "$CMAKE_GENERATOR" ..
else
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "$CMAKE_GENERATOR" -T "$CMAKE_TOOLSET" ..
fi
fi
+5
View File
@@ -58,6 +58,11 @@ if [ "$BUILD_DEPLOYMENT" = true ]; then
echo "Skipping non-release configuration";
exit 0;
fi
if [ "$TRAVIS_OS_NAME" = "windows" ]; then
echo "Skipping non-release platform"
exit 0
fi
fi
export RELEASE_BUILD
+7 -2
View File
@@ -16,14 +16,19 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
cd $HOME
if [ "${BUILD_DEPLOYMENT}" = true ]; then
wget -c "https://github.com/probonopd/AppImageKit/releases/download/5/AppImageAssistant" # (64-bit)
chmod a+x ./AppImageAssistant
wget -O appimagetool -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" # (64-bit)
chmod a+x ./appimagetool
wget -O linuxdeployqt -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" # (64-bit)
chmod a+x ./linuxdeployqt
fi
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
gem install xcpretty
brew update
brew outdated cmake || brew upgrade cmake
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
choco install mingw ninja
fi
cmake --version
+34 -1
View File
@@ -8,7 +8,40 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
for config in $BUILD_CONFIGS
do
cd "$config"
ninja appimage
# Compile all targets
ninja all
# Install Freespace2 targets
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/fso -DCOMPONENT=Unspecified -P cmake_install.cmake
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/fso -DCOMPONENT=Freespace2 -P cmake_install.cmake
# We need to be a bit creative for determining the AppImage name since we don't want to hard-code the name
FILENAME="$(find /tmp/release/$config/fso/bin -name 'fs2_open_*' -type f -printf "%f\n").AppImage"
$HOME/appimagetool -n /tmp/release/$config/fso "/tmp/release/$config/fso/$FILENAME"
: <<'END'
# Install qtFRED targets
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/qtfred/usr -DCOMPONENT=Unspecified -P cmake_install.cmake
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/qtfred/usr -DCOMPONENT=qtFRED -P cmake_install.cmake
PREV="$(pwd)"
cd /tmp/release/$config/qtfred
unset QTDIR; unset QT_PLUGIN_PATH; unset LD_LIBRARY_PATH
$HOME/linuxdeployqt usr/qtfred.desktop -bundle-non-qt-libs
# Move our AppRun script to the right location
mv usr/AppRun AppRun
echo "Embed newer libstdc++ for distros that don't come with it (ubuntu 14.04)";
mkdir -p usr/optional/; mkdir -p usr/optional/libstdc++/;
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 ./usr/optional/libstdc++/;
$HOME/appimagetool -n . "$(find /tmp/release/$config/qtfred/usr/bin -name 'qtfred_*' -type f -printf "%f\n").AppImage"
cd "$PREV"
END
cd ..
done
+6
View File
@@ -22,4 +22,10 @@ elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
curl --upload-file build.log.tar.gz "https://transfer.sh/build.log.tar.gz"
exit $XCODE_RET
fi
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
if [ "$CMAKE_GENERATOR" = "Ninja" ]; then
cmake --build . --config "$CONFIGURATION"
else
cmake --build . --config "$CONFIGURATION" -- /verbosity:minimal
fi
fi
+7
View File
@@ -34,3 +34,10 @@
fun:lua_rawget
fun:_ZN12_GLOBAL__N_117ade_index_handlerEP9lua_State
}
{
False-positive uninitialized variable warning
Memcheck:Cond
fun:_Z23cf_check_location_flagsjj
fun:_Z29cf_create_default_path_stringPcjiPKcbj
...
}
+3 -1
View File
@@ -1,4 +1,6 @@
[Desktop Entry]
Type=Application
Name=FreeSpace Open
Exec=$<TARGET_FILE_NAME:Freespace2>
Icon=app_icon.png
Icon=app_icon
Categories=Game;
+6 -8
View File
@@ -6,18 +6,16 @@ configure_file("${CMAKE_CURRENT_LIST_DIR}/AppRun.in" "${CMAKE_CURRENT_BINARY_DIR
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/AppRun.gen")
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>" DESTINATION "." RENAME "AppRun")
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>" DESTINATION "." RENAME "AppRun"
COMPONENT "Freespace2")
configure_file("${CMAKE_CURRENT_LIST_DIR}/AppImage.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/AppImage.desktop.gen" @ONLY)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/AppImage.desktop.gen")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop" DESTINATION "." RENAME "fso.desktop")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop" DESTINATION "." RENAME "fso.desktop"
COMPONENT "Freespace2")
install(FILES "${CMAKE_SOURCE_DIR}/freespace2/resources/app_icon.png" DESTINATION ".")
add_custom_target(appimage
COMMAND "${APPIMAGE_ASSISTANT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/fs2_open_${FSO_BINARY_SUFFIX}.AppImage")
add_dependencies(appimage install)
install(FILES "${CMAKE_SOURCE_DIR}/freespace2/resources/app_icon.png" DESTINATION "."
COMPONENT "Freespace2")
+4 -3
View File
@@ -36,6 +36,7 @@ set(WARNING_FLAGS
/wd4592 # "symbol will be dynamically initialized" is being generated by a compiler bug, see https://stackoverflow.com/a/34027257 for an explanation - m!m
$<$<CONFIG:Release>:/wd4101> # In release mode there are unreferenced variables because debug needs them
/wd4995 # "'vsprintf': name was marked as #pragma deprecated" is being caused by our custom definition of vsprintf. I have no idea what causes this or how to fix it - m!m
/wd4723 # "potential divide by 0" is caused by some code that definitely will not divide by zero - m!m
)
target_compile_options(compiler INTERFACE ${WARNING_FLAGS})
@@ -135,9 +136,9 @@ else()
ENDIF()
endif()
target_compile_definitions(compiler INTERFACE _CRT_SECURE_NO_DEPRECATE
_CRT_SECURE_NO_WARNINGS _SECURE_SCL=0 NOMINMAX "$<$<CONFIG:FastDebug>:_ITERATOR_DEBUG_LEVEL=0>")
target_compile_definitions(compiler INTERFACE _CRT_SECURE_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS _SECURE_SCL=0 NOMINMAX
"$<$<CONFIG:FastDebug>:_ITERATOR_DEBUG_LEVEL=0>" _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
if (FSO_FATAL_WARNINGS)
# Make warnings fatal if the right variable is set
target_compile_options(compiler INTERFACE "/WX")
+2
View File
@@ -39,6 +39,8 @@ target_link_libraries(code PUBLIC md5)
target_link_libraries(code PUBLIC discord-rpc)
target_link_libraries(code PUBLIC libRocket)
enable_clang_tidy(code)
IF (FSO_USE_SPEECH)
+1
View File
@@ -87,6 +87,7 @@ namespace AI {
Fix_heat_seeker_stealth_bug,
Fix_linked_primary_bug,
Force_beam_turret_fov,
Free_afterburner_use,
Glide_decay_requires_thrust,
Hack_improve_non_homing_swarm_turret_fire_accuracy,
Huge_turret_weapons_ignore_bombs,
+2
View File
@@ -357,6 +357,8 @@ void parse_ai_profiles_tbl(const char *filename)
set_flag(profile, "$smart afterburner management:", AI::Profile_Flags::Smart_afterburner_management);
set_flag(profile, "$free afterburner use:", AI::Profile_Flags::Free_afterburner_use);
set_flag(profile, "$allow rapid secondary dumbfire:", AI::Profile_Flags::Allow_rapid_secondary_dumbfire);
set_flag(profile, "$huge turret weapons ignore bombs:", AI::Profile_Flags::Huge_turret_weapons_ignore_bombs);
+2 -2
View File
@@ -642,7 +642,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
accelerate_ship(aip, 1.0f);
ship *shipp = &Ships[Pl_objp->instance];
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (dot_to_enemy > 0.75f)) {
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (dot_to_enemy > 0.75f)) {
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
afterburners_start(Pl_objp);
aip->afterburner_stop_time = Missiontime + 3*F1_0;
@@ -684,7 +684,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
accelerate_ship(aip, accel);
ship *shipp = &Ships[Pl_objp->instance];
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel > 0.95f)) {
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel > 0.95f)) {
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
afterburners_start(Pl_objp);
aip->afterburner_stop_time = Missiontime + 3*F1_0;
+8 -6
View File
@@ -745,6 +745,8 @@ void parse_ai_class()
set_aic_flag(aicp, "$smart afterburner management:", AI::Profile_Flags::Smart_afterburner_management);
set_aic_flag(aicp, "$free afterburner use:", AI::Profile_Flags::Free_afterburner_use);
set_aic_flag(aicp, "$allow rapid secondary dumbfire:", AI::Profile_Flags::Allow_rapid_secondary_dumbfire);
set_aic_flag(aicp, "$huge turret weapons ignore bombs:", AI::Profile_Flags::Huge_turret_weapons_ignore_bombs);
@@ -1791,7 +1793,7 @@ float get_wing_lowest_av_ab_speed(object *objp)
wingnum = aip->wing;
if (((shipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(sip->flags[Ship::Info_Flags::Afterburner])) || (shipp->current_max_speed < 5.0f) || (objp->phys_info.afterburner_max_vel.xyz.z <= shipp->current_max_speed) || !(aip->ai_flags[AI::AI_Flags::Free_afterburner_use])) {
if (((shipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(sip->flags[Ship::Info_Flags::Afterburner])) || (shipp->current_max_speed < 5.0f) || (objp->phys_info.afterburner_max_vel.xyz.z <= shipp->current_max_speed) || !(aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) {
lowest_max_av_ab_speed = shipp->current_max_speed;
}
else
@@ -1816,7 +1818,7 @@ float get_wing_lowest_av_ab_speed(object *objp)
if ((oaip->mode == AIM_WAYPOINTS) && (oaip->wing == wingnum) && (oaip->ai_flags[AI::AI_Flags::Formation_object, AI::AI_Flags::Formation_wing])) {
float cur_max;
if ((oshipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(osip->flags[Ship::Info_Flags::Afterburner]) || (o->phys_info.afterburner_max_vel.xyz.z <= oshipp->current_max_speed) || !(oaip->ai_flags[AI::AI_Flags::Free_afterburner_use])) {
if ((oshipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(osip->flags[Ship::Info_Flags::Afterburner]) || (o->phys_info.afterburner_max_vel.xyz.z <= oshipp->current_max_speed) || !(oaip->ai_flags[AI::AI_Flags::Free_afterburner_use] || oaip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) {
cur_max = oshipp->current_max_speed;
}
else
@@ -4413,7 +4415,7 @@ void ai_fly_to_target_position(vec3d* target_pos, bool* pl_done_p=NULL, bool* pl
ab_allowed = false;
}
if (!(sip->flags[Ship::Info_Flags::Afterburner]) || (shipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(aip->ai_flags[AI::AI_Flags::Free_afterburner_use])) {
if (!(sip->flags[Ship::Info_Flags::Afterburner]) || (shipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) {
ab_allowed = false;
}
@@ -9943,7 +9945,7 @@ void ai_big_guard()
ai_turn_towards_vector(&goal_pt, Pl_objp, Ship_info[Ships[Pl_objp->instance].ship_info_index].srotation_time, nullptr, nullptr, 0.0f, 0);
accelerate_ship(aip, 1.0f);
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (cur_guard_rad > 1.1f * max_guard_dist)) {
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (cur_guard_rad > 1.1f * max_guard_dist)) {
vec3d v2g;
float dot_to_goal_point;
@@ -10066,7 +10068,7 @@ void ai_guard()
compute_desired_rvec(&rvec, &goal_point, &Pl_objp->pos);
ai_turn_towards_vector(&goal_point, Pl_objp, Ship_info[shipp->ship_info_index].srotation_time, nullptr, nullptr, 0.0f, 0, &rvec);
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel_scale * (0.25f + dist_to_goal_point/700.0f) > 0.8f)) {
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel_scale * (0.25f + dist_to_goal_point/700.0f) > 0.8f)) {
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
afterburners_start(Pl_objp);
aip->afterburner_stop_time = Missiontime + 3*F1_0;
@@ -11784,7 +11786,7 @@ int ai_formation()
ship_info *sip = &Ship_info[shipp->ship_info_index];
bool ab_allowed = false;
if ((sip->flags[Ship::Info_Flags::Afterburner]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (aip->ai_flags[AI::AI_Flags::Free_afterburner_use])) {
if ((sip->flags[Ship::Info_Flags::Afterburner]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) {
ab_allowed = true;
} else {
if (Pl_objp->phys_info.flags & PF_AFTERBURNER_ON)
+3 -3
View File
@@ -1874,7 +1874,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
turret->last_fired_weapon_info_index = turret_weapon_class;
Script_system.SetHookObjects(4, "Ship", &Objects[parent_objnum], "Weapon", nullptr, "Beam", objp, "Target", &Objects[turret->turret_enemy_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[parent_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[parent_objnum]);
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
}
@@ -2009,7 +2009,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
wp->turret_subsys = turret;
Script_system.SetHookObjects(4, "Ship", &Objects[parent_objnum], "Weapon", objp, "Beam", nullptr, "Target", &Objects[turret->turret_enemy_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[parent_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[parent_objnum]);
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
// if the gun is a flak gun
@@ -2126,7 +2126,7 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
tsi->turret->last_fired_weapon_info_index = tsi->weapon_class;
Script_system.SetHookObjects(4, "Ship", &Objects[tsi->parent_objnum], "Weapon", &Objects[weapon_objnum], "Beam", nullptr, "Target", &Objects[tsi->turret->turret_enemy_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[tsi->parent_objnum]);
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[tsi->parent_objnum]);
Script_system.RemHookVars(4, "Ship", "Weapon", "Beam", "Target");
// muzzle flash?
+1 -1
View File
@@ -1547,7 +1547,7 @@ static void asteroid_maybe_break_up(object *pasteroid_obj)
}
asp->final_death_time = timestamp(-1);
}
Script_system.RunCondition(CHA_DEATH, '\0', NULL, pasteroid_obj);
Script_system.RunCondition(CHA_DEATH, pasteroid_obj);
Script_system.RemHookVar("Self");
}
}
+1
View File
@@ -1892,6 +1892,7 @@ int bm_load_sub_slow(const char *real_filename, const int num_ext, const char **
}
// umm, that's not good...
Warning(LOCATION, "Could not open file %s!", res.full_name.c_str());
return -1;
}
+1 -1
View File
@@ -962,7 +962,7 @@ size_t cam_get_num()
/**
* Looks up camera by name, returns -1 on failure
*/
camid cam_lookup(char *name)
camid cam_lookup(const char* name)
{
size_t i, size=Cameras.size();
for(i = 0; i < size; i++)
+2 -2
View File
@@ -68,7 +68,7 @@ public:
void set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time = 0.0f);
//Get
char *get_name() {return name;}
const char* get_name() { return name; }
int get_signature() {return sig;}
object *get_object_host();
int get_object_host_submodel();
@@ -163,7 +163,7 @@ camid cam_create(const char *n_name, vec3d *n_pos, vec3d *n_norm, object *n_obje
void cam_delete(camid cid);
bool cam_set_camera(camid cid);
void cam_reset_camera();
camid cam_lookup(char *name);
camid cam_lookup(const char* name);
camid cam_get_camera(uint index);
camid cam_get_current();
size_t cam_get_num();
+47 -2
View File
@@ -77,8 +77,8 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_PLAYERS, "data" DIR_SEPARATOR_STR "players", ".hcf", CF_TYPE_DATA },
{ CF_TYPE_PLAYER_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "images", ".pcx .png .dds", CF_TYPE_PLAYERS },
{ CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .png .dds", CF_TYPE_PLAYERS },
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css", CF_TYPE_PLAYERS },
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr", CF_TYPE_PLAYERS },
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css .json", CF_TYPE_PLAYERS },
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr .json", CF_TYPE_PLAYERS },
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .bx", CF_TYPE_DATA }, //clr=cached color
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .png .dds .fs2 .txt", CF_TYPE_DATA },
{ CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA },
@@ -89,6 +89,8 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc", CF_TYPE_DATA },
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
{ CF_TYPE_FREDDOCS, "data" DIR_SEPARATOR_STR "freddocs", ".html", CF_TYPE_DATA },
{ CF_TYPE_INTERFACE_MARKUP, "data" DIR_SEPARATOR_STR "interface" DIR_SEPARATOR_STR "markup", ".rml", CF_TYPE_INTERFACE },
{ CF_TYPE_INTERFACE_CSS, "data" DIR_SEPARATOR_STR "interface" DIR_SEPARATOR_STR "css", ".rcss", CF_TYPE_INTERFACE },
};
// clang-format on
@@ -1348,6 +1350,19 @@ void cfread_string_len(char *buf,int n, CFILE *file)
buf[len] = 0;
}
SCP_string cfread_string_len(CFILE *file)
{
int len = cfread_int(file);
SCP_string str;
str.resize(len);
if (len)
cfread(&str[0], len, 1, file);
return str;
}
// equivalent write functions of above read functions follow
int cfwrite_float(float f, CFILE *file)
@@ -1961,3 +1976,33 @@ int cflush(CFILE *cfile)
return result;
}
int cfile_get_path_type(const SCP_string& dir)
{
SCP_string buf = dir;
// Remove trailing slashes; avoid buffer overflow on 1-char strings
while (buf.size() > 0 && (buf[buf.size() - 1] == '\\' || buf[buf.size() - 1] == '/')) {
buf.resize(buf.size() - 1);
}
// Remove leading slashes
while (buf.size() > 0 && (buf[0] == '\\' || buf[0] == '/')) {
buf = buf.substr(1);
}
// Use official DIR_SEPARATOR_CHAR
for (char& c : buf) {
if (c == '\\' || c == '/') {
c = DIR_SEPARATOR_CHAR;
}
}
for (auto& Pathtype : Pathtypes) {
if (Pathtype.path != nullptr && buf == Pathtype.path) {
return Pathtype.index;
}
}
return CF_TYPE_INVALID;
}
+13 -2
View File
@@ -79,9 +79,11 @@ typedef struct {
#define CF_TYPE_SCRIPTS 35
#define CF_TYPE_FICTION 36
#define CF_TYPE_FREDDOCS 37
#define CF_TYPE_INTERFACE_MARKUP 38
#define CF_TYPE_INTERFACE_CSS 39
#define CF_MAX_PATH_TYPES 38 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
#define CF_MAX_PATH_TYPES \
40 // 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))
@@ -343,6 +345,13 @@ void cfread_string(char *buf,int n, CFILE *file);
*/
void cfread_string_len(char *buf,int n, CFILE *file);
/**
* @brief Read a string from the file where the length is stored in the file
* @param file The file to read the string from
* @return The string that was read
*/
SCP_string cfread_string_len(CFILE *file);
// functions for writing cfiles
int cfwrite_char(char c, CFILE *file);
int cfwrite_float(float f, CFILE *file);
@@ -434,6 +443,8 @@ int cfile_push_chdir(int type);
// restore directory on top of the stack
int cfile_pop_dir();
int cfile_get_path_type(const SCP_string& dir);
namespace cfile
{
// exceptions and other errors
-9
View File
@@ -232,7 +232,6 @@ Flag exe_params[] =
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fullscreen_window", },
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
{ "-pofspew", "Generate all ibx files immediately", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
{ "-tablecrcs", "Dump table CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
{ "-missioncrcs", "Dump mission CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
@@ -247,7 +246,6 @@ Flag exe_params[] =
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
{ "-benchmark_mode", "Puts the game into benchmark mode", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-benchmark_mode", },
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
{ "-json_pilot", "Dump pilot files in JSON format", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-json_pilot", },
{ "-json_profiling", "Generate JSON profiling output", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-json_profiling", },
{ "-profile_frame_time","Profile engine subsystems", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_timings", },
{ "-debug_window", "Enable the debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
@@ -490,7 +488,6 @@ cmdline_parm frame_profile_write_file("-profile_write_file", NULL, AT_NONE); //
cmdline_parm no_unfocused_pause_arg("-no_unfocused_pause", NULL, AT_NONE); //Cmdline_no_unfocus_pause
cmdline_parm benchmark_mode_arg("-benchmark_mode", NULL, AT_NONE); //Cmdline_benchmark_mode
cmdline_parm noninteractive_arg("-noninteractive", NULL, AT_NONE); //Cmdline_noninteractive
cmdline_parm json_pilot("-json_pilot", NULL, AT_NONE); //Cmdline_json_pilot
cmdline_parm json_profiling("-json_profiling", NULL, AT_NONE); //Cmdline_json_profiling
cmdline_parm show_video_info("-show_video_info", NULL, AT_NONE); //Cmdline_show_video_info
cmdline_parm frame_profile_arg("-profile_frame_time", NULL, AT_NONE); //Cmdline_frame_profile
@@ -521,7 +518,6 @@ bool Cmdline_profile_write_file = false;
bool Cmdline_no_unfocus_pause = false;
bool Cmdline_benchmark_mode = false;
bool Cmdline_noninteractive = false;
bool Cmdline_json_pilot = false;
bool Cmdline_json_profiling = false;
bool Cmdline_frame_profile = false;
bool Cmdline_show_video_info = false;
@@ -2088,11 +2084,6 @@ bool SetCmdlineParams()
Cmdline_noninteractive = true;
}
if (json_pilot.found())
{
Cmdline_json_pilot = true;
}
if (json_profiling.found())
{
Cmdline_json_profiling = true;
-1
View File
@@ -156,7 +156,6 @@ extern bool Cmdline_profile_write_file;
extern bool Cmdline_no_unfocus_pause;
extern bool Cmdline_benchmark_mode;
extern bool Cmdline_noninteractive;
extern bool Cmdline_json_pilot;
extern bool Cmdline_json_profiling;
extern bool Cmdline_frame_profile;
extern bool Cmdline_show_video_info;
+2 -2
View File
@@ -2345,7 +2345,7 @@ int check_control(int id, int key)
// which has just been released
Script_system.SetHookVar("Action", 's', Control_config[id].text);
Script_system.RunCondition(CHA_ONACTIONSTOPPED, '\0', NULL, NULL, id);
Script_system.RunCondition(CHA_ONACTIONSTOPPED, nullptr, id);
Script_system.RemHookVar("Action");
Control_config[id].continuous_ongoing = false;
@@ -2419,7 +2419,7 @@ void control_used(int id)
if (Control_config[id].used < Last_frame_timestamp) {
if (!Control_config[id].continuous_ongoing) {
Script_system.SetHookVar("Action", 's', Control_config[id].text);
Script_system.RunCondition(CHA_ONACTION, '\0', NULL, NULL, id);
Script_system.RunCondition(CHA_ONACTION, nullptr, id);
Script_system.RemHookVar("Action");
if (Control_config[id].type == CC_TYPE_CONTINUOUS)
+17 -7
View File
@@ -314,6 +314,11 @@ std::unique_ptr<DecoderStatus> initializeStatus(std::unique_ptr<InputStream>& st
status->videoCodecPars = getCodecParameters(status->videoStream);
if (properties.looping && status->videoCodecPars.codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) {
mprintf(("FFmpeg: Looping is not supported for inteplay (MVE) movies!\n"));
return nullptr;
}
int err;
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(57, 24, 255)
status->videoCodecCtx = avcodec_alloc_context3(status->videoCodec);
@@ -448,7 +453,7 @@ bool FFMPEGDecoder::initialize(const SCP_string& fileName, const PlaybackPropert
{
SCP_string movieName = fileName;
// First make the file name lower case
std::transform(movieName.begin(), movieName.end(), movieName.begin(), ::tolower);
std::transform(movieName.begin(), movieName.end(), movieName.begin(), [](char c) { return (char)::tolower(c); });
// Then remove the extension
size_t dotPos = movieName.find('.');
@@ -518,13 +523,18 @@ void FFMPEGDecoder::startDecoding() {
auto ctx = m_input->m_ctx->ctx();
AVPacket packet;
do {
auto seek_err = av_seek_frame(ctx, -1, 0, AVSEEK_FLAG_BACKWARD);
if (seek_err < 0) {
char errorStr[512];
av_strerror(seek_err, errorStr, sizeof(errorStr));
mprintf(("FFMPEG: Failed to seek to start of movie file! Error: %s\n", errorStr));
break;
if (m_properties.looping) {
// Only seek if we are looping the movie. The MVE code doesn't support seeking to this function may not be
// called there
auto seek_err = av_seek_frame(ctx, -1, 0, AVSEEK_FLAG_BACKWARD);
if (seek_err < 0) {
char errorStr[512];
av_strerror(seek_err, errorStr, sizeof(errorStr));
mprintf(("FFMPEG: Failed to seek to start of movie file! Error: %s\n", errorStr));
break;
}
}
videoDecoder->flushBuffers();
if (audioDecoder) {
audioDecoder->flushBuffers();
+20 -13
View File
@@ -44,21 +44,11 @@ struct PlaybackState {
int subtitle_font = -1;
};
void processEvents(PlaybackState* state) {
void processEvents()
{
io::mouse::CursorManager::get()->showCursor(false);
os_poll();
int k = key_inkey();
switch (k) {
case KEY_ESC:
case KEY_ENTER:
case KEY_SPACEBAR:
state->playing = false;
break;
default:
break;
}
}
template<typename... Args>
@@ -193,6 +183,21 @@ void movie_display_loop(Player* player, PlaybackState* state) {
// We will sleep at most half the time a frame would be displayed
auto sleepTime = static_cast<std::uint64_t>((1. / (4. * player->getMovieProperties().fps)) * 1000.);
auto listener = [state](const SDL_Event& event) {
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_KP_ENTER:
case SDLK_RETURN:
case SDLK_SPACE:
state->playing = false;
return true;
default:
return false;
}
};
// Use a dedicated listener here since we want to listen for the KEYUP event
auto key_handle = os::events::addEventListener(SDL_KEYUP, os::events::DEFAULT_LISTENER_WEIGHT - 10, listener);
auto lastDisplayTimestamp = timer_get_microseconds();
while (state->playing) {
TRACE_SCOPE(tracing::CutsceneStep);
@@ -209,7 +214,7 @@ void movie_display_loop(Player* player, PlaybackState* state) {
displayVideo(player, state);
}
processEvents(state);
processEvents();
if (passed < sleepTime) {
auto sleep = sleepTime - passed;
@@ -217,6 +222,8 @@ void movie_display_loop(Player* player, PlaybackState* state) {
os_sleep(static_cast<uint>(sleep));
}
}
os::events::removeEventListener(key_handle);
}
}
+8 -4
View File
@@ -24,11 +24,15 @@ void main()
// Now we compute the depth value in projection space using the clipping plane information
float view_depth = 2.0 * zNear * zFar / (zFar + zNear - depth_normalized * (zFar - zNear));
// This is the same formula that is also used by the main shader
float fog_dist = isinf(view_depth) ? 1.0 : clamp((view_depth - fog_start) * 0.75 * fog_scale, 0.0, 1.0);
if (isinf(view_depth)) {
fragOut0.rgb = color_in.rgb;
} else {
// This is the same formula that is also used by the main shader
float fog_dist = clamp((view_depth - fog_start) * 0.75 * fog_scale, 0.0, 1.0);
vec3 finalFogColor = srgb_to_linear(fog_color);
vec3 finalFogColor = srgb_to_linear(fog_color);
fragOut0.rgb = mix(color_in.rgb, finalFogColor, fog_dist);
fragOut0.rgb = mix(color_in.rgb, finalFogColor, fog_dist);
}
fragOut0.a = 1.0;
}
+15 -6
View File
@@ -280,11 +280,11 @@ void main()
}
if(gammaSpec) {
specColor.rgb = max(specColor.rgb, vec3(0.03f)); // hardcoded minimum specular value. read John Hable's blog post titled 'Everything Is Shiny'.
#ifdef FLAG_HDR
specColor.rgb = srgb_to_linear(specColor.rgb);
#endif
fresnelFactor = 1.0;
}
#ifdef FLAG_HDR
specColor.rgb = srgb_to_linear(specColor.rgb);
#endif
#endif
baseColor.rgb *= aoFactors.y;
specColor.rgb *= aoFactors.y;
@@ -292,20 +292,29 @@ void main()
#ifdef FLAG_TEAMCOLOR
vec4 teamMask = vec4(0.0, 0.0, 0.0, 0.0);
teamMask = texture(sMiscmap, vec3(texCoord, float(sMiscmapIndex)));
//For team colors applied to a diffuse or spec map, we assume that the base color of the diffuse
//at this point is vec3(0.5). To get accurate results, we subtract 0.5 from the team colors
vec3 team_color = ((base_color - vec3(0.5)) * teamMask.x) + ((stripe_color - vec3(0.5)) * teamMask.y);
vec3 color_offset = vec3(-0.5) * (teamMask.x + teamMask.y);
vec3 team_color = base_color * teamMask.x + stripe_color * teamMask.y + color_offset;
vec3 team_color_glow = (base_color * teamMask.b) + (stripe_color * teamMask.a);
#ifdef FLAG_HDR
team_color = srgb_to_linear(team_color);
team_color_glow = srgb_to_linear(team_color_glow) * GLOW_MAP_SRGB_MULTIPLIER;
baseColor.rgb = linear_to_srgb(baseColor.rgb);
specColor.rgb = linear_to_srgb(specColor.rgb);
#endif
baseColor.rgb += team_color;
baseColor.rgb = max(baseColor.rgb, vec3(0.0)); // We need to make sure that nothing here ever goes negative
specColor.rgb += team_color;
specColor.rgb = max(specColor.rgb, vec3(0.03));
#ifdef FLAG_HDR
baseColor.rgb = srgb_to_linear(baseColor.rgb);
specColor.rgb = srgb_to_linear(specColor.rgb);
#endif
#endif
#endif
// Lights aren't applied when we are rendering to the G-buffers since that gets handled later
@@ -0,0 +1,17 @@
in vec2 fragTexCoord;
in vec4 fragColor;
out vec4 fragOut0;
uniform bool textured;
uniform sampler2DArray baseMap;
uniform int baseMapIndex;
void main() {
if (textured) {
fragOut0 = texture(baseMap, vec3(fragTexCoord, float(baseMapIndex))) * fragColor;
} else {
fragOut0 = fragColor;
}
}
@@ -0,0 +1,18 @@
in vec2 vertPosition;
in vec4 vertColor;
in vec2 vertTexCoord;
out vec2 fragTexCoord;
out vec4 fragColor;
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
void main()
{
fragTexCoord = vertTexCoord;
fragColor = vertColor;
gl_Position = projMatrix * modelViewMatrix * vec4(vertPosition, 0.0, 1.0);
}
+4 -1
View File
@@ -53,8 +53,11 @@ else()
file(TO_NATIVE_PATH "${PATH_TYPE}" PATH_TYPE)
if (MINGW)
# There is a bug in CMake where it thinks MinGW uses forward slashes for paths but we need backslashes for Windows builds
string(REPLACE "/" "\\\\" PATH_TYPE "${PATH_TYPE}")
string(REPLACE "/" "\\" PATH_TYPE "${PATH_TYPE}")
endif()
# Properly escape back slashes in strings
string(REPLACE "\\" "\\\\" PATH_TYPE "${PATH_TYPE}")
GET_FILENAME_COMPONENT(FILE_NAME "${RELATIVE_FILE_PATH}" NAME)
string(MAKE_C_IDENTIFIER "${RELATIVE_FILE_PATH}" FIELD_NAME)
+230 -166
View File
@@ -26,18 +26,10 @@
#include <cstdlib>
// make use of the LOD checker for tbl/tbm parsing (from weapons.cpp)
extern SCP_vector<lod_checker> LOD_checker;
static SCP_vector<color> LOD_color;
int Warp_model;
int Knossos_warp_ani_used;
#define WARPHOLE_GROW_TIME (2.35f) // time for warphole to reach max size (also time to shrink to nothing once it begins to shrink)
#define MAX_FIREBALL_LOD 4
#define MAX_FIREBALLS 200
#define MAX_WARP_LOD 0
@@ -51,10 +43,8 @@ int fireball_used[MAX_FIREBALL_TYPES];
int Num_fireballs = 0;
int Num_fireball_types = 0;
int fireballs_inited = 0;
int Warp_glow_bitmap = -1;
int Warp_ball_bitmap = -1;
bool fireballs_inited = false;
bool fireballs_parsed = false;
#define FB_INDEX(fb) (fb-Fireballs)
@@ -114,12 +104,53 @@ void fireball_play_warphole_close_sound(fireball *fb)
snd_play_3d(gamesnd_get_game_sound(sound_index), &fireball_objp->pos, &Eye_position, fireball_objp->radius); // play warp sound effect
}
static void fireball_generate_unique_id(char *unique_id, int buffer_len, int fireball_index)
{
Assert((fireball_index >= 0) && (fireball_index < MAX_FIREBALL_TYPES));
switch (fireball_index)
{
// use sensible names for the fireball.tbl default entries
case FIREBALL_EXPLOSION_MEDIUM:
strncpy(unique_id, "Medium Explosion", buffer_len);
break;
case FIREBALL_WARP:
strncpy(unique_id, "Warp Effect", buffer_len);
break;
case FIREBALL_KNOSSOS:
strncpy(unique_id, "Knossos Effect", buffer_len);
break;
case FIREBALL_ASTEROID:
strncpy(unique_id, "Asteroid Explosion", buffer_len);
break;
case FIREBALL_EXPLOSION_LARGE1:
strncpy(unique_id, "Large Explosion 1", buffer_len);
break;
case FIREBALL_EXPLOSION_LARGE2:
strncpy(unique_id, "Large Explosion 2", buffer_len);
break;
// base the id on the index
default:
snprintf(unique_id, buffer_len, "Custom Fireball %d", fireball_index - NUM_DEFAULT_FIREBALLS + 1);
break;
}
// null-terminate
unique_id[buffer_len - 1] = '\0';
}
/**
* Set default colors for each explosion type (original values from object.cpp)
*/
static void fireball_set_default_color(int idx)
{
Assert( (idx >= 0) && (idx < MAX_FIREBALL_TYPES) );
Assert((idx >= 0) && (idx < MAX_FIREBALL_TYPES));
switch (idx)
{
@@ -153,71 +184,148 @@ static void fireball_set_default_color(int idx)
}
}
static void fireball_set_default_warp_attributes(int idx)
{
Assert((idx >= 0) && (idx < MAX_FIREBALL_TYPES));
switch (idx)
{
case FIREBALL_WARP:
case FIREBALL_KNOSSOS:
strcpy_s(Fireball_info[idx].warp_glow, "warpglow01");
strcpy_s(Fireball_info[idx].warp_ball, "warpball01");
strcpy_s(Fireball_info[idx].warp_model, "warp.pof");
break;
}
}
void fireball_info_clear(fireball_info *fb)
{
Assert(fb != nullptr);
memset(fb, 0, sizeof(fireball_info));
for (int i = 0; i < MAX_FIREBALL_LOD; ++i)
fb->lod[i].bitmap_id = -1;
fb->warp_glow_bitmap = -1;
fb->warp_ball_bitmap = -1;
fb->warp_model_id = -1;
}
int fireball_info_lookup(const char *unique_id)
{
for (int i = 0; i < Num_fireball_types; ++i)
if (!stricmp(Fireball_info[i].unique_id, unique_id))
return i;
return -1;
}
/**
* Parse fireball tbl
*
* NOTE: we can't be too trusting here so a tbm will only modify the LOD count, not add an entry
*/
void parse_fireball_tbl(const char *filename)
static void parse_fireball_tbl(const char *table_filename)
{
lod_checker lod_check;
color fb_color;
try
{
read_file_text(filename, CF_TYPE_TABLES);
read_file_text(table_filename, CF_TYPE_TABLES);
reset_parse();
required_string("#Start");
while (required_string_either("#End", "$Name:")) {
memset(&lod_check, 0, sizeof(lod_checker));
while (required_string_one_of(3, "#End", "$Name:", "$Unique ID:"))
{
fireball_info *fi;
int existing_idx = -1;
char unique_id[NAME_LENGTH];
char fireball_filename[MAX_FILENAME_LEN];
// unique ID, because indexes are unpredictable
memset(unique_id, 0, NAME_LENGTH);
if (optional_string("$Unique ID:"))
stuff_string(unique_id, F_NAME, NAME_LENGTH);
// base filename
required_string("$Name:");
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
stuff_string(fireball_filename, F_NAME, MAX_FILENAME_LEN);
lod_check.override = -1;
// find out if we are overriding a previous entry;
// per precedent, these strings should only be in TBMs
// UNLIKE precedent, we can now add fireballs in modular tables, not just replace them
if (Parsing_modular_table)
{
if (optional_string("+Explosion_Medium"))
existing_idx = FIREBALL_EXPLOSION_MEDIUM;
else if (optional_string("+Warp_Effect"))
existing_idx = FIREBALL_WARP;
else if (optional_string("+Knossos_Effect"))
existing_idx = FIREBALL_KNOSSOS;
else if (optional_string("+Asteroid"))
existing_idx = FIREBALL_ASTEROID;
else if (optional_string("+Explosion_Large1"))
existing_idx = FIREBALL_EXPLOSION_LARGE1;
else if (optional_string("+Explosion_Large2"))
existing_idx = FIREBALL_EXPLOSION_LARGE2;
else if (optional_string("+Custom_Fireball"))
stuff_int(&existing_idx);
// these entries should only be in TBMs, and it has to include at least one
if (Parsing_modular_table) {
if (optional_string("+Explosion_Medium")) {
lod_check.override = FIREBALL_EXPLOSION_MEDIUM;
}
else if (optional_string("+Warp_Effect")) {
lod_check.override = FIREBALL_WARP;
}
else if (optional_string("+Knossos_Effect")) {
lod_check.override = FIREBALL_KNOSSOS;
}
else if (optional_string("+Asteroid")) {
lod_check.override = FIREBALL_ASTEROID;
}
else if (optional_string("+Explosion_Large1")) {
lod_check.override = FIREBALL_EXPLOSION_LARGE1;
}
else if (optional_string("+Explosion_Large2")){
lod_check.override = FIREBALL_EXPLOSION_LARGE2;
}
else {
required_string("+Custom_Fireball");
stuff_int(&lod_check.override);
// we can ALSO override a previous entry by specifying a previously used unique ID
// either way will work, but if both are specified, unique ID takes precedence
if (strlen(unique_id) > 0)
{
int temp_idx = fireball_info_lookup(unique_id);
if (temp_idx >= 0)
existing_idx = temp_idx;
}
}
lod_check.num_lods = 1;
// now select our entry accordingly...
// are we using a previous entry?
if (existing_idx >= 0)
{
fi = &Fireball_info[existing_idx];
}
// we are creating a new entry, so set some defaults
else
{
// make sure we don't exceed the max
if (Num_fireball_types >= MAX_FIREBALL_TYPES)
{
error_display(0, "Too many fireball entries! Max is %d", MAX_FIREBALL_TYPES);
return;
}
// Do we have an LOD num
if (optional_string("$LOD:")) {
stuff_int(&lod_check.num_lods);
fi = &Fireball_info[Num_fireball_types];
fireball_info_clear(fi);
// If the table didn't specify a unique ID, generate one. This will be assigned a few lines later.
if (strlen(unique_id) == 0)
fireball_generate_unique_id(unique_id, NAME_LENGTH, Num_fireball_types);
// Set remaining fireball defaults
fireball_set_default_color(Num_fireball_types);
fireball_set_default_warp_attributes(Num_fireball_types);
Num_fireball_types++;
}
if (lod_check.num_lods > MAX_FIREBALL_LOD) {
lod_check.num_lods = MAX_FIREBALL_LOD;
// copy over what we already parsed
if (strlen(unique_id) > 0)
strcpy_s(fi->unique_id, unique_id);
strcpy_s(fi->lod[0].filename, fireball_filename);
// Do we have a LOD num?
if (optional_string("$LOD:"))
{
stuff_int(&fi->lod_count);
if (fi->lod_count > MAX_FIREBALL_LOD)
fi->lod_count = MAX_FIREBALL_LOD;
}
// check for particular lighting color
if (optional_string("$Light color:")) {
if (optional_string("$Light color:"))
{
int r, g, b;
stuff_int(&r);
@@ -228,90 +336,57 @@ void parse_fireball_tbl(const char *filename)
CLAMP(g, 0, 255);
CLAMP(b, 0, 255);
gr_init_color(&fb_color, r, g, b);
}
else {
// to keep things simple, we just use 0 alpha to indicate that a default value should be used
memset(&fb_color, 0, sizeof(color));
fi->exp_color[0] = (r / 255.0f);
fi->exp_color[1] = (g / 255.0f);
fi->exp_color[2] = (b / 255.0f);
}
// we may use one filename for multiple entries so we'll have to handle dupes post parse
LOD_checker.push_back(lod_check);
LOD_color.push_back(fb_color);
// check for custom warp glow
if (optional_string("$Warp glow:"))
stuff_string(fi->warp_glow, F_NAME, NAME_LENGTH);
// check for custom warp ball
if (optional_string("$Warp ball:"))
stuff_string(fi->warp_ball, F_NAME, NAME_LENGTH);
// check for custom warp model
if (optional_string("$Warp model:"))
stuff_string(fi->warp_model, F_NAME, NAME_LENGTH);
}
required_string("#End");
}
catch (const parse::ParseException& e)
{
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", table_filename, e.what()));
return;
}
}
void fireball_parse_tbl()
{
int i = 0, j;
SCP_vector<lod_checker>::iterator lod;
memset( &Fireball_info, 0, sizeof(fireball_info) * MAX_FIREBALL_TYPES );
if (fireballs_parsed)
return;
// every newly parsed fireball_info will get cleared before being added
// must do this outside of parse_fireball_tbl because it's called twice
Num_fireball_types = 0;
parse_fireball_tbl("fireball.tbl");
// look for any modular tables
parse_modular_table(NOX("*-fbl.tbm"), parse_fireball_tbl);
// we've got our list so pass it off for final checking and loading.
// we assume that entries in fireball.tbl are in the correct order
for (lod = LOD_checker.begin(); lod != LOD_checker.end(); ++lod) {
if ( (i < MAX_FIREBALL_TYPES) && (lod->override < 0) ) {
strcpy_s( Fireball_info[i].lod[0].filename, lod->filename );
Fireball_info[i].lod_count = lod->num_lods;
Num_fireball_types++;
if (LOD_color[i].alpha == 255) {
Fireball_info[i].exp_color[0] = (LOD_color[i].red / 255.0f);
Fireball_info[i].exp_color[1] = (LOD_color[i].green / 255.0f);
Fireball_info[i].exp_color[2] = (LOD_color[i].blue / 255.0f);
} else {
fireball_set_default_color(i);
}
}
i++;
}
// having to do this twice is less than optimal, but less error prone too.
// this handles (and should only have to handle) TBM related entries
i = 0;
for (lod = LOD_checker.begin(); lod != LOD_checker.end(); ++lod) {
// try entry replacement
if ( (lod->override >= 0) && (lod->override < Num_fireball_types) ) {
strcpy_s( Fireball_info[lod->override].lod[0].filename, lod->filename );
Fireball_info[lod->override].lod_count = lod->num_lods;
if (LOD_color[i].alpha == 255) {
Fireball_info[lod->override].exp_color[0] = (LOD_color[i].red / 255.0f);
Fireball_info[lod->override].exp_color[1] = (LOD_color[i].green / 255.0f);
Fireball_info[lod->override].exp_color[2] = (LOD_color[i].blue / 255.0f);
} else {
fireball_set_default_color(lod->override);
}
}
}
// fill in extra LOD filenames
for (i = 0; i < Num_fireball_types; i++) {
for (j = 1; j < Fireball_info[i].lod_count; j++) {
for (int i = 0; i < Num_fireball_types; i++)
{
for (int j = 1; j < Fireball_info[i].lod_count; j++)
sprintf( Fireball_info[i].lod[j].filename, "%s_%d", Fireball_info[i].lod[0].filename, j);
}
}
// done
LOD_checker.clear();
fireballs_parsed = true;
}
void fireball_load_data()
{
int i, idx;
@@ -330,13 +405,20 @@ void fireball_load_data()
Error(LOCATION, "Could not load %s anim file\n", fd->lod[idx].filename);
}
}
}
if ( Warp_glow_bitmap == -1 ) {
Warp_glow_bitmap = bm_load( NOX("warpglow01") );
}
if ( Warp_ball_bitmap == -1 ) {
Warp_ball_bitmap = bm_load( NOX("warpball01") );
if (strlen(fd->warp_glow) > 0) {
mprintf(("Loading warp glow '%s'\n", fd->warp_glow));
fd->warp_glow_bitmap = bm_load(fd->warp_glow);
} else {
fd->warp_glow_bitmap = -1;
}
if (strlen(fd->warp_ball) > 0) {
mprintf(("Loading warp ball '%s'\n", fd->warp_ball));
fd->warp_ball_bitmap = bm_load(fd->warp_ball);
} else {
fd->warp_ball_bitmap = -1;
}
}
}
@@ -346,11 +428,11 @@ void fireball_init()
int i;
if ( !fireballs_inited ) {
fireballs_inited = 1;
// Do all the processing that happens only once
fireball_parse_tbl();
fireball_load_data();
fireballs_inited = true;
}
// Reset everything between levels
@@ -361,17 +443,6 @@ void fireball_init()
// Goober5000 - reset Knossos warp flag
Knossos_warp_ani_used = 0;
mprintf(("Loading warp model\n"));
Warp_model = -1;
// Goober5000 - check for existence of file before trying to load it
if (cf_exists_full("warp.pof", CF_TYPE_MODELS))
{
Warp_model = model_load("warp.pof", 0, NULL, 0);
}
mprintf((" %d\n", Warp_model));
}
MONITOR( NumFireballsRend )
@@ -543,7 +614,7 @@ void fireball_maybe_play_warp_close_sound(fireball *fb)
life_left = fb->total_time - fb->time_elapsed;
if ( life_left < WARPHOLE_GROW_TIME ) {
if ( life_left < fb->warp_close_duration ) {
fireball_play_warphole_close_sound(fb);
fb->flags |= FBF_WARP_CLOSE_SOUND_PLAYED;
}
@@ -696,7 +767,7 @@ int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
/**
* Create a fireball, return object index.
*/
int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent_obj, float size, int reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, gamesnd_id warp_open_sound, gamesnd_id warp_close_sound)
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, gamesnd_id warp_open_sound, gamesnd_id warp_close_sound, float warp_open_duration, float warp_close_duration)
{
int n, objnum, fb_lod;
object *obj;
@@ -757,6 +828,8 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
fb->flags = extra_flags;
fb->warp_open_sound_index = warp_open_sound;
fb->warp_close_sound_index = warp_close_sound;
fb->warp_open_duration = (warp_open_duration < 0.0f) ? WARPHOLE_GROW_TIME : warp_open_duration;
fb->warp_close_duration = (warp_close_duration < 0.0f) ? WARPHOLE_GROW_TIME : warp_close_duration;
matrix orient;
if(orient_override != NULL){
@@ -861,9 +934,9 @@ void fireballs_page_in()
fireball_info *fd;
for ( i = 0; i < Num_fireball_types; i++ ) {
if((i < NUM_DEFAULT_FIREBALLS) || fireball_used[i]){
fd = &Fireball_info[i];
fd = &Fireball_info[i];
if((i < NUM_DEFAULT_FIREBALLS) || fireball_used[i]) {
// if this is a Knossos ani, only load if Knossos_warp_ani_used is true
if ( (i == FIREBALL_KNOSSOS) && !Knossos_warp_ani_used)
continue;
@@ -876,10 +949,19 @@ void fireballs_page_in()
bm_page_in_texture( fd->lod[idx].bitmap_id, fd->lod[idx].num_frames );
}
}
}
bm_page_in_texture( Warp_glow_bitmap );
bm_page_in_texture( Warp_ball_bitmap );
// page in glow and ball bitmaps, if we have any
bm_page_in_texture(fd->warp_glow_bitmap);
bm_page_in_texture(fd->warp_ball_bitmap);
// load the warp model, if we have one
if (strlen(fd->warp_model) > 0 && cf_exists_full(fd->warp_model, CF_TYPE_MODELS)) {
mprintf(("Loading warp model '%s'\n", fd->warp_model));
fd->warp_model_id = model_load(fd->warp_model, 0, nullptr, 0);
} else {
fd->warp_model_id = -1;
}
}
}
void fireball_get_color(int idx, float *red, float *green, float *blue)
@@ -941,30 +1023,23 @@ int fireball_asteroid_explosion_type(asteroid_info *aip)
return index;
}
float fireball_wormhole_intensity( object *obj )
float fireball_wormhole_intensity(fireball *fb)
{
int num, objnum;
fireball *fb;
num = obj->instance;
objnum = OBJ_INDEX(obj);
Assertion( Fireballs[num].objnum == objnum, "Basic sanity check. Fireballs[num].objnum (%d) should == objnum (%d)", Fireballs[num].objnum, objnum );
fb = &Fireballs[num];
float t = fb->time_elapsed;
float rad;
if ( t < WARPHOLE_GROW_TIME ) {
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f);
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
rad = 1;
if ( t < fb->warp_open_duration ) {
rad = (float)pow(t / fb->warp_open_duration, 0.4f);
} else if ( t < fb->total_time - fb->warp_close_duration ) {
rad = 1.0f;
} else {
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f);
rad = (float)pow((fb->total_time - t) / fb->warp_close_duration, 0.4f);
}
return rad;
}
extern void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, bool warp_3d, int warp_glow_bitmap, int warp_ball_bitmap, int warp_model_id);
void fireball_render(object* obj, model_draw_list *scene)
{
int num;
@@ -996,21 +1071,10 @@ void fireball_render(object* obj, model_draw_list *scene)
case FIREBALL_WARP_EFFECT: {
float percent_life = fb->time_elapsed / fb->total_time;
float rad = obj->radius * fireball_wormhole_intensity(fb);
float rad;
// Code to make effect grow/shrink.
float t = fb->time_elapsed;
if ( t < WARPHOLE_GROW_TIME ) {
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
rad = obj->radius;
} else {
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
}
warpin_queue_render(scene, obj, &obj->orient, &obj->pos, Fireballs[num].current_bitmap, rad, percent_life, obj->radius, (Fireballs[num].flags & FBF_WARP_3D) );
fireball_info *fi = &Fireball_info[fb->fireball_info_index];
warpin_queue_render(scene, obj, &obj->orient, &obj->pos, fb->current_bitmap, rad, percent_life, obj->radius, (fb->flags & FBF_WARP_3D) != 0, fi->warp_glow_bitmap, fi->warp_ball_bitmap, fi->warp_model_id);
}
break;
+28 -14
View File
@@ -36,10 +36,11 @@ class asteroid_info;
#define MAX_FIREBALL_TYPES 32 // The maximum number of fireballs that can be defined
#define NUM_DEFAULT_FIREBALLS 6
#define MAX_FIREBALL_LOD 4
#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 {
@@ -50,11 +51,22 @@ typedef struct fireball_lod {
} fireball_lod;
typedef struct fireball_info {
char unique_id[NAME_LENGTH];
int lod_count;
float exp_color[3];
fireball_lod lod[4];
fireball_lod lod[MAX_FIREBALL_LOD];
float exp_color[3]; // red, green, blue
char warp_glow[NAME_LENGTH];
int warp_glow_bitmap;
char warp_ball[NAME_LENGTH];
int warp_ball_bitmap;
char warp_model[NAME_LENGTH];
int warp_model_id;
} fireball_info;
extern fireball_info Fireball_info[MAX_FIREBALL_TYPES];
extern int Num_fireball_types;
// flag values for fireball struct flags member
#define FBF_WARP_CLOSE_SOUND_PLAYED (1<<0)
#define FBF_WARP_CAPITAL_SIZE (1<<1)
@@ -72,8 +84,12 @@ typedef struct fireball {
char lod; // current LOD
float time_elapsed; // in seconds
float total_time; // total lifetime of animation in seconds
gamesnd_id warp_open_sound_index; // for warp-effect - Goober5000
gamesnd_id warp_close_sound_index; // for warp-effect - Goober5000
// for warp-effect - Goober5000
gamesnd_id warp_open_sound_index;
gamesnd_id warp_close_sound_index;
float warp_open_duration;
float warp_close_duration;
} fireball;
// end move
@@ -82,10 +98,15 @@ void fireball_render(object* obj, model_draw_list *scene);
void fireball_delete( object * obj );
void fireball_process_post(object * obj, float frame_time);
// This does not load all the data, just the filenames and such. Only used by FRED.
void fireball_parse_tbl();
int fireball_info_lookup(const char *unique_id);
// 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, gamesnd_id warp_open_sound=gamesnd_id(), gamesnd_id warp_close_sound=gamesnd_id());
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reversed=0, vec3d *velocity=nullptr, float warp_lifetime=0.0f, int ship_class=-1, matrix *orient=nullptr, int low_res=0, int extra_flags=0, gamesnd_id warp_open_sound=gamesnd_id(), gamesnd_id warp_close_sound=gamesnd_id(), float warp_open_duration=-1.0f, float warp_close_duration=-1.0f);
void fireball_render_plane(int plane);
void fireball_close();
@@ -111,14 +132,7 @@ int fireball_ship_explosion_type(ship_info *sip);
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(model_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;
float fireball_wormhole_intensity( fireball *fb );
// Goober5000
extern int Knossos_warp_ani_used;
+8 -12
View File
@@ -21,10 +21,6 @@
#include "render/batching.h"
#include "ship/ship.h"
extern int Warp_model;
extern int Warp_glow_bitmap;
extern int Warp_ball_bitmap;
void warpin_batch_draw_face( int texture, vertex *v1, vertex *v2, vertex *v3 )
{
vec3d norm;
@@ -45,7 +41,7 @@ void warpin_batch_draw_face( int texture, vertex *v1, vertex *v2, vertex *v3 )
batching_add_tri(texture, vertlist); // TODO render as emissive
}
void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, bool warp_3d, int warp_glow_bitmap, int warp_ball_bitmap, int warp_model_id)
{
vec3d center;
vec3d vecs[5];
@@ -60,7 +56,7 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
verts[1] = verts[2] = verts[3] = verts[4] = verts[0];
if (Warp_glow_bitmap >= 0) {
if (warp_glow_bitmap >= 0) {
float r = radius;
bool render_it = true;
@@ -99,12 +95,12 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
float alpha = (The_mission.flags[Mission::Mission_Flags::Fullneb]) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
//batch_add_bitmap(Warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, &verts[4], 0, r, alpha);
batching_add_bitmap(Warp_glow_bitmap, &verts[4], 0, r, alpha);
//batch_add_bitmap(warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, &verts[4], 0, r, alpha);
batching_add_bitmap(warp_glow_bitmap, &verts[4], 0, r, alpha);
}
}
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
if ( (warp_model_id >= 0) && (warp_3d || Cmdline_3dwarp) ) {
model_render_params render_info;
float scale = radius / 25.0f;
@@ -119,7 +115,7 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
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);
model_render_queue( &render_info, scene, warp_model_id, orient, pos);
} else {
float Grid_depth = radius/2.5f;
@@ -171,14 +167,14 @@ void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, ve
warpin_batch_draw_face( texture_bitmap_num, &verts[0], &verts[3], &verts[4] );
}
if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
if (warp_ball_bitmap >= 0 && Cmdline_warp_flash) {
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);
warp_ball.render(warp_ball_bitmap, max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
}
}
}
+3 -3
View File
@@ -404,9 +404,9 @@ int gameseq_process_events()
state_reentry--;
return gs[gs_current_stack].current_state;
}
}
int gameseq_get_event_idx(char *s)
int gameseq_get_event_idx(const char* s)
{
for(int i = 0; i < Num_gs_event_text; i++)
{
@@ -418,7 +418,7 @@ int gameseq_get_event_idx(char *s)
return -1;
}
int gameseq_get_state_idx(char *s)
int gameseq_get_state_idx(const char* s)
{
for(int i = 0; i < Num_gs_state_text; i++)
{
+2 -2
View File
@@ -197,8 +197,8 @@ void game_do_state(int current_state);
bool GameState_Stack_Valid();
//WMC
int gameseq_get_event_idx(char *s);
int gameseq_get_state_idx(char *s);
int gameseq_get_event_idx(const char* s);
int gameseq_get_state_idx(const char* s);
//zookeeper
int gameseq_get_state_idx(int state);
+1 -1
View File
@@ -28,7 +28,7 @@
#define MISSION_DESC_LENGTH 512
// from player.h
#define CALLSIGN_LEN 28 // shortened from 32 to allow .plr to be attached without exceeding MAX_FILENAME_LEN
#define CALLSIGN_LEN (MAX_FILENAME_LEN - 4 - 1) // shortened from 32 to allow .json to be attached without exceeding MAX_FILENAME_LEN
#define SHORT_CALLSIGN_PIXEL_W 80 // max width of short_callsign[] in pixels
#define MAX_IFFS 10
+1 -1
View File
@@ -389,7 +389,7 @@ template <class T> void CAP( T& v, T mn, T mx )
}
// faster version of CAP()
#define CLAMP(x, min, max) do { if ( (x) < (min) ) (x) = (min); else if ((x) > (max)) (x) = (max); } while(0)
#define CLAMP(x, min, max) do { if ( (x) < (min) ) (x) = (min); else if ((x) > (max)) (x) = (max); } while(false)
//=========================================================
// Memory management functions
+2 -2
View File
@@ -74,8 +74,8 @@
#define SIZE_T_ARG "%Iu"
#define PTRDIFF_T_ARG "%Id"
#define likely(x)
#define unlikely(x)
#define likely(x) (x)
#define unlikely(x) (x)
#define USED_VARIABLE
+21 -1
View File
@@ -7,8 +7,9 @@
*
*/
#include "globalincs/pstypes.h"
#include "globalincs/version.h"
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "parse/parselo.h"
@@ -130,5 +131,24 @@ bool version::operator!=(const version& other) const {
return !(*this == other);
}
SCP_string get_version_string()
{
SCP_string str;
sprintf(str, "FreeSpace 2 Open v%s", FS_VERSION_FULL);
#ifndef NDEBUG
str += " Debug";
#endif
// Lets get some more info in here
switch (gr_screen.mode) {
case GR_OPENGL:
str += " OpenGL";
break;
}
return str;
}
}
+7
View File
@@ -85,6 +85,13 @@ bool check_at_least(const version& v);
*/
SCP_string format_version(const version& v);
/**
* @brief
* @return
*/
SCP_string get_version_string();
}
#endif
+12 -1
View File
@@ -49,6 +49,7 @@ class movie_material;
class batched_bitmap_material;
class nanovg_material;
class decal_material;
class interface_material;
class transform_stack {
@@ -154,13 +155,15 @@ enum shader_type {
SDR_TYPE_DEFERRED_LIGHTING,
SDR_TYPE_DEFERRED_CLEAR,
SDR_TYPE_VIDEO_PROCESS,
SDR_TYPE_PASSTHROUGH_RENDER, //!< Shader for doing the old style fixed-function rendering. Only used internally, use SDR_TYPE_DEFAULT_MATERIAL.
SDR_TYPE_PASSTHROUGH_RENDER, //!< Shader for doing the old style fixed-function rendering. Only used internally, use
//!< SDR_TYPE_DEFAULT_MATERIAL.
SDR_TYPE_SHIELD_DECAL,
SDR_TYPE_BATCHED_BITMAP,
SDR_TYPE_DEFAULT_MATERIAL,
SDR_TYPE_NANOVG,
SDR_TYPE_DECAL,
SDR_TYPE_SCENE_FOG,
SDR_TYPE_ROCKET_UI,
NUM_SHADER_TYPES
};
@@ -780,6 +783,8 @@ typedef struct screen {
void (*gf_render_primitives_batched)(batched_bitmap_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void (*gf_render_nanovg)(nanovg_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void (*gf_render_decals)(decal_material* material_info, primitive_type prim_type, vertex_layout* layout, int num_elements, const indexed_vertex_source& buffers);
void (*gf_render_rocket_primitives)(interface_material* material_info, primitive_type prim_type,
vertex_layout* layout, int n_indices, int vertex_buffer, int index_buffer);
bool (*gf_is_capable)(gr_capability capability);
bool (*gf_get_property)(gr_property property, void* destination);
@@ -1039,6 +1044,12 @@ __inline void gr_render_model(model_material* material_info, indexed_vertex_sour
(*gr_screen.gf_render_model)(material_info, vert_source, bufferp, texi);
}
__inline void gr_render_rocket_primitives(interface_material* material_info, primitive_type prim_type,
vertex_layout* layout, int n_indices, int vertex_buffer, int index_buffer)
{
(*gr_screen.gf_render_rocket_primitives)(material_info, prim_type, layout, n_indices, vertex_buffer, index_buffer);
}
__inline bool gr_is_capable(gr_capability capability)
{
return (*gr_screen.gf_is_capable)(capability);
+7
View File
@@ -351,6 +351,12 @@ void gr_stub_render_primitives_batched(batched_bitmap_material* /*material_info
{
}
void gr_stub_render_rocket_primitives(interface_material* /*material_info*/, primitive_type /*prim_type*/,
vertex_layout* /*layout*/, int /*n_indices*/, int /*vertex_buffer*/,
int /*index_buffer*/)
{
}
bool gr_stub_is_capable(gr_capability /*capability*/)
{
return false;
@@ -511,6 +517,7 @@ bool gr_stub_init()
gr_screen.gf_render_movie = gr_stub_render_movie;
gr_screen.gf_render_nanovg = gr_stub_render_nanovg;
gr_screen.gf_render_primitives_batched = gr_stub_render_primitives_batched;
gr_screen.gf_render_rocket_primitives = gr_stub_render_rocket_primitives;
gr_screen.gf_is_capable = gr_stub_is_capable;
gr_screen.gf_get_property = [](gr_property,void*) { return false; };
+12 -1
View File
@@ -55,7 +55,18 @@ void line_draw_list::add_vertex(int x, int y, int resize_mode, const color* colo
vtx.position.x = i2fl(x);
vtx.position.y = i2fl(y);
gr_resize_screen_posf(&vtx.position.x, &vtx.position.y, nullptr, nullptr, resize_mode);
float w_scale = 1.0f;
float h_scale = 1.0f;
bool do_resize = gr_resize_screen_posf(&vtx.position.x, &vtx.position.y, &w_scale, &h_scale, resize_mode);
int offset_x = ((do_resize) ? gr_screen.offset_x_unscaled : gr_screen.offset_x);
int offset_y = ((do_resize) ? gr_screen.offset_y_unscaled : gr_screen.offset_y);
// m!m - This is silly but there is no better solution at the moment...
vtx.position.x += i2fl(offset_x) * w_scale;
vtx.position.y += i2fl(offset_y) * h_scale;
vtx.color.xyzw.x = color->red / 255.f;
vtx.color.xyzw.y = color->green / 255.f;
vtx.color.xyzw.z = color->blue / 255.f;
+22
View File
@@ -123,6 +123,18 @@ void material_set_distortion(distortion_material *mat_info, int texture, bool th
mat_info->set_cull_mode(false);
mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
}
void material_set_rocket_interface(interface_material* mat_info, int texture, const vec2d& offset)
{
mat_info->set_texture_map(TM_BASE_TYPE, texture);
mat_info->set_offset(offset);
mat_info->set_cull_mode(false);
mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
mat_info->set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
}
void material_set_movie(movie_material* mat_info, int y_bm, int u_bm, int v_bm) {
mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
@@ -890,3 +902,13 @@ uint decal_material::get_shader_flags() const {
return flags;
}
interface_material::interface_material()
{
set_shader_type(SDR_TYPE_ROCKET_UI);
offset.x = 0;
offset.y = 0;
}
void interface_material::set_offset(const vec2d& new_offset) { this->offset = new_offset; }
vec2d interface_material::get_offset() { return offset; }
+15 -6
View File
@@ -315,9 +315,8 @@ class movie_material : public material {
void setVtex(int _Vtex);
};
class batched_bitmap_material : public material
{
public:
class batched_bitmap_material : public material {
public:
batched_bitmap_material();
};
@@ -326,19 +325,29 @@ class nanovg_material : public material {
nanovg_material();
};
class decal_material : public material
{
public:
class decal_material : public material {
public:
decal_material();
uint get_shader_flags() const override;
};
class interface_material : public material {
vec2d offset;
public:
interface_material();
void set_offset(const vec2d& new_offset);
vec2d get_offset();
};
gr_alpha_blend material_determine_blend_mode(int base_bitmap, bool is_transparent);
gr_zbuffer_type material_determine_depth_mode(bool depth_testing, bool is_transparent);
void material_set_interface(material* mat_info, int texture, bool blended, float alpha);
void material_set_rocket_interface(interface_material* mat_info, int texture, const vec2d& offset);
void material_set_unlit(material* mat_info, int texture, float alpha, bool blending, bool depth_testing);
void material_set_unlit_emissive(material* mat_info, int texture, float alpha, float color_scale);
void material_set_unlit_color(material* mat_info, int texture, color *clr, bool blending, bool depth_testing);
+1
View File
@@ -1174,6 +1174,7 @@ void opengl_setup_function_pointers()
gr_screen.gf_render_movie = gr_opengl_render_movie;
gr_screen.gf_render_nanovg = gr_opengl_render_nanovg;
gr_screen.gf_render_decals = gr_opengl_render_decals;
gr_screen.gf_render_rocket_primitives = gr_opengl_render_rocket_primitives;
gr_screen.gf_is_capable = gr_opengl_is_capable;
gr_screen.gf_get_property = gr_opengl_get_property;
+16
View File
@@ -825,6 +825,22 @@ void gr_opengl_render_primitives_batched(batched_bitmap_material* material_info,
opengl_render_primitives(prim_type, layout, n_verts, buffer_handle, offset, 0);
}
void gr_opengl_render_rocket_primitives(interface_material* material_info, primitive_type prim_type,
vertex_layout* layout, int n_indices, int vertex_buffer, int index_buffer)
{
GR_DEBUG_SCOPE("Render rocket ui primitives");
gr_set_2d_matrix();
opengl_tnl_set_rocketui_material(material_info);
opengl_bind_vertex_layout(*layout, opengl_buffer_get_id(GL_ARRAY_BUFFER, vertex_buffer),
opengl_buffer_get_id(GL_ELEMENT_ARRAY_BUFFER, index_buffer));
glDrawElements(opengl_primitive_type(prim_type), n_indices, GL_UNSIGNED_INT, nullptr);
gr_end_2d_matrix();
}
void opengl_draw_textured_quad(GLfloat x1,
GLfloat y1,
+2
View File
@@ -58,6 +58,8 @@ void gr_opengl_render_primitives_distortion(distortion_material* material_info,
void gr_opengl_render_movie(movie_material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, int buffer, size_t buffer_offset);
void gr_opengl_render_nanovg(nanovg_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void gr_opengl_render_decals(decal_material* material_info, primitive_type prim_type, vertex_layout* layout, int num_elements, const indexed_vertex_source& binding);
void gr_opengl_render_rocket_primitives(interface_material* material_info, primitive_type prim_type,
vertex_layout* layout, int n_indices, int vertex_buffer, int index_buffer);
void opengl_draw_textured_quad(GLfloat x1, GLfloat y1, GLfloat u1, GLfloat v1,
GLfloat x2, GLfloat y2, GLfloat u2, GLfloat v2 );
@@ -73,9 +73,6 @@ static GLuint Bloom_framebuffer = 0;
static GLuint Bloom_textures[2] = { 0 };
static GLuint Post_framebuffer_id[2] = { 0 };
static GLuint Post_shadow_framebuffer_id = 0;
static GLuint Post_shadow_texture_id = 0;
static GLuint Post_shadow_depth_texture_id = 0;
static int Post_texture_width = 0;
static int Post_texture_height = 0;
@@ -864,76 +861,6 @@ void opengl_setup_bloom_textures()
GL_state.BindFrameBuffer(0);
}
static bool opengl_init_shadow_framebuffer(int size, GLenum color_format) {
mprintf(("Trying to create %dx%d %d-bit shadow framebuffer\n", size, size, color_format == GL_RGBA32F ? 32 : 16));
glGenFramebuffers(1, &Post_shadow_framebuffer_id);
GL_state.BindFrameBuffer(Post_shadow_framebuffer_id);
glGenTextures(1, &Post_shadow_texture_id);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
GL_state.Texture.Enable(Post_shadow_texture_id);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, color_format, size, size, 4, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, Post_shadow_texture_id, 0);
glGenTextures(1, &Post_shadow_depth_texture_id);
GL_state.Texture.Enable(Post_shadow_depth_texture_id);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32, size, size, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, Post_shadow_depth_texture_id, 0);
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status == GL_FRAMEBUFFER_COMPLETE) {
// Everything is fine
mprintf(("Shadow framebuffer created successfully.\n"));
return true;
}
// Clean up resources
glDeleteTextures(1, &Post_shadow_texture_id);
glDeleteTextures(1, &Post_shadow_depth_texture_id);
glDeleteFramebuffers(1, &Post_shadow_framebuffer_id);
Post_shadow_texture_id = 0;
Post_shadow_depth_texture_id = 0;
Post_shadow_framebuffer_id = 0;
const char* error;
switch (status) {
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
error = "Incomplete framebuffer attachment";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
error = "Framebuffer is missing an attachment";
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
error = "Framebuffer configuration is unsupported";
break;
default:
error = "Unknown framebuffer status";
break;
}
mprintf(("Failed to create framebuffer: %s\n", error));
return false;
}
// generate and test the framebuffer and textures that we are going to use
static bool opengl_post_init_framebuffer()
{
@@ -953,17 +880,6 @@ static bool opengl_post_init_framebuffer()
opengl_setup_bloom_textures();
if ( Cmdline_shadow_quality ) {
int size = (Cmdline_shadow_quality == 2 ? 1024 : 512);
if (!opengl_init_shadow_framebuffer(size, GL_RGBA32F)) {
if (!opengl_init_shadow_framebuffer(size, GL_RGBA16F)) {
mprintf(("Failed to create either 32 or 16-bit color shadow framebuffer. Disabling shadow support.\n"));
Cmdline_shadow_quality = 0;
}
}
}
GL_state.BindFrameBuffer(0);
rval = true;
+6 -1
View File
@@ -64,6 +64,7 @@ opengl_uniform_block_binding GL_uniform_blocks[] = {
* Static lookup reference for shader uniforms
* When adding a new shader, list all associated uniforms and attributes here
*/
// clang-format off
static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_MODEL, "main-v.sdr", "main-f.sdr", "main-g.sdr",
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::NORMAL, opengl_vert_attrib::TANGENT, opengl_vert_attrib::MODEL_ID }, "Model Rendering" },
@@ -100,7 +101,7 @@ static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_DEFERRED_LIGHTING, "deferred-v.sdr", "deferred-f.sdr", 0,
{ opengl_vert_attrib::POSITION }, "Deferred Lighting" },
{ SDR_TYPE_DEFERRED_CLEAR, "deferred-clear-v.sdr", "deferred-clear-f.sdr", 0,
{ opengl_vert_attrib::POSITION }, "Clear Deferred Lighting Buffer" },
@@ -127,7 +128,11 @@ static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_SCENE_FOG, "post-v.sdr", "fog-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Scene fogging" },
{ SDR_TYPE_ROCKET_UI, "rocketui-v.sdr", "rocketui-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::COLOR, opengl_vert_attrib::TEXCOORD }, "libRocket UI" },
};
// clang-format on
/**
* Static lookup reference for shader variant uniforms
+109 -58
View File
@@ -412,70 +412,92 @@ void opengl_destroy_all_buffers()
GL_vertex_buffers_in_use = 0;
}
static bool opengl_init_shadow_framebuffer(int size, GLenum color_format)
{
mprintf(("Trying to create %dx%d %d-bit shadow framebuffer\n", size, size, color_format == GL_RGBA32F ? 32 : 16));
glGenFramebuffers(1, &shadow_fbo);
GL_state.BindFrameBuffer(shadow_fbo);
glGenTextures(1, &Shadow_map_depth_texture);
GL_state.Texture.Enable(Shadow_map_depth_texture);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32, size, size, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, Shadow_map_depth_texture, 0);
glGenTextures(1, &Shadow_map_texture);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
GL_state.Texture.Enable(Shadow_map_texture);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, color_format, size, size, 4, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, Shadow_map_texture, 0);
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
GL_state.BindFrameBuffer(0);
if (status == GL_FRAMEBUFFER_COMPLETE) {
// Everything is fine
mprintf(("Shadow framebuffer created successfully.\n"));
return true;
}
// Clean up resources
glDeleteTextures(1, &Shadow_map_texture);
glDeleteTextures(1, &Shadow_map_depth_texture);
glDeleteFramebuffers(1, &shadow_fbo);
Shadow_map_texture = 0;
Shadow_map_depth_texture = 0;
shadow_fbo = 0;
const char* error;
switch (status) {
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
error = "Incomplete framebuffer attachment";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
error = "Framebuffer is missing an attachment";
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
error = "Framebuffer configuration is unsupported";
break;
default:
error = "Unknown framebuffer status";
break;
}
mprintf(("Failed to create framebuffer: %s\n", error));
return false;
}
void opengl_tnl_init()
{
Transform_buffer_handle = opengl_create_texture_buffer_object();
if(Cmdline_shadow_quality)
{
//Setup shadow map framebuffer
glGenFramebuffers(1, &shadow_fbo);
GL_state.BindFrameBuffer(shadow_fbo);
glGenTextures(1, &Shadow_map_depth_texture);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
GL_state.Texture.Enable(Shadow_map_depth_texture);
opengl_set_object_label(GL_TEXTURE, Shadow_map_depth_texture, "Scene shadow depth map");
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT);
//glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
//glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
if (Cmdline_shadow_quality) {
int size = (Cmdline_shadow_quality == 2 ? 1024 : 512);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32, size, size, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, size, size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, Shadow_map_depth_texture, 0);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Shadow_map_depth_texture, 0);
glGenTextures(1, &Shadow_map_texture);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
GL_state.Texture.Enable(Shadow_map_texture);
opengl_set_object_label(GL_TEXTURE, Shadow_map_texture, "Scene shadow map");
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB32F, size, size, 4, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, size, size, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, Shadow_map_texture, 0);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Shadow_map_texture, 0);
GL_state.BindFrameBuffer(0);
opengl_check_for_errors("post_init_framebuffer()");
if (!opengl_init_shadow_framebuffer(size, GL_RGBA32F)) {
if (!opengl_init_shadow_framebuffer(size, GL_RGBA16F)) {
mprintf(("Failed to create either 32 or 16-bit color shadow framebuffer. Disabling shadow support.\n"));
Cmdline_shadow_quality = 0;
}
}
}
gr_opengl_deferred_init();
@@ -974,6 +996,7 @@ void opengl_tnl_set_material_nanovg(nanovg_material* material_info) {
Current_shader->program->Uniforms.setUniformi("nvg_tex", 0);
}
void opengl_tnl_set_material_decal(decal_material* material_info) {
opengl_tnl_set_material(material_info, false);
@@ -1016,6 +1039,34 @@ void opengl_tnl_set_material_decal(decal_material* material_info) {
}
}
void opengl_tnl_set_rocketui_material(interface_material* material_info)
{
vec3d offset = vmd_zero_vector;
offset.xyz.x = material_info->get_offset().x;
offset.xyz.y = material_info->get_offset().y;
matrix4 modelViewMatrix;
vm_matrix4_set_transform(&modelViewMatrix, &vmd_identity_matrix, &offset);
opengl_tnl_set_material(material_info, false);
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", modelViewMatrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
Current_shader->program->Uniforms.setUniformi("textured", material_info->is_textured() ? GL_TRUE : GL_FALSE);
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
if (material_info->is_textured()) {
float u_scale, v_scale;
uint32_t array_index;
if (!gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), material_info->get_texture_type(),
&u_scale, &v_scale, &array_index)) {
mprintf(("WARNING: Error setting bitmap texture (%i)!\n", material_info->get_texture_map(TM_BASE_TYPE)));
}
Current_shader->program->Uniforms.setUniformi("baseMapIndex", array_index);
}
}
void gr_opengl_set_viewport(int x, int y, int width, int height) {
glViewport(x, y, width, height);
}
+1
View File
@@ -74,6 +74,7 @@ void opengl_tnl_set_material_movie(movie_material* material_info);
void opengl_tnl_set_material_batched(batched_bitmap_material * material_info);
void opengl_tnl_set_material_nanovg(nanovg_material * material_info);
void opengl_tnl_set_material_decal(decal_material * material_info);
void opengl_tnl_set_rocketui_material(interface_material* material_info);
void opengl_tnl_set_model_material(model_material *material_info);
+17
View File
@@ -21,6 +21,23 @@
#include "NanoVGRenderer.h"
#include "tracing/tracing.h"
#ifndef NDEBUG
// That is a wrapper function for log prints to be availiable for nanovg components. For now it is stb_truetype.h
// Planted by ksotar with blessing from asarium
extern "C" {
void nvgOldCPrintf(SCP_FORMAT_STRING const char *message, ...) {
SCP_string buf;
va_list args;
va_start(args, message);
vsprintf(buf, message, args);
va_end(args);
outwnd_printf2("%s", message);
}
}
#endif
namespace {
using namespace graphics::paths;
+4
View File
@@ -6,3 +6,7 @@ Changes to fontstash.h
- Increased memory size for newer stb_truetype version
- Removed pixel snapping from fons__getQuad
- Include <malloc.h> as malloc and free weren't found for some reason
Changes to stb_truetype.h
- Added extern function to print in log. Made Assert on missed glyph a bit more friendly
- Explicit fallthrough comment for gcc
File diff suppressed because it is too large. Load diff
+3
View File
@@ -1633,6 +1633,9 @@ void hud_config_as_observer(ship *shipp,ai_info *aif)
void hud_config_as_player()
{
if (HUD_config.is_observer) { // If he was observer before
hud_config_restore();
}
}
// ---------------------------------------------------------------------------------------------------------------
+1 -1
View File
@@ -615,7 +615,7 @@ void hud_sourced_print(int source, const char *msg)
// Invoke the scripting hook
Script_system.SetHookVar("Text", 's', const_cast<char*>(msg));
Script_system.SetHookVar("SourceType", 'i', &source);
Script_system.SetHookVar("SourceType", 'i', source);
Script_system.RunCondition(CHA_HUDMSGRECEIVED);
+5
View File
@@ -1991,6 +1991,7 @@ void load_gauge_center_reticle(gauge_settings* settings)
int scaleX = 15;
int scaleY = 10;
int size = 5;
int autoaim_frame = -1;
settings->origin[0] = 0.5f;
settings->origin[1] = 0.5f;
@@ -2040,8 +2041,12 @@ void load_gauge_center_reticle(gauge_settings* settings)
if (optional_string("Firepoint Y coordinate multiplier:"))
stuff_int(&scaleY);
if(optional_string("Autoaim Frame:"))
stuff_int(&autoaim_frame);
hud_gauge->initBitmaps(fname);
hud_gauge->initFirepointDisplay(firepoints, scaleX, scaleY, size);
hud_gauge->setAutoaimFrame(autoaim_frame);
gauge_assign_common(settings, std::move(hud_gauge));
}
+40 -1
View File
@@ -229,6 +229,7 @@ static int Threat_lock_frame; // frame offset of current lock flashing warnin
HudGaugeReticle::HudGaugeReticle():
HudGauge(HUD_OBJECT_CENTER_RETICLE, HUD_CENTER_RETICLE, true, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_TOPDOWN | VM_OTHER_SHIP), 255, 255, 255)
{
has_autoaim_lock = false;
}
void HudGaugeReticle::initBitmaps(char *fname)
@@ -248,9 +249,40 @@ void HudGaugeReticle::initFirepointDisplay(bool firepoint, int scaleX, int scale
void HudGaugeReticle::render(float /*frametime*/)
{
ship_info *sip = &Ship_info[Player_ship->ship_info_index];
if (autoaim_frame_offset > 0 || sip->autoaim_lock_snd.isValid() || sip->autoaim_lost_snd.isValid()) {
ship *shipp = &Ships[Objects[Player->objnum].instance];
ship_weapon *swp = &shipp->weapons;
ai_info *aip = &Ai_info[shipp->ai_index];
if (aip->target_objnum != -1) {
bool autoaiming = false;
autoaiming = in_autoaim_fov(shipp, swp->current_primary_bank, &Objects[aip->target_objnum]);
if (autoaiming) {
if (!has_autoaim_lock && sip->autoaim_lock_snd.isValid()) {
snd_play(gamesnd_get_game_sound(sip->autoaim_lock_snd));
//snd_play( gamesnd_get_game_sound(ship_get_sound(Player_obj, GameSounds::THREAT_FLASH)));
}
has_autoaim_lock = true;
}
else {
if (has_autoaim_lock && sip->autoaim_lost_snd.isValid()) {
snd_play(gamesnd_get_game_sound(sip->autoaim_lost_snd));
}
has_autoaim_lock = false;
}
}
}
setGaugeColor(HUD_C_BRIGHT);
renderBitmap(crosshair.first_frame, position[0], position[1]);
if (has_autoaim_lock)
renderBitmap(crosshair.first_frame + autoaim_frame_offset, position[0], position[1]);
else
renderBitmap(crosshair.first_frame, position[0], position[1]);
if (firepoint_display) {
fp.clear();
@@ -342,6 +374,13 @@ void HudGaugeReticle::getFirepointStatus() {
}
}
void HudGaugeReticle::setAutoaimFrame(int framenum) {
if (framenum < 0 || framenum > crosshair.num_frames - 1)
autoaim_frame_offset = 0;
else
autoaim_frame_offset = framenum;
}
void HudGaugeReticle::pageIn()
{
bm_page_in_aabitmap( crosshair.first_frame, crosshair.num_frames);
+3
View File
@@ -42,6 +42,8 @@ protected:
int firepoint_size;
int firepoint_scale_x;
int firepoint_scale_y;
int autoaim_frame_offset;
bool has_autoaim_lock;
public:
HudGaugeReticle();
void render(float frametime) override;
@@ -49,6 +51,7 @@ public:
void pageIn() override;
void initFirepointDisplay(bool firepoint, int scaleX, int scaleY, int size);
void getFirepointStatus();
void setAutoaimFrame(int framenum);
};
class HudGaugeThrottle: public HudGauge
+16 -16
View File
@@ -105,7 +105,7 @@ int Menu_pgdn_coords[GR_NUM_RESOLUTIONS][2] = {
typedef struct mmode_item {
int instance; // instance in Ships/Wings array of this menu item
int active; // active items are in bold text -- inactive items greyed out
char text[NAME_LENGTH]; // text to display on the menu
SCP_string text; // text to display on the menu
} mmode_item;
#define MAX_MENU_ITEMS 50 // max number of items in the menu
@@ -154,7 +154,7 @@ int keys_used[] = { KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_
#define TYPE_REPAIR_REARM_ABORT_ITEM 5
char Comm_order_types[NUM_COMM_ORDER_TYPES][NAME_LENGTH];
SCP_string Comm_order_types[NUM_COMM_ORDER_TYPES];
comm_order Comm_orders[NUM_COMM_ORDER_ITEMS];
@@ -207,25 +207,25 @@ void hud_init_comm_orders()
for (i = 0; i < NUM_COMM_ORDER_TYPES; i++)
{
strcpy_s(Comm_order_types[i], temp_comm_order_types[i]);
Comm_order_types[i] = temp_comm_order_types[i];
}
for (i = 0; i < NUM_COMM_ORDER_ITEMS; i++)
{
strcpy_s(Comm_orders[i].name, XSTR(Sexp_comm_orders[i].name, Sexp_comm_orders[i].xstring));
Comm_orders[i].name = XSTR(Sexp_comm_orders[i].name, Sexp_comm_orders[i].xstring);
Comm_orders[i].item = Sexp_comm_orders[i].item;
}
}
// Text to display on the messaging menu when using the shortcut keys
char *comm_order_get_text(int item)
const char *comm_order_get_text(int item)
{
int i;
for (i = 0; i < NUM_COMM_ORDER_ITEMS; i++)
{
if (Comm_orders[i].item == item)
return Comm_orders[i].name;
return Comm_orders[i].name.c_str();
}
// not found
@@ -404,7 +404,7 @@ int hud_squadmsg_count_ships(int add_to_menu)
if (add_to_menu)
{
Assert ( Num_menu_items < MAX_MENU_ITEMS );
strcpy_s( MsgItems[Num_menu_items].text, shipp->get_display_string() );
MsgItems[Num_menu_items].text = shipp->get_display_string();
end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text); // truncate the name if it has a # in it
MsgItems[Num_menu_items].instance = SHIP_INDEX(shipp);
MsgItems[Num_menu_items].active = 1;
@@ -485,7 +485,7 @@ int hud_squadmsg_count_wings( int add_to_menu )
count++;
if ( add_to_menu ) {
Assert ( Num_menu_items < MAX_MENU_ITEMS );
strcpy_s( MsgItems[Num_menu_items].text, Wings[wingnum].name );
MsgItems[Num_menu_items].text = Wings[wingnum].name;
end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text);
MsgItems[Num_menu_items].instance = wingnum;
MsgItems[Num_menu_items].active = 1;
@@ -507,7 +507,7 @@ int hud_squadmsg_count_wings( int add_to_menu )
count++;
if ( add_to_menu ) {
Assert ( Num_menu_items < MAX_MENU_ITEMS );
strcpy_s( MsgItems[Num_menu_items].text, Wings[i].name );
MsgItems[Num_menu_items].text = Wings[i].name;
end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text);
MsgItems[Num_menu_items].instance = i;
MsgItems[Num_menu_items].active = 1;
@@ -1625,7 +1625,7 @@ void hud_squadmsg_type_select( )
// Add the items
for (i = 0; i < NUM_COMM_ORDER_TYPES; i++)
{
strcpy_s(MsgItems[i].text, Comm_order_types[i]);
MsgItems[i].text = Comm_order_types[i];
MsgItems[i].active = 1; // assume active
}
Num_menu_items = NUM_COMM_ORDER_TYPES;
@@ -1916,7 +1916,7 @@ void hud_squadmsg_reinforcement_select()
}
Assert ( Num_menu_items < MAX_MENU_ITEMS );
strcpy_s( MsgItems[Num_menu_items].text, rp->name );
MsgItems[Num_menu_items].text = rp->name;
end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text);
MsgItems[Num_menu_items].instance = i;
MsgItems[Num_menu_items].active = 0;
@@ -1984,7 +1984,7 @@ void hud_squadmsg_ship_command()
// the order will be activated if the bit is set for the ship.
if ( default_orders & Comm_orders[i].item ) {
Assert ( Num_menu_items < MAX_MENU_ITEMS );
strcpy_s(MsgItems[Num_menu_items].text, Comm_orders[i].name);
MsgItems[Num_menu_items].text = Comm_orders[i].name.c_str();
MsgItems[Num_menu_items].instance = Comm_orders[i].item;
MsgItems[Num_menu_items].active = 0;
// check the bit to see if the command is active
@@ -2027,7 +2027,7 @@ void hud_squadmsg_ship_command()
if ( !all_accept ) {
// either modify the text if a partial accept, or grey it out if no one accepts
if ( partial_accept ) {
strcat_s( MsgItems[Num_menu_items].text, XSTR( "(*)", 320) );
MsgItems[Num_menu_items].text += XSTR("(*)", 320);
} else {
MsgItems[Num_menu_items].active = 0;
}
@@ -2085,7 +2085,7 @@ void hud_squadmsg_wing_command()
// to be available in the wing.
if ( default_orders & Comm_orders[i].item ) {
Assert ( Num_menu_items < MAX_MENU_ITEMS );
strcpy_s(MsgItems[Num_menu_items].text, Comm_orders[i].name);
MsgItems[Num_menu_items].text = Comm_orders[i].name;
MsgItems[Num_menu_items].instance = Comm_orders[i].item;
MsgItems[Num_menu_items].active = 0;
@@ -2445,7 +2445,7 @@ int hud_query_order_issued(char *to, char *order_name, char *target_name, int ti
for (i = 0; i < NUM_COMM_ORDER_ITEMS; i++)
if (!stricmp(order_name, Comm_orders[i].name))
if (!stricmp(order_name, Comm_orders[i].name.c_str()))
order = Comm_orders[i].item;
// Goober5000 - if not found, check compatibility
@@ -2679,7 +2679,7 @@ void HudGaugeSquadMessage::render(float /*frametime*/)
for ( i = 0; i < nitems; i++ ) {
int item_num;
char *text = MsgItems[First_menu_item+i].text;
const char *text = MsgItems[First_menu_item+i].text.c_str();
// blit the background
// hud_set_default_color();
+1 -1
View File
@@ -63,7 +63,7 @@ class object;
// data structure to hold character string of commands for comm menu
typedef struct comm_order {
char name[NAME_LENGTH];
SCP_string name;
int item;
} comm_order;
+10 -8
View File
@@ -4364,7 +4364,7 @@ void HudGaugeLeadSight::render(float /*frametime*/)
// hud_cease_subsystem_targeting() will cease targeting the current targets subsystems
//
void hud_cease_subsystem_targeting(int print_message)
void hud_cease_subsystem_targeting(bool print_message)
{
int ship_index;
@@ -4383,15 +4383,17 @@ void hud_cease_subsystem_targeting(int print_message)
hud_lock_reset();
}
// hud_cease_targeting() will cease all targeting (main target and subsystem)
//
void hud_cease_targeting()
// hud_cease_targeting() will cease targeting main target and subsystem
// does not turn off auto-targeting by default
void hud_cease_targeting(bool deliberate)
{
set_target_objnum( Player_ai, -1 );
Players[Player_num].flags &= ~PLAYER_FLAGS_AUTO_TARGETING;
hud_cease_subsystem_targeting(0);
HUD_sourced_printf(HUD_SOURCE_HIDDEN, "%s", XSTR( "Deactivating targeting system", 325));
hud_lock_reset();
hud_cease_subsystem_targeting(false);
if (deliberate) {
Players[Player_num].flags &= ~PLAYER_FLAGS_AUTO_TARGETING;
HUD_sourced_printf(HUD_SOURCE_HIDDEN, "%s", XSTR("Deactivating targeting system", 325));
}
}
// hud_restore_subsystem_target() will remember the last targeted subsystem
+3 -2
View File
@@ -26,6 +26,7 @@ struct weapon_info;
#define MATCH_SPEED_THRESHOLD 0.1f // minimum speed target must be moving for match speed to apply
#define CARGO_RADIUS_DELTA 100 // distance added to radius required for cargo scanning
#define CAPITAL_CARGO_RADIUS_DELTA 250 // distance added to radius required for cargo scanning
const int CARGO_RADIUS_REAL_DELTA = 50; // difference in distances used for cargo scanning of subsystems (which also uses object radius), vs whole-ship scanning
#define CARGO_REVEAL_MIN_DIST 150 // minimum distance for reveal cargo (used if radius+CARGO_RADIUS_DELTA < CARGO_REVEAL_MIN_DIST)
#define CAP_CARGO_REVEAL_MIN_DIST 300 // minimum distance for reveal cargo (used if radius+CARGO_RADIUS_DELTA < CARGO_REVEAL_MIN_DIST)
#define CARGO_MIN_DOT_TO_REVEAL 0.95 // min dot to proceed to have cargo scanning take place
@@ -113,8 +114,8 @@ void hud_target_random_ship();
void hud_target_next_subobject();
void hud_target_prev_subobject();
void hud_cease_subsystem_targeting(int print_message=1);
void hud_cease_targeting();
void hud_cease_subsystem_targeting(bool print_message = true);
void hud_cease_targeting(bool deliberate = false);
void hud_restore_subsystem_target(ship* shipp);
int subsystem_in_sight(object* objp, ship_subsys* subsys, vec3d *eye, vec3d* subsystem);
vec3d* get_subsystem_world_pos(object* parent_obj, ship_subsys* subsys, vec3d* world_pos);
+3 -2
View File
@@ -81,7 +81,8 @@ SCP_string getJoystickGUID(SDL_Joystick *stick)
joystickGUID.resize(GUID_STR_SIZE - 1);
// Make sure the GUID is upper case
std::transform(begin(joystickGUID), end(joystickGUID), begin(joystickGUID), toupper);
std::transform(begin(joystickGUID), end(joystickGUID), begin(joystickGUID),
[](char c) { return (char)::toupper(c); });
return joystickGUID;
}
@@ -96,7 +97,7 @@ bool isCurrentJoystick(Joystick* testStick) {
}
SCP_string guidStr(currentGUID);
std::transform(begin(guidStr), end(guidStr), begin(guidStr), toupper);
std::transform(begin(guidStr), end(guidStr), begin(guidStr), [](char c) { return (char)::toupper(c); });
if (testStick->getGUID() != guidStr) {
return false; // GUID doesn't match
+1 -1
View File
@@ -2667,7 +2667,7 @@ int button_function(int n)
// stop targeting ship
case STOP_TARGETING_SHIP:
hud_cease_targeting();
hud_cease_targeting(true);
break;
// stop targeting subsystems on ship
+1 -1
View File
@@ -256,7 +256,7 @@ void mouse_mark_button( uint flags, int set)
SDL_UnlockMutex( mouse_lock );
Script_system.SetHookVar("MouseButton", 'i', &flags);
Script_system.SetHookVar("MouseButton", 'i', flags);
//WMC - On Mouse Pressed and On Mouse Released hooks
if (set == 1)
+14 -11
View File
@@ -192,13 +192,6 @@ void labviewer_change_model(char *model_fname, int lod = 0, int sel_index = -1)
Lab_model_num = model_load(model_fname, (valid_ship) ? Ship_info[sel_index].n_subsystems : 0, subsystems, 0);
if (Lab_model_num >= 0) {
strcpy_s(Lab_model_filename, model_fname);
}
else {
memset(Lab_model_filename, 0, sizeof(Lab_model_filename));
}
if (valid_ship) {
if (Lab_model_num >= 0) {
model_page_in_textures(Lab_model_num, sel_index);
@@ -1289,7 +1282,7 @@ void labviewer_make_desc_window(Button * /*caller*/)
void labviewer_make_ship_window(Button * /*caller*/)
{
GUIObject *cbp;
TreeItem *ctip, *stip;
TreeItem *stip;
int x, idx;
if (Lab_mode == LAB_MODE_SHIP) {
@@ -1349,8 +1342,7 @@ void labviewer_make_ship_window(Button * /*caller*/)
stip = Lab_species_nodes[Species_info.size()];
}
ctip = cmp->AddItem(stip, it->name, (int)std::distance(Ship_info.cbegin(), it), false, labviewer_change_ship);
cmp->AddItem(ctip, "Model", 0, false, labviewer_change_ship_lod);
cmp->AddItem(stip, it->name, (int)std::distance(Ship_info.cbegin(), it), false, labviewer_change_ship);
//cmp->AddItem(ctip, "Debris", 99, false, labviewer_change_ship_lod);
}
@@ -1393,7 +1385,7 @@ void labviewer_make_ship_window(Button * /*caller*/)
void labviewer_change_ship_lod(Tree* caller)
{
int ship_index = (int)(caller->GetSelectedItem()->GetParentItem()->GetData());
int ship_index = caller->GetSelectedItem()->GetData();
Assert(ship_index >= 0);
if (Lab_selected_object == -1)
@@ -1418,6 +1410,16 @@ void labviewer_change_ship_lod(Tree* caller)
Lab_last_selected_ship = Lab_selected_index;
labviewer_change_model(Ship_info[ship_index].pof_file, caller->GetSelectedItem()->GetData(), ship_index);
//update the displayed POF filename
//moved out of labviewer_change_model which apparently doesn't do much after the first ship is loaded
if (Lab_model_num >= 0) {
strcpy_s(Lab_model_filename, Ship_info[ship_index].pof_file);
}
else {
memset(Lab_model_filename, 0, sizeof(Lab_model_filename));
}
if (Ship_info[ship_index].uses_team_colors) {
Lab_team_color = Ship_info[ship_index].default_team_name;
}
@@ -1438,6 +1440,7 @@ void labviewer_change_ship(Tree *caller)
labviewer_update_desc_window();
labviewer_update_flags_window();
labviewer_update_variables_window();
labviewer_change_ship_lod(caller);
}
// --------------------------- Weapons Window --------------------------------
+27
View File
@@ -0,0 +1,27 @@
#include "libs/jansson.h"
namespace {
int json_write_callback(const char *buffer, size_t size, void *data) {
auto* cfp = (CFILE*)data;
if ((size_t)cfwrite(buffer, 1, (int)size, cfp) != size) {
return -1; // Error
} else {
return 0; // Success
}
}
size_t json_read_callback(void *buffer, size_t buflen, void *data) {
auto fp = (CFILE*)data;
return (size_t)cfread(buffer, 1, (int)buflen, fp);
}
}
int json_dump_cfile(const json_t* json, CFILE* file, size_t flags) {
return json_dump_callback(json, json_write_callback, file, flags);
}
json_t* json_load_cfile(CFILE* cfile, size_t flags, json_error_t* error) {
return json_load_callback(json_read_callback, cfile, flags, error);
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "cfile/cfile.h"
#include <jansson.h>
int json_dump_cfile(const json_t *json, CFILE* file, size_t flags);
json_t *json_load_cfile(CFILE* cfile, size_t flags, json_error_t *error);
+6
View File
@@ -2397,6 +2397,12 @@ void vm_vec_random_cone(vec3d *out, const vec3d *in, float min_angle, float max_
const matrix *rot;
matrix m;
if (max_angle < min_angle) {
auto tmp = min_angle;
min_angle = max_angle;
max_angle = tmp;
}
// get an orientation matrix
if(orient != NULL){
rot = orient;
+68 -32
View File
@@ -32,16 +32,13 @@
#include "popup/popup.h"
#include "ship/ship.h"
#include "ui/ui.h"
#include "barracks.h"
#include "mod_table/mod_table.h"
//Returns 0 on failure, 1 on success
int delete_pilot_file( char *pilot_name ); // manage_pilot.cpp
// stats defines
//#define NUM_STAT_LINES (21 + MAX_SHIP_CLASSES) // Goober5000
#define STAT_COLUMN1_W 40
#define STAT_COLUMN1_W 40*2 // as we might use Unicode //ksotar
#define STAT_COLUMN2_W 10
static int Stat_column1_w[GR_NUM_RESOLUTIONS] =
@@ -84,6 +81,7 @@ static int Barracks_stats_coords[GR_NUM_RESOLUTIONS][4] = {
}
};
static int Barracks_stats2_coords[GR_NUM_RESOLUTIONS][3] = {
{ // GR_640
276, 212, 81 // X2, , W2
@@ -270,6 +268,9 @@ UI_XSTR Barracks_text[GR_NUM_RESOLUTIONS][BARRACKS_NUM_TEXT] = {
static size_t Num_stat_lines;
static char (*Stat_labels)[STAT_COLUMN1_W];
static char (*Stats)[STAT_COLUMN2_W];
static uint16_t Stats_max_width; // If Unicode language is used then we adapt stats width for new words/strings length
static uint16_t Stats_X2; // And numbers position adapted as well
static int Player_sel_mode;
@@ -303,7 +304,7 @@ void barracks_squad_change_popup();
#define STRCPY1(a, b) do { \
Assert(strlen(b) < STAT_COLUMN1_W); \
strcpy_s(a, b); \
} while (0)
} while (false)
void barracks_init_stats(scoring_struct *stats)
{
@@ -388,28 +389,30 @@ void barracks_init_stats(scoring_struct *stats)
Num_stat_lines++;
Assert(Num_stat_lines < Max_stat_lines);
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary friendly hits:", 59));
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Secondary friendly hits:", 59));
sprintf(Stats[Num_stat_lines], "%u", stats->s_bonehead_hits);
Num_stat_lines++;
Assert(Num_stat_lines < Max_stat_lines);
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary hit %:", 60));
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Secondary hit %:", 60));
if (stats->s_shots_fired > 0) {
f = (float) stats->s_shots_hit * 100.0f / (float) stats->s_shots_fired;
} else {
f = (float)stats->s_shots_hit * 100.0f / (float)stats->s_shots_fired;
}
else {
f = 0.0f;
}
sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
sprintf(Stats[Num_stat_lines], XSTR("%.1f%%", 55), f);
Num_stat_lines++;
Assert(Num_stat_lines < Max_stat_lines);
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary friendly hit %:", 61));
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Secondary friendly hit %:", 61));
if (stats->s_shots_fired > 0) {
f = (float) stats->s_bonehead_hits * 100.0f / (float) stats->s_shots_fired;
} else {
f = (float)stats->s_bonehead_hits * 100.0f / (float)stats->s_shots_fired;
}
else {
f = 0.0f;
}
sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
sprintf(Stats[Num_stat_lines], XSTR("%.1f%%", 55), f);
Num_stat_lines++;
Assert(Num_stat_lines < Max_stat_lines);
@@ -418,12 +421,12 @@ void barracks_init_stats(scoring_struct *stats)
Num_stat_lines++;
Assert(Num_stat_lines < Max_stat_lines);
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Total kills:", 62));
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Total kills:", 62));
sprintf(Stats[Num_stat_lines], "%d", stats->kill_count_ok);
Num_stat_lines++;
Assert(Num_stat_lines < Max_stat_lines);
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Assists:", 63));
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Assists:", 63));
sprintf(Stats[Num_stat_lines], "%d", stats->assists);
Num_stat_lines++;
@@ -433,7 +436,7 @@ void barracks_init_stats(scoring_struct *stats)
Num_stat_lines++;
Assert(Num_stat_lines < Max_stat_lines);
strcpy_s(Stat_labels[Num_stat_lines], XSTR( "Current Score:", 1583));
strcpy_s(Stat_labels[Num_stat_lines], XSTR("Current Score:", 1583));
sprintf(Stats[Num_stat_lines], "%d", stats->score);
Num_stat_lines++;
@@ -447,7 +450,7 @@ void barracks_init_stats(scoring_struct *stats)
Stats[Num_stat_lines][0] = 0;
Num_stat_lines++;
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "*Kills by Ship Type", 64));
STRCPY1(Stat_labels[Num_stat_lines], XSTR("*Kills by Ship Type", 64));
Stats[Num_stat_lines][0] = 0;
Num_stat_lines++;
@@ -482,13 +485,29 @@ void barracks_init_stats(scoring_struct *stats)
// add the score from kills
Assert((Num_stat_lines + 1) < Max_stat_lines);
STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Score from kills only:", 1636));
STRCPY1(Stat_labels[Num_stat_lines], XSTR("Score from kills only:", 1636));
sprintf(Stats[Num_stat_lines], "%d", score_from_kills);
Num_stat_lines++;
for (i=0; i<Num_stat_lines; i++) {
font::force_fit_string(Stat_labels[i], Stat_column1_w[gr_screen.res], Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD]);
font::force_fit_string(Stats[i], Stat_column2_w[gr_screen.res], Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD]);
int w;
Stats_max_width = 0;
Stats_X2 = 0;
if (Unicode_text_mode && (gr_screen.res != GR_640)) {
for (i = 0; i < Num_stat_lines; i++) { // Find the longest string in labels to base list appearance on that
gr_get_string_size(&w, nullptr, Stat_labels[i]);
if (Stats_max_width < w)
Stats_max_width = (uint16_t)w;
}
Stats_max_width += 20;
Stats_X2 = Stats_max_width + 46;
}
else {
Stats_max_width = (uint16_t) Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD];
Stats_X2 = (uint16_t) Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD];
for (i = 0; i < Num_stat_lines; i++) {
font::force_fit_string(Stat_labels[i], Stat_column1_w[gr_screen.res], Stats_max_width);
font::force_fit_string(Stats[i], Stat_column2_w[gr_screen.res], Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD]);
}
}
}
@@ -539,7 +558,7 @@ int barracks_new_pilot_selected()
Cur_pilot->callsign[0] = 0; // this indicates no pilot active
return -1;
} else {
if (!Pilot.load_savefile(Cur_pilot->current_campaign)) {
if (!Pilot.load_savefile(Cur_pilot, Cur_pilot->current_campaign)) {
// set single player squad image to multi if campaign can't be loaded
strcpy_s(Cur_pilot->s_squad_filename, Cur_pilot->m_squad_filename);
}
@@ -667,6 +686,24 @@ int barracks_pilot_accepted()
return 0;
}
void barracks_accept_pilot(player* plr) {
// set pilot image
if (Game_mode & GM_MULTIPLAYER) {
player_set_squad_bitmap(plr, plr->m_squad_filename, true);
} else {
player_set_squad_bitmap(plr, plr->s_squad_filename, false);
}
// MWA -- I think that we should be writing plr here.
Pilot.save_player(plr);
Player = &Players[Player_num];
Player->assign(plr);
os_config_write_string(nullptr, "LastPlayer", plr->callsign);
gameseq_post_event(GS_EVENT_MAIN_MENU);
}
// scroll up barracks pilot list one line
void barracks_scroll_callsign_up()
{
@@ -831,7 +868,6 @@ void barracks_delete_pilot()
{
char buf[MAX_FILENAME_LEN];
int active = 0;
int del_rval;
if (!Num_pilots) {
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
@@ -857,7 +893,7 @@ void barracks_delete_pilot()
strcpy_s(buf, Pilots[Selected_line]);
del_rval = delete_pilot_file(buf);
auto del_rval = delete_pilot_file(buf);
if ( !del_rval ) {
popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, XSTR("Error\nFailed to delete pilot file. File may be read-only.", 1599));
@@ -953,7 +989,7 @@ void barracks_init_player_stuff(int mode)
Get_file_list_filter = barracks_pilot_filter;
Num_pilots =
cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.plr"), CF_SORT_TIME,
cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.json"), CF_SORT_TIME,
nullptr, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
int ranks[MAX_PILOTS];
@@ -1190,18 +1226,18 @@ void barracks_display_pilot_stats()
gr_get_string_size(&w, &h, str);
i = Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y + h / 2 - 1;
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD], i, Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] - w - 2, i, GR_RESIZE_MENU);
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] + 1, i, Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD], i, GR_RESIZE_MENU);
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD], i, Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width - w - 2, i, GR_RESIZE_MENU);
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width + 1, i, Stats_X2 + Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD], i, GR_RESIZE_MENU);
} else {
gr_set_color_fast(&Color_text_normal);
}
gr_get_string_size(&w, NULL, str);
gr_printf_menu(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] - w, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
gr_printf_menu(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width - w, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
str = Stats[z];
if (*str) {
gr_printf_menu(Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
gr_printf_menu(Stats_X2, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
}
y += font_height;
+4
View File
@@ -12,6 +12,8 @@
#ifndef _BARRACKS_H
#define _BARRACKS_H
#include "playerman/player.h"
extern int Barracks_overlay_id;
// initialize the barracks
@@ -23,4 +25,6 @@ void barracks_do_frame(float frametime);
// close the barracks
void barracks_close();
void barracks_accept_pilot(player* plr);
#endif // _BARRACKS_H
+12 -9
View File
@@ -10,15 +10,16 @@
#include <cstdlib>
#include <climits>
#include "freespace.h"
#include "anim/animplay.h"
#include "anim/packunpack.h"
#include "cmdline/cmdline.h"
#include "freespace.h"
#include "gamehelp/contexthelp.h"
#include "gamesequence/gamesequence.h"
#include "gamesnd/eventmusic.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/alphacolors.h"
#include "globalincs/version.h"
#include "graphics/generic.h"
#include "io/key.h"
#include "io/mouse.h"
@@ -33,9 +34,9 @@
#include "network/multiui.h"
#include "network/multiutil.h"
#include "parse/parselo.h"
#include "scripting/scripting.h"
#include "playerman/player.h"
#include "popup/popup.h"
#include "scripting/scripting.h"
#include "sound/audiostr.h"
#ifndef NDEBUG
@@ -410,6 +411,8 @@ void main_hall_init(const SCP_string &main_hall_name)
return;
}
// gameseq_post_event(GS_EVENT_SCRIPTING);
int idx;
SCP_string main_hall_to_load;
@@ -923,9 +926,10 @@ void main_hall_do(float frametime)
// custom action
case SCRIPT_REGION:
const char *lua = it->lua_action.c_str();
bool success = Script_system.EvalString(lua, NULL, NULL, lua);
if(!success)
Warning(LOCATION, "mainhall '+Door Action / $Script' failed to evaluate \"%s\"; check your syntax", lua);
bool success = Script_system.EvalString(lua, lua);
if (!success)
Warning(LOCATION,
"mainhall '+Door Action / $Script' failed to evaluate \"%s\"; check your syntax", lua);
break;
} // END switch (code)
@@ -1666,20 +1670,19 @@ void main_hall_reset_ambient_vol()
void main_hall_blit_version()
{
int w, h;
char version_string[100];
// format the version string
get_version_string(version_string, sizeof(version_string));
auto version_string = gameversion::get_version_string();
int old_font = font::get_current_fontnum();
font::set_font(Main_hall->font);
// get the length of the string
gr_get_string_size(&w,&h,version_string);
gr_get_string_size(&w, &h, version_string.c_str());
// print the string near the lower left corner
gr_set_color_fast(&Color_bright_white);
gr_string(5, gr_screen.max_h_unscaled_zoomed - (h * 2 + 6), version_string, GR_RESIZE_MENU_ZOOMED);
gr_string(5, gr_screen.max_h_unscaled_zoomed - (h * 2 + 6), version_string.c_str(), GR_RESIZE_MENU_ZOOMED);
font::set_font(old_font);
}
+143 -28
View File
@@ -11,14 +11,14 @@
#include <climits>
#include <cctype>
#include "freespace.h"
#include "cfile/cfile.h"
#include "cmdline/cmdline.h"
#include "debugconsole/console.h"
#include "freespace.h"
#include "gamesequence/gamesequence.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/alphacolors.h"
#include "globalincs/version.h"
#include "io/key.h"
#include "localization/localize.h"
#include "menuui/mainhallmenu.h"
@@ -34,6 +34,7 @@
#include "popup/popup.h"
#include "ui/ui.h"
#include "playermenu.h"
#include "graphics/paths/PathRenderer.h"
// --------------------------------------------------------------------------------------------------------
@@ -203,20 +204,18 @@ void player_select_eval_very_first_pilot();
void player_select_commit();
void player_select_cancel_create();
extern int delete_pilot_file(char *pilot_name);
/*
* validate that a pilot/player was created with the same language FSO is currently using
*
* @param pilots callsign
* @note not longer needed if intel entry "primary keys" change to a non-translated value
*/
bool valid_pilot_lang(char *callsign)
bool valid_pilot_lang(const char *callsign)
{
char pilot_lang[LCL_LANG_NAME_LEN+1], current_lang[LCL_LANG_NAME_LEN+1];
SCP_string filename = callsign;
filename += ".plr";
filename += ".json";
lcl_get_language_name(current_lang);
if (Pilot.verify(filename.c_str(), NULL, pilot_lang)) {
@@ -353,7 +352,7 @@ void player_select_do()
// Goober5000 - display a popup warning about problems in the mod
if ((Global_warning_count > 10 || Global_error_count > 0) && !Startup_warning_dialog_displayed) {
char text[512];
sprintf(text, "Warning!\n\nThe currently active mod has generated %d warnings and/or errors during program startup. These could have been caused by anything from incorrectly formated table files to corrupt models. While FreeSpace Open will attempt to compensate for these issues, it cannot guarantee a trouble-free gameplay experience. Source Code Project staff cannot provide assistance or support for these problems, as they are caused by the mod's data files, not FreeSpace Open's source code.", Global_warning_count + Global_error_count);
sprintf(text, "Warning!\n\nThe currently active mod has generated %d warnings and/or errors during program startup. These could have been caused by anything from incorrectly formated table files to corrupt models.\n\nWhile FreeSpace Open will attempt to compensate for these issues, it cannot guarantee a trouble-free gameplay experience.\n\nPlease contact the authors of the mod for assistance.", Global_warning_count + Global_error_count);
popup(PF_TITLE_BIG | PF_TITLE_RED | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, text);
Startup_warning_dialog_displayed = true;
}
@@ -476,7 +475,7 @@ void player_select_close()
}
// if(Player_select_palette >= 0){
// bm_release(Player_select_palette);
//Player_select_palette = -1;
//Player_select_palette = -1;GS_EVENT_MAIN_MENU
// }
// setup the player struct
@@ -502,9 +501,11 @@ void player_select_close()
Player = NULL;
} else {
// NOTE: this may fail if there is no current campaign, it's not fatal
Pilot.load_savefile(Player->current_campaign);
Pilot.load_savefile(Player, Player->current_campaign);
}
os_config_write_string(nullptr, "LastPlayer", Player->callsign);
if (Player_select_force_main_hall != "") {
main_hall_init(Player_select_force_main_hall);
}
@@ -750,14 +751,14 @@ int player_select_create_new_pilot()
void player_select_delete_pilot()
{
char filename[MAX_PATH_LEN + 1];
int i, del_rval;
int i;
// tack on the full path and the pilot file extension
// build up the path name length
// make sure we do this based upon whether we're in single or multiplayer mode
strcpy_s( filename, Pilots[Player_select_pilot] );
del_rval = delete_pilot_file(filename);
auto del_rval = delete_pilot_file(filename);
if ( !del_rval ) {
popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, XSTR("Error\nFailed to delete pilot file. File may be read-only.", 1599));
@@ -816,8 +817,6 @@ void player_select_scroll_list_down()
// fill in the data on the last played pilot (callsign and is_multi or not)
int player_select_get_last_pilot_info()
{
// TODO: Replace this with a function that does this properly for the new pilot code.
const char *last_player = os_config_read_string( NULL, "LastPlayer", NULL);
if (last_player == NULL) {
@@ -850,11 +849,15 @@ int player_select_get_last_pilot()
return 0;
}
Get_file_list_filter = player_select_pilot_file_filter;
Player_select_num_pilots = cf_get_file_list_preallocated(
MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.plr"), CF_SORT_TIME, nullptr,
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
auto pilots = player_select_enumerate_pilots();
// Copy the enumerated pilots into the appropriate local variables
Player_select_num_pilots = static_cast<int>(pilots.size());
for (auto i = 0; i < MAX_PILOTS; ++i) {
if (i < static_cast<int>(pilots.size())) {
strcpy_s(Pilots_arr[i], pilots[i].c_str());
}
Pilots[i] = Pilots_arr[i];
}
Player_select_pilot = -1;
idx = 0;
@@ -889,12 +892,15 @@ void player_select_init_player_stuff(int mode)
// set the select mode to single player for default
Player_select_mode = mode;
// load up the list of players based upon the Player_select_mode (single or multiplayer)
Get_file_list_filter = player_select_pilot_file_filter;
Player_select_num_pilots =
cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.plr"), CF_SORT_TIME,
nullptr, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
auto pilots = player_select_enumerate_pilots();
// Copy the enumerated pilots into the appropriate local variables
Player_select_num_pilots = static_cast<int>(pilots.size());
for (auto i = 0; i < MAX_PILOTS; ++i) {
if (i < static_cast<int>(pilots.size())) {
strcpy_s(Pilots_arr[i], pilots[i].c_str());
}
Pilots[i] = Pilots_arr[i];
}
// if we have a "last_player", and they're in the list, bash them to the top of the list
if (Player_select_last_pilot[0] != '\0') {
@@ -1126,13 +1132,13 @@ void player_select_process_input(int k)
void player_select_display_copyright()
{
int sx, sy, w;
char Copyright_msg1[256], Copyright_msg2[256];
char Copyright_msg2[256];
// strcpy_s(Copyright_msg1, XSTR("Descent: FreeSpace - The Great War, Copyright c 1998, Volition, Inc.", -1));
gr_set_color_fast(&Color_white);
// sprintf(Copyright_msg1, NOX("FreeSpace 2"));
get_version_string(Copyright_msg1, sizeof(Copyright_msg1));
auto Copyright_msg1 = gameversion::get_version_string();
if (Unicode_text_mode) {
// Use a Unicode character if we are in unicode mode instead of using special characters
strcpy_s(Copyright_msg2, XSTR("Copyright \xC2\xA9 1999, Volition, Inc. All rights reserved.", 385));
@@ -1140,10 +1146,10 @@ void player_select_display_copyright()
sprintf(Copyright_msg2, XSTR("Copyright %c 1999, Volition, Inc. All rights reserved.", 385), lcl_get_font_index(font::get_current_fontnum()) + 4);
}
gr_get_string_size(&w, NULL, Copyright_msg1);
gr_get_string_size(&w, nullptr, Copyright_msg1.c_str());
sx = (int)std::lround((gr_screen.max_w_unscaled / 2) - w/2.0f);
sy = (gr_screen.max_h_unscaled - 2) - 2*gr_get_font_height();
gr_string(sx, sy, Copyright_msg1, GR_RESIZE_MENU);
gr_string(sx, sy, Copyright_msg1.c_str(), GR_RESIZE_MENU);
gr_get_string_size(&w, NULL, Copyright_msg2);
sx = (int)std::lround((gr_screen.max_w_unscaled / 2) - w/2.0f);
@@ -1384,3 +1390,112 @@ void player_tips_popup()
}
} while(ret > 0);
}
SCP_vector<SCP_string> player_select_enumerate_pilots() {
// load up the list of players based upon the Player_select_mode (single or multiplayer)
Get_file_list_filter = player_select_pilot_file_filter;
SCP_vector<SCP_string> pilots;
cf_get_file_list(pilots, CF_TYPE_PLAYERS, "*.json", CF_SORT_TIME, nullptr, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
return pilots;
}
SCP_string player_get_last_player()
{
const char* last_player = os_config_read_string(nullptr, "LastPlayer", nullptr);
if (last_player == nullptr) {
// No last player stored
return SCP_string();
}
return SCP_string(last_player);
}
void player_finish_select(const char* callsign, bool is_multi) {
Player_num = 0;
Player = &Players[0];
Player->flags |= PLAYER_FLAGS_STRUCTURE_IN_USE;
// New pilot file makes no distinction between multi pilots and regular ones, so let's do this here.
if (is_multi) {
Player->flags |= PLAYER_FLAGS_IS_MULTI;
}
// WMC - Set appropriate game mode
if ( Player->flags & PLAYER_FLAGS_IS_MULTI ) {
Game_mode = GM_MULTIPLAYER;
} else {
Game_mode = GM_NORMAL;
}
// now read in a the pilot data
if ( !Pilot.load_player(callsign, Player) ) {
Error(LOCATION,"Couldn't load pilot file, bailing");
Player = nullptr;
} else {
// NOTE: this may fail if there is no current campaign, it's not fatal
Pilot.load_savefile(Player, Player->current_campaign);
}
os_config_write_string(nullptr, "LastPlayer", Player->callsign);
gameseq_post_event(GS_EVENT_MAIN_MENU);
}
bool player_create_new_pilot(const char* callsign, bool is_multi, const char* copy_from_callsign) {
SCP_string buf = callsign;
drop_white_space(buf);
auto invalid_name = false;
if (!isalpha(buf[0])) {
invalid_name = true;
} else {
for (auto idx=1; buf[idx]; idx++) {
if (!isalpha(buf[idx]) && !isdigit(buf[idx]) && !strchr(VALID_PILOT_CHARS, buf[idx])) {
invalid_name = true;
break;
}
}
}
if (buf.empty()) {
invalid_name = true;
}
if (invalid_name) {
return false;
}
// Create the new pilot, and write out his file
// if this is the first guy, we should set the Player struct
if (Player == nullptr) {
Player = &Players[0];
Player->reset();
Player->flags |= PLAYER_FLAGS_STRUCTURE_IN_USE;
}
if (copy_from_callsign != nullptr) {
// attempt to read in the pilot file of the guy to be cloned
if (!Pilot.load_player(copy_from_callsign, Player)) {
Error(LOCATION, "Couldn't load pilot file, bailing");
return false;
}
}
strcpy_s(Player->callsign, buf.c_str());
init_new_pilot(Player, copy_from_callsign == nullptr);
// set him as being a multiplayer pilot if we're in the correct mode
if (is_multi) {
Player->flags |= PLAYER_FLAGS_IS_MULTI;
Player->stats.flags |= STATS_FLAG_MULTIPLAYER;
}
// create his pilot file
Pilot.save_player(Player);
// unset the player
Player->reset();
Player = nullptr;
return true;
}
+11 -1
View File
@@ -12,6 +12,8 @@
#ifndef _PLAYER_SELECT_MENU_HEADER_FILE
#define _PLAYER_SELECT_MENU_HEADER_FILE
#include "globalincs/pstypes.h"
// general defines
#define PLAYER_SELECT_MODE_SINGLE 0 // looking through single player pilots
#define PLAYER_SELECT_MODE_MULTI 1 // looking through multi player pilots
@@ -39,6 +41,14 @@ void player_tips_close();
extern int Player_select_screen_active;
// check the pilots language
bool valid_pilot_lang(char *callsign);
bool valid_pilot_lang(const char *callsign);
SCP_vector<SCP_string> player_select_enumerate_pilots();
SCP_string player_get_last_player();
void player_finish_select(const char* callsign, bool is_multi);
bool player_create_new_pilot(const char* callsign, bool is_multi, const char* copy_from_callsign = nullptr);
#endif
+5 -2
View File
@@ -22,6 +22,7 @@
#include "menuui/mainhallmenu.h"
#include "menuui/readyroom.h"
#include "menuui/techmenu.h" // for tech menu reset stuff
#include "mission/missionload.h"
#include "mission/missionparse.h"
#include "mission/missioncampaign.h"
#include "missionui/missionscreencommon.h"
@@ -471,7 +472,9 @@ int build_standalone_mission_list_do_frame()
// tack on an extension
strcat_s(filename, FS_MISSION_FILE_EXT);
if (!get_mission_info(filename)) {
// check if we can list the mission and if loading basic info didn't return an error code
if (!mission_is_ignored(filename) && !get_mission_info(filename)) {
Standalone_mission_names[Num_standalone_missions_with_info] = vm_strdup(The_mission.name);
Standalone_mission_flags[Num_standalone_missions_with_info] = The_mission.game_type;
int y = Num_lines * (font_height + 2);
@@ -481,7 +484,7 @@ int build_standalone_mission_list_do_frame()
fs_builtin_mission *fb = game_find_builtin_mission(filename);
if((fb != NULL) && (fb->flags & FSB_FROM_VOLITION)){
flags |= READYROOM_FLAG_FROM_VOLITION;
}
}
// add the line
sim_room_line_add(READYROOM_LINE_MISSION, Standalone_mission_names[Num_standalone_missions_with_info], Mission_filenames[Num_standalone_missions_with_info], list_x1 + M_TEXT_X, y, flags);
+14 -14
View File
@@ -609,7 +609,8 @@ void brief_preload_icon_anim(brief_icon *bi)
// force read of data from disk, so we don't glitch on initial playback
if ( ga->first_frame == -1 ) {
ga->first_frame = bm_load_animation(ga->filename, &ga->num_frames);
Assert(ga->first_frame >= 0);
if ( ga->first_frame < 0 )
Warning(LOCATION, "Failed to load icon %s!", ga->filename);
}
}
@@ -624,13 +625,13 @@ void brief_preload_fade_anim(brief_icon *bi)
return;
// force read of data from disk, so we don't glitch on initial playback
if ( ha->first_frame == -1 ) {
if ( ha->first_frame == -1 )
hud_anim_load(ha);
Assert(ha->first_frame >= 0);
}
gr_set_bitmap(ha->first_frame);
gr_aabitmap(0, 0);
if ( ha->first_frame >= 0 ) {
gr_set_bitmap(ha->first_frame);
gr_aabitmap(0, 0);
}
}
void brief_preload_highlight_anim(brief_icon *bi)
@@ -644,15 +645,15 @@ void brief_preload_highlight_anim(brief_icon *bi)
return;
// force read of data from disk, so we don't glitch on initial playback
if ( ha->first_frame == -1 ) {
if ( ha->first_frame == -1 )
hud_anim_load(ha);
Assert(ha->first_frame >= 0);
if ( ha->first_frame >= 0 ) {
bi->highlight_anim = *ha;
gr_set_bitmap(ha->first_frame);
gr_aabitmap(0, 0);
}
bi->highlight_anim = *ha;
gr_set_bitmap(ha->first_frame);
gr_aabitmap(0, 0);
}
/**
@@ -920,7 +921,6 @@ void brief_render_icon(int stage_num, int icon_num, float frametime, int selecte
ga = &bii->regular;
if (ga->first_frame < 0) {
Int3();
return;
}
+15 -28
View File
@@ -43,6 +43,7 @@
#include "pilotfile/pilotfile.h"
#include "playerman/player.h"
#include "popup/popup.h"
#include "scripting/scripting.h"
#include "ship/ship.h"
#include "starfield/supernova.h"
#include "ui/ui.h"
@@ -91,8 +92,6 @@ LOCAL UI_BUTTON Campaign_okb, Campaign_cancelb;
campaign Campaign;
bool campaign_is_ignored(const char *filename);
/**
* Returns a string (which is malloced in this routine) of the name of the given freespace campaign file.
* In the type field, we return if the campaign is a single player or multiplayer campaign.
@@ -247,10 +246,10 @@ int mission_campaign_maybe_add(const char *filename)
char *desc = NULL;
int type, max_players;
// don't add ignored campaigns
if (campaign_is_ignored(filename)) {
return 0;
}
// don't add ignored campaigns
if (campaign_is_ignored(filename)) {
return 0;
}
if ( mission_campaign_get_info( filename, name, &type, &max_players, &desc) ) {
if ( !MC_multiplayer && (type == CAMPAIGN_TYPE_SINGLE) ) {
@@ -678,7 +677,7 @@ int mission_campaign_load( char *filename, player *pl, int load_savefile, bool r
if (!Fred_running && load_savefile && (Campaign.type == CAMPAIGN_TYPE_SINGLE)) {
// savefile can fail to load for numerous otherwise non-fatal reasons
// if it doesn't load in that case then it will be (re)created at save
if ( !Pilot.load_savefile(Campaign.filename) ) {
if ( !Pilot.load_savefile(pl, Campaign.filename) ) {
// but if the data is invalid for the savefile then it is fatal
if ( Pilot.is_invalid() ) {
Campaign.filename[0] = 0;
@@ -892,23 +891,6 @@ void mission_campaign_delete_all_savefiles(char *pilot_name)
}
}
/**
* The following code only ever called by CSFE!!!!
*/
void campaign_savefile_load(char *fname, char *pname)
{
if (Campaign.type == CAMPAIGN_TYPE_SINGLE) {
Game_mode &= ~GM_MULTIPLAYER;
Game_mode &= GM_NORMAL;
}
else
Game_mode |= GM_MULTIPLAYER;
strcpy_s(Player->callsign, pname);
Pilot.load_savefile(fname);
}
/**
* Sets up the internal veriables of the campaign structure so the player can play the next mission.
* If there are no more missions available in the campaign, this function returns -1, else 0 if the mission was
@@ -1220,6 +1202,9 @@ void mission_campaign_mission_over(bool do_next_mission)
Pilot.save_savefile();
}
// runs the new scripting conditional hook, "On Campaign Mission Accept" --wookieejedi
Script_system.RunCondition(CHA_CMISSIONACCEPT);
} else {
// free up the goals and events which were just malloced. It's kind of like erasing any fact
// that the player played this mission in the campaign.
@@ -1244,7 +1229,7 @@ void mission_campaign_mission_over(bool do_next_mission)
Sexp_nodes[mission_obj->formula].value = SEXP_UNKNOWN;
}
if (do_next_mission)
mission_campaign_next_mission(); // sets up whatever needs to be set to actually play next mission
}
@@ -1659,9 +1644,11 @@ bool campaign_is_ignored(const char *filename)
{
SCP_string filename_no_ext = filename;
drop_extension(filename_no_ext);
std::transform(filename_no_ext.begin(), filename_no_ext.end(), filename_no_ext.begin(),
[](char c) { return (char)::tolower(c); });
for (SCP_vector<SCP_string>::iterator ii = Ignored_campaigns.begin(); ii != Ignored_campaigns.end(); ++ii) {
if (*ii == filename_no_ext) {
for (auto &ii: Ignored_campaigns) {
if (ii == filename_no_ext) {
return true;
}
}
@@ -1841,7 +1828,7 @@ void mission_campaign_exit_loop()
* all previous missions marked skipped
* this relies on correct mission ordering in the campaign file
*/
void mission_campaign_jump_to_mission(char *name, bool no_skip)
void mission_campaign_jump_to_mission(const char* name, bool no_skip)
{
int i = 0, mission_num = -1;
char dest_name[64], *p;
+3 -3
View File
@@ -182,6 +182,8 @@ int mission_campaign_load_by_name_csfe( char *filename, char *callsign );
// load up and initialize a new campaign
int mission_campaign_load( char *filename, player *pl = NULL, int load_savefile = 1, bool reset_stats = true );
bool campaign_is_ignored(const char *filename);
// function to save the state of the campaign between missions or to load a campaign save file
extern int mission_campaign_save( void );
@@ -230,8 +232,6 @@ int mission_campaign_savefile_save();
int campaign_savefile_save(char *pname);
// Deletes the campaign save camp under the player name pname
void campaign_delete_save( char *cfn, char *pname);
// Loads campaign camp from fname under player name pname
void campaign_savefile_load(char *fname, char *pname);
// get name and type of specified campaign file
int mission_campaign_get_info(const char *filename, char *name, int *type, int *max_players, char **desc = NULL);
@@ -264,7 +264,7 @@ void mission_campaign_skip_to_next(int start_game = 1);
void mission_campaign_exit_loop();
// jump to specified mission
void mission_campaign_jump_to_mission(char *name, bool no_skip = false);
void mission_campaign_jump_to_mission(const char* name, bool no_skip = false);
// stuff for the end of the campaign of the single player game
void mission_campaign_end_init();
+27 -4
View File
@@ -29,6 +29,8 @@ extern mission The_mission; // need to send this info to the briefing
extern int shifted_ascii_table[];
extern int ascii_table[];
SCP_vector<SCP_string> Ignored_missions;
// -----------------------------------------------
// For recording most recent missions played
// -----------------------------------------------
@@ -41,9 +43,9 @@ int Num_recent_missions;
//
// Update the Recent_missions[][] array
//
void ml_update_recent_missions(char *filename)
void ml_update_recent_missions(const char* filename)
{
char tmp[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN], *p;
char tmp[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN];
int i,j;
@@ -52,7 +54,7 @@ void ml_update_recent_missions(char *filename)
}
// get a pointer to just the basename of the filename (including extension)
p = strrchr(filename, DIR_SEPARATOR_CHAR);
const char* p = strrchr(filename, DIR_SEPARATOR_CHAR);
if ( p == NULL ) {
p = filename;
} else {
@@ -76,12 +78,28 @@ void ml_update_recent_missions(char *filename)
Assert(Num_recent_missions <= MAX_RECENT_MISSIONS);
}
bool mission_is_ignored(const char *filename)
{
SCP_string filename_no_ext = filename;
drop_extension(filename_no_ext);
std::transform(filename_no_ext.begin(), filename_no_ext.end(), filename_no_ext.begin(),
[](char c) { return (char)::tolower(c); });
for (auto &ii: Ignored_missions) {
if (ii == filename_no_ext) {
return true;
}
}
return false;
}
// Mission_load takes no parameters.
// It sets the following global variables
// Game_current_mission_filename
// returns -1 if failed, 0 if successful
int mission_load(char *filename_ext)
int mission_load(const char* filename_ext)
{
TRACE_SCOPE(tracing::LoadMissionLoad);
@@ -100,6 +118,11 @@ int mission_load(char *filename_ext)
*ext = 0; // remove any extension!
}
if (mission_is_ignored(filename)) {
mprintf(("MISSION LOAD: Tried to load an ignored mission! Aborting..."));
return -1;
}
strcat_s(filename, FS_MISSION_FILE_EXT);
// does the magical mission parsing
+6 -1
View File
@@ -21,11 +21,16 @@
extern char Recent_missions[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN];
extern int Num_recent_missions;
extern SCP_vector<SCP_string> Ignored_missions;
// Mission_load takes no parameters.
// It sets the following global variables:
// Game_current_mission_filename
int mission_load(char *filename_ext);
int mission_load(const char* filename_ext);
bool mission_is_ignored(const char *filename);
// Functions for mission load menu
void mission_load_menu_init();
+5 -5
View File
@@ -1602,14 +1602,14 @@ void message_queue_process()
Script_system.SetHookVar("SenderString", 's', who_from);
builtinMessage = q->builtin_type != -1;
Script_system.SetHookVar("Builtin", 'b', &builtinMessage);
Script_system.SetHookVar("Builtin", 'b', builtinMessage);
if (Message_shipnum >= 0) {
sender = &Objects[Ships[Message_shipnum].objnum];
}
Script_system.SetHookObject("Sender", sender);
Script_system.RunCondition(CHA_MSGRECEIVED, 0, NULL, sender);
Script_system.RunCondition(CHA_MSGRECEIVED, sender);
Script_system.RemHookVars(5, "Name", "Message", "SenderString", "Builtin", "Sender");
@@ -2155,7 +2155,7 @@ int message_is_playing()
// Functions below pertain only to personas!!!!
// given a character string, try to find the persona index
int message_persona_name_lookup( char *name )
int message_persona_name_lookup(const char* name)
{
int i;
@@ -2342,7 +2342,7 @@ void message_pagein_mission_messages()
// ---------------------------------------------------
// Add and remove messages - used by autopilot code now, but useful elswhere
bool add_message(const char *name, char *message, int persona_index, int multi_team)
bool add_message(const char* name, const char* message, int persona_index, int multi_team)
{
MissionMessage msg;
strcpy_s(msg.name, name);
@@ -2357,7 +2357,7 @@ bool add_message(const char *name, char *message, int persona_index, int multi_t
return true;
}
bool change_message(const char *name, char *message, int persona_index, int multi_team)
bool change_message(const char* name, const char* message, int persona_index, int multi_team)
{
for (int i = Num_builtin_messages; i < Num_messages; i++)
{
+3 -3
View File
@@ -211,7 +211,7 @@ void message_send_unique_to_player( char *id, void *data, int source, int priori
void message_send_builtin_to_player( int type, ship *shipp, int priority, int timing, int group, int delay, int multi_target, int multi_team_filter );
// functions to deal with personas
int message_persona_name_lookup( char *name );
int message_persona_name_lookup(const char* name);
// preload mission messages (this is called by the level paging code when running with low memory)
void message_pagein_mission_messages();
@@ -231,7 +231,7 @@ void message_load_wave(int index, const char *filename);
// these two are probably safe
// if change_message fails to find the message it'll fall through to add_message
bool add_message(const char *name, char *message, int persona_index, int multi_team);
bool change_message(const char *name, char *message, int persona_index, int multi_team);
bool add_message(const char* name, const char* message, int persona_index, int multi_team);
bool change_message(const char* name, const char* message, int persona_index, int multi_team);
#endif
+28 -6
View File
@@ -1837,6 +1837,7 @@ int parse_create_object_sub(p_object *p_objp)
{
int i, j, k, objnum, shipnum;
int anchor_objnum = -1;
bool brought_in_docked_wing = false;
ai_info *aip;
ship_subsys *ptr;
ship *shipp;
@@ -1865,7 +1866,10 @@ int parse_create_object_sub(p_object *p_objp)
if (object_is_docked(p_objp) && !(p_objp->flags[Mission::Parse_Object_Flags::SF_Dock_leader]) && (p_objp->wingnum >= 0))
{
if (!Fred_running)
{
parse_bring_in_docked_wing(p_objp, p_objp->wingnum, shipnum);
brought_in_docked_wing = true;
}
}
// if arriving through knossos, adjust objpj->pos to plane of knossos and set flag
@@ -2439,13 +2443,14 @@ int parse_create_object_sub(p_object *p_objp)
}
// If the ship is in a wing, this will be done in mission_set_wing_arrival_location() instead
if (Game_mode & GM_IN_MISSION && shipp->wingnum == -1) {
// If the ship is in a wing, but the wing is docked then addition of bool brought_in_docked_wing accounts for that status --wookieejedi
if (Game_mode & GM_IN_MISSION && ((shipp->wingnum == -1) || (brought_in_docked_wing))) {
if (anchor_objnum >= 0)
Script_system.SetHookObjects(2, "Ship", &Objects[objnum], "Parent", &Objects[anchor_objnum]);
else
Script_system.SetHookObjects(2, "Ship", &Objects[objnum], "Parent", NULL);
Script_system.RunCondition(CHA_ONSHIPARRIVE, 0, NULL, &Objects[objnum]);
Script_system.RunCondition(CHA_ONSHIPARRIVE, &Objects[objnum]);
Script_system.RemHookVars(2, "Ship", "Parent");
}
@@ -6142,7 +6147,7 @@ void mission_set_wing_arrival_location( wing *wingp, int num_to_set )
else
Script_system.SetHookObjects(2, "Ship", objp, "Parent", NULL);
Script_system.RunCondition(CHA_ONSHIPARRIVE, 0, NULL, objp);
Script_system.RunCondition(CHA_ONSHIPARRIVE, objp);
Script_system.RemHookVars(2, "Ship", "Parent");
if (wingp->arrival_location != ARRIVE_FROM_DOCK_BAY) {
@@ -6232,9 +6237,12 @@ void reset_arrival_to_false(p_object *pobjp, bool reset_wing)
/**
* In both retail and SCP, the dock "leader" is defined as the only guy in his
* group with a non-false arrival cue
* group with a non-false arrival cue.
*
* If we are forcing a leader, that means *none* of the ships in this dock group
* have a non-false arrival cue, so we just need to pick one
*/
void parse_object_mark_dock_leader_helper(p_object *pobjp, p_dock_function_info *infop)
void parse_object_mark_dock_leader_sub(p_object *pobjp, p_dock_function_info *infop, bool force_a_leader)
{
int cue_to_check;
@@ -6250,7 +6258,7 @@ void parse_object_mark_dock_leader_helper(p_object *pobjp, p_dock_function_info
}
// is he a leader (using the definition above)?
if (!sexp_is_locked_false(cue_to_check))
if (!sexp_is_locked_false(cue_to_check) || force_a_leader)
{
p_object *existing_leader;
@@ -6280,6 +6288,16 @@ void parse_object_mark_dock_leader_helper(p_object *pobjp, p_dock_function_info
}
}
void parse_object_mark_dock_leader_helper(p_object *pobjp, p_dock_function_info *infop)
{
parse_object_mark_dock_leader_sub(pobjp, infop, false);
}
void parse_object_choose_arbitrary_dock_leader_helper(p_object *pobjp, p_dock_function_info *infop)
{
parse_object_mark_dock_leader_sub(pobjp, infop, true);
}
// Goober5000
void parse_object_set_handled_flag_helper(p_object *pobjp, p_dock_function_info * /*infop*/)
{
@@ -6389,6 +6407,10 @@ void mission_parse_set_up_initial_docks()
if (dfi.maintained_variables.int_value == 0)
{
Warning(LOCATION, "No dock leaders found in the docking group containing %s. The group will not appear in-mission!\n", pobjp->name);
// for FRED, we must arbitrarily choose a dock leader, otherwise the entire docked group will not be loaded
if (Fred_running)
dock_evaluate_all_docked_objects(pobjp, &dfi, parse_object_choose_arbitrary_dock_leader_helper);
}
else if (dfi.maintained_variables.int_value > 1)
{
+2 -2
View File
@@ -839,9 +839,9 @@ void message_training_setup(int m, int length, char *special_message)
training_process_message(Training_buf);
Training_num_lines = split_str(Training_buf, TRAINING_LINE_WIDTH, Training_line_lengths, Training_lines, MAX_TRAINING_MESSAGE_LINES);
Assert( Training_num_lines >= 0 );
Assert(Training_num_lines >= 0);
if (message_play_training_voice(Messages[m].wave_info.index) < 0) {
if ((message_play_training_voice(Messages[m].wave_info.index) < 0) || (Master_voice_volume <= 0)) {
if (length > 0)
Training_message_timestamp = timestamp(length * 1000);
else
+6
View File
@@ -47,6 +47,7 @@
#include "popup/popup.h"
#include "render/3d.h"
#include "ship/ship.h"
#include "sound/fsspeech.h"
#include "species_defs/species_defs.h"
#include "weapon/weapon.h"
@@ -1929,6 +1930,11 @@ void commit_pressed()
if (!(The_mission.flags[Mission::Mission_Flags::No_briefing]))
gamesnd_play_iface(InterfaceSounds::COMMIT_PRESSED);
// plieblang - resume simulated speech if necessary
if (!Player->auto_advance) {
fsspeech_pause(false);
}
// save the player loadout
if ( !(Game_mode & GM_MULTIPLAYER) ) {
strcpy_s(Player_loadout.filename, Game_current_mission_filename);
+1 -2
View File
@@ -4082,8 +4082,7 @@ void wl_apply_current_loadout_to_all_ships_in_current_wing()
if ((result == 0) || (result == 2))
{
SCP_string temp;
sprintf(temp, XSTR("Insufficient %s available to arm %s", 1632),
Weapon_info[weapon_type_to_add].get_display_string());
sprintf(temp, XSTR("Insufficient %s available to arm %s", 1632), Weapon_info[weapon_type_to_add].get_display_string(), ship_name);
error_messages.push_back(temp);
error_flag = true;
+38
View File
@@ -9,11 +9,13 @@
#include "globalincs/version.h"
#include "localization/localize.h"
#include "mission/missioncampaign.h"
#include "mission/missionload.h"
#include "mission/missionmessage.h"
#include "missionui/fictionviewer.h"
#include "mod_table/mod_table.h"
#include "parse/parselo.h"
#include "sound/sound.h"
#include "playerman/player.h"
int Directive_wait_time;
bool True_loop_argument_sexps;
@@ -121,10 +123,34 @@ void parse_mod_table(const char *filename)
mprintf(("Game Settings Table: Removed extension on ignored campaign file name %s\n", campaign_name.c_str()));
}
// we want case-insensitive matching, so make this lowercase
std::transform(campaign_name.begin(), campaign_name.end(), campaign_name.begin(),
[](char c) { return (char)::tolower(c); });
Ignored_campaigns.push_back(campaign_name);
}
}
// Note: this feature does not ignore missions that are contained in campaigns
if (optional_string("#Ignored Mission File Names")) {
SCP_string mission_name;
while (optional_string("$Mission File Name:")) {
stuff_string(mission_name, F_NAME);
// remove extension?
if (drop_extension(mission_name)) {
mprintf(("Game Settings Table: Removed extension on ignored mission file name %s\n", mission_name.c_str()));
}
// we want case-insensitive matching, so make this lowercase
std::transform(mission_name.begin(), mission_name.end(), mission_name.begin(),
[](char c) { return (char)::tolower(c); });
Ignored_missions.push_back(mission_name);
}
}
if (optional_string("$Red-alert applies to delayed ships:")) {
stuff_boolean(&Red_alert_applies_to_delayed_ships);
if (Red_alert_applies_to_delayed_ships) {
@@ -376,6 +402,18 @@ void parse_mod_table(const char *filename)
}
}
if (optional_string("$Player warpout speed:")) {
stuff_float(&Player_warpout_speed);
}
if (optional_string("$Target warpout match percent:")) {
stuff_float(&Target_warpout_match_percent);
}
if (optional_string("$Minimum player warpout time:")) {
stuff_float(&Minimum_player_warpout_time);
}
required_string("#END");
}
catch (const parse::ParseException& e)
+2 -2
View File
@@ -642,7 +642,7 @@ public:
bool is_transparent;
int FindTexture(int bm_handle);
int FindTexture(char *name);
int FindTexture(const char* name);
void PageIn();
void PageOut(bool release);
@@ -1005,7 +1005,7 @@ extern void submodel_get_two_random_points_better(int model_num, int submodel_nu
// Returns the index. second functions returns the index of the docking bay with
// the specified name
extern int model_find_dock_index(int modelnum, int dock_type, int index_to_start_at = 0);
extern int model_find_dock_name_index(int modelnum, char *name);
extern int model_find_dock_name_index(int modelnum, const char* name);
// returns the actual name of a docking point on a model, needed by Fred.
char *model_get_dock_name(int modelnum, int index);
+1 -1
View File
@@ -35,7 +35,7 @@ const char *Animation_type_names[MAX_TRIGGER_ANIMATION_TYPES] =
"turret-fired"
};
int model_anim_match_type(char *p)
int model_anim_match_type(const char* p)
{
int i;
+3 -1
View File
@@ -12,6 +12,8 @@
#ifndef _MODELANIM_H
#define _MODELANIM_H
#include "gamesnd/gamesnd.h"
#include "globalincs/pstypes.h"
#include <climits>
#define MAX_TRIGGERED_ANIMATIONS 15
@@ -149,7 +151,7 @@ void model_anim_set_initial_states(ship *shipp);
void model_anim_fix_reverse_times(ship_info *sip);
// gets animation type index from string name
int model_anim_match_type(char *p);
int model_anim_match_type(const char* p);
// starts an animation of a certan type that may be assosiated with a submodel of a ship (returns true if an animation was started)
bool model_anim_start_type(ship_subsys *pss, int animation_type, int subtype, int direction, bool instant = false); // for a specific subsystem
Loaded 100 of 291 files, more files were not shown because too many files have changed in this diff. Show more