Compare commits

...
Author SHA1 Message Date
John Fernandez ce28f60cf1 Whoops 2023-12-19 11:48:21 -05:00
John Fernandez 3e858b601e Attempt without downloading Vulkan SDK 2023-12-19 11:36:43 -05:00
John Fernandez f2314970bb Test Changes To coverity workflow 2023-12-19 11:30:04 -05:00
JohnAFernandez 366c1a9d0b Merge pull request #5891 from MjnMixael/self_credits_update
Self Credits update
2023-12-18 13:31:18 -05:00
mjn-mixael 0594a487c8 credit with my real name instead of online handle 2023-12-15 14:38:26 -06:00
JohnAFernandez f8733eab72 Merge pull request #5890 from MjnMixael/fix_obt_table
Make internal table file match updated parsing preference
2023-12-15 14:23:55 -05:00
mjn-mixael 8dcc4a24e9 make internal table file match updated parsing preference 2023-12-15 13:04:25 -06:00
Goober5000 bf4d7a3114 Merge pull request #5888 from Goober5000/fix_qtfred_option
fix crash in QtFRED
2023-12-14 20:57:10 -05:00
Goober5000 5e8a4f754d fix crash in QtFRED
Not sure how this option became false, but it should be true in order for the checkable menu option to be set up properly.
2023-12-14 18:56:10 -05:00
JohnAFernandez d0a537ff82 Merge pull request #5868 from MjnMixael/more_scpui_options
More scpui options
2023-12-14 12:48:36 -05:00
JohnAFernandez e7c98d6d23 Merge pull request #5880 from MjnMixael/fix_render_overhead
Fix renderOverheadModel's reliance on wss_slots
2023-12-14 12:48:16 -05:00
JohnAFernandez 36e7598ceb Merge pull request #5879 from JohnAFernandez/Fix-Player-Menu-Smarter
QOL: Don't reset the position in the player list if we switch modes
2023-12-11 17:46:28 -05:00
Mike Nelson 0672bd94e9 This should be Game instead of Graphics 2023-12-11 11:26:02 -06:00
Mike Nelson c7792cd781 Merge branch 'master' into more_scpui_options 2023-12-11 11:22:33 -06:00
JohnAFernandez 252392b26a Merge pull request #5865 from MjnMixael/scpui_multi_options
Scpui multi options
2023-12-11 11:54:53 -05:00
JohnAFernandez 65677542cb Merge pull request #5869 from MjnMixael/disable_cmdline_overrides
Disable cmdline overrides
2023-12-11 11:50:22 -05:00
mjn-mixael 691bbca2b2 remove renderOverheadModel's reliance on wss_slots 2023-12-11 09:36:49 -06:00
John Fernandez cd95b143a0 Only init player screen if we need to 2023-12-11 00:46:21 -05:00
Goober5000 a360a1f5f1 Merge pull request #5877 from Goober5000/bump_missionlog
bump missionlog limit
2023-12-10 18:20:52 -05:00
Goober5000 d1119b2353 bump missionlog limit
This limit has not been bumped since the original public source release.  The final mission in Shepherds has been experiencing mysterious bugs which were finally tracked down to the mission log overflowing its limit and discarding log entries.  Ideally the mission log should be made dynamic and the pruning mechanisms removed, but for the 24.0 release, it suffices to bump the limit.
2023-12-10 00:33:22 -05:00
JohnAFernandez c37e1b1c96 Merge pull request #5871 from Goober5000/juggling_fix
juggling fix
2023-12-09 14:30:43 -05:00
Goober5000 fd6ca9dde9 juggling fix
Volition used a bit of juggling when deleting the briefing editor pointer.  Turns out this actually prevents a crash in certain situations, so let's put it back.

Follow-up to #5866.
2023-12-09 14:04:53 -05:00
Goober5000 fbb3a8f6a5 Merge pull request #5829 from Goober5000/oswpt_registry_ptrs
replace pointers with indexes in ship registry and oswpt
2023-12-09 00:23:33 -05:00
JohnAFernandez 0e63d64647 Merge pull request #5451 from BMagnu/animation_driver
Animation Drivers
2023-12-08 20:58:54 -05:00
Goober5000 de50f693ae Merge pull request #5811 from Goober5000/perform_on_mission_skip
implement on-mission-skip SEXP
2023-12-08 20:05:20 -05:00
Goober5000 6e9b31cb5a replace pointers with indexes in ship registry and oswpt
This refactors the ship registry and the OSWPT struct to store data as indexes rather than pointers.  This is a prerequisite for making these collections dynamic in the future.  See also #5800.
2023-12-08 19:45:58 -05:00
Fabian Woltermann e316c28258 Merge pull request #5607 from EatThePath/opt/luastring
LuaDrawstring optimization
2023-12-08 17:18:20 +01:00
JohnAFernandez 1ef528af5f Merge pull request #5867 from MjnMixael/discord_option_category
Change the discord option category to "game"
2023-12-08 10:48:31 -05:00
EatThePath e536413259 Deferred light mesh submission optimizations (#5828)
* Reorganized opengl deferred light mesh drawing to submit all data before,
beginning to submit draws, and also to reduce total bind calls needed.

* Leftover unused variable cleanup

* CI didn't like my loops, maybe it'll like these.

* unused variable cleanup.
2023-12-08 07:40:42 -05:00
Goober5000 ccbe7efcbe Merge pull request #5866 from Goober5000/fred_autosave
add more autosaving in FRED
2023-12-07 18:12:37 -05:00
mjn-mixael 1fcf51bd92 unused vars 2023-12-07 16:55:41 -06:00
mjn-mixael b9938b854f commandline to disable using ingame options 2023-12-07 16:45:43 -06:00
mjn-mixael ad06cb1c5b disable commandline options overriding in-game options 2023-12-07 15:00:33 -06:00
mjn-mixael b62a7fbe3d no unfocused pause & localization + cleanup 2023-12-07 11:54:45 -06:00
mjn-mixael 4011a0800d screenshake option 2023-12-07 11:33:01 -06:00
mjn-mixael 8f7c6a0ed8 and force dropdown selector for display selection 2023-12-07 10:45:17 -06:00
mjn-mixael 9e719440c9 Change the discord option category to "game" 2023-12-07 10:31:15 -06:00
Goober5000 6692540cbf add more autosaving in FRED
FRED has an autosave feature but it wasn't invoked in too many places.  This adds autosaving whenever a major dialog is closed, unless it was closed by hitting Cancel.  NB: Autosave is not yet implemented in qtFRED.

Also, `addvariabledlg` incorrectly referred to `OnOk` instead of `OnOK` and `CMessageEditorDlg` incorrectly referred to `OnOK` instead of `OnOk`, so this fixes those and distinguishes `OnOk` by renaming it `OnButtonOk` to be consistent with the event editor and other dialogs.
2023-12-06 17:55:26 -05:00
mjn-mixael 668fc18d5c Make these two dropdown options to account for the longer string values 2023-12-06 15:29:32 -06:00
mjn-mixael a101e3cf77 spelling is hard 2023-12-06 15:25:37 -06:00
mjn-mixael dcce4a6538 Set the globals at player select rather than player load 2023-12-06 15:08:23 -06:00
mjn-mixael 7ce3217f17 multi login info & ip address list API 2023-12-06 12:49:38 -06:00
mjn-mixael 33a1b1f8ca clean up and fix 2023-12-06 09:59:36 -06:00
mjn-mixael a29a97f39a xstrs 2023-12-06 08:22:26 -06:00
Goober5000 8d40d7467e Merge pull request #5861 from BMagnu/fix_windowres_warning
Avoid a casting warning in cmdline.cpp
2023-12-06 01:07:22 -05:00
Goober5000 eb57482c1a Merge pull request #5864 from Goober5000/fix_query_node_argument_type
fix query_node_argument_type()
2023-12-06 01:05:53 -05:00
Goober5000 50f083043b fix query_node_argument_type()
Calling `query_node_argument_type()` on a node with no parent is a valid use case, so return the proper argument type.  Fixes a crash discovered by Applemush.
2023-12-05 17:03:48 -05:00
Goober5000 d02bd6ca04 Merge pull request #5862 from Goober5000/no_arrival_music
allow nonexistence of arrival overlays
2023-12-05 16:53:15 -05:00
Goober5000 22962afcde allow nonexistence of arrival overlays
Ever since retail, the code has assumed that a soundtrack would always have arrival music.  This removes that requirement.  If arrival music is missing, it will just be skipped.
2023-12-05 16:19:46 -05:00
Birk Magnussen 1f9c9a3673 Catch nonexistant curves 2023-12-05 21:25:22 +01:00
Birk Magnussen f3922f35e8 Properly cast to avoid a warning 2023-12-05 19:16:16 +01:00
Birk Magnussen bb5bfad828 Fix parsing and asserts 2023-12-05 18:54:30 +01:00
JohnAFernandez 18ac8425ee Merge pull request #5859 from MjnMixael/fix_language_selection
Only use- in-game language if the mod table option is enabled
2023-12-05 12:10:03 -05:00
BMagnu f6167bb89a Make sure that the openxr_loader subproject is forced to the correct debug iterator level (#5860) 2023-12-05 17:00:01 +00:00
Birk Magnussen c8ceb289ba Actually run drivers 2023-12-05 17:47:44 +01:00
Birk Magnussen 9ea64627ab property drivers 2023-12-05 17:47:43 +01:00
Birk Magnussen 6e9ca36481 fix driver parsing 2023-12-05 17:47:43 +01:00
Birk Magnussen 90dbdc4236 Add remap driver 2023-12-05 17:47:43 +01:00
Birk Magnussen 3a35f7ebe7 make curve inferment constant 2023-12-05 17:47:42 +01:00
Birk Magnussen 05f190b36c Ensure driver source precedence 2023-12-05 17:47:42 +01:00
Birk Magnussen 0924a392aa Add basic driver sources 2023-12-05 17:47:41 +01:00
Birk Magnussen 21db833dee Add driver files 2023-12-05 17:47:41 +01:00
Birk Magnussen 86011f2669 Driverify time 2023-12-05 17:47:41 +01:00
Birk Magnussen 2bd143e093 Separate Animation State tracking from direction and time tracking 2023-12-05 17:47:40 +01:00
mjn-mixael 79d3077071 quick & dirty initial work for the toggle options 2023-12-05 09:30:04 -06:00
mjn-mixael aacd14e1df only use- in-game language if the mod table option is enabled 2023-12-04 15:58:41 -06:00
BMagnu 43afcd5ea6 VR Lua interface (#5858)
* Allow lua to check whether VR is enabled

* Add global hook condition

* Add missing descriptionm
2023-12-04 20:39:26 +00:00
BMagnu b98544d862 Merge pull request #5583 from BMagnu/openxr
Add VR support through OpenXR
2023-12-05 04:57:19 +09:00
Birk Magnussen 7867dc77bd external Openxr vars on mac 2023-12-04 20:38:50 +01:00
Birk Magnussen 426c227b68 Actually make sure that OpenXR is not a target on maxc 2023-12-04 20:24:42 +01:00
Birk Magnussen 612bdcf4df Do not link OpenXR on mac 2023-12-04 20:20:41 +01:00
ETP 0d712d6fc0 Minor code cleanup. 2023-12-04 14:12:31 -05:00
Taylor Richards 62fa0c081b Merge pull request #5856 from notimaginative/mac_name_change_fixes
update nebula script for Mac filename changes
2023-12-04 00:13:23 -05:00
Taylor Richards 8035a2b32a update nebula script for Mac filename changes 2023-12-03 17:19:08 -05:00
ETP f7f2c58746 New method to wrap strings to drawing widths, and use of that method in lua gr.drawstring, resolves #5495 2023-12-03 14:31:33 -05:00
Goober5000 7bf0fd137d Merge pull request #5855 from Goober5000/coverity_magic
change two global variables to be scoped
2023-12-03 01:18:06 -05:00
Goober5000 6d818f1e3b Merge pull request #5565 from Goober5000/plieblang_good_primary_time
Add plieblang's good primary time SEXP
2023-12-02 23:45:46 -05:00
Goober5000 e23b5533aa change two global variables to be scoped
These variables are only ever used in the scope of `os_get_legacy_user_dir()`, so they can be scoped rather than global.  This should fix a Coverity issue on the `DCF(low_mem` debug console function.
2023-12-02 23:39:24 -05:00
Goober5000 6b79571edc Merge pull request #5854 from Goober5000/fix_api_format
fix Lua API arguments
2023-12-02 18:26:12 -05:00
JohnAFernandez 27f022b2f2 Merge pull request #5799 from JohnAFernandez/Fix-many-old-divide-by-issues
Add safety to crusty old physics code (coverity issue)
2023-12-02 18:19:54 -05:00
JohnAFernandez 4578fbc900 Merge pull request #5851 from MjnMixael/sound_assertion
Add assertion when getting a loaded sound index
2023-12-02 18:11:07 -05:00
John Fernandez bfde2144a2 Typo 2023-12-02 18:01:51 -05:00
John Fernandez 1787f4457b Add safety to crusty old physics code 2023-12-02 18:01:51 -05:00
Goober5000 be14c34f7d reset the timestamp instead of checking the size 2023-12-02 14:56:31 -05:00
Goober5000 da66bd65da feedback 1 2023-12-02 14:56:30 -05:00
Goober5000 dc7aa86147 updates based on comments 2023-12-02 14:56:30 -05:00
Goober5000 4bf743765c plieblang's good-primary-time 2023-12-02 14:56:30 -05:00
Taylor Richards b4e3ebe085 Merge pull request #5853 from notimaginative/mac_arm64_builds
add mac arm64 builds to CI workflow
2023-12-02 14:46:20 -05:00
Goober5000 ada432a1f3 fix Lua API arguments
Make sure the return value is actually a float so that the float format can process it.

Follow up to #5831.  Fixes a crash for invalid movies.
2023-12-02 13:04:14 -05:00
Goober5000 25d796afe4 implement on-mission-skip SEXP
Adds a SEXP that specifically checks for whether a player has skipped a mission.  This can be used to set tech room entries, allowed ships/weapons, and other campaign data that would otherwise break if a player skipped a mission.

This only applies to the the failed-five-times popup.  For this to work with the `skipmemymissionyo` cheat, it would be necessary to load every intervening mission and check the events.  That being said, `skipmemymissionyo` already automatically allows all ships and weapons, so there is much less, if any, need for this SEXP in that case.
2023-12-02 01:25:14 -05:00
Goober5000 1a034031d1 Merge pull request #4634 from Goober5000/sexp_reset_event
add reset-event and reset-goal
2023-12-02 01:03:38 -05:00
Goober5000 23098666e2 Merge pull request #5506 from MageKing17/bugfix/debrief-failure-skip-count
Restore (mostly-)retail debrief failure counting behavior.
2023-12-01 23:41:48 -05:00
Taylor Richards 5490751167 skip tests on mac if target arch doesn't match host
An arm64 mac can run unittests on a x86_64 build, but not the other way
around. So if the target arch doesn't match the build host arch then
just skip the tests. Saves us from a far more complicated fix that would
only produce the same test results anyway.
2023-12-01 23:05:56 -05:00
Taylor Richards 4bc9cf0846 set IS_ARM64 correctly if building on different arch 2023-12-01 23:01:29 -05:00
BMagnu dd9248fc22 Fix merge errors 2023-12-02 11:50:01 +09:00
BMagnu c2ed03ca59 Merge branch 'master' into openxr 2023-12-02 11:42:55 +09:00
Taylor Richards 7491a82d74 always build embedfile and unittests for host arch 2023-12-01 21:15:13 -05:00
MageKing17 2f0c0f1d6f Restore (mostly-)retail debrief failure counting behavior.
Back in 2008 (in commit 2c45dbbb5f), some retail code incrementing `Player->failures_this_session` was removed, seemingly by accident. A month later, a bug related to this was fixed (in commit 28a408deee) in a different way. Since this fix is rendered redundant by the restoration of the original behavior, I've removed it and put back in the old behavior. This is only "mostly-retail" because the retail code didn't check `Game_mode & GM_CAMPAIGN_MODE`.
2023-12-01 18:14:55 -08:00
Taylor Richards 3b231b375f add mac arm64 builds to CI workflow 2023-12-01 20:55:29 -05:00
Taylor Richards 07fb5bec0e support new prebuilt libs on mac (#5852) 2023-12-01 20:54:41 -05:00
mjn-mixael e51815a933 Add assertion when getting a loaded sound index 2023-12-01 11:27:17 -06:00
Goober5000 ea6e503ea1 Merge pull request #5839 from Goober5000/radar_timestamps
make radar timestamps type-safe
2023-11-30 13:19:58 -05:00
JohnAFernandez a381ecc607 Merge pull request #5844 from MjnMixael/fred_on_mission_load
FRED on mission load hook
2023-11-30 11:42:48 -05:00
Asteroth 125e47d749 Add cockpit 'sway' (#5840)
* add cockpit sway

* remove 5000 scaling factor
2023-11-30 10:52:39 -05:00
JohnAFernandez d280800bce Merge pull request #5847 from MjnMixael/remove_cd_checks
Remove the cd checks that always returned true anyway
2023-11-30 10:38:19 -05:00
JohnAFernandez a1c9b108ed Merge pull request #5842 from Baezon/gravity-fixes
Two gravity fixes
2023-11-30 10:38:05 -05:00
JohnAFernandez d7a06c893f Merge pull request #5848 from MjnMixael/fix_medal_parsing
Fix medal parsing issue
2023-11-30 10:37:33 -05:00
m!m 3aa672c855 Merge pull request #5843 from asarium/build/ci_qtfred
Reenable QtFred building for Linux CI builds
2023-11-29 21:08:05 +01:00
mjn-mixael 8acbe82aa0 fix medal parsing 2023-11-29 13:08:05 -06:00
JohnAFernandez 5227e2e0c4 Merge pull request #5830 from MjnMixael/vectorize_multi_pxo
Vectorize multi pxo
2023-11-29 13:47:04 -05:00
mjn-mixael 95baa85750 remove the cd checks that always returned true anyway 2023-11-29 11:27:31 -06:00
mjn-mixael fb1ffd8413 fred on mission load hook 2023-11-29 09:14:07 -06:00
asarium f43732c5da Reenable QtFred building for Linux CI builds
Qt has been added to the build image which eliminates the need to
dynamically install it which removed a possible point of failure.

At the moment this is only enabled for pull request builds and should
not affect nightly or release builds.
2023-11-29 11:34:42 +01:00
Asteroth 8dbe0e7b8a gravity fixes 2023-11-29 02:34:26 -05:00
mjn-mixael 3ad66b988d unused var 2023-11-28 20:48:21 -06:00
mjn-mixael 969759426a list instead of vector 2023-11-28 20:31:54 -06:00
m!m 224503391f Merge pull request #5841 from asarium/fix/build-upload
Update container image to fix artifact uploads
2023-11-28 14:29:08 +01:00
asarium 0edc6267aa Update container image to fix artifact uploads
The previous version of the image accidentally removed the /tmp
directory which broke things in the GitHub actions.

Initially, an update for the upload/download actions was tried which had
no effect but keeping these updated is probably a good idea.
2023-11-28 10:58:28 +01:00
Goober5000 def75287eb convert radar timestamps to new system
Also convert true/false variables to boolean.
2023-11-28 00:09:25 -05:00
Goober5000 c427014fc2 just use the flag 2023-11-27 18:19:56 -05:00
Goober5000 99d140fb83 indicate 'done' events with a flag 2023-11-27 18:19:56 -05:00
Goober5000 808e5bedd9 address feedback 2023-11-27 18:19:56 -05:00
Goober5000 6dfd1ed0b8 add reset-event and reset-goal
These new SEXP operators clear all status information from an event or goal, making it as if the event or goal had never been evaluated.

Implements feature discussed in #4184.
2023-11-27 18:19:56 -05:00
m!m 369b90a156 Merge pull request #5833 from asarium/update_compilers
Update PR build image and compilers
2023-11-27 08:23:13 +01:00
mjn-mixael 7bb6a8ae86 negate this 2023-11-26 23:49:02 -06:00
Goober5000 7afb00e976 Merge pull request #5800 from Goober5000/reduce_ship_info_ptrs
avoid storing ship_info pointers in data structures
2023-11-26 23:30:13 -05:00
JohnAFernandez c4fe9e664f Merge pull request #5836 from MjnMixael/fix_hud_translations
Do not translate these if setting is enabled
2023-11-26 22:19:56 -05:00
JohnAFernandez eda9f16294 Merge pull request #5835 from MjnMixael/language_out_of_bounds
Verify this is in bounds and add vector_inbound macro
2023-11-26 22:19:32 -05:00
mjn-mixael f7dddc35d1 inline and remove signed check for size_t 2023-11-26 20:55:37 -06:00
mjn-mixael b8806e958d do not translate these if setting is enabled 2023-11-26 19:52:34 -06:00
mjn-mixael 40cf32133f in bounds check for language ext 2023-11-26 19:28:06 -06:00
Mike Nelson 691ec74406 Mission custom strings (#5544) 2023-11-26 19:15:30 -05:00
Goober5000 359886fee1 Merge pull request #5831 from Goober5000/movie_duration
add Lua function for movie duration
2023-11-26 16:00:26 -05:00
Mike Nelson 9b86d2f16d Scpui language selector (#5826)
* SCPUI in-game language selector

* xstr support

* proper debug print format

* minor fixes

* Save the language as json data rather than an index into the languages array

* ext instead of id for clarity

* Do this more formally

* unused param
2023-11-26 11:52:15 -05:00
asarium 260f15624b Update PR build image and compilers
This advances the versions for Clang to 16 and GCC to 13 along with
fixing any warnings these new versions are detecting now.

The new image versions also include Vulkan so the additional workflow
step for installing that is not necessary anymore.
2023-11-26 12:23:57 +01:00
mjn-mixael 6de870766a address additional feedback 2023-11-25 10:25:58 -06:00
Goober5000 072e802863 add Lua function for movie duration
This retrieves the duration from the movie stream.  Thanks to @asarium for pointing me in the right direction.
2023-11-23 13:11:40 -05:00
mjn-mixael 2ca9d6672c address feedback 2023-11-23 10:47:55 -06:00
mjn-mixael 7281e8d127 unused 2023-11-22 13:18:27 -06:00
mjn-mixael a730f30435 cleanup for checks 2023-11-22 13:07:16 -06:00
mjn-mixael cd5f044217 vectorize the chat 2023-11-22 12:31:05 -06:00
mjn-mixael 8b90cda3f4 nullptr 2023-11-22 09:52:13 -06:00
JohnAFernandez 6b2ced4643 Merge pull request #5815 from MageKing17/feature/direction-blind-contrails
Implement direction-blind contrails option.
2023-11-21 23:32:18 -05:00
JohnAFernandez 5ee051c55f Merge pull request #5803 from Baezon/start-loop-end-snd-weapons
Add Start/Loop/End sounds for weapons
2023-11-21 23:29:23 -05:00
Goober5000 ecc452088c Merge pull request #5751 from Goober5000/freespace_timestamps
upgrade timestamps referenced in freespace.cpp
2023-11-21 18:30:14 -05:00
mjn-mixael 841ae430c0 Vectorize the players list 2023-11-21 16:06:27 -06:00
Mike Nelson 3f7ffdb6a0 Localize strings in ship_select_blit_info (#5824) 2023-11-21 13:05:24 -05:00
Tyler Blount 737717fe3f Merge pull request #5569 from MjnMixael/loadout_no_validation
Do not validate loadouts
2023-11-20 21:57:57 -07:00
JohnAFernandez a463ac19cf Merge pull request #5825 from Baezon/fix-head-on-lasers
Fix for lasers with head on bitmaps
2023-11-20 21:57:53 -05:00
mjn-mixael 9d0ee6ab0d vectorize the channel list 2023-11-20 16:48:43 -06:00
Asteroth 703269aa71 fix for lasers with head on bitmaps 2023-11-20 17:27:11 -05:00
JohnAFernandez b7a0170cd1 Merge pull request #5818 from EatThePath/opt/single_batching
Remove redundant batching_render_all calls
2023-11-20 10:33:30 -05:00
JohnAFernandez 6f263365af Merge pull request #5761 from JohnAFernandez/Coverity-COPY_INSTEAD_OF_MOVE-ISSUES
These std moves were suggested by Coverity as optimizations
2023-11-19 23:11:26 -05:00
Goober5000 6435843c24 Merge pull request #5817 from Goober5000/fix_player_entry_delay
fix loadout dialog updating in FRED
2023-11-19 19:22:09 -05:00
Goober5000 22ee5d5c15 Merge pull request #5819 from Goober5000/the_new_old_checkbox
FRED checkbox upgrade
2023-11-19 19:22:00 -05:00
Mike Nelson 5fadb12b0f Deprecate IsValid in favor of isValid (#5814) 2023-11-19 18:58:35 -05:00
Taylor Richards e94c515ab8 fix deprecation warnings on newer ffmpeg versions (#5822) 2023-11-19 16:41:53 -05:00
Taylor Richards d83ddeed0f add arm64 detection and naming support (#5821) 2023-11-19 16:41:18 -05:00
Taylor Richards 3556d41b44 disable png neon optimizations on arm (#5820) 2023-11-19 16:41:03 -05:00
Mike Nelson f2df96b4bb remove is docked check for transfer-cargo sexp (#5810) 2023-11-19 11:25:14 -05:00
wookieejedi 9eeb3307d0 Expose isValid parse object check to scripting (#5816) 2023-11-19 07:51:33 -05:00
Goober5000 a406b43876 Merge pull request #5808 from Goober5000/rename_vaporize_chance
rename Vaporize Percent Chance
2023-11-18 23:04:38 -05:00
Goober5000 c86802e9c1 use alternate overlap fix
Back out the manual resize fix and apply a simpler fix that is less hackish.  See this other StackOverflow article:
https://stackoverflow.com/questions/57951333/cchecklistbox-items-get-overlapped-on-selection-if-app-build-using-visual-studi
2023-11-18 19:26:52 -05:00
Goober5000 5b4065bd53 FRED checkbox upgrade
The overlapping checkboxes problem described in #5494 is the result of the checkbox list item height being slightly too small.  A fix for this, which requires a subclass of `CCheckListBox`, is described in the following StackOverflow article:
https://stackoverflow.com/questions/3147958/mfc-cchecklistbox-items-overlap

It turns out there is already a subclass of `CCheckListBox` in the codebase: `ShipCheckListBox`, a class that was apparently left on the cutting room floor when DaveB refactored the team loadout dialog on 2/23/99.  It allows an entire selected range of items to be toggled by pressing the spacebar.  I've augmented it with the StackOverflow fix, and I've added it to the team loadout dialog as well as some other places that could benefit from it.

Fixes the other half of #5494.
2023-11-18 18:44:39 -05:00
ETP 5fd439fb60 Clean now-unused batch rendering flag. 2023-11-18 16:26:10 -05:00
ETP 2043f836ed Clean extra batched buffer run in particles 2023-11-18 15:53:47 -05:00
ETP 4a3c7fc9a9 Batched buffers are rendered soon after this anyway and the overhead is considerable.
Also removed what appears to be accidentally duplicated lines
2023-11-18 15:52:55 -05:00
Goober5000 e0e3f7e7ac fix loadout dialog updating in FRED
We need to call `UpdateData()` in the `OnOK()` function and in several other places so that the member variables are populated with the most recent input from the UI.  This prevents certain input (such as Player Entry Delay changes) from being lost by being overwritten with stale stored values.

This fixes a bug reported by Kitsune where the Player Entry Delay box did not work properly.  It also fixes the random checkbox issue from #5494.
2023-11-18 15:44:48 -05:00
Goober5000 542d9741c4 Merge pull request #5813 from Goober5000/fix_grid
small briefing bugfix
2023-11-18 15:04:10 -05:00
MageKing17 68eef5949b Implement direction-blind contrails option.
One of the features requested in #5378 (specifically the one requested in #5274), this adds a new "$Contrails use absolute speed:" option to game_settings.tbl, which makes the `ct_below_limit()` function check `objp->phys_info.speed` instead of `objp->phys_info.fspeed`. This allows contrails to appear when moving in a direction other than forwards.
2023-11-18 10:51:40 -08:00
Goober5000 7958670868 small briefing bugfix
Prevent "Disable grid rendering" from being stuck on.  Fixes a bug reported by Kitsune.
2023-11-18 12:34:28 -05:00
Mike Nelson 226ed40cec Move no campaign warning to on Ready Room click (#5809)
* Move no campaign warning to on ready room click

* Add a log print
2023-11-18 11:10:39 -05:00
Mike Nelson d454a74716 Add child enum suffix option (#5798) 2023-11-17 21:45:36 -05:00
Mike Nelson 4ff96abd9e Merge branch 'master' into loadout_no_validation 2023-11-17 10:29:50 -06:00
Mike Nelson 5bc1200731 Fred cutscene dialog (#5618)
* fred cutscene editor and deprecate alias types

* properly handle right-click delete

* cleanup

* these must be ints also
2023-11-17 11:27:05 -05:00
Asteroth b23dff91e7 revert removal of allow relative (#5807) 2023-11-16 22:20:54 -05:00
Goober5000 3af831e0b7 rename Vaporize Percent Chance
This option was misleadingly named when originally introduced, so give it a more sensible name.  The old name is still accepted for backwards compatibility.
2023-11-16 15:57:53 -05:00
Mike Nelson bcae459b56 Add way to offset directive help text only (#5802)
* add way to offset directive help text only

* specify which offset
2023-11-15 07:50:21 -05:00
Goober5000 ff7d85a60f Merge pull request #5806 from Baezon/fix-changing-bank-num
Fix for changing the number of banks on a ship
2023-11-15 00:10:30 -05:00
Goober5000 267fcfc6f8 also check ship_info_size() 2023-11-14 23:32:20 -05:00
Asteroth 8587bf768b fix changing number of banks 2023-11-14 20:04:55 -05:00
JohnAFernandez 535ff9f99a Merge pull request #5608 from Goober5000/move_cmdline_option
move -no_unfocused_pause
2023-11-14 16:01:20 -05:00
Asteroth 422ccaa514 fix 2023-11-14 13:15:30 -05:00
wookieejedi a3e27f566f Allow Modders to Set Rotational Scaling Multiplier for Asteroids/Debris (#5801)
* Allow Modders to Set Rotational Scaling Multiplier for Asteroids/Debris

Previously, there was no way to limit the velocity at which asteroids/debris randomly rotated. There was a way to set maximum speed, thus this PR follows that convention and adds a way to cap the rotational velocity scaling. This PR allows modders to set caps per type, including setting the value to 0 for no rotation.

A single scaling value was used b/c it was the most straightforward value to se via table and it was the employed the least code changes. Asteroids pick a random normalized vector for their rotation when spawning, and then that value is scaled by a random multiplier.

* use full multiplier instead
2023-11-14 08:02:16 -05:00
Asteroth 9ecb451efe more tweaks 2023-11-13 18:53:15 -05:00
Asteroth e3d2c02f99 tweak 2023-11-13 17:55:48 -05:00
Asteroth 13170a235e add start/loop/end sounds for weapons 2023-11-13 17:52:50 -05:00
Goober5000 5406445ed4 replace pointers with indexes in WarpEffect 2023-11-13 14:05:39 -05:00
Goober5000 301b9453b6 replace pointers with indexes in cockpit_display 2023-11-13 12:48:08 -05:00
JohnAFernandez cd32c2ce42 Merge pull request #5778 from freijon/fix_opt_flags
Don't ignore user-set -O* flags
2023-11-13 11:08:34 -05:00
Goober5000 7b1b1113da upgrade timestamps referenced in freespace.cpp
Convert additional timestamps to use the new timestamp system.  This covers all timestamps referred to in freespace.cpp.  For purposes of organization, the fade-in/fade-out timestamps have been moved to light.h|cpp and the training timestamps have been moved to missiontraining.h|cpp.

There are also several related code enhancements:
1. `FadeType` has been converted from `enum` to `enum class`
2. Initialization of the various training variables has been added to `training_mission_init` (previously they had never been reset between missions)
3. Validity checks have been added to the relevant locations for these timestamps
2023-11-12 15:22:30 -05:00
JohnAFernandez 1f32834d9d Merge pull request #5792 from MjnMixael/lua_enum_remove_item
Add ability to remove an enum item from a list
2023-11-12 14:31:49 -05:00
Mike Nelson bee0742aa2 downgrade this to a log print (#5791) 2023-11-12 10:07:16 -05:00
Mike Nelson d336d395db Fix incorrect out of bounds check (#5795) 2023-11-12 10:07:04 -05:00
Goober5000 1953bd9c49 Merge pull request #5748 from Goober5000/event_currency_tweaks
Event currency tweaks
2023-11-12 01:40:07 -05:00
Joshua Glatt e27cbe9517 Disallow Replace Container Data for all special argument SEXPs (#5793) 2023-11-12 01:38:55 -05:00
Goober5000 4b5d4320f8 Merge pull request #5794 from Goober5000/missionsave_tweaks
FRED missionsave updates
2023-11-11 23:43:00 -05:00
Goober5000 ed7f3e6880 Merge pull request #5787 from Goober5000/refactor_argument_functions
refactor argument functions
2023-11-11 19:39:55 -05:00
Goober5000 980d2c2bcc Merge pull request #5797 from Goober5000/fix_5773
fix 5773
2023-11-11 18:29:15 -05:00
Goober5000 17dfa0ddb9 fix 5773
In #5773, this use of frand_range(0, N) needed to be converted to Random::next(N+1), just like several other similar instances in that PR.

Fixes #5796.
2023-11-11 17:58:37 -05:00
Goober5000 5f511e34e3 FRED missionsave updates
1. Use the `optional_string_fred`/`fout` pattern so the FRED comment parser can follow along with the mission file
2. Since the #Custom Data section is optional and requires a version bump, don't output the section header if the section is empty
2023-11-11 14:34:17 -05:00
Goober5000 31c8739ecd Merge pull request #5788 from Goober5000/rcs_thruster_refactor
rcs thruster refactor
2023-11-11 13:17:48 -05:00
Goober5000 8e23c32b8c Merge pull request #5765 from Goober5000/subsystems_blown_optimization
optimization for checking whether subsystems are blown
2023-11-11 13:07:01 -05:00
mjn-mixael b628b665cf Do this using brain 2023-11-11 11:51:45 -06:00
mjn-mixael 7a367b10ad Add ability to remove an enum item from a list 2023-11-11 11:30:07 -06:00
wookieejedi 09c885c4af Add built-in xstrs for SCP-added custom controls (#5790) 2023-11-11 12:06:24 -05:00
JohnAFernandez 9ac6060abd Merge pull request #5522 from MjnMixael/mainhall_lua_esc
Custom lua action for mainhall esc keypress
2023-11-11 00:02:15 -05:00
JohnAFernandez a34f37fa8d Merge pull request #5645 from MjnMixael/lua_dynamic_enums
Lua Child Enums for Sexp types
2023-11-11 00:01:44 -05:00
JohnAFernandez 7645704ac2 Merge pull request #5753 from Baezon/moar-curves
Moar curves
2023-11-11 00:01:29 -05:00
wookieejedi b25e76cb65 Fix documentation error in On State Start (#5789) 2023-11-10 19:46:55 -05:00
BMagnu a9cfd27455 Expose more submodel instance and submodel attributes and functions to Lua (#5766)
* Add global to local for matrices

* Add lua integration

* Get Submodel from Submodel instance

* Add submodel functions

* Add model instance from submodel instance

* Fix index

* Fix copy paste error
2023-11-11 07:23:47 +09:00
Goober5000 110f609dea Merge pull request #5701 from Goober5000/jumpnode_constify
add const where appropriate to the jump node API
2023-11-09 17:52:30 -05:00
Birk Magnussen ba3ac66958 X compile error 2 2023-11-09 23:43:09 +01:00
Birk Magnussen 274366c8ad X compile error 2023-11-09 23:39:26 +01:00
Birk Magnussen df285b7ae1 Fix rebase errors 2023-11-09 23:14:08 +01:00
Birk Magnussen 7eec846b3d readd hudtarget 2023-11-09 22:56:47 +01:00
Birk Magnussen 25a9f6abe2 Avoid OGL errors 2023-11-09 22:56:07 +01:00
Birk Magnussen f0737f1b87 Tidyup, Linux init code is now tested 2023-11-09 22:56:07 +01:00
Birk Magnussen dbefa6d333 Actually init GLX 2023-11-09 22:56:07 +01:00
Birk Magnussen 54c0680b2a Fix HUD speed 2023-11-09 22:56:06 +01:00
Birk Magnussen 058cec3d2c Make VR 2D-Screen Auto recenter 2023-11-09 22:56:06 +01:00
Birk Magnussen a73cc9bfce Add option for window-scaling 2023-11-09 22:55:27 +01:00
Birk Magnussen 245ac3f6b3 Safe type conversions 2023-11-09 22:53:59 +01:00
Birk Magnussen ee6159c685 Fix incorrect print order 2023-11-09 22:53:59 +01:00
Birk Magnussen 68f9d90629 Proper swapchain AR detection 2023-11-09 22:53:59 +01:00
Birk Magnussen 2523218fdc Fix interfacing with the very segfaulty oculus runtime 2023-11-09 22:53:59 +01:00
Birk Magnussen b323760659 HUD offset never makes any sense 2023-11-09 22:53:54 +01:00
Birk Magnussen 5a93f78933 Mac Compile 2023-11-09 22:52:56 +01:00
Birk Magnussen e99341d79f Fix compile issues 2023-11-09 22:52:56 +01:00
Birk Magnussen 54a188d46a Try fixing compile on mac 2023-11-09 22:52:55 +01:00
Birk Magnussen f686046a1d Properly force VR AR 2023-11-09 22:52:51 +01:00
Birk Magnussen 61f8e0370b Fix Warning again again 2023-11-09 22:52:19 +01:00
Birk Magnussen 397125fc6e Fix Warning again 2023-11-09 22:52:19 +01:00
Birk Magnussen 6f458d5398 Fix Warning 2023-11-09 22:52:19 +01:00
Birk Magnussen 1223808a14 Need to output linear for OpenXR 2023-11-09 22:52:18 +01:00
Birk Magnussen 19c4c6edba Make sure scripts have correct Proj_fov 2023-11-09 22:50:59 +01:00
Birk Magnussen bfeb86f017 Properly apply asymmetric FOV to g3_rotate_ functions 2023-11-09 22:50:29 +01:00
Birk Magnussen e7ded2b4cd Integrate per-eye fov overrides 2023-11-09 22:49:44 +01:00
Birk Magnussen b2d1da6701 Enable Asymmetric Projection FOV 2023-11-09 22:49:41 +01:00
Birk Magnussen d0086c31b8 Fix asymmetric top-down fov and add logging 2023-11-09 22:48:55 +01:00
Birk Magnussen d9786f8aae Clang 2023-11-09 22:48:54 +01:00
Birk Magnussen fe916eb7ce Fix Warnings 2023-11-09 22:48:54 +01:00
Birk Magnussen a476897963 Fix BUild Issues 2023-11-09 22:48:54 +01:00
Birk Magnussen e404f32c7b Add warning if extension is not present 2023-11-09 22:48:54 +01:00
Birk Magnussen 77a2f5345f Fix HUD Message Head 2023-11-09 22:48:17 +01:00
Birk Magnussen 41efb57879 Lead indicator slew 2023-11-09 22:47:05 +01:00
Birk Magnussen 729aa2f6f7 Fixup HUD for slewing 2023-11-09 22:45:07 +01:00
Birk Magnussen 346ce5c975 Fix lighting 2023-11-09 22:43:51 +01:00
Birk Magnussen d1d64a0afb Autoslew HUD 2023-11-09 22:43:51 +01:00
Birk Magnussen 94cd6cf8bb Fix retail stars and screenshake 2023-11-09 22:43:51 +01:00
Birk Magnussen 9b09818b49 Cleanup 2023-11-09 22:43:50 +01:00
Birk Magnussen 1ab0d74939 Static linkage on Linux 2023-11-09 22:43:50 +01:00
Birk Magnussen 474db9e184 Fix mouse cursor rendering 2023-11-09 22:43:50 +01:00
Birk Magnussen 36cb7a62d6 Fix OpenGL Errors 2023-11-09 22:43:50 +01:00
Birk Magnussen cb1f1e9c0b Build Warnings 2023-11-09 22:43:49 +01:00
Birk Magnussen 9dc291569f Make OpenXR session creation build on llinux 2023-11-09 22:43:49 +01:00
Birk Magnussen 5da1a075ad Restore Debug timers 2023-11-09 22:43:31 +01:00
Birk Magnussen ad05ce147e Tidy up code 2023-11-09 22:43:31 +01:00
Birk Magnussen 9a227de872 Add option to scale down HUD in OpenXR mode 2023-11-09 22:43:30 +01:00
Birk Magnussen d4ca441449 Add graphics stubs 2023-11-09 22:43:30 +01:00
Birk Magnussen 4ea99eb461 Properly init HMD FoV 2023-11-09 22:43:27 +01:00
Birk Magnussen e01dabeb59 Lock VR behind flag 2023-11-09 22:42:46 +01:00
Birk Magnussen 27e80a3fff Fix VR coordinate transforms 2023-11-09 22:42:46 +01:00
Birk Magnussen 3ab8cb097c 2D flats as plane in space 2023-11-09 22:42:46 +01:00
Birk Magnussen 3721f8165d Basic Stereoscopy 2023-11-09 22:42:43 +01:00
Birk Magnussen f94119d722 Properly init OpenXR and just blit the backbuffer to both eyes for now 2023-11-09 22:40:19 +01:00
Birk Magnussen 5e78054a66 Properly init an OpenXR session, at least on Win32 2023-11-09 22:40:19 +01:00
Birk Magnussen cfe64748a4 Add Graphics abstraction layer 2023-11-09 22:40:18 +01:00
Birk Magnussen 7a281781e3 Make OpenXR linkable 2023-11-09 22:40:18 +01:00
Birk Magnussen a859192587 Basic OpenXR initialization 2023-11-09 22:39:58 +01:00
Goober5000 fa49d05e0c feedback 2023-11-09 15:48:43 -05:00
Goober5000 d8ff77f57f Merge pull request #5782 from Goober5000/build_fixes
a few build fixes
2023-11-09 15:27:38 -05:00
Birk Magnussen fdc8c246f5 Add OpenXR 2023-11-09 20:15:25 +01:00
BMagnu 395aadba6b Merge pull request #5676 from BMagnu/window_resolution
Add command line option for window resolution
2023-11-10 04:13:44 +09:00
Birk Magnussen 1625d86ad7 new res argument 2023-11-09 18:47:57 +01:00
Goober5000 187d24c2f4 rcs thruster refactor
Here's some low-hanging fruit for reducing the memory footprint of `ship_info`.  This turns the maneuvering thrusters array into a vector, refactors the names a bit, fixes thruster activation when `-nosound` is active, reduces the number of calls to `ship_get_thruster_status`, adds some const-correctness, and converts the timestamps to the new system.
2023-11-09 12:44:40 -05:00
mjn-mixael 47ac8a56a0 Some cleanup 2023-11-09 10:26:32 -06:00
JohnAFernandez 72ccbff147 Merge pull request #5781 from MjnMixael/mainhall_input_control
Mainhall ignore input
2023-11-09 09:51:39 -05:00
JohnAFernandez 9960d4bc9f Merge pull request #5755 from Baezon/particle-parent-size-factor
Allow particles to inherit size and lifetime
2023-11-09 09:50:27 -05:00
JohnAFernandez 2334138b99 Merge pull request #5774 from Baezon/lua-burst-params
Add lua burst values
2023-11-09 09:49:56 -05:00
Goober5000 a0b7134b9b refactor argument functions
Move some special-arg helper functions to sexp.h, as requested by jg18.  While we're at it, also refactor the names and add documentation.
2023-11-08 22:46:25 -05:00
Goober5000andJohnAFernandez b20efdec80 Update code/utils/HeapAllocator.cpp
Co-authored-by: JohnAFernandez <[email protected]>
2023-11-08 20:08:37 -05:00
Goober5000 b546dcf949 Merge pull request #5773 from Goober5000/frand_to_Random
convert some instances of frand_range to Random::next
2023-11-08 19:58:31 -05:00
Goober5000 15329b9564 Merge pull request #5786 from BMagnu/fix_headani
Fix wingman headanis
2023-11-08 19:58:19 -05:00
Goober5000 94bd1af5cd Merge pull request #5785 from Goober5000/waypoint_list_fix
fix invalid pointer access to waypoint lists
2023-11-08 19:57:55 -05:00
Birk Magnussen 367f48cf2f fix warning 2023-11-08 20:07:55 +01:00
Birk Magnussen eff00035fa Fix wingman Headani's when they're scaled up 2023-11-08 19:56:58 +01:00
Goober5000 ba2c2f03fb add index check 2023-11-08 13:39:00 -05:00
Goober5000 309bf0b3ea fix invalid pointer access to waypoint lists
Previously (since 2012!) a waypoint would store its parent list as a pointer.  However, this pointer can become invalidated if the waypoint list vector is resized.  To prevent this, store the parent list as an index.

This also renames the waypoint's `objnum` field to `m_objnum` to match the naming of the other fields.
2023-11-08 13:34:56 -05:00
Taylor Richards b62c49ec81 add version check to fix older ffmpeg versions (#5784) 2023-11-08 13:29:50 -05:00
mjn-mixael e34c82d7d1 bool + static cast 2023-11-08 09:25:22 -06:00
mjn-mixael 67e00da79b mainhall ignore input 2023-11-08 08:57:31 -06:00
JohnAFernandez 8528bfe750 Merge pull request #5777 from MjnMixael/hide_yo_jumpnode
Only untarget jumpnode if we're in a mission
2023-11-07 19:14:58 -05:00
Goober5000 37c344a127 a few build fixes
1. use `SIZE_T_ARG` instead of `"%lu"`; should fix format warning in #5780
2. since `HeapAllocator::checkRangesMerged()` has no effect unless running in debug, `#ifdef` out the function; should fix CI warning in #5778
2023-11-07 17:51:55 -05:00
Goober5000 b5b922cbf0 Merge pull request #5779 from Baezon/fix-collision-bug
Fix collision bug
2023-11-07 17:19:15 -05:00
Asteroth 1cbeae2cd9 make sure these remain copies 2023-11-07 15:52:36 -05:00
Goober5000 4292303018 Merge pull request #5776 from Goober5000/fred_import_fixes
FRED import fixes
2023-11-07 15:30:27 -05:00
Jonas Frei 3ebdc51c48 Don't ignore user-set -O* flags 2023-11-07 21:21:28 +01:00
mjn-mixael 6e8ab64523 only untarget if we're in a mission 2023-11-07 08:33:44 -06:00
Asteroth 1b04d9f22c trigger state 2023-11-07 01:22:44 -05:00
Goober5000 4013cf6046 FRED import fixes
Some patches for mission imports:
1. Check that the path isn't empty (the user didn't select "This PC") before continuing
2. Count successful imports
3. Avoid treating an import as a newly saved single mission unless the import was successful
2023-11-07 01:09:10 -05:00
Goober5000 26df8e9a45 assert -> assertion 2023-11-06 13:24:06 -05:00
Goober5000 bb3e3eadfc additional optimizations 2023-11-06 13:24:06 -05:00
Goober5000 b5e215a85c optimization for checking whether subsystems are blown
In many calls to `ship_get_subsystem_strength`, the caller doesn't care about the actual number, just whether the subsystem type is destroyed.  So this adds an optimization to check specifically for that.  In the case of `SUBSYSTEM_ENGINE`, this avoids an iteration over every subsystem on the ship which, for a ship with many turrets, can be significant.
2023-11-06 13:24:04 -05:00
Goober5000 da4eeb3582 Merge pull request #5771 from Goober5000/const_modelcollide
protect model_collide input values
2023-11-06 13:07:45 -05:00
Goober5000 dc578c2479 Merge pull request #5772 from Goober5000/const_eeo
protect eval_enemy_obj_struct input values
2023-11-06 13:07:34 -05:00
BMagnu 3522f3be91 Removed unused variables (#5775) 2023-11-06 18:05:11 +00:00
Goober5000 bd52d75ab9 tweaks 2023-11-06 11:37:01 -05:00
JohnAFernandez a54dc0ded7 Merge pull request #5767 from BMagnu/scripting_in_mission_state
Add a scripting-in-mission state
2023-11-06 11:07:59 -05:00
Goober5000 c076cd11f1 feedback 2023-11-06 10:23:50 -05:00
JohnAFernandez b42c7af847 Merge pull request #5742 from JohnAFernandez/Get-rid-of-int3s
Get rid of remaining int3s in AI code
2023-11-06 10:07:05 -05:00
John Fernandez 5893ef836c Feedback 2023-11-06 09:47:46 -05:00
Asteroth 9eeb7e7983 add burst values 2023-11-06 03:22:21 -05:00
Goober5000 71fa18927c Merge pull request #5770 from Goober5000/fix_fred_warning
fix a FRED compilation warning
2023-11-06 01:55:39 -05:00
Goober5000 ae89ed2b9d convert some instances of frand_range to Random::next
Some of the `frand_range` calls were used for integer calculations, so we can use `Random::next` now.

This also reduces the number of C-style casts in the codebase.
2023-11-06 01:48:29 -05:00
Goober5000 24a4c0df6a protect eval_enemy_obj_struct input values
Add `const` to the `eval_enemy_obj_struct` struct so its values aren't inadvertently overwritten.  Handle a bit of const-correctness propagation.  Also add default member initialization to the struct.
2023-11-06 00:05:54 -05:00
Goober5000 a5f90ddcc1 fix a FRED compilation warning
One of the Voice Acting Manager dialog's strings is now too long for the .rc file and is truncated at 256 characters.  Fortunately this can be worked around by setting it at runtime.
2023-11-05 21:43:36 -05:00
Goober5000 3fe94fc3f4 protect model_collide input values
Add `const` to the `mc_info` struct so its values aren't inadvertently overwritten.  Tweak some of the collision code to prevent overwrites.

Also remove the `flak_muzzle_flash` declaration since that function no longer exists.
2023-11-05 21:17:46 -05:00
Goober5000 f89d437506 Merge pull request #5762 from Goober5000/command_tweaks
Command fixes and tweaks
2023-11-05 20:37:35 -05:00
Birk Magnussen 86a8c1c6f5 Make this a pushing state, not a setting state 2023-11-05 23:42:35 +01:00
Birk Magnussen f72fb68615 Also add the state name 2023-11-05 23:13:35 +01:00
Birk Magnussen 3447b76736 Also change header 2023-11-05 22:23:06 +01:00
Birk Magnussen 7dd52a4214 Add scripting state that does not end mission 2023-11-05 22:04:23 +01:00
Birk Magnussen 8671b9e2f7 Make res parsing a warning 2023-11-05 17:40:15 +01:00
Goober5000 b861989fb6 Merge pull request #5764 from Goober5000/tweak_soundtrack_warning
two small tweaks
2023-11-05 11:12:12 -05:00
Goober5000 1c8a272eca two small tweaks
1. Update soundtrack message to make it easier for modders to track down missing files
2. Update sexp help for ai-stay-near-ship to show the right argument count
2023-11-04 21:05:54 -04:00
Goober5000 221b0dc7ee Command fixes and tweaks
In a few places where the game checks for the command sender, it should check for #Command as well, as long as the mission flag to override #Command is present.

Additionally, while the mission's command sender was originally intended to be a ship, it has been used to specify an alternative to #Command as well.  But this caused problems when the "override #Command" mission flag was active, as it transformed a hashed source into a non-hashed source.  So this commit adds a check to treat the source as hashed, if necessary, if a replacement has occurred.

Fixes #5749.
2023-11-03 17:27:20 -04:00
John Fernandez 0a5cf6ad9d Try the std moves suggested by Coverity
For many coverity issues
2023-11-03 14:40:04 -04:00
JohnAFernandez 2cb12b8ff7 Merge pull request #5593 from MjnMixael/rank_display_names
Rank display name and title
2023-11-03 14:34:55 -04:00
JohnAFernandez 9f173e8cd9 Merge pull request #5750 from MjnMixael/log_timer_padding
Provide a way to account for timer padding in the mission log
2023-11-03 14:34:17 -04:00
JohnAFernandez 6588daaca5 Merge pull request #5758 from JohnAFernandez/Coverity-Improper-Use-Of-Negative
Coverity improper use of negative
2023-11-03 14:32:36 -04:00
JohnAFernandez 9cd648a206 Merge pull request #5760 from TheForce172/fix/5759
Fix #5759 Sticky Support Ship
2023-11-03 14:32:13 -04:00
The Force 44c797f65b Disable support hud when Force rearm done 2023-11-03 14:10:00 +00:00
The Force 46b9c27dfe Fix #5759
Code should only be run in Dock stage 4.
also add extra check if ship is repairing itself
2023-11-03 12:48:57 +00:00
John Fernandez 33e3b13d43 More limited check 2023-11-02 23:27:46 -04:00
John Fernandez 8351d4f623 Ensure we don't use bad indexes in argument_of ops
For coverity 1523820
2023-11-02 23:22:28 -04:00
John Fernandez e0443739bd Always double check that active_goal is positive
Both branches of this ternary assume that it's positive.  Coverity 1523821
2023-11-02 22:42:02 -04:00
JohnAFernandez 80a206151c Merge pull request #5752 from MjnMixael/global_disable_loadout_restoration
Mod setting to disable FSO's internal loadout restoration
2023-11-02 19:25:46 -04:00
JohnAFernandez 64a592d0d5 Merge pull request #5756 from MjnMixael/custom_data_bounds_check
Missed a couple out of bounds checks
2023-11-02 19:25:27 -04:00
JohnAFernandez c30559a63a Merge pull request #5698 from Goober5000/waypoints_upgrade
Waypoints upgrade
2023-11-02 19:24:55 -04:00
JohnAFernandez 245cec5a34 Merge pull request #5694 from MjnMixael/lua_audio_upgrades
Upgrade Lua Sound Handling methods
2023-11-02 14:36:38 -04:00
JohnAFernandez ddedc1bd8e Merge pull request #5739 from MjnMixael/fix_general_order_paths
how about an if/then/else that actually works?
2023-11-02 14:34:23 -04:00
JohnAFernandez 6b71812e7b Merge pull request #5744 from JohnAFernandez/Handle-Oct30-Covscan-issues
Handle oct30 covscan issues
2023-11-02 12:19:16 -04:00
JohnAFernandez 844e9affea Merge pull request #5729 from JohnAFernandez/Fix-pointer-to-local-scope
Change the scope of this pointer
2023-11-02 12:18:53 -04:00
mjn-mixael b69cdc08ee Merge branch 'master' into loadout_no_validation
# Conflicts:
#	fred2/fred.rc
2023-11-02 09:30:42 -05:00
mjn-mixael 69d56172b0 missed a couple out of bounds checks 2023-11-02 08:27:45 -05:00
Asteroth 9d2a89f778 fix subsys position getting (#5740) 2023-11-02 08:15:39 -04:00
Asteroth adcc19085d more docs 2023-11-02 02:30:38 -04:00
Asteroth faddde8307 Merge remote-tracking branch 'upstream/master' into particle-parent-size-factor 2023-11-02 02:27:59 -04:00
Asteroth 0355d2b8d1 update docs 2023-11-02 02:27:40 -04:00
JohnAFernandez 21f42ce47b Merge pull request #5536 from MjnMixael/mission_custom_data
Mission custom data
2023-11-01 20:24:37 -04:00
Asteroth 574b1e6197 accidental shadow 2023-11-01 19:46:00 -04:00
mjn-mixael 34e57d301a Mod setting to disable FSO's internal loadout restoration 2023-11-01 17:49:04 -05:00
Asteroth dc83e4f14a few fixes 2023-11-01 18:16:38 -04:00
Asteroth 3c837b7e9a add all the curves 2023-11-01 18:08:45 -04:00
John Fernandez c7b77a5b24 Add a weekly coverity workflow
Since we removed travis ci, coverity has been unused for six years.  This allows us to submit a linux build to coverity scanning once a week.
2023-11-01 17:06:41 -04:00
mjn-mixael 5a58ff46f2 Add check to mission version 2023-11-01 15:53:04 -05:00
mjn-mixael 4145717363 Merge branch 'master' into mission_custom_data 2023-11-01 15:50:41 -05:00
mjn-mixael eca583074a update check for 23_3 data 2023-11-01 12:59:25 -05:00
mjn-mixael 723bdcb9f1 Merge branch 'master' into loadout_no_validation 2023-11-01 12:56:05 -05:00
Goober5000 cb4fe955ea change GetColor() signature 2023-11-01 11:03:04 -04:00
mjn-mixael ed83ed79ec provide a way to account for timer padding in the mission log 2023-11-01 09:35:30 -05:00
Goober5000 02669338e8 C++ casts 2023-11-01 10:03:51 -04:00
Goober5000 6e86a3a035 Merge pull request #5747 from Goober5000/directive_special_fix
make sure events are current before they become special
2023-11-01 09:36:44 -04:00
Goober5000 4f8344c91e Merge pull request #5741 from Goober5000/misc_updates
some polishing of recent changes
2023-11-01 09:36:33 -04:00
Goober5000 643d18c6f8 Merge pull request #5746 from TheForce172/fix-shader
Fix #5743
2023-11-01 09:36:24 -04:00
JohnAFernandez 8dc481d034 Merge pull request #5736 from BMagnu/alpha_mult_glow
Account for Glow and Spec maps for alpha-multiplied ships
2023-11-01 04:01:47 -04:00
JohnAFernandez 3ba2193d3f Merge pull request #5624 from MjnMixael/xstr_debug_filter
xstr debug filter
2023-11-01 03:31:06 -04:00
JohnAFernandez 8693fa37eb Merge pull request #5732 from Baezon/fix-damaged-engine-max-vel
Fix for ets changes when engines are <15%
2023-11-01 03:30:22 -04:00
JohnAFernandez 3764146957 Merge pull request #5611 from MjnMixael/force_rearm_sexp
Force rearm sexp
2023-11-01 03:29:09 -04:00
John Fernandez 50c923d397 Have fallback for !pmi 2023-11-01 03:26:30 -04:00
Goober5000 617c903cbd tweaks 2023-11-01 00:31:39 -04:00
Goober5000 b6903fbdf4 make sure events are current before they become special
There is an implicit assumption in the code that the `MEF_DIRECTIVE_SPECIAL` flag could not be set on an event until after the `MEF_CURRENT` flag was also set.  This change makes that assumption explicit, and also adds a check in `mission_process_event` to be sure the flag setting doesn't happen out of order.  This situation is very rare, but can happen if the following conditions are true:

1. there is an event directive checking for the destruction of a wing
2. the wing has multiple waves
3. the directive uses the older `is-event-true-delay` technique to control when it is displayed
4. the directive becomes temporarily true before it can be displayed and while there are still waves remaining

This previously caused the "directive special" logic to occur before the "event current" logic occurred, skipping the proper setting of `born_on_date`.

Fixes Github #5725 and Mantis 930.
2023-11-01 00:00:45 -04:00
mjn-mixael dc751a9c5d address feedback 2023-10-31 16:33:27 -05:00
Goober5000 dff0b2acb4 convert event status to enum 2023-10-31 15:56:35 -04:00
Goober5000 ea10ac157f split off the event currency functionality from Sexp_useful_number and move the setting of it 2023-10-31 14:57:48 -04:00
mjn-mixael 173a3d23e8 add comments 2023-10-31 13:36:58 -05:00
The Force 98e20c0979 Fix #5743 2023-10-31 18:07:33 +00:00
JohnAFernandez db02a829aa Fix uninitialized scalars 2 (#5737)
* Make sure we handle unknown location types

Avoids edge-case gargabe pointer 1522974

* Make sure local vectors are at least set to zero

For coverity 1522985

* Make sure from_table is initialized

When creating a replacement texture object, for coverity 1522989

* Change to Unreachable to help Linters

This was a false positive uninitialized scalar, Coverity 1523726.  Hopefully, changing to UNREACHABLE() will help linters avoid this false positive in the future.

* Initialize xyw on this struct instantiation

For coverity 1523730

* Add early return for ade_set_args if error

For coverity 1523732
2023-10-31 13:49:44 -04:00
JohnAFernandez cfe92a4d32 Fix auto copies (#5738)
* fix inefficient (auto x : container) loops

* Don't make two copies of every element...

* Fix more loops

* Last inefficient auto loops
2023-10-31 13:47:48 -04:00
John Fernandez 7f9a10a9a0 ensure that these functions can rely on pmi
For coverity 1523731
2023-10-31 13:37:23 -04:00
John Fernandez 925e2e53f4 A few more int3's 2023-10-31 13:09:03 -04:00
John Fernandez 0e7f24bcac Make sure we don't load nonsense nebulas
For coverity 1523734
2023-10-31 12:51:16 -04:00
John Fernandez b2d85b8e2f Add early return for low level bug
For coverity 1523734
2023-10-31 12:46:17 -04:00
John Fernandez e23409f5f8 Remove the final INT3's in AI code 2023-10-31 10:32:48 -04:00
John Fernandez 381e45f483 Replace remaining Int3's in aibig and aicode
Replacing with Unreachables and Assertions
2023-10-31 09:49:02 -04:00
Goober5000 2d2db58905 some polishing of recent changes
1. The player can target other object types besides ships, so when creating an `object_ship_wing_point_team`, make sure it is a ship
2. A few recent mission features require a version bump, but not all missions use these features; so do a "soft bump" where the mission version is updated only if necessary
3. Remove an unneeded #include by adding a `struct team_data` declaration (see #5599)
2023-10-30 22:59:37 -04:00
mjn-mixael 2b3da41a6d how about an if/then/else that actually works? 2023-10-30 15:46:25 -05:00
mjn-mixael 9da948be56 fix type mismatch 2023-10-30 15:16:16 -04:00
Birk Magnussen 79454fb6c4 Also Alpha-Fade Glow and Spec 2023-10-30 20:08:33 +01:00
John Fernandez 10ed12182c Change the scope of world_goal_pos
Coverity 1523195, change the scope of this variable so that the pointer is not invalidated outside of the if block.
2023-10-30 11:05:43 -04:00
Asteroth 729e448fe5 review fixes 2023-10-30 02:10:18 -04:00
Asteroth 96ae3d0608 Revert "fix subsys pos finding for improved subsys attack pathing"
This reverts commit 55ed0a08f6.
2023-10-30 00:44:37 -04:00
Asteroth 55ed0a08f6 fix subsys pos finding for improved subsys attack pathing 2023-10-30 00:44:22 -04:00
Asteroth c017ef9b8a fix for ets changes when engines are <15% 2023-10-29 23:54:36 -04:00
Birk Magnussen e071603ac0 Multiply emissive with alpha 2023-10-29 10:29:01 +01:00
mjn-mixael e6792ab441 Merge branch 'master' into lua_dynamic_enums
# Conflicts:
#	code/parse/sexp.cpp
#	code/parse/sexp.h
#	fred2/sexp_tree.cpp
#	fred2/sexp_tree.h
#	qtfred/src/ui/widgets/sexp_tree.cpp
#	qtfred/src/ui/widgets/sexp_tree.h
2023-10-28 17:50:26 -05:00
mjn-mixael 5d6c34c2ab Upgrade lua sound handle with pause/resume methods and channel selection 2023-10-25 08:31:06 -05:00
Goober5000 17ad0e09dd add const where appropriate to the jump node API
See title.
2023-10-21 15:59:24 -04:00
mjn-mixael a0c787aa83 Merge branch 'master' into lua_dynamic_enums 2023-10-20 16:13:15 -05:00
Goober5000 ee27abf693 make CI happy 2023-10-20 16:23:50 -04:00
Goober5000 6bcd2f730c update qtfred 2023-10-20 15:51:29 -04:00
Goober5000 c8d78816b0 remaining const updates 2023-10-20 15:32:46 -04:00
Goober5000 b53f3fc803 handle ship_return_seconds_to_goal for WPF_BACKTRACK 2023-10-20 14:58:18 -04:00
Goober5000 d1f0b9343f change iterators 2023-10-20 14:58:18 -04:00
Goober5000 0b2d4768f3 new sexp for waypoint index and backtrack 2023-10-20 14:58:17 -04:00
Goober5000 42fc9891e3 waypoint upgrades 2023-10-20 14:58:17 -04:00
mjn-mixael bfd261a1d3 Merge branch 'master' into lua_dynamic_enums
# Conflicts:
#	code/parse/sexp/LuaSEXP.cpp
2023-10-18 23:11:39 -05:00
Birk Magnussen 0c8564f085 Add option for window-scaling 2023-10-12 20:41:59 +02:00
mjn-mixael 6d08a90106 Prevent out-of-range assert 2023-09-30 13:13:20 -05:00
mjn-mixael 92ed875e69 allow for lua enums to reference lua enums 2023-09-30 10:36:55 -05:00
mjn-mixael 1dc701270f optimize this entirely out of release builds 2023-09-23 18:35:36 -05:00
mjn-mixael 41b10e4d40 xstr debug filter 2023-09-22 23:44:15 -05:00
mjn-mixael f2d0bfdb31 add abort rearm 2023-09-18 09:06:09 -05:00
mjn-mixael 6350a67e73 Cleanup force-rearm 2023-09-18 09:05:53 -05:00
Goober5000 bfad425738 move -no_unfocused_pause
As requested on Discord.  I don't use this option myself, so I welcome any arguments why this should or shouldn't change categories.
2023-09-16 22:27:21 -04:00
mjn-mixael e387038cc3 base implementation of force-rearm 2023-09-15 13:55:37 -05:00
mjn-mixael 52b7a3d198 rank display name and title 2023-09-09 10:54:04 -05:00
mjn-mixael b7045f1756 do not validate loadouts feature 2023-08-22 23:29:18 -05:00
mjn-mixael accb842ffa fix duplicate detection 2023-08-04 18:41:07 -05:00
mjn-mixael 97adef1d87 frakking ints bro 2023-07-31 22:02:20 -05:00
mjn-mixael bb6917ab3b custom lua action for mainhall esc keypress 2023-07-28 09:30:30 -05:00
mjn-mixael 861a9c9c4a Add default custom data with descriptions that will show in FRED 2023-07-25 16:01:23 -05:00
mjn-mixael d2d1d8f996 qtFRED saving of custom data 2023-07-25 10:05:34 -05:00
mjn-mixael 46530b78b7 Working FRED implementation 2023-07-25 10:00:58 -05:00
mjn-mixael cf3b5e8085 base implementation of mission custom data 2023-07-24 16:51:06 -05:00
Asteroth 71ac62e395 add parent size and parent lifetime 2023-05-24 23:54:38 -04:00
676 changed files with 73051 additions and 4395 deletions

No files matched your search

+27 -39
View File
@@ -6,7 +6,7 @@ on:
- 'nightly_*'
env:
QT_VERSION: 5.12.9
QT_VERSION: 5.12.12
jobs:
build_linux:
@@ -15,36 +15,17 @@ jobs:
configuration: [FastDebug, Release]
name: Linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-3d30dc5
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
# - name: Cache Qt
# id: cache-qt-lin
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: gcc-5
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
@@ -64,7 +45,7 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: linux-${{ matrix.configuration }}
path: ${{ github.workspace }}/build/install/*.AppImage
@@ -80,12 +61,12 @@ jobs:
submodules: true
fetch-depth: '0'
- name: Download Release builds
uses: actions/download-artifact@v1
uses: actions/download-artifact@v3
with:
name: linux-Release
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-FastDebug
path: builds
@@ -183,7 +164,7 @@ jobs:
shell: bash
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
path: ${{ github.workspace }}/build/install/*
@@ -203,12 +184,12 @@ jobs:
submodules: true
fetch-depth: '0'
- name: Download Release builds
uses: actions/download-artifact@v1
uses: actions/download-artifact@v3
with:
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
@@ -234,7 +215,7 @@ jobs:
matrix:
configuration: [FastDebug, Release]
compiler: [clang]
arch: [x86_64]
arch: [x86_64, arm64]
name: Mac
runs-on: macos-latest
steps:
@@ -276,6 +257,7 @@ jobs:
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
@@ -284,23 +266,27 @@ jobs:
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
ARCH: ${{ matrix.arch }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Package build result
working-directory: ./build/bin
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
# Ref: https://github.com/actions/runner-images/issues/2619
run: gtar -cvzf macos-build-${{ matrix.configuration }}.tgz *.app
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: mac-${{ matrix.configuration }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}.tgz
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
mac_zip:
name: Build Mac distribution zip
needs: build_mac
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
matrix:
arch: [x86_64, arm64]
steps:
- uses: actions/checkout@v2
name: Checkout
@@ -309,22 +295,24 @@ jobs:
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Download Release builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: mac-Release
name: mac-Release-${{ matrix.arch }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: mac-FastDebug
name: mac-FastDebug-${{ matrix.arch }}
path: builds
- name: Unpack builds
working-directory: ./builds
run: |
tar -xvzf macos-build-Release.tgz
tar -xvzf macos-build-FastDebug.tgz
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
- name: Create Distribution package
working-directory: ./builds
env:
ARCH: ${{ matrix.arch }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
- name: Upload result package
working-directory: ./builds
+31 -70
View File
@@ -6,7 +6,7 @@ on:
- 'release_*'
env:
QT_VERSION: 5.12.9
QT_VERSION: 5.12.12
jobs:
create_release:
@@ -44,65 +44,19 @@ jobs:
name: Linux
needs: create_release # Don't run this job until create_release is done and successful
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-3d30dc5
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
# - name: Cache Qt
# id: cache-qt-lin
# uses: actions/cache@v1
# cache the Qt directory so we don't have to reinstall it every time
# cache.inputs:
# path - A list of files, directories, and wildcard patterns to cache and restore. See @actions/glob for supported patterns.
# key - An explicit key for restoring and saving the cache
# restore-keys - An ordered list of keys to use for restoring the cache if no cache hit occurred for key
# cache.outputs:
# cache-hit true when an exact match was found for the key, false otherwise.
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# installs Qt in the action workflow
# install-qt-action.inputs:
# version desired qt version to install
# host Host platform of Qt, default to platform used by runs-on
# target target platform of Qt, default to desktop
# arch target architecture of Qt, only used for windows or android builds
# dir root dir Qt will be installed to
# install-deps if true, auto-install dependencies on linux. Default true
# modules whitespace delimited list string of additional addon modules to install
# archives whitespace delimited list string of Qt archives to install
# cached if true, Don't download Qt but set ENVARs; use with cache.outputs.cache-hit
# setup-python Set to false to skip using setup-python to find/download a valid python version
# set-env if true, set ENVARs; default = false
# aqtversion version of aqtinstall to use; default = 2.0.0
# py7zrversion version of py7zr to use; default = 0.16.1
# extra additional arguments to pass to aqinstall
# ENVARS set:
# Qt5_DIR / Qt6_DIR
# Qt bin dir appended to PATH
# QT_PLUGIN_PATH, QML2_IMPORT_PATH, PKG_CONFIG_PATH, LD_LIBRARY_PATH
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
- uses: actions/checkout@v1
# checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
name: Checkout
with:
submodules: true # `true` to checkout submodules, `recursive` to recursively checkout submodules
ref: '${{ github.ref }}'
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: gcc-5
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
@@ -122,7 +76,7 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
# Upload the url file for use with other runners
# upload-artifact.inputs:
# if-no-files-found=warn What to do if path fails to find any files.
@@ -149,13 +103,13 @@ jobs:
ref: '${{ github.ref }}'
- name: Download Release builds
# Grab the release builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-Release
path: builds
- name: Download FastDebug builds
# Grab the debug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-FastDebug
path: builds
@@ -166,7 +120,7 @@ jobs:
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Linux
- name: Upload result package
# Stash the result to artifact filespace
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: ${{ steps.generate_package.outputs.package_name }}
path: ${{ steps.generate_package.outputs.package_path }}
@@ -266,7 +220,7 @@ jobs:
shell: bash
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
path: ${{ github.workspace }}/build/install/*
@@ -290,13 +244,13 @@ jobs:
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Download Release builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
@@ -311,13 +265,13 @@ jobs:
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Windows
- name: Upload result package
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: ${{ steps.generate_package.outputs.package_name }}
path: ${{ steps.generate_package.outputs.package_path }}
- name: Upload debug package
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: ${{ steps.generate_package.outputs.debug_name }}
path: ${{ steps.generate_package.outputs.debug_path }}
@@ -336,7 +290,7 @@ jobs:
matrix:
configuration: [FastDebug, Release]
compiler: [clang]
arch: [x86_64]
arch: [x86_64, arm64]
name: Mac
needs: create_release
runs-on: macos-latest
@@ -373,6 +327,7 @@ jobs:
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
@@ -381,23 +336,27 @@ jobs:
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
ARCH: ${{ matrix.arch }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Package build result
working-directory: ./build/bin
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
# Ref: https://github.com/actions/runner-images/issues/2619
run: gtar -cvzf macos-build-${{ matrix.configuration }}.tgz *.app
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: mac-${{ matrix.configuration }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}.tgz
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
mac_zip:
name: Build Mac distribution zip
needs: build_mac
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
matrix:
arch: [x86_64, arm64]
steps:
- uses: actions/checkout@v2
name: Checkout
@@ -406,26 +365,28 @@ jobs:
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Download Release builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: mac-Release
name: mac-Release-${{ matrix.arch }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: mac-FastDebug
name: mac-FastDebug-${{ matrix.arch }}
path: builds
- name: Unpack builds
working-directory: ./builds
run: |
tar -xvzf macos-build-Release.tgz
tar -xvzf macos-build-FastDebug.tgz
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
- name: Create Distribution package
id: generate_package
working-directory: ./builds
env:
ARCH: ${{ matrix.arch }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
- name: Upload result package
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: ${{ steps.generate_package.outputs.package_name }}
path: ${{ steps.generate_package.outputs.package_path }}
-6
View File
@@ -24,12 +24,6 @@ jobs:
name: Checkout
with:
submodules: true
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
+27 -39
View File
@@ -6,7 +6,7 @@ on:
- 'test/*'
env:
QT_VERSION: 5.12.9
QT_VERSION: 5.12.12
jobs:
build_linux:
@@ -15,22 +15,8 @@ jobs:
configuration: [FastDebug, Release]
name: Linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-3d30dc5
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
# - name: Cache Qt
# id: cache-qt-lin
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
- uses: actions/checkout@v1
name: Checkout
with:
@@ -41,16 +27,11 @@ jobs:
[[ "${{ github.ref }}" =~ ^refs\/heads\/test\/(.*)$ ]]
# Override the revision string so that the builds are named correctly
echo "set(FSO_VERSION_REVISION_STR ${BASH_REMATCH[1]})" > "version_override.cmake"
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: gcc-5
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
@@ -70,7 +51,7 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: linux-${{ matrix.configuration }}
path: ${{ github.workspace }}/build/install/*.AppImage
@@ -87,12 +68,12 @@ jobs:
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Download Release builds
uses: actions/download-artifact@v1
uses: actions/download-artifact@v3
with:
name: linux-Release
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-FastDebug
path: builds
@@ -196,7 +177,7 @@ jobs:
shell: bash
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
path: ${{ github.workspace }}/build/install/*
@@ -217,12 +198,12 @@ jobs:
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Download Release builds
uses: actions/download-artifact@v1
uses: actions/download-artifact@v3
with:
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
path: builds
@@ -248,7 +229,7 @@ jobs:
matrix:
configuration: [FastDebug, Release]
compiler: [clang]
arch: [x86_64]
arch: [x86_64, arm64]
name: Mac
runs-on: macos-latest
steps:
@@ -289,6 +270,7 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
@@ -297,23 +279,27 @@ jobs:
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
ARCH: ${{ matrix.arch }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Package build result
working-directory: ./build/bin
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
# Ref: https://github.com/actions/runner-images/issues/2619
run: gtar -cvzf macos-build-${{ matrix.configuration }}.tgz *.app
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
- name: Upload build result
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: mac-${{ matrix.configuration }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}.tgz
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
mac_zip:
name: Build Mac distribution zip
needs: build_mac
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
strategy:
matrix:
arch: [x86_64, arm64]
steps:
- uses: actions/checkout@v2
name: Checkout
@@ -322,22 +308,24 @@ jobs:
fetch-depth: '0'
ref: '${{ github.ref }}'
- name: Download Release builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: mac-Release
name: mac-Release-${{ matrix.arch }}
path: builds
- name: Download FastDebug builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: mac-FastDebug
name: mac-FastDebug-${{ matrix.arch }}
path: builds
- name: Unpack builds
working-directory: ./builds
run: |
tar -xvzf macos-build-Release.tgz
tar -xvzf macos-build-FastDebug.tgz
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
- name: Create Distribution package
working-directory: ./builds
env:
ARCH: ${{ matrix.arch }}
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
- name: Upload result package
working-directory: ./builds
+14 -20
View File
@@ -6,42 +6,27 @@ on:
- master
env:
QT_VERSION: 5.12.9
QT_VERSION: 5.12.12
jobs:
build_linux:
strategy:
matrix:
configuration: [Debug, Release]
compiler: [gcc-5, gcc-10]
compiler: [gcc-5, gcc-13, clang-16]
cmake_options: [""]
include:
# Also include configurations that check if the code compiles without the graphics backends
- configuration: Debug
compiler: gcc-10
compiler: gcc-13
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
- configuration: Release
compiler: gcc-10
compiler: gcc-13
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
name: Linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-3d30dc5
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
# - name: Cache Qt
# id: cache-qt-lin
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
- uses: actions/checkout@v1
name: Checkout
with:
@@ -50,13 +35,22 @@ jobs:
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
- name: Configure ccache
run: |
ccache --set-config=sloppiness=pch_defines,time_macros
ccache -p
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
CCACHE_PATH: /usr/local/bin/ccache
ENABLE_QTFRED: ON
Qt5_DIR: /qt/${{ env.QT_VERSION }}/gcc_64/lib/cmake/Qt5
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
- name: Show CCache statistics
run: ccache --show-stats
+19 -27
View File
@@ -3,41 +3,27 @@ name: Check a pull request
on: [pull_request]
env:
QT_VERSION: 5.12.9
QT_VERSION: 5.12.12
jobs:
build_linux:
strategy:
matrix:
configuration: [Debug, Release]
compiler: [gcc-5, gcc-10, clang-9]
compiler: [gcc-5, gcc-13, clang-16]
cmake_options: [""]
include:
# Also include configurations that check if the code compiles without the graphics backends
- configuration: Debug
compiler: gcc-10
compiler: gcc-13
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
- configuration: Release
compiler: gcc-10
compiler: gcc-13
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
name: Linux
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-3d30dc5
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
steps:
# - name: Cache Qt
# id: cache-qt-lin
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
# setup-python: 'false'
# aqtversion: ==1.1.3
- uses: actions/checkout@v1
name: Checkout
with:
@@ -47,17 +33,18 @@ jobs:
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
vulkan-query-version: 1.3.204.0
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
save: false # Caches are created by a separate job and only restored for PRs
verbose: 1
- name: Configure ccache
run: ccache --set-config=sloppiness=pch_defines,time_macros
- name: Configure CMake
env:
CONFIGURATION: ${{ matrix.configuration }}
COMPILER: ${{ matrix.compiler }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
CCACHE_PATH: /usr/local/bin/ccache
ENABLE_QTFRED: ON
Qt5_DIR: /qt/${{ env.QT_VERSION }}/gcc_64/lib/cmake/Qt5
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
@@ -68,6 +55,8 @@ jobs:
CONFIGURATION: ${{ matrix.configuration }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Show CCache statistics
run: ccache --show-stats
- name: Run Clang Tidy
# Clang-tidy reuses the precompiled headers so this only makes sense for the clang compilers
if: startsWith(matrix.compiler, 'clang-')
@@ -182,7 +171,7 @@ jobs:
matrix:
configuration: [Debug, Release]
compiler: [clang]
arch: [x86_64]
arch: [x86_64, arm64]
cmake_options: [""]
name: Mac
runs-on: macos-latest
@@ -210,7 +199,8 @@ jobs:
- name: ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}-${{ matrix.arch }}
save: false # Caches are created by a separate job and only restored for PRs
- name: Prepare Vulkan SDK
uses: humbletim/[email protected]
with:
@@ -223,6 +213,7 @@ jobs:
COMPILER: ${{ matrix.compiler }}
ARCHITECTURE: ${{ matrix.arch }}
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Compile
working-directory: ./build
@@ -231,6 +222,7 @@ jobs:
working-directory: ./build
env:
CONFIGURATION: ${{ matrix.configuration }}
ARCH: ${{ matrix.arch }}
XDG_RUNTIME_DIR: /root
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
- name: Run Clang Tidy
@@ -0,0 +1,68 @@
name: Weekly Coverity Scan for Freespace Open
# adapted from code by "albert-github" on the doxygen repository
# many thanks for figuring this out first so it could be less painful for us!
#This mode is for testing
on: [push, pull_request]
# In production, push on a specific schedule
#on:
# schedule:
# - cron: "5 0 * * 5" # Run once per a week on Friday morning (midnight UTC, 4 AM EST), to avoid Coverity's submission limits
env:
QT_VERSION: 5.12.12
coverity_email: [email protected]
coverity_token: ${{ secrets.COVERITY_TOKEN }}
jobs:
build:
name: Build FSO With Coverity Wrapper
runs-on: ${{ matrix.config.os }}
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
strategy:
fail-fast: false
matrix:
config:
- { name: "GCC on ubuntu", os: ubuntu-latest, build_type: "Release" }
steps:
- name: Checkout
uses: actions/checkout@v1
with:
submodules: recursive # `true` to checkout submodules, `recursive` to recursively checkout submodules
# pipe results of wget to a log file because it's very verbose and rarely fails
- name: Install Coverity
run: |
wget -o wgetlog.txt -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=${{ env.coverity_token }}&project=scp-fs2open/fs2open.github.com" -O coverity_tool.tgz
mkdir cov-scan
tar ax -f coverity_tool.tgz --strip-components=1 -C cov-scan
- name: Setup Environment
run: |
echo "$(pwd)/cov-scan/bin" >> $GITHUB_PATH
echo "NPROC=$(getconf _NPROCESSORS_ONLN)" >> $GITHUB_ENV
- name: Configure CMake for FSO
env:
CONFIGURATION: Release
compiler: gcc-5
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
- name: Build FSO with Coverity Wrapper
working-directory: ./build
env:
CONFIGURATION: Release
run: cov-build --dir cov-int ninja -k 20 all
- name: Compress Results
working-directory: ./build
run: tar zcf cov-scan.tgz cov-int
#Comment this out when testing to keep from running into upload limits
- name: Upload to Coverity
run: |
cd build
curl --form token=${{ env.coverity_token }} --form email=${{ env.coverity_email }} --form [email protected] --form version="$(git rev-parse HEAD)" --form description="Automatic GHA scan" 'https://scan.coverity.com/builds?project=scp-fs2open/fs2open.github.com'
+3 -14
View File
@@ -47,20 +47,6 @@ endif()
PROJECT(FS2_Open LANGUAGES ${FSO_LANGUAGES})
find_program(CCACHE_PROGRAM ccache)
# Currently only GCC support ccache properly without generating additional warnings
# Enable ccache on Mac even for clang
if(CCACHE_PROGRAM AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR APPLE))
if(NOT CMAKE_C_COMPILER_LAUNCHER)
message(STATUS "Using ccache for C compilation: ${CCACHE_PROGRAM}")
SET(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
endif()
if(NOT CMAKE_CXX_COMPILER_LAUNCHER)
message(STATUS "Using ccache for C++ compilation: ${CCACHE_PROGRAM}")
SET(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
endif()
endif()
IF(CMAKE_CROSSCOMPILING)
SET(IMPORT_EXE_DIR "IMPORT_EXE_DIR-NOTFOUND" CACHE FILEPATH "Required for a cross compiling build, point to binary directory of a cmake build for the real OS")
INCLUDE(${IMPORT_EXE_DIR}/ImportExecutables.cmake)
@@ -141,6 +127,8 @@ OPTION(FSO_BUILD_WITH_OPENGL_DEBUG "Enables debug option for OpenGL" OFF)
OPTION(FSO_BUILD_WITH_VULKAN "Enable compilation of the Vulkan renderer" OFF)
OPTION(FSO_BUILD_WITH_OPENXR_DEBUG "Enables debug option for OpenXR" OFF)
MARK_AS_ADVANCED(FORCE FSO_CMAKE_DEBUG)
MARK_AS_ADVANCED(FORCE FSO_BUILD_INCLUDED_LIBS)
MARK_AS_ADVANCED(FORCE FSO_USE_OPENALSOFT)
@@ -154,6 +142,7 @@ mark_as_advanced(FORCE FSO_BUILD_WITH_FFMPEG)
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENGL)
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENGL_DEBUG)
mark_as_advanced(FORCE FSO_BUILD_WITH_VULKAN)
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENXR_DEBUG)
# Include cotire file from https://github.com/sakra/cotire/
include(cotire)
+17 -9
View File
@@ -4,14 +4,13 @@ if [ "$COMPILER" = "gcc-5" ]; then
export CC=gcc-5
export CXX=g++-5
fi
if [ "$COMPILER" = "gcc-10" ]; then
export CC=gcc-10
export CXX=g++-10
if [ "$COMPILER" = "gcc-13" ]; then
export CC=gcc-13
export CXX=g++-13
fi
if [ "$COMPILER" = "clang-9" ]; then
# Work around bug in clang that uses the wrong installation directory: https://bugs.llvm.org/show_bug.cgi?id=47460
export CC=$(readlink -f $(which clang-9))
export CXX=$(readlink -f $(which clang++-9))
if [ "$COMPILER" = "clang-16" ]; then
export CC=clang-16
export CXX=clang++-16
fi
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH
@@ -34,6 +33,11 @@ if [[ "$COMPILER" =~ ^clang.*$ ]]; then
CXXFLAGS="$CXXFLAGS -Qunused-arguments"
fi
if [ ! "$CCACHE_PATH" = "" ]; then
echo "Using ccache at $CCACHE_PATH"
CMAKE_OPTIONS="$CMAKE_OPTIONS -DCMAKE_C_COMPILER_LAUNCHER=$CCACHE_PATH -DCMAKE_CXX_COMPILER_LAUNCHER=$CCACHE_PATH"
fi
mkdir build
cd build
@@ -44,7 +48,11 @@ export LD_LIBRARY_PATH
if [ "$RUNNER_OS" = "macOS" ]; then
brew install ninja
fi
# CMAKE_JOB_POOLS and CMAKE_JOB_POOL_LINK ensure that when using ninja, link operations are done sequentially
# we have some build rules that do not play nice with parallel invocation and that fixes these issues
cmake -G Ninja -DFSO_FATAL_WARNINGS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON $CMAKE_OPTIONS $PLATFORM_CMAKE_OPTIONS \
-DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DCMAKE_BUILD_TYPE=$CONFIGURATION \
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=OFF \
-DSHADERS_ENABLE_COMPILATION=ON ..
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=${ENABLE_QTFRED:-OFF} \
-DSHADERS_ENABLE_COMPILATION=ON -DCMAKE_JOB_POOLS=link=1 -DCMAKE_JOB_POOL_LINK=link ..
+4 -4
View File
@@ -26,11 +26,11 @@ elif [ "$OS" = "Windows" ]; then
echo "debug_name=$(get_package_name)-debug-$ARCH-$SIMD.7z" >> $GITHUB_OUTPUT
echo "debug_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z")" >> $GITHUB_OUTPUT
elif [ "$OS" = "Mac" ]; then
tar -cvzf "$(get_package_name)-builds-Mac.tar.gz" *.app
tar -cvzf "$(get_package_name)-builds-Mac-$ARCH.tar.gz" *.app
echo "package_path=$(pwd)/$(get_package_name)-builds-Mac.tar.gz" >> $GITHUB_OUTPUT
echo "package_name=$(get_package_name)-builds-Mac.tar.gz" >> $GITHUB_OUTPUT
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Mac.tar.gz")" >> $GITHUB_OUTPUT
echo "package_path=$(pwd)/$(get_package_name)-builds-Mac-$ARCH.tar.gz" >> $GITHUB_OUTPUT
echo "package_name=$(get_package_name)-builds-Mac-$ARCH.tar.gz" >> $GITHUB_OUTPUT
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Mac-$ARCH.tar.gz")" >> $GITHUB_OUTPUT
else
echo "Invalid OS: $OS"
fi
+7
View File
@@ -5,6 +5,13 @@ HERE=$(dirname "$SCRIPT")
export LD_LIBRARY_PATH=$(pwd)/bin/lib:$LD_LIBRARY_PATH
# if on mac and building for architecture that doesn't match host
# then unittests will fail so we just need to skip it (for now)
if [ "$RUNNER_OS" = "macOS" ] && [ "$ARCH" != "$(uname -m)" ]; then
echo "Skipping tests due to architecture mismatch!"
exit 0
fi
if [ "$CONFIGURATION" = "Debug"] && [[ "$RUNNER_OS" != "macOS" ]] ; then
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
--suppressions="$HERE/valgrind.supp" ./bin/unittests --gtest_shuffle
+9 -5
View File
@@ -8,7 +8,8 @@ from file_list import ReleaseFile
from util import retry_multi, GLOBAL_TIMEOUT
LINUX_KEY = "Linux"
MACOSX_KEY = "Mac"
MACOSX_X64_KEY = "Mac-x86_64"
MACOSX_ARM64_KEY = "Mac-arm64"
WIN32_SSE2_KEY = "Win32-SSE2"
WIN64_SSE2_KEY = "Win64-SSE2"
WIN32_AVX_KEY = "Win32-AVX"
@@ -34,7 +35,8 @@ metadata = {
platforms = {
LINUX_KEY: 'linux',
MACOSX_KEY: 'macosx',
MACOSX_X64_KEY: 'macosx',
MACOSX_ARM64_KEY: 'macosx',
WIN32_SSE2_KEY: 'windows',
WIN64_SSE2_KEY: 'windows',
WIN32_AVX_KEY: 'windows',
@@ -43,7 +45,8 @@ platforms = {
envs = {
LINUX_KEY: 'linux && x86_64', # Linux only has 64bit builds
MACOSX_KEY: 'macosx',
MACOSX_X64_KEY: 'macosx && x86_64',
MACOSX_ARM64_KEY: 'macosx && arm64',
WIN32_SSE2_KEY: 'windows',
WIN64_SSE2_KEY: 'windows && x86_64',
WIN32_AVX_KEY: 'windows && avx',
@@ -135,7 +138,7 @@ def render_nebula_release(version, stability, files, config):
'label': label,
'properties': props,
})
elif group == MACOSX_KEY and fn.startswith(os.path.basename(fn) + '.app/'):
elif group.startswith('Mac') and fn.startswith(os.path.basename(fn) + '.app/'):
if 'qtfred' in fn:
if '-FASTDBG' in fn:
label = 'QtFRED Debug'
@@ -148,7 +151,8 @@ def render_nebula_release(version, stability, files, config):
label = None
props = {
"x64": True, # All Mac builds are 64-bit
"arm64": "arm64" in fn,
"x64": "x64" in fn,
"sse2": True, # There are no forced options on mac but 64-bit always implies SSE2 so we set that here
"avx": False,
"avx2": False,
+3 -2
View File
@@ -53,8 +53,9 @@ Alternatively, if there is a package in your software repository then you should
[img]https://scp.indiegames.us/img/mac-icon.png[/img] [color=green][size=12pt]macOS[/size][/color]
[size=8pt]macOS 10.9+, 64-bit (Intel)[/size]
${build(groups["Mac"].mainFile)}
[size=8pt]macOS 10.9+[/size]
[b]Intel (64-bit):[/b] ${build(groups["Mac"].subFiles["x86_64"])}
[b]Apple Silicon:[/b] ${build(groups["Mac"].subFiles["arm64"])}
These builds are not signed and so by default will fail to launch. To run them simply right-click on the app, click open, then click open again on the security confirmation dialog. You should only have to do this once for each app.
If running the game through Knossos or Knossos.NET this step should not be necessary.
+6
View File
@@ -7,3 +7,9 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
else()
set(IS_64BIT FALSE)
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|ARM64)")
set(IS_ARM64 TRUE)
else()
set(IS_ARM64 FALSE)
endif()
+8
View File
@@ -22,6 +22,14 @@ SET(LIBRAY_DESTINATION "../Frameworks")
set(PLATFORM_MAC TRUE CACHE INTERNAL "" FORCE)
# Maybe override arm64 setting if we are compiling for different architecture
# If not specified, or if it's a universal build, then this should do nothing
if(CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
set(IS_ARM64 TRUE)
elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
set(IS_ARM64 FALSE)
endif()
# Generate and don't strip debug symbols
# These settings don't seem to generate debug symbols for code and Freespace2
# so those settings are set manually in code and Freespace2's CMakeLists.txt files
+1
View File
@@ -9,6 +9,7 @@
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
#cmakedefine01 IS_64BIT
#cmakedefine01 IS_ARM64
#cmakedefine01 SCP_HAVE_STRCASECMP
#cmakedefine01 SCP_HAVE_STRNCASECMP
+29 -8
View File
@@ -83,20 +83,41 @@ if(SUPPORTS_SHIFT_NEGATIVE_VALUE)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-shift-negative-value")
endif()
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-parameter")
# Check if there is a user-set optimisation flag
string(REGEX MATCH "-O[a-zA-Z|0-9]+" CXX_OPT_FLAG ${CXX_BASE_FLAGS})
string(REGEX MATCH "-O[a-zA-Z|0-9]+" C_OPT_FLAG ${C_BASE_FLAGS})
set(COMPILER_FLAGS_DEBUG "-Og -g -Wshadow")
# If no user-set opt flag, set -O2 and -Og
if ("${CXX_OPT_FLAG}" STREQUAL "")
set(CXX_OPT_FLAG_RELEASE "-O2")
set(CXX_OPT_FLAG_DEBUG "-Og")
else()
set(CXX_OPT_FLAG_RELEASE "${CXX_OPT_FLAG}")
set(CXX_OPT_FLAG_DEBUG "${CXX_OPT_FLAG}")
endif()
if ("${C_OPT_FLAG}" STREQUAL "")
set(C_OPT_FLAG_RELEASE "-O2")
set(C_OPT_FLAG_DEBUG "-Og")
else()
set(C_OPT_FLAG_RELEASE "${C_OPT_FLAG}")
set(C_OPT_FLAG_DEBUG "${C_OPT_FLAG}")
endif()
# Always use the base flags and add our compiler flags at the bacl
set(CXX_FLAGS_RELEASE "${CXX_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-parameter")
set(C_FLAGS_RELEASE "${C_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-parameter")
set(CXX_FLAGS_DEBUG "${CXX_OPT_FLAG_DEBUG} -g -Wshadow")
set(C_FLAGS_DEBUG "${C_OPT_FLAG_DEBUG} -g -Wshadow")
# Always use the base flags and add our compiler flags at the back
set(CMAKE_CXX_FLAGS "${CXX_BASE_FLAGS} ${COMPILER_FLAGS}")
set(CMAKE_C_FLAGS "${C_BASE_FLAGS} ${COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
set(CMAKE_CXX_FLAGS_RELEASE ${CXX_FLAGS_RELEASE})
set(CMAKE_C_FLAGS_RELEASE ${C_FLAGS_RELEASE})
set(CMAKE_CXX_FLAGS_DEBUG ${CXX_FLAGS_DEBUG})
set(CMAKE_C_FLAGS_DEBUG ${C_FLAGS_DEBUG})
set(CMAKE_EXE_LINKER_FLAGS "")
+28 -6
View File
@@ -113,19 +113,41 @@ if(SUPPORTS_STRINGOP_TRUNCATION)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-stringop-overflow")
endif()
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
# Check if there is a user-set optimisation flag
string(REGEX MATCH "-O[a-zA-Z|0-9]+" CXX_OPT_FLAG ${CXX_BASE_FLAGS})
string(REGEX MATCH "-O[a-zA-Z|0-9]+" C_OPT_FLAG ${C_BASE_FLAGS})
set(COMPILER_FLAGS_DEBUG "-Og -g -Wshadow")
# If no user-set opt flag, set -O2 and -Og
if ("${CXX_OPT_FLAG}" STREQUAL "")
set(CXX_OPT_FLAG_RELEASE "-O2")
set(CXX_OPT_FLAG_DEBUG "-Og")
else()
set(CXX_OPT_FLAG_RELEASE "${CXX_OPT_FLAG}")
set(CXX_OPT_FLAG_DEBUG "${CXX_OPT_FLAG}")
endif()
if ("${C_OPT_FLAG}" STREQUAL "")
set(C_OPT_FLAG_RELEASE "-O2")
set(C_OPT_FLAG_DEBUG "-Og")
else()
set(C_OPT_FLAG_RELEASE "${C_OPT_FLAG}")
set(C_OPT_FLAG_DEBUG "${C_OPT_FLAG}")
endif()
set(CXX_FLAGS_RELEASE "${CXX_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
set(C_FLAGS_RELEASE "${C_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
set(CXX_FLAGS_DEBUG "${CXX_OPT_FLAG_DEBUG} -g -Wshadow")
set(C_FLAGS_DEBUG "${C_OPT_FLAG_DEBUG} -g -Wshadow")
# Always use the base flags and add our compiler flags at the back
set(CMAKE_CXX_FLAGS "${CXX_BASE_FLAGS} ${COMPILER_FLAGS}")
set(CMAKE_C_FLAGS "${C_BASE_FLAGS} ${COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
set(CMAKE_CXX_FLAGS_RELEASE ${CXX_FLAGS_RELEASE})
set(CMAKE_C_FLAGS_RELEASE ${C_FLAGS_RELEASE})
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
set(CMAKE_CXX_FLAGS_DEBUG ${CXX_FLAGS_DEBUG})
set(CMAKE_C_FLAGS_DEBUG ${C_FLAGS_DEBUG})
set(CMAKE_EXE_LINKER_FLAGS "${LINKER_FLAGS}")
+3 -1
View File
@@ -35,7 +35,9 @@ ELSE()
SET(FSO_BINARY_SUFFIX "${FSO_VERSION_MAJOR}_${FSO_VERSION_MINOR}_${FSO_VERSION_BUILD}_${FSO_VERSION_REVISION_STR}")
ENDIF()
IF(IS_64BIT)
IF(IS_ARM64)
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_arm64")
ELSEIF(IS_64BIT)
# This is a 64-bit builds
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_x64")
ENDIF()
+15
View File
@@ -25,6 +25,10 @@ if (FSO_BUILD_WITH_OPENGL)
endif()
endif()
if(FSO_BUILD_WITH_OPENXR_DEBUG)
add_definitions(-DFS_OPENXR_DEBUG)
endif()
TARGET_LINK_LIBRARIES(code PUBLIC openal)
TARGET_LINK_LIBRARIES(code PUBLIC ${LUA_LIBS})
TARGET_LINK_LIBRARIES(code PUBLIC ${PNG_LIBS})
@@ -75,6 +79,17 @@ target_link_libraries(code PUBLIC hidapi::hidapi)
target_link_libraries(code PUBLIC imgui)
IF(NOT APPLE)
target_link_libraries(code PUBLIC OpenXR::openxr_loader)
target_include_directories(code PUBLIC OpenXR::Headers)
ENDIF()
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
# On Linux, we need to access X11 window data.
# On Windows, SDL already provides everything, so no need to do anything
find_package(X11)
target_link_libraries(code PUBLIC ${X11_LIBRARIES})
ENDIF()
# Headers for standalone "gui" on UNIX
IF(UNIX)
TARGET_LINK_LIBRARIES(code PUBLIC ${MONGOOSE_LIBS})
+3 -3
View File
@@ -277,7 +277,7 @@ typedef struct ai_info {
// Probably become obsolete, to be replaced by path_start, path_cur, etc.
waypoint_list *wp_list; // waypoint list being followed
size_t wp_index; // waypoint index in list
int wp_index; // waypoint index in list
int wp_flags; // waypoint flags, see WPF_xxxx
int waypoint_speed_cap; // -1 no cap, otherwise cap - changed to int by Goober5000
@@ -533,11 +533,11 @@ extern void ai_ignore_wing(object *ignorer, int wingnum);
extern void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type);
extern void ai_stay_still(object *still_objp, vec3d *view_pos);
extern void ai_do_default_behavior(object *obj);
extern void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags);
extern void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags, int start_index);
extern void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hit_normal);
extern void ai_ship_destroy(int shipnum);
extern vec3d ai_get_acc_limit(vec3d* vel_limit, const object* objp);
extern void ai_turn_towards_vector(vec3d *dest, object *objp, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec = nullptr, vec3d* turnrate_mod = nullptr);
extern void ai_turn_towards_vector(const vec3d *dest, object *objp, const vec3d *slide_vec, const vec3d *rel_pos, float bank_override, int flags, const vec3d *rvec = nullptr, const vec3d* turnrate_mod = nullptr);
extern void init_ai_object(int objnum);
extern void ai_init(void); // Call this one to parse ai.tbl.
extern void ai_level_init(void); // Call before each level to reset AI
+1
View File
@@ -47,6 +47,7 @@ namespace AI {
Depart_sound_played,// Goober5000 - replacement for AL's hack ;)
Target_own_team, // this attack goal is allowed to target friendlies
Afterburn_hard, // afterburn as hard as possible to the goal
Waypoints_in_reverse, // decrement instead of increment
NUM_VALUES
};
+4 -4
View File
@@ -258,7 +258,7 @@ void parse_ai_profiles_tbl(const char *filename)
if (optional_string("$Glide Attack Percent:")) {
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
//While we're at it, verify the range
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.0f) {
@@ -271,7 +271,7 @@ void parse_ai_profiles_tbl(const char *filename)
if (optional_string("$Circle Strafe Percent:")) {
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
//While we're at it, verify the range
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.0f) {
@@ -284,7 +284,7 @@ void parse_ai_profiles_tbl(const char *filename)
if (optional_string("$Glide Strafe Percent:")) {
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
//While we're at it, verify the range
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.0f) {
@@ -297,7 +297,7 @@ void parse_ai_profiles_tbl(const char *filename)
if (optional_string("$Random Sidethrust Percent:")) {
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
//While we're at it, verify the range
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
+3 -4
View File
@@ -538,8 +538,7 @@ bool ai_new_maybe_reposition_attack_subsys() {
model_local_to_global_point(&geye, &ep->pnt, pm, 0, &Pl_objp->orient, &Pl_objp->pos);
// get world pos of subsystem
polymodel* tgt_pm = model_get(Ship_info[Ships[target_objp->instance].ship_info_index].model_num);
model_local_to_global_point(&gsubpos, &vmd_zero_vector, tgt_pm, aip->targeted_subsys->system_info->subobj_num, &En_objp->orient, &En_objp->pos);
get_subsystem_pos(&gsubpos, target_objp, aip->targeted_subsys);
// you're in sight! shoot it!
if (ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, 0))
@@ -547,6 +546,7 @@ bool ai_new_maybe_reposition_attack_subsys() {
// not in sight, gotta get there
vec3d* good_pos = nullptr;
vec3d world_goal_pos;
// For performance reasons we only recheck once a second, otherwise we reuse the last found target.
if (timestamp_elapsed(aip->next_dynamic_path_check_time)) {
vec3d tgt2pl = Pl_objp->pos - target_objp->pos;
@@ -568,7 +568,6 @@ bool ai_new_maybe_reposition_attack_subsys() {
vm_rot_point_around_line(&goal_pos, &tgt2pl, angle2goal, &vmd_zero_vector, &cross);
// then scale in (or out) towards our subsys
vec3d world_goal_pos;
float new_radius = ((subsys_dist - pl_dist) * (angle2goal / angle2subsys)) + pl_dist;
vm_vec_copy_scale(&world_goal_pos, &goal_pos, new_radius / pl_dist);
world_goal_pos += target_objp->pos;
@@ -1842,7 +1841,7 @@ void ai_big_strafe()
/*
if ( aip->goal_objnum != aip->target_objnum ) {
Int3(); // what is going on here? - Get Alan
UNREACHABLE("The goal objnum does not match the target objnum in ai_big_strafe(), please report to the SCP!"); // what is going on here? - Get Alan
aip->mode = AIM_NONE;
return;
}
+250 -99
View File
@@ -287,6 +287,15 @@ float AI_frametime;
char** Ai_class_names = NULL;
//used for good-primary-time
typedef struct {
object_ship_wing_point_team subject;
object_ship_wing_point_team target;
int weapon_index;
} primary_fire_info;
static SCP_vector<primary_fire_info> Preferred_primary_info;
typedef struct {
int team;
int weapon_index;
@@ -294,7 +303,7 @@ typedef struct {
int ship_registry_index;
} huge_fire_info;
SCP_vector<huge_fire_info> Ai_huge_fire_info;
static SCP_vector<huge_fire_info> Ai_huge_fire_info;
int Ai_last_arrive_path; // index of ship_bay path used by last arrival from a fighter bay
@@ -386,10 +395,10 @@ int is_preferred_weapon(int weapon_num, object *firer_objp, object *target_objp)
continue;
auto ship_entry = &Ship_registry[hfi->ship_registry_index];
if (!ship_entry->objp)
if (!ship_entry->has_objp())
continue;
int signature = ship_entry->objp->signature;
int signature = ship_entry->objp()->signature;
// sigatures, weapon_index, and team must match
if ( (signature == target_signature) && (hfi->weapon_index == weapon_num) && (hfi->team == firer_team) )
@@ -1001,6 +1010,9 @@ void ai_level_init()
ai_init_secondary_info();
Ai_last_arrive_path=0;
// clear out the preferred primaries so that it doesn't persist between missions or between mission reloads
Preferred_primary_info.clear();
}
// BEGIN STEALTH
@@ -1303,7 +1315,7 @@ void ai_compensate_for_retail_turning(vec3d* vel_limit, vec3d* acc_limit, float
// If rvec != NULL, use it to match bank by calling vm_angular_move_matrix.
// (rvec defaults to NULL)
// optionally specified turnrate_mod contains multipliers for each component of the turnrate (RATE, so 0.5 = slower)
void ai_turn_towards_vector(vec3d* dest, object* objp, vec3d* slide_vec, vec3d* rel_pos, float bank_override, int flags, vec3d* rvec, vec3d* turnrate_mod)
void ai_turn_towards_vector(const vec3d* dest, object* objp, const vec3d* slide_vec, const vec3d* rel_pos, float bank_override, int flags, const vec3d* rvec, const vec3d* turnrate_mod)
{
matrix curr_orient;
vec3d vel_in, vel_out, desired_fvec, src;
@@ -1316,7 +1328,7 @@ void ai_turn_towards_vector(vec3d* dest, object* objp, vec3d* slide_vec, vec3d*
// Don't allow a ship to turn if it has no engine strength.
// AL 3-12-98: objp may not always be a ship!
if ( (objp->type == OBJ_SHIP) && !(flags & AITTV_VIA_SEXP) ) {
if (!Ships[objp->instance].flags[Ship::Ship_Flags::Maneuver_despite_engines] && ship_get_subsystem_strength(&Ships[objp->instance], SUBSYSTEM_ENGINE) <= 0.0f)
if (!Ships[objp->instance].flags[Ship::Ship_Flags::Maneuver_despite_engines] && ship_subsystems_blown(&Ships[objp->instance], SUBSYSTEM_ENGINE))
return;
}
@@ -2567,7 +2579,7 @@ void ai_attack_object(object* attacker, object* attacked, int ship_info_index)
}
// don't abort a support call if you're disabled!
if (ship_get_subsystem_strength(&Ships[attacker->instance], SUBSYSTEM_ENGINE) > 0.0f)
if (!ship_subsystems_blown(&Ships[attacker->instance], SUBSYSTEM_ENGINE))
ai_set_goal_abort_support_call(attacker, aip);
aip->ok_to_target_timestamp = timestamp(DELAY_TARGET_TIME); // No dynamic targeting for 7 seconds.
@@ -2643,7 +2655,7 @@ void ai_evade_object(object *evader, object *evaded)
Assert(Ships[evader->instance].ai_index != -1);
if (evaded == evader) {
Int3(); // Bogus! Who tried to get me to evade myself! Trace out and fix!
UNREACHABLE("Ship %s is trying to evade itself. Please report to the SCP!", Ships[evader->instance].ship_name); // Bogus! Who tried to get me to evade myself! Trace out and fix!
return;
}
@@ -3404,7 +3416,7 @@ void ai_dock_with_object(object *docker, int docker_index, object *dockee, int d
aip->submode_start_time = Missiontime;
break;
default:
Int3(); // Bogus dock_type.
UNREACHABLE("Unknown dock type in ai_dock_with_object of %d. Please report to the SCP!", dock_type); // Bogus dock_type.
}
// Goober5000 - we no longer need to set dock_path_index because it's easier to grab the path from the dockpoint
@@ -3464,12 +3476,19 @@ void ai_dock_with_object(object *docker, int docker_index, object *dockee, int d
// Cause a ship to fly its waypoints.
// flags tells:
// WPF_REPEAT Set -> repeat waypoints.
void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags)
// WPF_REPEAT Set -> repeat waypoints.
// WPF_BACKTRACK Go in reverse.
void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags, int start_index)
{
ai_info *aip;
Assert(wp_list != NULL);
if (start_index < 0 || start_index >= (int)wp_list->get_waypoints().size())
{
Warning(LOCATION, "Starting index for %s on '%s' is out of range!", Ships[objp->instance].ship_name, wp_list->get_name());
start_index = (wp_flags & WPF_BACKTRACK) ? (int)wp_list->get_waypoints().size() - 1 : 0;
}
aip = &Ai_info[Ships[objp->instance].ai_index];
if ( (aip->mode == AIM_WAYPOINTS) && (aip->wp_list == wp_list) )
@@ -3477,7 +3496,7 @@ void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags)
if (aip->wp_index == INVALID_WAYPOINT_POSITION)
{
Warning(LOCATION, "aip->wp_index should have been assigned already!");
aip->wp_index = 0;
aip->wp_index = start_index;
}
return;
}
@@ -3493,7 +3512,7 @@ void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags)
aip->ai_flags.remove(AI::AI_Flags::Formation_object);
aip->wp_list = wp_list;
aip->wp_index = 0;
aip->wp_index = start_index;
aip->wp_flags = wp_flags;
aip->mode = AIM_WAYPOINTS;
@@ -3736,7 +3755,7 @@ void ai_update_aim(ai_info *aip)
bool ai_willing_to_afterburn_hard(ai_info* aip) {
return aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC ?
The_mission.ai_profile->flags[AI::Profile_Flags::Dynamic_goals_afterburn_hard] :
aip->goals[aip->active_goal].flags[AI::Goal_Flags::Afterburn_hard];
(aip->active_goal > -1 && aip->goals[aip->active_goal].flags[AI::Goal_Flags::Afterburn_hard]);
}
// pedal to the metal!!1!
@@ -4485,9 +4504,6 @@ void ai_safety()
aip->submode = AISS_2;
aip->submode_start_time = Missiontime;
break;
case AISS_1a: // Pick a safe point because we just got whacked!
Int3();
break;
case AISS_2:
if (ai_safety_goto_spot(Pl_objp) < 25.0f) {
aip->submode = AISS_3;
@@ -4497,8 +4513,9 @@ void ai_safety()
case AISS_3:
ai_safety_circle_spot(Pl_objp);
break;
case AISS_1a: // Pick a safe point because we just got whacked!
default:
Int3(); // Illegal submode for ai_safety();
UNREACHABLE("Bad AI submode for ai_safety mode of %d. Please report to the SCP!", aip->submode); // Illegal submode for ai_safety();
break;
}
}
@@ -4510,7 +4527,7 @@ void ai_safety()
// optionally returns true if Pl_objp's (pl_treat_as_ship_p) fly to order was issued to him directly,
// or if the order was issued to his wing (returns false) (can be NULL, and result is only
// valid if Pl_done_p was not NULL and was set true by function.
void ai_fly_to_target_position(vec3d* target_pos, bool* pl_done_p=NULL, bool* pl_treat_as_ship_p=NULL)
void ai_fly_to_target_position(const vec3d* target_pos, bool* pl_done_p=NULL, bool* pl_treat_as_ship_p=NULL)
{
float dot, dist_to_goal;
ship *shipp = &Ships[Pl_objp->instance];
@@ -4842,11 +4859,11 @@ void ai_waypoints()
// sanity checking for stuff that should never happen
if (aip->wp_index == INVALID_WAYPOINT_POSITION) {
if (aip->wp_list == NULL) {
Warning(LOCATION, "Waypoints should have been assigned already!");
ai_start_waypoints(Pl_objp, &Waypoint_lists.front(), WPF_REPEAT);
UNREACHABLE("Waypoints should have been assigned already!");
ai_start_waypoints(Pl_objp, &Waypoint_lists.front(), WPF_REPEAT, 0);
} else {
Warning(LOCATION, "Waypoints should have been started already!");
ai_start_waypoints(Pl_objp, aip->wp_list, WPF_REPEAT);
UNREACHABLE("Waypoints should have been started already!");
ai_start_waypoints(Pl_objp, aip->wp_list, WPF_REPEAT, 0);
}
}
@@ -4856,17 +4873,32 @@ void ai_waypoints()
ai_fly_to_target_position(aip->wp_list->get_waypoints()[aip->wp_index].get_pos(), &done, &treat_as_ship);
if ( done ) {
bool reached_end;
// go on to next waypoint in path
++aip->wp_index;
if (aip->wp_flags & WPF_BACKTRACK) {
--aip->wp_index;
reached_end = (aip->wp_index == -1);
} else {
++aip->wp_index;
reached_end = (aip->wp_index == (int)aip->wp_list->get_waypoints().size());
}
if ( aip->wp_index == aip->wp_list->get_waypoints().size() ) {
if (reached_end) {
// have reached the last waypoint. Do I repeat?
if ( aip->wp_flags & WPF_REPEAT ) {
// go back to the start.
aip->wp_index = 0;
if (aip->wp_flags & WPF_BACKTRACK) {
aip->wp_index = (int)aip->wp_list->get_waypoints().size() - 1;
} else {
aip->wp_index = 0;
}
} else {
// stay on the last waypoint.
--aip->wp_index;
if (aip->wp_flags & WPF_BACKTRACK) {
++aip->wp_index;
} else {
--aip->wp_index;
}
// Log a message that the wing or ship reached his waypoint and
// remove the goal from the AI goals of the ship pr wing, respectively.
@@ -5459,6 +5491,61 @@ float G_collision_time;
vec3d G_predicted_pos, G_fire_pos;
/*
* plieblang
* Used by the good-primary-time sexp to store the info supplied from there
* weapon_idx indexes into Weapon_info if the primary preference is being set
*/
void ai_set_or_clear_preferred_primary_weapon(bool set_it, const object_ship_wing_point_team *subject, const object_ship_wing_point_team *target, int weapon_idx)
{
// force the ai to reselect a primary instead of possibly waiting the normal elapsed time
for (auto so : list_range(&Ship_obj_list))
{
auto subject_objp = &Objects[so->objnum];
if (subject_objp->flags[Object::Object_Flags::Should_be_dead])
continue;
auto subject_shipp = &Ships[subject_objp->instance];
if (!subject->matches(subject_shipp))
continue;
auto subject_aip = &Ai_info[subject_shipp->ai_index];
if (subject_aip->target_objnum < 0)
continue;
auto target_objp = &Objects[subject_aip->target_objnum];
if (target_objp->type != OBJ_SHIP || !target->matches(&Ships[target_objp->instance]))
continue;
// for AIs that match this subject-target pair, select a new primary immediately
subject_aip->primary_select_timestamp = timestamp(1);
}
if (set_it)
{
for (auto& ppi : Preferred_primary_info)
{
if (ppi.subject == *subject && ppi.target == *target)
{
ppi.weapon_index = weapon_idx;
return;
}
}
// not found, so add a new entry
Preferred_primary_info.push_back({ *subject, *target, weapon_idx });
}
else
{
Preferred_primary_info.erase(
std::remove_if(Preferred_primary_info.begin(), Preferred_primary_info.end(), [&](const primary_fire_info& ppi) {
return ppi.subject == *subject && ppi.target == *target;
}), Preferred_primary_info.end()
);
}
}
//old version of this fuction, this will be useful for playing old missions and not having the new primary
//selection code throw off the balance of the mission.
// If:
@@ -5544,6 +5631,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
{
// Pointer Set Up
ship *shipp = &Ships[objp->instance];
ship *other_shipp = nullptr;
ship_weapon *swp = &shipp->weapons;
// Debugging
@@ -5555,6 +5643,46 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
return -1;
}
bool other_is_ship = (other_objp->type == OBJ_SHIP);
if (other_is_ship)
{
other_shipp = &Ships[other_objp->instance];
//if the good-primary-time sexp has been used, return that weapon immediately
//if smart primary weapon selection isn't set, turning this override behavior off might not do anything
//however this seems acceptable
for (const auto &ppi : Preferred_primary_info)
{
if (ppi.subject.matches(shipp) && ppi.target.matches(other_shipp))
{
int weapon_idx = ppi.weapon_index;
//figure out what bank the weapon belongs to
int bank_num = -1;
for (int i = 0; i < MAX_SHIP_PRIMARY_BANKS; i++) {
if (weapon_idx == swp->primary_bank_weapons[i]) {
bank_num = i;
break;
}
}
//if it's a valid bank, set it and return
if (bank_num != -1) {
//forcing a ship to use a certain primary should prevent it from linking weapons
shipp->flags.set(Ship::Ship_Flags::Force_primary_unlinking);
swp->current_primary_bank = bank_num;
return bank_num;
}
}
}
}
// we're not prioritizing a specific primary weapon
shipp->flags.remove(Ship::Ship_Flags::Force_primary_unlinking);
//not using the new AI, use the old version of this function instead.
if (!(Ai_info[shipp->ai_index].ai_profile_flags[AI::Profile_Flags::Smart_primary_weapon_selection]))
{
@@ -5590,12 +5718,11 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
}
}
bool other_is_ship = (other_objp->type == OBJ_SHIP);
float enemy_remaining_shield = get_shield_pct(other_objp);
if ( other_is_ship )
{
ship_info* other_sip = &Ship_info[Ships[other_objp->instance].ship_info_index];
ship_info* other_sip = &Ship_info[other_shipp->ship_info_index];
if (other_sip->class_type >= 0 && Ship_types[other_sip->class_type].flags[Ship::Type_Info_Flags::Targeted_by_huge_Ignored_by_small_only]) {
//Check if we have a capital+ weapon on board
@@ -5611,7 +5738,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
if (enemy_remaining_shield <= 0.05f || (wip->shield_factor * 1.33f > wip->armor_factor))
{
swp->current_primary_bank = i;
nprintf(("AI", "%i: Ship %s selecting weapon %s (capital+) vs target %s\n", Framecount, Ships[objp->instance].ship_name, wip->name, Ships[other_objp->instance].ship_name));
nprintf(("AI", "%i: Ship %s selecting weapon %s (capital+) vs target %s\n", Framecount, shipp->ship_name, wip->name, other_shipp->ship_name));
return i;
}
}
@@ -5649,7 +5776,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
i_hullfactor_prev_bank = 0; // Just switch to the first one
}
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (no shields) vs target %s\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_hullfactor_prev_bank]].name, (other_is_ship ? Ships[other_objp->instance].ship_name : "non-ship") ));
nprintf(("AI", "%i: Ship %s selecting weapon %s (no shields) vs target %s\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_hullfactor_prev_bank]].name, (other_is_ship ? other_shipp->ship_name : "non-ship") ));
return i_hullfactor_prev_bank; // Return
}
@@ -5771,6 +5898,11 @@ void set_primary_weapon_linkage(object *objp)
shipp->flags.remove(Ship::Ship_Flags::Primary_linked);
//bail if it's been included in a good-primary-time
if (shipp->flags[Ship::Ship_Flags::Force_primary_unlinking]) {
return;
}
// AL: ensure target is a ship!
if ( (aip->target_objnum != -1) && (Objects[aip->target_objnum].type == OBJ_SHIP) ) {
// If trying to destroy a big ship (i.e., not disable/disarm), always unleash all weapons
@@ -6050,6 +6182,7 @@ int ai_fire_primary_weapon(object *objp)
enemy_sip = NULL;
}
//plieblang - added check for size of Preferred_primaries to force reevaluation if good-primary-time has been used in the meantime
if ( (swp->current_primary_bank < 0) || (swp->current_primary_bank >= swp->num_primary_banks) || timestamp_elapsed(aip->primary_select_timestamp)) {
Weapon::Info_Flags flags = Weapon::Info_Flags::NUM_VALUES;
if ( aip->targeted_subsys != NULL ) {
@@ -6057,7 +6190,7 @@ int ai_fire_primary_weapon(object *objp)
}
ai_select_primary_weapon(objp, enemy_objp, flags);
ship_primary_changed(shipp); // AL: maybe send multiplayer information when AI ship changes primaries
aip->primary_select_timestamp = timestamp(5 * 1000); // Maybe change primary weapon five seconds from now.
aip->primary_select_timestamp = timestamp(5 * MILLISECONDS_PER_SECOND); // Maybe change primary weapon five seconds from now.
}
//We can only check LoS if we have a target defined
@@ -6132,7 +6265,7 @@ int ai_fire_primary_weapon(object *objp)
int type;
type = aip->targeted_subsys->system_info->type;
if (ship_get_subsystem_strength(&Ships[tobjp->instance], type) == 0.0f) {
if (ship_subsystems_blown(&Ships[tobjp->instance], type)) {
aip->target_objnum = -1;
return 0;
}
@@ -7721,8 +7854,8 @@ void ai_stealth_sweep()
break;
default:
Int3();
UNREACHABLE("Bad submode in ai_steath_sweep of %d. Please report to the SCP!", aip->submode_parm0);
break;
}
// when close to goal_pt, update next goal pt
@@ -8497,13 +8630,13 @@ void ai_cruiser_chase()
ship *shipp = &Ships[Pl_objp->instance];
ai_info *aip = &Ai_info[shipp->ai_index];
Assertion(En_objp->type == OBJ_SHIP, "En_objp is of type %d which is illegal in ai_cruiser_chase. Please report to the SCP!", En_objp->type);
if (En_objp->type != OBJ_SHIP) {
Int3();
return;
}
Assertion(En_objp->instance > -1, "En_objp has a bad instance of %d which is illegal in ai_cruiser_chase. Please report to the SCP!", En_objp->instance);
if (En_objp->instance < 0) {
Int3();
return;
}
@@ -8672,9 +8805,7 @@ void ai_chase()
flagset<Ship::Ship_Flags> enemy_shipp_flags;
int has_fired = -1;
if (aip->mode != AIM_CHASE) {
Int3();
}
Assertion(aip->mode == AIM_CHASE, "ai_chase was called but the ship was not in the chase ai mode. It is in %d instead. This is a fundamental problem and needs to be reported to the SCP, right away!", aip->mode);
// by default we try to chase anything
bool go_after_it = true;
@@ -8806,38 +8937,40 @@ void ai_chase()
// Set predicted_enemy_pos.
// See if attacking a subsystem.
weapon_info* wip = ai_get_weapon(&shipp->weapons);
bool ballistic = !IS_VEC_NULL(&The_mission.gravity) && wip->gravity_const != 0.0f;
if (aip->targeted_subsys != NULL && get_shield_pct(En_objp) < HULL_DAMAGE_THRESHOLD_PERCENT) {
Assert(En_objp->type == OBJ_SHIP);
vec3d target_pos;
get_subsystem_pos(&target_pos, En_objp, aip->targeted_subsys);
if (wip) {
bool ballistic = !IS_VEC_NULL(&The_mission.gravity) && wip->gravity_const != 0.0f;
if (aip->targeted_subsys != NULL && get_shield_pct(En_objp) < HULL_DAMAGE_THRESHOLD_PERCENT) {
Assert(En_objp->type == OBJ_SHIP);
vec3d target_pos;
get_subsystem_pos(&target_pos, En_objp, aip->targeted_subsys);
if (!ballistic)
predicted_enemy_pos = target_pos;
else {
vec3d gravity_vec = The_mission.gravity * wip->gravity_const;
has_valid_ballistic_trajectory =
physics_lead_ballistic_trajectory(&Pl_objp->pos, &target_pos, &aip->last_aim_enemy_vel, wip->max_speed, &gravity_vec, &predicted_enemy_pos);
if (has_valid_ballistic_trajectory)
predicted_enemy_pos = Pl_objp->pos + predicted_enemy_pos * vm_vec_dist(&Pl_objp->pos, &target_pos);
else
if (!ballistic)
predicted_enemy_pos = target_pos;
}
else {
vec3d gravity_vec = The_mission.gravity * wip->gravity_const;
has_valid_ballistic_trajectory =
physics_lead_ballistic_trajectory(&Pl_objp->pos, &target_pos, &aip->last_aim_enemy_vel, wip->max_speed, &gravity_vec, &predicted_enemy_pos);
predicted_vec_to_enemy = real_vec_to_enemy;
} else {
if (!ballistic)
set_predicted_enemy_pos(&predicted_enemy_pos, Pl_objp, &aip->last_aim_enemy_pos, &aip->last_aim_enemy_vel, aip);
else {
vec3d gravity_vec = The_mission.gravity * wip->gravity_const;
has_valid_ballistic_trajectory =
physics_lead_ballistic_trajectory(&Pl_objp->pos, &aip->last_aim_enemy_pos, &aip->last_aim_enemy_vel, wip->max_speed, &gravity_vec, &predicted_enemy_pos);
if (has_valid_ballistic_trajectory)
predicted_enemy_pos = Pl_objp->pos + predicted_enemy_pos * vm_vec_dist(&Pl_objp->pos, &aip->last_aim_enemy_pos);
else
if (has_valid_ballistic_trajectory)
predicted_enemy_pos = Pl_objp->pos + predicted_enemy_pos * vm_vec_dist(&Pl_objp->pos, &target_pos);
else
predicted_enemy_pos = target_pos;
}
predicted_vec_to_enemy = real_vec_to_enemy;
} else {
if (!ballistic)
set_predicted_enemy_pos(&predicted_enemy_pos, Pl_objp, &aip->last_aim_enemy_pos, &aip->last_aim_enemy_vel, aip);
else {
vec3d gravity_vec = The_mission.gravity * wip->gravity_const;
has_valid_ballistic_trajectory =
physics_lead_ballistic_trajectory(&Pl_objp->pos, &aip->last_aim_enemy_pos, &aip->last_aim_enemy_vel, wip->max_speed, &gravity_vec, &predicted_enemy_pos);
if (has_valid_ballistic_trajectory)
predicted_enemy_pos = Pl_objp->pos + predicted_enemy_pos * vm_vec_dist(&Pl_objp->pos, &aip->last_aim_enemy_pos);
else
set_predicted_enemy_pos(&predicted_enemy_pos, Pl_objp, &aip->last_aim_enemy_pos, &aip->last_aim_enemy_vel, aip);
}
}
}
}
@@ -9164,7 +9297,7 @@ void ai_chase()
}
break;
default:
Int3(); // Impossible!
UNREACHABLE("Somehow we changed a call to get a random number in ai_chase so it's not 0-4, please report to the SCP!"); // Impossible!
}
}
@@ -9690,7 +9823,7 @@ float dock_orient_and_approach(object *docker_objp, int docker_index, object *do
// Goober5000 - moved out here to save calculations
if (dock_mode != DOA_DOCK_STAY)
if (!Ships[docker_objp->instance].flags[Ship::Ship_Flags::Maneuver_despite_engines] && ship_get_subsystem_strength(&Ships[docker_objp->instance], SUBSYSTEM_ENGINE) <= 0.0f)
if (!Ships[docker_objp->instance].flags[Ship::Ship_Flags::Maneuver_despite_engines] && ship_subsystems_blown(&Ships[docker_objp->instance], SUBSYSTEM_ENGINE))
return 9999.9f;
// If dockee has moved much, then path will be recreated.
@@ -10610,7 +10743,7 @@ void ai_big_guard()
break;
default:
Int3(); // Illegal submode for Guard mode.
UNREACHABLE("Illegal submode of %d for guard mode in ai_big_guard. Please report to the SCP!", aip->submode);
// AL 06/03/97 comment out Int3() to allow milestone to get out the door
aip->submode = AIS_GUARD_PATROL;
aip->submode_start_time = Missiontime;
@@ -10639,7 +10772,7 @@ void ai_guard()
guard_objp = &Objects[aip->guard_objnum];
if (guard_objp == Pl_objp) {
Int3(); // This seems illegal. Why is a ship guarding itself?
UNREACHABLE("The ship %s has been found to be guarding itself in ai_guard. Please report to the SCP!", shipp->ship_name); // This seems illegal. Why is a ship guarding itself?
aip->guard_objnum = -1;
return;
}
@@ -10818,7 +10951,7 @@ void ai_guard()
break;
default:
Int3(); // Illegal submode for Guard mode.
UNREACHABLE("Illegal ai submode of %d for guard mode in ai_guard for ship %s. Pleae report to the SCP!", aip->submode, shipp->ship_name);
// AL 06/03/97 comment out Int3() to allow milestone to get out the door
aip->submode = AIS_GUARD_PATROL;
aip->submode_start_time = Missiontime;
@@ -10962,7 +11095,7 @@ void ai_do_objects_repairing_stuff( object *repaired_objp, object *repair_objp,
break;
default:
Int3(); // bogus type of repair info
UNREACHABLE("Illegal repair info type of %d in ai_do_objects_repairing_stuff. Pleae report to the SCP!", how);
}
// repair_objp might be NULL if we are cleaning up this mode because of the support ship
@@ -10999,7 +11132,7 @@ void ai_do_objects_repairing_stuff( object *repaired_objp, object *repair_objp,
break;
default:
Int3(); // bogus type of repair info
UNREACHABLE("Illegal repair info type of %d in ai_do_objects_repairing_stuff. Pleae report to the SCP!", how);
}
}
@@ -11823,7 +11956,7 @@ void ai_dock()
default:
{
Int3(); // Error, bogus submode
UNREACHABLE("Illegal dock submode of %d in ai_dock. Pleae report to the SCP!", aip->submode);
}
} // end of switch statement
@@ -12013,7 +12146,7 @@ void ai_process_subobjects(int objnum)
}
// Deal with a ship with blown out engines.
if (ship_get_subsystem_strength(shipp, SUBSYSTEM_ENGINE) == 0.0f) {
if (ship_subsystems_blown(shipp, SUBSYSTEM_ENGINE)) {
// Karajorma - if Player_use_ai is ever fixed to work on multiplayer it should be checked that any player ships
// aren't under AI control here
if ((!(objp->flags[Object::Object_Flags::Player_ship])) && (sip->is_fighter_bomber()) && !(shipp->flags[Ship::Ship_Flags::Dying])) {
@@ -12077,7 +12210,7 @@ object *get_wing_leader(int wingnum)
// If this ship is disabled, try another ship in the wing.
int n = 0;
while (!Ships[ship_num].flags[Ship::Ship_Flags::Maneuver_despite_engines] && ship_get_subsystem_strength(&Ships[ship_num], SUBSYSTEM_ENGINE) == 0.0f) {
while (!Ships[ship_num].flags[Ship::Ship_Flags::Maneuver_despite_engines] && ship_subsystems_blown(&Ships[ship_num], SUBSYSTEM_ENGINE)) {
n++;
if (n >= wingp->current_count) {
@@ -12477,7 +12610,6 @@ int ai_formation()
}
if (aip->mode == AIM_WAYPOINTS) {
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_path_order_bug]){
// skip if wing leader has no waypoint order or a different waypoint list
if ((laip->mode != AIM_WAYPOINTS) || !(aip->wp_list == laip->wp_list)){
@@ -12489,8 +12621,15 @@ int ai_formation()
aip->wp_index = laip->wp_index;
aip->wp_flags = laip->wp_flags;
if ((aip->wp_list != NULL) && (aip->wp_index == aip->wp_list->get_waypoints().size()))
--aip->wp_index;
if (aip->wp_list != nullptr) {
if (aip->wp_flags & WPF_BACKTRACK) {
if (aip->wp_index == -1)
++aip->wp_index;
} else {
if (aip->wp_index == (int)aip->wp_list->get_waypoints().size())
--aip->wp_index;
}
}
}
#ifndef NDEBUG
@@ -12780,14 +12919,23 @@ void ai_do_repair_frame(object *objp, ai_info *aip, float frametime)
repaired = ship_do_rearm_frame( objp, frametime ); // hook to do missile rearming
// See if fully repaired. If so, cause process to stop.
if ( repaired && (repair_aip->submode == AIS_DOCK_4)) {
repair_aip->submode = AIS_UNDOCK_0;
repair_aip->submode_start_time = Missiontime;
// if repairing player object -- tell him done with repair
if ( !MULTIPLAYER_CLIENT ) {
ai_do_objects_repairing_stuff( objp, &Objects[support_objnum], REPAIR_INFO_COMPLETE );
if ( repaired ) {
// We can repair ships without being docked, so only do this if we are docked
if (repair_aip->submode == AIS_DOCK_4) {
repair_aip->submode = AIS_UNDOCK_0;
repair_aip->submode_start_time = Missiontime;
// if repairing player object -- tell him done with repair
if (!MULTIPLAYER_CLIENT) {
ai_do_objects_repairing_stuff(objp, &Objects[support_objnum], REPAIR_INFO_COMPLETE);
}
}
//If Repairing self
else if (&Objects[support_objnum] == objp) { // Undocking ends the repair,
// but since we don'tneed to do that in this case, end it here
ai_do_objects_repairing_stuff(objp, &Objects[support_objnum], REPAIR_INFO_END);
if (!MULTIPLAYER_CLIENT) {
hud_support_view_stop();
}
}
}
}
@@ -13398,8 +13546,8 @@ int ai_acquire_emerge_path(object *pl_objp, int parent_objnum, int allowed_path_
Assertion(shipp->ai_index >= 0, "Arriving ship does not have a valid ai index. Has %d instead. Please report!", shipp->ai_index);
ai_info *aip = &Ai_info[shipp->ai_index];
Assertion(parent_objnum > -1, "parent_objnum in ai_acquire_emerge_path was found to be %d, which is an invalid value. Please report to the SCP!", parent_objnum);
if ( parent_objnum == -1 ) {
Int3();
return -1;
}
@@ -14153,7 +14301,7 @@ void ai_maybe_depart(object *objp)
if (!shipp->is_departing()) {
if (sip->is_fighter_bomber()) {
if (aip->warp_out_timestamp == 0) {
//if (ship_get_subsystem_strength(shipp, SUBSYSTEM_WEAPONS) == 0.0f) {
//if (ship_subsystems_blown(shipp, SUBSYSTEM_WEAPONS)) {
// aip->warp_out_timestamp = timestamp(Random::next(10, 19) * 1000);
//}
} else if (timestamp_elapsed(aip->warp_out_timestamp)) {
@@ -14258,7 +14406,7 @@ void ai_warp_out(object *objp)
case AIS_WARP_5:
break;
default:
Int3(); // Illegal submode for warping out.
UNREACHABLE("Illegal ai submode of %d in ai_warp_out. Pleae report to the SCP!", aip->submode);
}
}
@@ -14504,7 +14652,7 @@ int aas_1(object *objp, ai_info *aip, vec3d *safe_pos)
return 1;
} else {
Int3(); // Illegal -- supposedly avoiding a shockwave, but neither ship nor weapon. What is it!?
UNREACHABLE("aas_1 has been passed an invalid object type of %d, please report to the SCP!", objp->type);
}
return 0;
@@ -14633,8 +14781,8 @@ void ai_maybe_self_destruct(object *objp, ai_info *aip)
// mission would be broken.
// Also, don't blow up the ship if it has a ship flag preventing this - Goober5000
if ((Ship_info[shipp->ship_info_index].is_small_ship()) && (shipp->wingnum >= 0) && !(shipp->flags[Ship::Ship_Flags::No_disabled_self_destruct])) {
if ((ship_get_subsystem_strength(shipp, SUBSYSTEM_ENGINE) <= 0.0f) ||
(ship_get_subsystem_strength(shipp, SUBSYSTEM_WEAPONS) <= 0.0f)) {
if ((ship_subsystems_blown(shipp, SUBSYSTEM_ENGINE)) ||
(ship_subsystems_blown(shipp, SUBSYSTEM_WEAPONS))) {
if (aip->self_destruct_timestamp < 0)
aip->self_destruct_timestamp = timestamp(90 * 1000); // seconds until self-destruct
} else {
@@ -14768,7 +14916,7 @@ void validate_mode_submode(ai_info *aip)
case SM_ATTACK_FOREVER:
break;
default:
Int3();
UNREACHABLE("validate_mode_submode found an illegal submode for AIM_CHASE of %d. Please report to the SCP!", aip->submode);
}
break;
@@ -14782,7 +14930,7 @@ void validate_mode_submode(ai_info *aip)
case AIS_STRAFE_POSITION:
break;
default:
Int3();
UNREACHABLE("validate_mode_submode found an illegal submode for AIM_STRAFE of %d. Please report to the SCP!", aip->submode);
}
break;
}
@@ -14811,6 +14959,9 @@ void ai_frame(int objnum)
//Default to glide OFF
Pl_objp->phys_info.flags &= ~PF_GLIDING;
// turn off trigger down
shipp->weapons.flags.remove(Ship::Weapon_Flags::Primary_trigger_down);
// warping out?
if ((aip->mode == AIM_WARP_OUT) || (aip->ai_flags[AI::AI_Flags::Trying_unsuccessfully_to_warp]))
@@ -15914,7 +16065,7 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hit_normal)
objp_hitter = hit_objp;
hitter_objnum = OBJ_INDEX(hit_objp);
} else {
Int3(); // Hmm, what kind of object hit this if not weapon or ship? Get MikeK.
UNREACHABLE("ai_ship_hit has been passed an invalid object type of %d, please report to the SCP!", hit_objp->type);
return;
}
@@ -16393,8 +16544,8 @@ void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int doc
// of a path_num associated with than dockbay (this is an index into polymodel->paths[])
int ai_return_path_num_from_dockbay(object *dockee_objp, int dockbay_index)
{
if ( dockbay_index < 0 || dockee_objp == NULL ) {
Int3(); // should never happen
Assertion(dockbay_index > -1 && dockee_objp != nullptr, "ai_return_path_num_from_dockbay has been passed invalid docking info: %s dockbay index of %d, please report to the SCP!", dockee_objp == nullptr ? "null pointer dockee object and " : "", dockbay_index);
if ( dockbay_index < 0 || dockee_objp == nullptr ) {
return -1;
}
+63 -59
View File
@@ -214,7 +214,7 @@ void ai_maybe_add_form_goal(wing* wingp)
int wingnum;
if (Netgame.type_flags & NG_TYPE_TEAM) {
const ship_registry_entry* ship_regp = ship_registry_get(Ships[wingp->ship_index[j]].ship_name);
wingnum = TVT_wings[ship_regp->p_objp->team];
wingnum = TVT_wings[ship_regp->p_objp()->team];
ai_add_ship_goal_player(AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, Ships[Wings[wingnum].ship_index[Wings[wingnum].special_ship]].ship_name, aip);
} else {
wingnum = Starting_wings[0];
@@ -487,10 +487,12 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list, ai_info *ai
// these goals cannot be associated to wings, but can to a ship in a wing. So, we should find out
// if the ship is in a wing so we can purge goals which might operate on that wing
ship_index = ship_name_lookup(name);
if ( ship_index == -1 ) {
Int3(); // get allender -- this is sort of odd
return;
Assertion(ship_index > -1, "Found a bad ship_index of %d in ai_goal_purge_invalid_goals, please report to the SCP!", ship_index); // get allender -- this is sort of odd
if ( ship_index < 0 ) {
return;
}
wingnum = Ships[ship_index].wingnum;
purge_goal = goal_list;
@@ -726,7 +728,7 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
// from the mission goals (i.e. those goals which come from events) in that we don't
// use sexpressions for goals from the player...so we enumerate all the parameters
void ai_add_goal_sub_player(int type, int mode, int submode, char *target_name, ai_goal *aigp, const ai_lua_parameters& lua_target )
void ai_add_goal_sub_player(int type, int mode, int submode, const char *target_name, ai_goal *aigp, const ai_lua_parameters& lua_target )
{
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
@@ -813,7 +815,7 @@ int ai_goal_num(ai_goal *goals)
}
void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, char *target_name, ai_goal *aigp )
void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, const char *target_name, ai_goal *aigp )
{
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
@@ -830,7 +832,7 @@ void ai_add_goal_sub_scripting(int type, int mode, int submode, int priority, ch
aigp->priority = priority;
}
void ai_add_ship_goal_scripting(int mode, int submode, int priority, char *shipname, ai_info *aip)
void ai_add_ship_goal_scripting(int mode, int submode, int priority, const char *shipname, ai_info *aip)
{
int empty_index;
ai_goal *aigp;
@@ -854,7 +856,7 @@ void ai_add_ship_goal_scripting(int mode, int submode, int priority, char *shipn
// is issued to ship or wing (from player), mode is AI_GOAL_*. submode is the submode the
// ship should go into. shipname is the object of the action. aip is the ai_info pointer
// of the ship receiving the order
void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip, const ai_lua_parameters& lua_target)
void ai_add_ship_goal_player( int type, int mode, int submode, const char *shipname, ai_info *aip, const ai_lua_parameters& lua_target)
{
int empty_index;
ai_goal *aigp;
@@ -875,7 +877,7 @@ void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, a
// adds a goal from the player to the given wing (which in turn will add it to the proper
// ships in the wing
void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum, const ai_lua_parameters& lua_target)
void ai_add_wing_goal_player( int type, int mode, int submode, const char *shipname, int wingnum, const ai_lua_parameters& lua_target)
{
int i, empty_index;
wing *wingp = &Wings[wingnum];
@@ -899,7 +901,7 @@ void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, i
// common routine to add a sexpression mission goal to the appropriate goal structure.
void ai_add_goal_sub_sexp( int sexp, int type, ai_info *aip, ai_goal *aigp, char *actor_name )
void ai_add_goal_sub_sexp( int sexp, int type, ai_info *aip, ai_goal *aigp, const char *actor_name )
{
int node, dummy, op;
@@ -913,22 +915,30 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_info *aip, ai_goal *aigp, char
switch (op) {
case OP_AI_WAYPOINTS_ONCE:
case OP_AI_WAYPOINTS: {
case OP_AI_WAYPOINTS:
{
int ref_type;
bool is_nan, is_nan_forever;
ref_type = Sexp_nodes[CDR(node)].subtype;
if (ref_type == SEXP_ATOM_STRING || ref_type == SEXP_ATOM_CONTAINER_DATA) { // referenced by name
// save the waypoint path name -- the list will get resolved when the goal is checked
// for achievability.
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index); // waypoint path name;
Assertion(ref_type == SEXP_ATOM_STRING || ref_type == SEXP_ATOM_CONTAINER_DATA, "Found a bad ref_type in ai_add_goal_sub_sexp of %d. Please report to the SCP!", ref_type);
// referenced by name
// save the waypoint path name -- the list will get resolved when the goal is checked
// for achievability.
aigp->target_name = ai_get_goal_target_name(CTEXT(CDR(node)), &aigp->target_name_index); // waypoint path name;
} else
Int3();
aigp->priority = atoi( CTEXT(CDR(CDR(node))) );
aigp->ai_mode = AI_GOAL_WAYPOINTS;
if ( op == OP_AI_WAYPOINTS_ONCE )
aigp->ai_mode = AI_GOAL_WAYPOINTS_ONCE;
if (CDDDDR(node) < 0)
aigp->int_data = 0; // handle optional node separately because we don't subtract 1 here
else
aigp->int_data = eval_num(CDDDDR(node), is_nan, is_nan_forever) - 1;
if (is_sexp_true(CDDDDDR(node)))
aigp->flags.set(AI::Goal_Flags::Waypoints_in_reverse);
break;
}
@@ -990,9 +1000,9 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_info *aip, ai_goal *aigp, char
// this goal needs some extra setup
// if this doesn't work, the goal will be immediately removed
auto ship_entry = ship_registry_get(aigp->target_name);
if (ship_entry && ship_entry->shipp)
if (ship_entry && ship_entry->has_shipp())
{
auto target_aip = &Ai_info[ship_entry->shipp->ai_index];
auto target_aip = &Ai_info[ship_entry->shipp()->ai_index];
target_aip->ai_flags.set(AI::AI_Flags::Awaiting_repair);
Assertion(aip != nullptr, "Must provide aip if assigning a rearm goal!");
ai_goal_fixup_dockpoints( aip, aigp );
@@ -1452,15 +1462,8 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int /*
int gindex;
ai_goal *aigp;
#ifndef NDEBUG
// Goober5000 - none of the goals act on the actor, as in ai_add_goal_sub_sexp
if (!strcmp(name, Ships[aip->shipnum].ship_name))
{
// not good
Int3();
return;
}
#endif
Assertion(strcmp(name, Ships[aip->shipnum].ship_name) != 0, "The goals apply to the actor in ai_add_goal_ship_internal for ship %s, please report to the SCP!", name);
// find an empty slot to put this goal in.
gindex = ai_goal_find_empty_slot( aip->goals, aip->active_goal );
@@ -1511,7 +1514,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int /*
break;
default:
Int3(); // unsupported internal goal -- see Mike K or Mark A.
UNREACHABLE("unsupported internal goal of %d found in ai_add_goal_ship_internal. Please report to the SCP", goal_type); // see Mike K or Mark A.
return;
}
@@ -1589,7 +1592,7 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// if the wing target is valid then be sure to set the override bit so that it always
// gets executed next
if ( aigp->ai_mode == AI_GOAL_FORM_ON_WING ) {
if (!target_ship_entry || !target_ship_entry->shipp)
if (!target_ship_entry || !target_ship_entry->has_shipp())
return ai_achievability::NOT_ACHIEVABLE;
aigp->flags.set(AI::Goal_Flags::Goal_override);
@@ -1649,7 +1652,7 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// can't determine the status of this goal if ship not valid
// or we haven't found a valid subsystem index yet
if ( !target_ship_entry || !target_ship_entry->shipp || (aigp->flags[AI::Goal_Flags::Subsys_needs_fixup]) ) {
if ( !target_ship_entry || !target_ship_entry->has_shipp() || (aigp->flags[AI::Goal_Flags::Subsys_needs_fixup]) ) {
status = 0;
break;
}
@@ -1658,13 +1661,13 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// as 0 so we can continue. (The subsystem name must be turned into an index into the ship's subsystems
// for this goal to be valid).
Assert ( aigp->ai_submode >= 0 );
ssp = ship_get_indexed_subsys( target_ship_entry->shipp, aigp->ai_submode );
ssp = ship_get_indexed_subsys( target_ship_entry->shipp(), aigp->ai_submode );
if (ssp != NULL) {
// see MWA 3/20/97 comment above - instead of checking the mission log, check the current hits
status = (ssp->current_hits <= 0.0f) ? 1 : 0;
} else {
// not supposed to ever happen, but could if there is a mismatch between the table and model subsystems
nprintf(("AI", "Couldn't find subsystem %d for ship %s\n", aigp->ai_submode, target_ship_entry->shipp->ship_name));
nprintf(("AI", "Couldn't find subsystem %d for ship %s\n", aigp->ai_submode, target_ship_entry->shipp()->ship_name));
status = 0;
}
break;
@@ -1677,11 +1680,11 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// destroyed when shipnum is valid
// can't determine the status of this goal if ship not valid
if (!target_ship_entry || !target_ship_entry->shipp) {
if (!target_ship_entry || !target_ship_entry->has_shipp()) {
status = 0;
} else {
// see MWA 3/20/97 comment above - instead of checking the mission log, check the current hits
status = (target_ship_entry->shipp->subsys_info[SUBSYSTEM_ENGINE].aggregate_current_hits <= 0.0f) ? 1 : 0;
status = (target_ship_entry->shipp()->subsys_info[SUBSYSTEM_ENGINE].aggregate_current_hits <= 0.0f) ? 1 : 0;
}
break;
}
@@ -1693,11 +1696,11 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// destroyed when shipnum is valid
// can't determine the status of this goal if ship not valid
if (!target_ship_entry || !target_ship_entry->shipp) {
if (!target_ship_entry || !target_ship_entry->has_shipp()) {
status = 0;
} else {
// see MWA 3/20/97 comment above - instead of checking the mission log, check the current hits
status = (target_ship_entry->shipp->subsys_info[SUBSYSTEM_TURRET].aggregate_current_hits <= 0.0f) ? 1 : 0;
status = (target_ship_entry->shipp()->subsys_info[SUBSYSTEM_TURRET].aggregate_current_hits <= 0.0f) ? 1 : 0;
}
break;
}
@@ -1725,8 +1728,8 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
}
// fly-to-ship can potentially be determined
if (aigp->ai_mode == AI_GOAL_FLY_TO_SHIP && target_ship_entry && target_ship_entry->objp) {
auto dist = vm_vec_dist(&target_ship_entry->objp->pos, &objp->pos);
if (aigp->ai_mode == AI_GOAL_FLY_TO_SHIP && target_ship_entry && target_ship_entry->has_objp()) {
auto dist = vm_vec_dist(&target_ship_entry->objp()->pos, &objp->pos);
if (dist < aigp->float_data) {
return_val = ai_achievability::SATISFIED;
status = 1;
@@ -1840,9 +1843,9 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// Goober5000 - before doing anything else, check if this is a disarm goal for an arrived ship...
if ((status == SHIP_STATUS_ARRIVED) && (aigp->ai_mode == AI_GOAL_DISARM_SHIP || aigp->ai_mode == AI_GOAL_DISARM_SHIP_TACTICAL))
{
if (target_ship_entry && target_ship_entry->shipp) {
if (target_ship_entry && target_ship_entry->has_shipp()) {
// if the ship has no turrets, we can't disarm it!
if (target_ship_entry->shipp->subsys_info[SUBSYSTEM_TURRET].type_count == 0)
if (target_ship_entry->shipp()->subsys_info[SUBSYSTEM_TURRET].type_count == 0)
return ai_achievability::NOT_ACHIEVABLE;
} else {
UNREACHABLE("Target name %s is not an arrived ship!", aigp->target_name);
@@ -1876,8 +1879,8 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
}
if (!(aigp->flags[AI::Goal_Flags::Dockee_index_valid])) {
if (target_ship_entry && target_ship_entry->shipp) {
int modelnum = Ship_info[target_ship_entry->shipp->ship_info_index].model_num;
if (target_ship_entry && target_ship_entry->has_shipp()) {
int modelnum = Ship_info[target_ship_entry->shipp()->ship_info_index].model_num;
aigp->dockee.index = model_find_dock_name_index(modelnum, aigp->dockee.name);
aigp->flags.set(AI::Goal_Flags::Dockee_index_valid);
} else
@@ -1894,11 +1897,11 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
return ai_achievability::NOT_KNOWN;
// we must also determine if we're prevented from docking for any reason
if (!target_ship_entry || !target_ship_entry->shipp) {
if (!target_ship_entry || !target_ship_entry->has_shipp()) {
UNREACHABLE("Target name %s is not an arrived ship!", aigp->target_name);
return ai_achievability::NOT_ACHIEVABLE; // force this goal to be invalid
}
auto goal_objp = target_ship_entry->objp;
auto goal_objp = target_ship_entry->objp();
// if the ship that I am supposed to dock with is docked with something else, then I need to put my goal on hold
// [MK, 4/23/98: With Mark, we believe this fixes the problem of Comet refusing to warp out after docking with Omega.
@@ -1947,9 +1950,9 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// might happen too, so err on the safe side. (Yay for emergent paragraph justification!)
if ((aip->mode == AIM_DOCK) && (aip->submode >= AIS_UNDOCK_0))
{
if ( target_ship_entry && target_ship_entry->shipp ) {
if ( target_ship_entry && target_ship_entry->has_objp() ) {
// only put it on hold if it's someone other than the guy we're undocking from right now!!
if (aip->goal_objnum != target_ship_entry->shipp->objnum)
if (aip->goal_objnum != target_ship_entry->objnum)
return ai_achievability::NOT_KNOWN;
} else {
UNREACHABLE("Target name %s is not an arrived ship!", aigp->target_name);
@@ -1962,8 +1965,8 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// have fixed up the subsystem name (of the subsystem to destroy) into an index into
// the ship's subsystem list
if ( aigp->flags[AI::Goal_Flags::Subsys_needs_fixup] ) {
if ( target_ship_entry && target_ship_entry->shipp ) {
aigp->ai_submode = ship_find_subsys( target_ship_entry->shipp, aigp->docker.name );
if ( target_ship_entry && target_ship_entry->has_shipp() ) {
aigp->ai_submode = ship_find_subsys( target_ship_entry->shipp(), aigp->docker.name );
aigp->flags.remove(AI::Goal_Flags::Subsys_needs_fixup);
} else {
UNREACHABLE("Target name %s is not an arrived ship!", aigp->target_name);
@@ -1972,11 +1975,11 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
}
} else if ( ((aigp->ai_mode == AI_GOAL_IGNORE) || (aigp->ai_mode == AI_GOAL_IGNORE_NEW)) && (status == SHIP_STATUS_ARRIVED) ) {
// for ignoring a ship, call the ai_ignore object function, then declare the goal satisfied
if (!target_ship_entry || !target_ship_entry->shipp) {
if (!target_ship_entry || !target_ship_entry->has_objp()) {
UNREACHABLE("Target name %s is not an arrived ship!", aigp->target_name);
return ai_achievability::NOT_ACHIEVABLE; // force this goal to be invalid
}
auto ignored = target_ship_entry->objp;
auto ignored = target_ship_entry->objp();
ai_ignore_object(objp, ignored, (aigp->ai_mode == AI_GOAL_IGNORE_NEW));
@@ -2030,22 +2033,22 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
if ( status == SHIP_STATUS_GONE )
return ai_achievability::NOT_ACHIEVABLE;
if ( !target_ship_entry || !target_ship_entry->shipp ) {
if ( !target_ship_entry || !target_ship_entry->has_shipp() ) {
UNREACHABLE("Target name %s is not an arrived ship!", aigp->target_name);
return ai_achievability::NOT_ACHIEVABLE;
}
// if destination currently being repaired, then goal is still active
if ( Ai_info[target_ship_entry->shipp->ai_index].ai_flags[AI::AI_Flags::Being_repaired] )
if ( Ai_info[target_ship_entry->shipp()->ai_index].ai_flags[AI::AI_Flags::Being_repaired] )
return ai_achievability::ACHIEVABLE;
// if the destination ship is dying or departing (but not completed yet), the mark goal as
// not achievable.
if ( target_ship_entry->shipp->is_dying_or_departing())
if ( target_ship_entry->shipp()->is_dying_or_departing())
return ai_achievability::NOT_ACHIEVABLE;
// if the destination object is no longer awaiting repair, then remove the item
if ( !(Ai_info[target_ship_entry->shipp->ai_index].ai_flags[AI::AI_Flags::Awaiting_repair]) )
if ( !(Ai_info[target_ship_entry->shipp()->ai_index].ai_flags[AI::AI_Flags::Awaiting_repair]) )
return ai_achievability::NOT_ACHIEVABLE;
// not repairing anything means that he can do this goal!!!
@@ -2060,7 +2063,7 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// if he is repairing something, he can satisfy his repair goal (his goal_objnum)
// return GOAL_NOT_KNOWN which is kind of a hack which puts the goal on hold until it can be
// satisfied.
if ( aip->goal_objnum != target_ship_entry->shipp->objnum )
if ( aip->goal_objnum != target_ship_entry->objnum )
return ai_achievability::NOT_KNOWN;
return ai_achievability::ACHIEVABLE;
@@ -2334,10 +2337,11 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
case AI_GOAL_WAYPOINTS: // do nothing for waypoints
case AI_GOAL_WAYPOINTS_ONCE: {
int flags = 0;
if ( current_goal->ai_mode == AI_GOAL_WAYPOINTS)
if (current_goal->ai_mode == AI_GOAL_WAYPOINTS)
flags |= WPF_REPEAT;
ai_start_waypoints(objp, current_goal->wp_list, flags);
if (current_goal->flags[AI::Goal_Flags::Waypoints_in_reverse])
flags |= WPF_BACKTRACK;
ai_start_waypoints(objp, current_goal->wp_list, flags, current_goal->int_data);
break;
}
@@ -2544,7 +2548,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
break;
default:
Int3();
UNREACHABLE("unsupported goal of %d found in ai_process_mission_orders. Please report to the SCP", current_goal->ai_mode);
break;
}
+4 -4
View File
@@ -168,17 +168,17 @@ extern void ai_process_mission_orders( int objnum, ai_info *aip );
extern int ai_goal_num(ai_goal *goals);
// adds goals to ships/wing through sexpressions
extern void ai_add_ship_goal_scripting(int mode, int submode, int priority, char *shipname, ai_info *aip);
extern void ai_add_ship_goal_scripting(int mode, int submode, int priority, const char *shipname, ai_info *aip);
extern void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip );
extern void ai_add_wing_goal_sexp( int sexp, int type, wing *wingp );
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_info *aip, ai_goal *aigp, char *actor_name);
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_info *aip, ai_goal *aigp, const char *actor_name);
extern int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp );
extern void ai_remove_wing_goal_sexp( int sexp, wing *wingp );
// adds goals to ships/sings through player orders
extern void ai_add_ship_goal_player(int type, int mode, int submode, char* shipname, ai_info* aip, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
extern void ai_add_wing_goal_player(int type, int mode, int submode, char* shipname, int wingnum, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
extern void ai_add_ship_goal_player(int type, int mode, int submode, const char* shipname, ai_info* aip, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
extern void ai_add_wing_goal_player(int type, int mode, int submode, const char* shipname, int wingnum, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
extern void ai_remove_ship_goal( ai_info *aip, int index );
extern void ai_clear_ship_goals( ai_info *aip );
+22 -16
View File
@@ -97,29 +97,35 @@ SCP_vector<SCP_string> ai_lua_get_general_order_categories(bool enabled_only)
return list;
}
// Provides a list of general orders for mission saving. You can only get one kind
// of list at a time. If onlyEnabled and onlyValid are both true, for example, you will get
// a list of onlyEnabled orders. If you need a list of enabled orders that are also valid, you'll
// need to get both lists separately and compare.
SCP_vector<SCP_string> ai_lua_get_general_orders(bool onlyEnabled, bool onlyValid, const SCP_string& category)
{
SCP_vector<SCP_string> list;
for (auto order : Lua_player_orders) {
for (const auto& order : Lua_player_orders) {
if (order.second.generalOrder) {
bool add = false;
// Only enabled orders
if (onlyEnabled && order.second.cur_enabled) {
add = true;
// Only valid orders
} else if (onlyValid && order.second.cur_valid) {
add = true;
// Only orders that match the category requested
} else if ((!category.empty()) && (order.second.category == category)) {
add = true;
// All general orders
} else {
if (!onlyEnabled && !onlyValid && category.empty()) {
add = true;
} else {
// Only enabled orders
if (onlyEnabled && order.second.cur_enabled) {
add = true;
// Only valid orders
} else if (onlyValid && order.second.cur_valid) {
add = true;
// Only orders that match the category requested
} else if ((!category.empty()) && (order.second.category == category)) {
add = true;
}
}
if (add) {
@@ -161,7 +167,7 @@ void ai_lua_validate_general_order(int sexp_op, bool validity)
}
void ai_lua_reset_general_orders() {
for (auto order : Lua_player_orders) {
for (const auto& order : Lua_player_orders) {
ai_lua_enable_general_order(order.first, false);
ai_lua_validate_general_order(order.first, false);
}
@@ -248,7 +254,7 @@ void ai_lua_start_general(int lua_sexp_id, int target_objnum)
ai_info aip;
aip.shipnum = -1;
if (target_objnum >= 0) {
if (target_objnum >= 0 && Objects[target_objnum].type == OBJ_SHIP) {
aip.lua_ai_target = {object_ship_wing_point_team(&Ships[Objects[target_objnum].instance]), {}};
}
+33 -49
View File
@@ -72,29 +72,29 @@ const char* Turret_valid_types[NUM_TURRET_TYPES] = {
};
typedef struct eval_enemy_obj_struct {
int turret_parent_objnum; // parent of turret
float weapon_travel_dist; // max targeting range of turret weapon
int enemy_team_mask;
int weapon_system_ok; // is the weapon subsystem of turret ship ok
int eeo_flags;
int turret_parent_objnum = -1; // parent of turret
float weapon_travel_dist = 0.0f; // max targeting range of turret weapon
int enemy_team_mask = 0;
bool weapon_system_ok = false; // is the weapon subsystem of turret ship ok
int eeo_flags = 0;
vec3d *tpos;
vec3d *tvec;
ship_subsys *turret_subsys;
int current_enemy;
const vec3d *tpos = nullptr;
const vec3d *tvec = nullptr;
const ship_subsys *turret_subsys = nullptr;
int current_enemy = -1;
float nearest_attacker_dist; // nearest ship
int nearest_attacker_objnum;
float nearest_attacker_dist = 99999.0f; // nearest ship
int nearest_attacker_objnum = -1;
float nearest_homing_bomb_dist; // nearest homing bomb
int nearest_homing_bomb_objnum;
float nearest_homing_bomb_dist = 99999.0f; // nearest homing bomb
int nearest_homing_bomb_objnum = -1;
float nearest_bomb_dist; // nearest non-homing bomb
int nearest_bomb_objnum;
float nearest_bomb_dist = 99999.0f; // nearest non-homing bomb
int nearest_bomb_objnum = -1;
float nearest_dist; // nearest ship attacking this turret
int nearest_objnum;
float nearest_dist = 99999.0f; // nearest ship attacking this turret
int nearest_objnum = -1;
} eval_enemy_obj_struct;
// the current world orientation of the turret matrix, corresponding to its fvec and uvec defined in the model
@@ -120,7 +120,7 @@ void turret_instance_find_world_orient(matrix* out_mat, int model_instance_num,
*
* @return 1 if objp is in fov of the specified turret. Otherwise return 0.
*/
bool object_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist)
bool object_in_turret_fov(const object *objp, const ship_subsys *ss, const vec3d *tvec, const vec3d *tpos, float dist)
{
vec3d v2e;
float size_mod;
@@ -215,7 +215,7 @@ int turret_select_best_weapon(ship_subsys *turret, object * /*target*/)
/**
* Returns true if all weapons in swp have the specified flag
*/
bool all_turret_weapons_have_flags(ship_weapon *swp, flagset<Weapon::Info_Flags> flags)
bool all_turret_weapons_have_flags(const ship_weapon *swp, flagset<Weapon::Info_Flags> flags)
{
int i;
for(i = 0; i < swp->num_primary_banks; i++)
@@ -232,7 +232,7 @@ bool all_turret_weapons_have_flags(ship_weapon *swp, flagset<Weapon::Info_Flags>
return true;
}
bool all_turret_weapons_have_flags(ship_weapon *swp, Weapon::Info_Flags flags)
bool all_turret_weapons_have_flags(const ship_weapon *swp, Weapon::Info_Flags flags)
{
int i;
for (i = 0; i < swp->num_primary_banks; i++)
@@ -253,7 +253,7 @@ bool all_turret_weapons_have_flags(ship_weapon *swp, Weapon::Info_Flags flags)
* Returns true if any of the weapons in swp have flags
*
*/
bool turret_weapon_has_flags(ship_weapon *swp, Weapon::Info_Flags flags)
bool turret_weapon_has_flags(const ship_weapon *swp, Weapon::Info_Flags flags)
{
Assert(swp != NULL);
@@ -279,7 +279,7 @@ bool turret_weapon_has_flags(ship_weapon *swp, Weapon::Info_Flags flags)
/**
* Just gloms all the flags from all the weapons into one variable. More efficient if all you need to do is test for the existence of a flag.
*/
flagset<Weapon::Info_Flags> turret_weapon_aggregate_flags(ship_weapon *swp)
flagset<Weapon::Info_Flags> turret_weapon_aggregate_flags(const ship_weapon *swp)
{
Assert(swp != NULL);
@@ -307,7 +307,7 @@ flagset<Weapon::Info_Flags> turret_weapon_aggregate_flags(ship_weapon *swp)
* @note It might be a little faster to optimize based on WP_LASER should only appear in primaries
* and WP_MISSILE in secondaries. but in the interest of future coding I leave it like this.
*/
bool turret_weapon_has_subtype(ship_weapon *swp, int subtype)
bool turret_weapon_has_subtype(const ship_weapon *swp, int subtype)
{
Assert(swp != NULL);
@@ -492,7 +492,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
{
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
ship *shipp;
ship_subsys *ss = eeo->turret_subsys;
auto ss = eeo->turret_subsys;
float dist, dist_comp;
bool turret_has_no_target = false;
@@ -772,8 +772,6 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
*/
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag, bool flak_flag, bool laser_flag, bool missile_flag)
{
//float weapon_travel_dist;
int weapon_system_ok;
eval_enemy_obj_struct eeo;
ship_weapon *swp = &turret_subsys->weapons;
@@ -788,10 +786,7 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
// weapon_travel_dist=wip->lssm_lock_range;
// Set flag based on strength of weapons subsystem. If weapons subsystem is destroyed, don't let turrets fire at bombs
weapon_system_ok = 0;
if ( ship_get_subsystem_strength( &Ships[Objects[turret_parent_objnum].instance], SUBSYSTEM_WEAPONS ) > 0 ) {
weapon_system_ok = 1;
}
bool weapon_system_ok = !ship_subsystems_blown(&Ships[Objects[turret_parent_objnum].instance], SUBSYSTEM_WEAPONS);
// Initialize eeo struct.
eeo.turret_parent_objnum = turret_parent_objnum;
@@ -823,18 +818,6 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
eeo.tvec = tvec;
eeo.turret_subsys = turret_subsys;
eeo.nearest_attacker_dist = 99999.0f;
eeo.nearest_attacker_objnum = -1;
eeo.nearest_homing_bomb_dist = 99999.0f;
eeo.nearest_homing_bomb_objnum = -1;
eeo.nearest_bomb_dist = 99999.0f;
eeo.nearest_bomb_objnum = -1;
eeo.nearest_dist = 99999.0f;
eeo.nearest_objnum = -1;
// here goes the new targeting priority setting
int n_tgt_priorities;
int priority_weapon_idx = -1;
@@ -1064,7 +1047,7 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
break;
default:
Int3(); //Means invalid number passed.
UNREACHABLE("Invalid target type of %d sent to get_nearest_turret_objnum. Please report to the SCP!", turret_subsys->turret_targeting_order[i]);
}
}
}
@@ -1171,9 +1154,9 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
Assert( !((Objects[enemy_objnum].flags[Object::Object_Flags::Flak_protected]) && flak_flag) );
Assert( !((Objects[enemy_objnum].flags[Object::Object_Flags::Laser_protected]) && laser_flag) );
Assert( !((Objects[enemy_objnum].flags[Object::Object_Flags::Missile_protected]) && missile_flag) );
Assertion(!Objects[enemy_objnum].flags[Object::Object_Flags::Protected], "find_turret_enemy selected an object of type %d %s that is protected, please report to the SCP!", Objects[enemy_objnum].type, Objects[enemy_objnum].type == OBJ_SHIP ? Ships[Objects[enemy_objnum].instance].ship_name : "");
if ( Objects[enemy_objnum].flags[Object::Object_Flags::Protected] ) {
Int3();
enemy_objnum = aip->target_objnum;
}
}
@@ -1385,7 +1368,8 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
set_predicted_enemy_pos_turret(predicted_enemy_pos, &gun_pos, objp, &enemy_point, &target_vel, wip->max_speed, ss->turret_time_enemy_in_range * (weapon_system_strength + 1.0f)/2.0f);
else {
vec3d shoot_vec;
if (physics_lead_ballistic_trajectory(&gun_pos, &enemy_point, &target_vel, wip->max_speed, &The_mission.gravity, &shoot_vec)) {
vec3d gravity_vec = The_mission.gravity * wip->gravity_const;
if (physics_lead_ballistic_trajectory(&gun_pos, &enemy_point, &target_vel, wip->max_speed, &gravity_vec, &shoot_vec)) {
*predicted_enemy_pos = gun_pos + shoot_vec * 1000.0f;
} else {
if ((ss->system_info->flags[Model::Subsystem_Flags::Turret_reset_idle]) && (timestamp_elapsed(ss->rotation_timestamp))) {
@@ -1578,7 +1562,7 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
if(stride <= 0){
stride = 1;
}
int offset = (int)frand_range(0.0f, (float)(aifft_list_size % stride));
int offset = Random::next((aifft_list_size % stride) + 1); // returns an offset in [0, size % stride] inclusive
int idx;
float dot_fov_modifier = 0.0f;
@@ -2869,7 +2853,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
}
}
bool turret_std_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
bool turret_std_fov_test(const ship_subsys *ss, const vec3d *gvec, const vec3d *v2e, float size_mod)
{
model_subsystem *tp = ss->system_info;
float dot = vm_vec_dot(v2e, gvec);
@@ -2879,7 +2863,7 @@ bool turret_std_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
return false;
}
bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
bool turret_adv_fov_test(const ship_subsys *ss, const vec3d *gvec, const vec3d *v2e, float size_mod)
{
model_subsystem *tp = ss->system_info;
float dot = vm_vec_dot(v2e, gvec);
@@ -2905,7 +2889,7 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
return false;
}
bool turret_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
bool turret_fov_test(const ship_subsys *ss, const vec3d *gvec, const vec3d *v2e, float size_mod)
{
bool in_fov = false;
if (ss->system_info->turret_base_fov > -1.0f)
+3 -3
View File
@@ -22,19 +22,19 @@ anim_instance *init_anim_instance(anim *ptr, int bpp)
{
anim_instance *inst;
Assertion(ptr, "Bad pointer in init_anim_instance(), please report to the SCP!");
if (!ptr) {
Int3();
return NULL;
}
if ( ptr->flags & ANF_STREAMED ) {
Assertion(ptr->file_offset > -1, "Bad file offset of %d in init_anim_instance(), please report to the SCP!", ptr->file_offset);
if ( ptr->file_offset < 0 ) {
Int3();
return NULL;
}
} else {
Assertion(ptr->data, "Bad data in init_anim_instance(), please report to the SCP!");
if ( !ptr->data ) {
Int3();
return NULL;
}
}
+13 -10
View File
@@ -401,12 +401,12 @@ object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int asteroi
vec3d rotvel;
if ( Game_mode & GM_NORMAL ) {
vm_vec_rand_vec_quick(&rotvel);
vm_vec_scale(&rotvel, frand()/4.0f + 0.1f);
vm_vec_scale(&rotvel, asip->rotational_vel_multiplier * (frand()/4.0f + 0.1f));
objp->phys_info.rotvel = rotvel;
vm_vec_rand_vec_quick(&objp->phys_info.vel);
} else {
static_randvec( rand_base++, &rotvel );
vm_vec_scale(&rotvel, static_randf(rand_base++)/4.0f + 0.1f);
vm_vec_scale(&rotvel, asip->rotational_vel_multiplier * (static_randf(rand_base++)/4.0f + 0.1f));
objp->phys_info.rotvel = rotvel;
static_randvec( rand_base++, &objp->phys_info.vel );
}
@@ -1332,10 +1332,9 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
// copy important data
int copy_flags = mc.flags; // make a copy of start end positions of sphere in big ship RF
vec3d copy_p0, copy_p1;
copy_p0 = *mc.p0;
copy_p1 = *mc.p1;
int orig_flags = mc.flags; // make a copy of start end positions of sphere in big ship RF
vec3d orig_p0 = *mc.p0;
vec3d orig_p1 = *mc.p1;
// first test against the sphere - if this fails then don't do any submodel tests
mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE;
@@ -1361,7 +1360,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
}
// Only check single submodel now, since children of moving submodels are handled as moving as well
mc.flags = copy_flags | MC_SUBMODEL;
mc.flags = orig_flags | MC_SUBMODEL;
// check each submodel in turn
for (auto submodel: submodel_vector) {
@@ -1406,9 +1405,9 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
}
// Now complete base model collision checks that do not take into account rotating submodels.
mc.flags = copy_flags;
*mc.p0 = copy_p0;
*mc.p1 = copy_p1;
mc.flags = orig_flags;
mc.p0 = &orig_p0;
mc.p1 = &orig_p1;
mc.orient = &heavy_obj->orient;
// usual ship_ship collision test
@@ -2239,6 +2238,10 @@ static void asteroid_parse_section()
stuff_float(&asteroid_p->max_speed);
}
if (optional_string("$Rotational Velocity Multiplier:")) {
stuff_float(&asteroid_p->rotational_vel_multiplier);
}
if(optional_string("$Damage Type:")) {
char buf[NAME_LENGTH];
stuff_string(buf, F_NAME, NAME_LENGTH);
+3 -1
View File
@@ -63,6 +63,7 @@ public:
int num_detail_levels; // number of detail levels for this ship
int detail_distance[MAX_ASTEROID_DETAIL_LEVELS]; // distance to change detail levels at
float max_speed; // cap on speed for asteroid
float rotational_vel_multiplier; // rotational velocity multiplier for asteroid --wookieejedi
int damage_type_idx; //Damage type of the asteroid
int damage_type_idx_sav; // stored value from table used to reset damage_type_idx
float inner_rad; // radius within which maximum area effect damage is applied
@@ -80,7 +81,8 @@ public:
float gravity_const; // multiplier for mission gravity
asteroid_info( )
: type(ASTEROID_TYPE_DEBRIS), num_detail_levels(0), max_speed(0), damage_type_idx(0),
: type(ASTEROID_TYPE_DEBRIS), num_detail_levels(0), max_speed(0),
rotational_vel_multiplier(1), damage_type_idx(0),
damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
fireball_radius_multiplier( -1 ), spawn_weight( 1 ), gravity_const( 0 )
+1 -1
View File
@@ -869,7 +869,7 @@ void EndAutoPilot()
Assert( CurrentNav >= 0 );
int goal = 0;
char *goal_name = NULL;
const char *goal_name = NULL;
if (Navs[CurrentNav].flags & NP_WAYPOINT)
{
+1
View File
@@ -425,6 +425,7 @@ DCF(bm_used, "Shows BmpMan Slot Usage") {
SCP_stringstream text;
text << "BmpMan Used Slots\n";
text << " " << std::dec << std::setw(4) << std::setfill('0') << none << ", NONE\n";
text << " " << std::dec << std::setw(4) << std::setfill('0') << pcx << ", PCX\n";
text << " " << std::dec << std::setw(4) << std::setfill('0') << user << ", User\n";
text << " " << std::dec << std::setw(4) << std::setfill('0') << tga << ", TGA\n";
+2
View File
@@ -681,6 +681,8 @@ CFILE* _cfopen(const char* source, int line, const char* file_path, const char*
} else {
// Path type given?
Assert( dir_type != CF_TYPE_ANY );
if (dir_type == CF_TYPE_ANY)
return NULL;
// Create the directory if necessary
cf_create_directory(dir_type, location_flags);
+1 -1
View File
@@ -1172,7 +1172,7 @@ void cf_build_file_list()
}
Warning(LOCATION, "Some critical files might be shadowed! Please check the debug log for details.\n\n"
"%lu file(s) detected, including:\n%s", count, shadowed.c_str());
SIZE_T_ARG " file(s) detected, including:\n%s", count, shadowed.c_str());
}
critical_shadowed.clear();
+1 -1
View File
@@ -82,7 +82,7 @@ void SpawnShipCheat::runCheat() {
if (ptr->system_info->type == SUBSYSTEM_TURRET)
{
ptr->weapons.flags.set(Ship::Weapon_Flags::Beam_Free);
ptr->turret_next_fire_stamp = timestamp((int)frand_range(50.0f, 4000.0f));
ptr->turret_next_fire_stamp = timestamp(Random::next(50, 4000));
}
}
+48 -9
View File
@@ -15,6 +15,7 @@
#include "globalincs/pstypes.h"
#include "globalincs/systemvars.h"
#include "globalincs/version.h"
#include "graphics/openxr.h"
#include "graphics/shadows.h"
#include "hud/hudconfig.h"
#include "io/joy.h"
@@ -196,6 +197,8 @@ Flag exe_params[] =
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
{ "-no_screenshake", "Disable screen shaking", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_screenshake", },
{ "-vr", "Enable Virtual Reality Mode", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-vr", },
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
//flag launcher text FSO on_flags off_flags category reference URL
{ "-nosound", "Disable all sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
@@ -219,6 +222,7 @@ Flag exe_params[] =
//flag launcher text FSO on_flags off_flags category reference URL
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
{ "-no_ingame_options", "Disable using ingame options", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ingame_options", },
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
@@ -264,7 +268,6 @@ Flag exe_params[] =
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", },
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
{ "-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", },
{ "-profile_frame_time","Profile frame time", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_time", },
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", },
@@ -409,6 +412,7 @@ cmdline_parm allow_autpilot_interrupt("-no_ap_interrupt", nullptr, AT_NONE);
cmdline_parm stretch_menu("-stretch_menu", nullptr, AT_NONE); // Cmdline_stretch_menu
cmdline_parm capture_mouse("-capture_mouse", nullptr, AT_NONE); // Cmdline_capture_mouse
cmdline_parm no_screenshake("-no_screenshake", nullptr, AT_NONE); // Cmdline_no_screenshake
cmdline_parm vr("-vr", nullptr, AT_NONE);
cmdline_parm deadzone("-deadzone",
"Sets the joystick deadzone. Integer value from 0 to 100 as a percentage of the joystick's range (100% would make the stick do nothing). Disables deadzone slider in the in-game Options menu.", AT_INT); //Cmdline_deadzone
@@ -419,6 +423,7 @@ int Cmdline_stretch_menu = 0;
bool Cmdline_capture_mouse = false;
int Cmdline_no_screenshake = 0;
int Cmdline_deadzone = -1;
bool Cmdline_enable_vr = false;
// Audio related
cmdline_parm voice_recognition_arg("-voicer", NULL, AT_NONE); // Cmdline_voice_recognition
@@ -456,6 +461,7 @@ SCP_string Cmdline_lang;
cmdline_parm loadallweapons_arg("-loadallweps", NULL, AT_NONE); // Cmdline_load_all_weapons
cmdline_parm nomovies_arg("-nomovies", NULL, AT_NONE); // Cmdline_nomovies -- Allows video streaming
cmdline_parm no_set_gamma_arg("-no_set_gamma", NULL, AT_NONE); // Cmdline_no_set_gamma
cmdline_parm no_ingame_options_arg("-no_ingame_options", NULL, AT_NONE); // Cmdline_no_ingame_options
cmdline_parm no_fbo_arg("-disable_fbo", NULL, AT_NONE); // Cmdline_no_fbo
cmdline_parm no_pbo_arg("-disable_pbo", NULL, AT_NONE); // Cmdline_no_pbo
cmdline_parm mipmap_arg("-mipmap", NULL, AT_NONE); // Cmdline_mipmap
@@ -479,6 +485,7 @@ cmdline_parm fix_registry("-fix_registry", NULL, AT_NONE);
int Cmdline_load_all_weapons = 0;
int Cmdline_nomovies = 0;
int Cmdline_no_set_gamma = 0;
bool Cmdline_no_ingame_options = false;
int Cmdline_no_fbo = 0;
int Cmdline_no_pbo = 0;
int Cmdline_ati_color_swap = 0;
@@ -513,7 +520,9 @@ cmdline_parm stats_arg("-stats", NULL, AT_NONE); // Cmdline_show_stats
cmdline_parm save_render_targets_arg("-save_render_target", NULL, AT_NONE); // Cmdline_save_render_targets
cmdline_parm window_arg("-window", NULL, AT_NONE); // Cmdline_window
cmdline_parm fullscreen_window_arg("-fullscreen_window", "Fullscreen/borderless window (Windows only)", AT_NONE);
cmdline_parm res_arg("-res", "Resolution, formatted like 1600x900", AT_STRING);
cmdline_parm deprecated_res_arg("-res", "Deprecated, resolution, formatted like 1600x900", AT_STRING);
cmdline_parm render_res_arg("-render_res", "Resolution, formatted like 1600x900", AT_STRING);
cmdline_parm window_res_arg("-window_res", "Window resolution, formatted like 1600x900.", AT_STRING);
cmdline_parm center_res_arg("-center_res", "Resolution of center monitor, formatted like 1600x900", AT_STRING);
cmdline_parm verify_vps_arg("-verify_vps", NULL, AT_NONE); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, "Ignore any cmdline_fso.cfg files", AT_NONE);
@@ -551,6 +560,7 @@ int Cmdline_show_stats = 0;
int Cmdline_save_render_targets = 0;
int Cmdline_window = 0;
int Cmdline_fullscreen_window = 0;
tl::optional<std::pair<uint16_t, uint16_t>>Cmdline_window_res = tl::nullopt;
char *Cmdline_res = 0;
char *Cmdline_center_res = 0;
int Cmdline_verify_vps = 0;
@@ -1713,31 +1723,48 @@ bool SetCmdlineParams()
// d3d windowed
if(window_arg.found()) {
// We need to set both values since we don't know if we are going to use the new config system
options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "0");
//options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "0");
Cmdline_window = 1;
}
if ( fullscreen_window_arg.found( ) )
{
options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "1");
//options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "1");
Cmdline_fullscreen_window = 1;
Cmdline_window = 0; /* Make sure no-one sets both */
}
if(res_arg.found()){
Cmdline_res = res_arg.str();
if(render_res_arg.found() || deprecated_res_arg.found()){
if (render_res_arg.found()) {
Cmdline_res = render_res_arg.str();
}
else {
Cmdline_res = deprecated_res_arg.str();
mprintf(("Deprecated -res argument. Use -render_res instead...\n"));
}
int width = 0;
/*int width = 0;
int height = 0;
if ( sscanf(Cmdline_res, "%dx%d", &width, &height) == 2 ) {
if (sscanf(Cmdline_res, "%dx%d", &width, &height) == 2) {
SCP_string override;
sprintf(override, "{\"width\":%d,\"height\":%d}", width, height);
options::OptionsManager::instance()->setOverride("Graphics.Resolution", override);
} else {
mprintf(("Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".\n", Cmdline_res));
Warning(LOCATION, "Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".\n", Cmdline_res);
}*/
}
if(window_res_arg.found()){
int width = 0;
int height = 0;
if ( sscanf(window_res_arg.str(), "%dx%d", &width, &height) == 2 ) {
Cmdline_window_res.emplace(static_cast<uint16_t>(width), static_cast<uint16_t>(height));
} else {
Warning(LOCATION, "Failed to parse -window_res parameter \"%s\". Must be in format \"<width>x<height>\".\n", window_res_arg.str());
}
}
if(center_res_arg.found()){
Cmdline_center_res = center_res_arg.str();
}
@@ -1846,6 +1873,14 @@ bool SetCmdlineParams()
}
}
if (vr.found()) {
Cmdline_enable_vr = true;
if (fov_arg.found() || fov_cockpit_arg.found()) {
Warning(LOCATION, "FoV Command line settings found. VR-Mode will override these with the HMD's native FoV...");
}
openxr_prepare();
}
if (orb_radar.found())
{
Cmdline_orb_radar = 1;
@@ -1901,6 +1936,10 @@ bool SetCmdlineParams()
Cmdline_no_set_gamma = 1;
}
if (no_ingame_options_arg.found()) {
Cmdline_no_ingame_options = true;
}
if(no_vsync_arg.found() )
{
Gr_enable_vsync = false;
+5 -1
View File
@@ -6,12 +6,13 @@
* source.
*
*/
*/
#ifndef FS_CMDLINE_HEADER_FILE
#define FS_CMDLINE_HEADER_FILE
#include <tl/optional.hpp>
int parse_cmdline(int argc, char *argv[]);
@@ -46,6 +47,7 @@ extern int Cmdline_use_last_pilot;
extern int Cmdline_window;
extern int Cmdline_fullscreen_window;
extern char *Cmdline_res;
extern tl::optional<std::pair<uint16_t, uint16_t>>Cmdline_window_res;
extern char *Cmdline_center_res;
@@ -89,6 +91,7 @@ extern int Cmdline_stretch_menu;
extern bool Cmdline_capture_mouse;
extern int Cmdline_no_screenshake;
extern int Cmdline_deadzone;
extern bool Cmdline_enable_vr;
// Audio related
extern int Cmdline_voice_recognition;
@@ -111,6 +114,7 @@ extern SCP_string Cmdline_lang;
extern int Cmdline_load_all_weapons;
extern int Cmdline_nomovies; // WMC Toggles movie playing support
extern int Cmdline_no_set_gamma;
extern bool Cmdline_no_ingame_options;
extern int Cmdline_no_fbo;
extern int Cmdline_no_pbo;
extern int Cmdline_mipmap;
+7 -7
View File
@@ -264,11 +264,11 @@ void control_config_common_init_bindings() {
(HUD_TARGETBOX_TOGGLE_WIREFRAME, KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, 1, "Toggle HUD Wireframe Target View", CC_TYPE_TRIGGER)
// Custom Controls
(CUSTOM_CONTROL_1, KEY_ALTED | KEY_SHIFTED | KEY_1, -1, COMPUTER_TAB, 0, "Custom Control 1", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_2, KEY_ALTED | KEY_SHIFTED | KEY_2, -1, COMPUTER_TAB, 0, "Custom Control 2", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_3, KEY_ALTED | KEY_SHIFTED | KEY_3, -1, COMPUTER_TAB, 0, "Custom Control 3", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_4, KEY_ALTED | KEY_SHIFTED | KEY_4, -1, COMPUTER_TAB, 0, "Custom Control 4", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_5, KEY_ALTED | KEY_SHIFTED | KEY_5, -1, COMPUTER_TAB, 0, "Custom Control 5", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_1, KEY_ALTED | KEY_SHIFTED | KEY_1, -1, COMPUTER_TAB, 1784, "Custom Control 1", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_2, KEY_ALTED | KEY_SHIFTED | KEY_2, -1, COMPUTER_TAB, 1785, "Custom Control 2", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_3, KEY_ALTED | KEY_SHIFTED | KEY_3, -1, COMPUTER_TAB, 1786, "Custom Control 3", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_4, KEY_ALTED | KEY_SHIFTED | KEY_4, -1, COMPUTER_TAB, 1787, "Custom Control 4", CC_TYPE_TRIGGER, true)
(CUSTOM_CONTROL_5, KEY_ALTED | KEY_SHIFTED | KEY_5, -1, COMPUTER_TAB, 1788, "Custom Control 5", CC_TYPE_TRIGGER, true)
.end(); // Builder
// init default preset
@@ -451,7 +451,7 @@ const char* Joy_button_text_french_u[] = {
"Bouton 13", "Bouton 14", "Bouton 15", "Bouton 16", "Bouton 17", "Bouton 18",
"Bouton 19", "Bouton 20", "Bouton 21", "Bouton 22", "Bouton 23", "Bouton 24",
"Bouton 25", "Bouton 26", "Bouton 27", "Bouton 28", "Bouton 29", "Bouton 30",
"Bouton 31", "Bouton 32", "Chapeau Arri\xc3\xa8""re", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
"Bouton 31", "Bouton 32", ("Chapeau Arri\xc3\xa8""re"), "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
};
const char* Joy_button_text_polish_u[] = {
@@ -460,7 +460,7 @@ const char* Joy_button_text_polish_u[] = {
"Przyc.13", "Przyc.14", "Przyc.15", "Przyc.16", "Przyc.17", "Przyc.18",
"Przyc.19", "Przyc.20", "Przyc.21", "Przyc.22", "Przyc.23", "Przyc.24",
"Przyc.25", "Przyc.26", "Przyc.27", "Przyc.28", "Przyc.29", "Przyc.30",
"Przyc.31", "Przyc.32", "Hat Ty\xc5\x82", "Hat Prz\xc3\xb3""d", "Hat Lewo", "Hat Prawo"
"Przyc.31", "Przyc.32", "Hat Ty\xc5\x82", ("Hat Prz\xc3\xb3""d"), "Hat Lewo", "Hat Prawo"
};
const char* Joy_button_text_english_u[] = {
+1
View File
@@ -52,6 +52,7 @@ struct MovieProperties {
FrameSize size;
float fps = -1.0f;
float duration = 0.0f;
FramePixelFormat pixelFormat = FramePixelFormat::Invalid;
};
-2
View File
@@ -222,7 +222,6 @@ void cutscene_mark_viewable(const char* filename)
// change to lower case
strlwr(file);
int i = 0;
for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut)
{
// change the cutscene file name to lower case
@@ -235,7 +234,6 @@ void cutscene_mark_viewable(const char* filename)
cut->flags.set(Cutscene::Cutscene_Flags::Viewable);
return;
}
i++;
}
Warning(LOCATION, "Could not find cutscene '%s' in listing; cannot mark it viewable...", filename);
+1
View File
@@ -503,6 +503,7 @@ MovieProperties FFMPEGDecoder::getProperties() const
props.size.height = static_cast<size_t>(m_status->videoCodecPars.height);
props.fps = static_cast<float>(getFrameRate(m_status->videoStream, m_status->videoCodecCtx));
props.duration = static_cast<float>(m_status->videoStream->duration * av_q2d(m_status->videoStream->time_base));
props.pixelFormat = getPixelFormat(getConversionFormat(m_status->videoCodecPars.pixel_format));
+7 -8
View File
@@ -926,10 +926,9 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
// copy important data
int copy_flags = mc.flags; // make a copy of start end positions of sphere in big ship RF
vec3d copy_p0, copy_p1;
copy_p0 = *mc.p0;
copy_p1 = *mc.p1;
int orig_flags = mc.flags; // make a copy of start end positions of sphere in big ship RF
vec3d orig_p0 = *mc.p0;
vec3d orig_p1 = *mc.p1;
// first test against the sphere - if this fails then don't do any submodel tests
mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE;
@@ -955,7 +954,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
}
// Only check single submodel now, since children of moving submodels are handled as moving as well
mc.flags = copy_flags | MC_SUBMODEL;
mc.flags = orig_flags | MC_SUBMODEL;
if (Ship_info[Ships[pship_obj->instance].ship_info_index].collision_lod > -1) {
mc.lod = Ship_info[Ships[pship_obj->instance].ship_info_index].collision_lod;
@@ -1005,9 +1004,9 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
}
// Now complete base model collision checks that do not take into account rotating submodels.
mc.flags = copy_flags;
*mc.p0 = copy_p0;
*mc.p1 = copy_p1;
mc.flags = orig_flags;
mc.p0 = &orig_p0;
mc.p1 = &orig_p1;
mc.orient = &heavy_obj->orient;
// usual ship_ship collision test
+8
View File
@@ -1,9 +1,17 @@
in vec4 fragTexCoord;
out vec4 fragOut0;
#ifdef COPY_ARRAY
uniform sampler2DArray tex;
#else
uniform sampler2D tex;
#endif
void main()
{
#ifdef COPY_ARRAY
fragOut0 = texture(tex, vec3(fragTexCoord.xy, 0));
#else
fragOut0 = texture(tex, fragTexCoord.xy);
#endif
}
+8
View File
@@ -263,6 +263,9 @@ void main()
if (FLAG_ACTIVE(MODEL_SDR_FLAG_SPEC)) {
specColor = texture(sSpecmap, vec3(texCoord, float(sSpecmapIndex)));
if (FLAG_ACTIVE(MODEL_SDR_FLAG_ALPHA_MULT)) {
specColor *= alphaMult;
}
if(alphaGloss) glossData = specColor.a;
if(gammaSpec) {
specColor.rgb = max(specColor.rgb, vec3(0.03f)); // hardcoded minimum specular value. read John Hable's blog post titled 'Everything Is Shiny'.
@@ -397,6 +400,11 @@ void main()
emissiveColor.rgb += glowColor * GLOW_MAP_INTENSITY;
}
if (FLAG_ACTIVE(MODEL_SDR_FLAG_ALPHA_MULT)) {
//Since this is emissive, we need to premultiply it for intensity, and apply alpha to not replace existing emissive
emissiveColor *= alphaMult;
}
if (FLAG_ACTIVE(MODEL_SDR_FLAG_FOG)) {
vec3 finalFogColor = fogColor.rgb;
if (FLAG_ACTIVE(MODEL_SDR_FLAG_HDR)) {
@@ -37,7 +37,6 @@ vec3 Uncharted2ToneMapping(vec3 hdr_color) // John Hable's filmic
hdr_color = ((hdr_color * (A * hdr_color + C * B) + D * E) / (hdr_color * (A * hdr_color + B) + D * F)) - E / F;
float white = ((W * (A * W + C * B) + D * E) / (W * (A * W + B) + D * F)) - E / F;
hdr_color /= white;
hdr_color = linear_to_srgb(hdr_color); // return from linear color space to SRGB color space
return hdr_color;
}
@@ -65,7 +64,6 @@ vec3 aces(vec3 hdr_color)
hdr_color = aces_input * hdr_color;
hdr_color = rtt_and_odt_fit(hdr_color);
hdr_color = aces_output * hdr_color;
hdr_color = linear_to_srgb(hdr_color);
return hdr_color;
}
@@ -79,7 +77,6 @@ vec3 aces_approx(vec3 hdr_color) // also filmic, higher contrast then Uncharted2
hdr_color *= 0.6f;
hdr_color = clamp((hdr_color*(a*hdr_color+b))/(hdr_color*(c*hdr_color+d)+e), 0.0f, 1.0f);
hdr_color = linear_to_srgb(hdr_color); // return from linear color space to SRGB color space
return hdr_color;
}
@@ -96,7 +93,6 @@ vec3 rhj_lumaToneMapping(vec3 hdr_color) // reinhard_jodie
float luma = dot(hdr_color, vec3(0.2126, 0.7152, 0.0722)); //dot products are a bit more expensive
float toneMappedLuma = luma / (1.0 + luma);
hdr_color *= toneMappedLuma / luma;
hdr_color = linear_to_srgb(hdr_color); // return from linear color space to SRGB color space
return hdr_color;
}
@@ -105,14 +101,12 @@ vec3 reinhard_extended(vec3 hdr_color)
float max_white = 1.0;
vec3 numerator = hdr_color * (1.0f + (hdr_color / vec3(max_white * max_white)));
hdr_color = numerator / (1.0f + hdr_color);
hdr_color = linear_to_srgb(hdr_color); // return from linear color space to SRGB color space
return hdr_color;
}
vec3 linearToneMapping(vec3 hdr_color)
{
hdr_color = clamp(hdr_color, 0., 1.);
hdr_color = linear_to_srgb(hdr_color); // return from linear color space to SRGB color space
return hdr_color;
}
@@ -155,7 +149,7 @@ vec3 PPC_RGB( vec3 color ) {
funswitch(color.g),
funswitch(color.b));
return linear_to_srgb(color);
return color;
}
@@ -174,7 +168,7 @@ vec3 PPC( vec3 color ) {
else {
luma_tone = sh_offsetY;
}
return linear_to_srgb(color * luma_tone / luma);
return color * luma_tone / luma;
}
@@ -213,5 +207,9 @@ void main()
break;
}
#ifdef LINEAR_OUT
fragOut0 = vec4(color.rgb, 1.0);
#else
fragOut0 = vec4(linear_to_srgb(color.rgb), 1.0);
#endif
}
+19 -19
View File
@@ -11,7 +11,7 @@ $AI:
+Actively Pursues: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Turrets attack this: YES
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Sentry Gun
$Counts for Alone: YES
@@ -32,7 +32,7 @@ $AI:
+Guards attack this: YES
+Turrets attack this: YES
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Escape Pod
$Praise Destruction: YES
@@ -51,7 +51,7 @@ $AI:
+Actively Pursues: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Turrets attack this: YES
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Cargo
$Scannable: YES
@@ -65,7 +65,7 @@ $Fog:
+Compl dist: 500.0
$AI:
+Passive docks: ( "cargo" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Support
$Counts for Alone: YES
@@ -92,7 +92,7 @@ $AI:
+Turrets attack this: YES
+Active docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
;;WMC - Stealth ships always have another type, so this isn't used
$Name: Stealth
@@ -118,7 +118,7 @@ $AI:
+Turrets attack this: YES
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Fighter
$Counts for Alone: YES
@@ -146,7 +146,7 @@ $AI:
+Can Form Wing: YES
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Bomber
$Counts for Alone: YES
@@ -174,7 +174,7 @@ $AI:
+Can Form Wing: YES
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
;;WMC - This fighter/bomber type doesn't seem to be used anywhere, because no ship is set as both fighter and bomber
$Name: Fighter/bomber
@@ -202,7 +202,7 @@ $AI:
+Can Form Wing: YES
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Transport
$Counts for Alone: YES
@@ -232,7 +232,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Freighter
$Counts for Alone: YES
@@ -264,7 +264,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: AWACS
$Counts for Alone: YES
@@ -294,7 +294,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Gas Miner
$Counts for Alone: YES
@@ -324,7 +324,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Cruiser
$Counts for Alone: YES
@@ -354,7 +354,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Corvette
$Counts for Alone: YES
@@ -384,7 +384,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Capital
$Counts for Alone: YES
@@ -414,7 +414,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Super Cap
$Counts for Alone: YES
@@ -442,7 +442,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Drydock
$Counts for Alone: YES
@@ -468,7 +468,7 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
$Name: Knossos Device
$Counts for Alone: YES
@@ -492,6 +492,6 @@ $AI:
+Passive docks: ( "support" )
+Ignored on cripple by: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "stealth" "fighter" "bomber" "fighter/bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
+Targeted by 'Huge' weapons and Ignored by 'small only' weapons: YES
$Vaporize Percent Chance: 0.0
$Skip Death Roll Percent Chance: 0.0
#End
+4 -2
View File
@@ -113,7 +113,8 @@ const char *GS_event_text[] =
"GS_EVENT_LAB",
"GS_EVENT_PXO_HELP",
"GS_EVENT_FICTION_VIEWER", // 65
"GS_EVENT_SCRIPTING"
"GS_EVENT_SCRIPTING",
"GS_EVENT_SCRIPTING_MISSION"
};
//XSTR:ON
@@ -176,7 +177,8 @@ const char *GS_state_text[] =
"GS_STATE_PXO_HELP", // 50
"GS_STATE_START_GAME",
"GS_STATE_FICTION_VIEWER",
"GS_STATE_SCRIPTING"
"GS_STATE_SCRIPTING",
"GS_STATE_SCRIPTING_MISSION"
};
//XSTR:ON
+2
View File
@@ -89,6 +89,7 @@ enum GS_EVENT {
GS_EVENT_PXO_HELP,
GS_EVENT_FICTION_VIEWER,
GS_EVENT_SCRIPTING,
GS_EVENT_SCRIPTING_MISSION,
GS_NUM_EVENTS // Last one++
};
@@ -159,6 +160,7 @@ enum GS_STATE {
GS_STATE_START_GAME,
GS_STATE_FICTION_VIEWER,
GS_STATE_SCRIPTING,
GS_STATE_SCRIPTING_MISSION,
GS_NUM_STATES // Last one++
};
+7 -5
View File
@@ -340,7 +340,7 @@ void event_music_init()
Warning(LOCATION, "Soundtrack file %s was not found with its specified extension, but another file %s exists in the modpack. Please update the extension and adjust audio specifications if necessary.", filename, res.name_ext.c_str());
#endif
Warning(LOCATION, "One or more files in '%s' could not be loaded. The soundtrack will not be used.", soundtrack.name);
Warning(LOCATION, "Soundtrack file %s was not found. The soundtrack '%s' will not be used.", filename, soundtrack.name);
all_patterns_valid = false;
break;
}
@@ -970,11 +970,13 @@ int event_music_friendly_arrival()
// overlay
if (Soundtracks[Current_soundtrack_num].flags & EMF_ALLIED_ARRIVAL_OVERLAY)
{
// Goober5000 - I didn't touch this part... for some reason, FS2 only has one
// Goober5000 - This is how retail did it. For some reason, FS2 only has one
// arrival music pattern, and this is it
Assert(Patterns[SONG_AARV_1].handle >= 0 );
audiostream_play(Patterns[SONG_AARV_1].handle, (Master_event_music_volume * aav_music_volume), 0); // no looping
audiostream_set_sample_cutoff(Patterns[SONG_AARV_1].handle, fl2i(Patterns[SONG_AARV_1].num_measures * Patterns[SONG_AARV_1].samples_per_measure) );
if (Patterns[SONG_AARV_1].handle >= 0)
{
audiostream_play(Patterns[SONG_AARV_1].handle, (Master_event_music_volume * aav_music_volume), 0); // no looping
audiostream_set_sample_cutoff(Patterns[SONG_AARV_1].handle, fl2i(Patterns[SONG_AARV_1].num_measures * Patterns[SONG_AARV_1].samples_per_measure));
}
}
// don't overlay
else
+2 -2
View File
@@ -191,8 +191,8 @@ class flagset {
return *this;
}
bool any_set() { return values.any(); }
bool none_set() { return values.none(); }
bool any_set() const { return values.any(); }
bool none_set() const { return values.none(); }
void from_u64(std::uint64_t num) { values = (unsigned long) num; }
+1 -1
View File
@@ -288,7 +288,7 @@ constexpr bool LoggingEnabled = false;
// Disabling this functionality is dangerous, crazy values can run rampant unchecked, and the longer it's disabled
// the more likely you are to have problems getting it working again.
#if defined(NDEBUG)
# define Assert(expr) do { ASSUME(expr); } while (false)
# define Assert(expr) do { ASSUME(expr); (void)sizeof(expr); } while (false)
#else
# define Assert(expr) do {\
if (!(expr)) {\
-7
View File
@@ -12,7 +12,6 @@
#include "debugconsole/console.h"
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "io/timer.h"
#include "nebula/neb.h"
#include "options/Option.h"
@@ -34,12 +33,6 @@ float Cutscene_delta_time = 1.0f;
//How far along a change is (0 to 1)
float Cutscene_bars_progress = 1.0f;
//FADEIN STUFF
shader Viewer_shader;
FadeType Fade_type = FI_NONE;
int Fade_start_timestamp = 0;
int Fade_end_timestamp = 0;
// The detail level. Anything below zero draws simple models earlier than it
// should. Anything above zero draws higher detail models longer than it should.
// -2=lowest
-13
View File
@@ -59,19 +59,6 @@
extern float Cutscene_bars_progress, Cutscene_delta_time;
extern int Cutscene_bar_flags;
//-----Fadein stuff
struct shader;
extern shader Viewer_shader;
enum FadeType {
FI_NONE,
FI_FADEIN,
FI_FADEOUT
};
extern FadeType Fade_type;
extern int Fade_start_timestamp;
extern int Fade_end_timestamp;
typedef struct vei {
angles_t angles; // Angles defining viewer location.
+1 -1
View File
@@ -34,7 +34,7 @@
#define ASSUME(x)
#if defined(NDEBUG)
# define Assertion(expr, msg, ...) do { } while (false)
# define Assertion(expr, msg, ...) do { (void)sizeof(expr); } while (false)
#else
/*
* NOTE: Assertion() can only use its proper functionality in compilers
+1 -1
View File
@@ -34,7 +34,7 @@
#define ASSUME(x)
#if defined(NDEBUG)
# define Assertion(expr, msg, ...) do {} while (false)
# define Assertion(expr, msg, ...) do { (void)sizeof(expr); } while (false)
#else
/*
* NOTE: Assertion() can only use its proper functionality in compilers
+1 -1
View File
@@ -36,7 +36,7 @@
#define ASSUME(x)
#if defined(NDEBUG)
# define Assertion(expr, msg, ...) do {} while (false)
# define Assertion(expr, msg, ...) do { (void)sizeof(expr); } while (false)
#else
/*
* NOTE: Assertion() can only use its proper functionality in compilers
+1 -1
View File
@@ -39,7 +39,7 @@
#define ASSUME(x)
#if defined(NDEBUG)
# define Assertion(expr, msg, ...) do { ASSUME(expr); } while (false)
# define Assertion(expr, msg, ...) do { ASSUME(expr); (void)sizeof(expr); } while (false)
#else
# define Assertion(expr, msg, ...) \
do { \
+10
View File
@@ -25,6 +25,16 @@ bool SCP_vector_contains(SCP_vector<T>& vector, T item) {
return std::find(vector.begin(), vector.end(), item) != vector.end();
}
template <typename T>
inline bool SCP_vector_inbounds(SCP_vector<T>& vector, int idx) {
return ((idx >= 0) && (idx < static_cast<int>(vector.size())));
}
template <typename T>
inline bool SCP_vector_inbounds(SCP_vector<T>& vector, size_t idx) {
return idx < vector.size();
}
template <typename T>
using SCP_list = std::list<T, std::allocator<T>>;
+54 -7
View File
@@ -25,6 +25,7 @@
#include "cmdline/cmdline.h"
#include "debugconsole/console.h"
#include "executor/global_executors.h"
#include "graphics/openxr.h"
#include "graphics/paths/PathRenderer.h"
#include "graphics/post_processing.h"
#include "graphics/util/GPUMemoryHeap.h"
@@ -265,6 +266,7 @@ static auto VideoDisplayOption = options::OptionBuilder<int>("Graphics.Display",
.serializer(videodisplay_serializer)
.enumerator(videodisplay_enumerator)
.display(videodisplay_display)
.flags({options::OptionFlags::ForceMultiValueSelection})
.default_val(0)
.change_listener(videodisplay_change)
.importance(99)
@@ -704,7 +706,7 @@ bool gr_resize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
*/
bool gr_unsize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
{
if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
if ( resize_mode == GR_RESIZE_NONE || resize_mode == GR_RESIZE_REPLACE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
return false;
}
@@ -1025,6 +1027,9 @@ void gr_close()
return;
}
if(Cmdline_enable_vr)
openxr_close();
if (Gr_original_gamma_ramp != nullptr && os::getSDLMainWindow() != nullptr) {
SDL_SetWindowGammaRamp(os::getSDLMainWindow(), Gr_original_gamma_ramp, (Gr_original_gamma_ramp + 256),
(Gr_original_gamma_ramp + 512));
@@ -1256,14 +1261,38 @@ static void init_colors()
Gr_ta_alpha.scale = 17;
}
static void gr_init_function_pointers(int mode) {
gr_screen = {};
switch (mode) {
case GR_OPENGL:
#ifdef WITH_OPENGL
gr_opengl_init_function_pointers();
#else
Error(LOCATION, "OpenGL renderer was requested but that was not compiled into this build.");
#endif
break;
case GR_VULKAN:
#ifdef WITH_VULKAN
graphics::vulkan::initialize_function_pointers();
#else
Error(LOCATION, "Vulkan renderer was requested but that was not compiled into this build.");
#endif
break;
case GR_STUB:
gr_stub_init_function_pointers();
break;
default:
UNREACHABLE("Invalid graphics mode requested"); // Invalid graphics mode
}
}
static bool gr_init_sub(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int mode, int width, int height,
int depth, float center_aspect_ratio)
{
int res = GR_1024;
bool rc = false;
gr_screen = {};
float aspect_ratio = (float)width / (float)height;
if ( (((width == 640) && (height == 480)) || ((width == 1024) && (height == 768))) && (aspect_ratio == center_aspect_ratio) ) {
@@ -1562,9 +1591,6 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
depth = d_depth;
}
if (Cmdline_vulkan)
mode = GR_VULKAN;
// if we are in standalone mode then just use special defaults
if (Is_standalone) {
mode = GR_STUB;
@@ -1574,6 +1600,8 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
center_aspect_ratio = -1.0f;
}
gr_init_function_pointers(mode);
if (gr_get_resolution_class(width, height) != GR_640) {
// check for hi-res interface files so that we can verify our width/height is correct
// if we don't have it then fall back to 640x480 mode instead
@@ -1591,6 +1619,17 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
}
}
if (Cmdline_enable_vr) {
float user_ar = i2fl(width) / i2fl(height);
float xr_ar = openxr_preinit(user_ar);
if (MAX(user_ar, xr_ar) / MIN(user_ar, xr_ar) > 1.05f) {
int newWidth = fl2i(i2fl(height) * xr_ar);
mprintf(("User specified resolution does not match OpenXR HMD aspect ratio. Adjusting width from %dpx to %dpx.", width, newWidth));
width = newWidth;
}
}
// These compiler macros will force windowed mode at the specified resolution if
// built in debug mode. This helps if you run with the debugger active as the
// game won't be switching from fullscreen to minimized every time you hit a breakpoint or
@@ -1709,6 +1748,9 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
Shadow_quality = ShadowQuality::Disabled;
}
if(Cmdline_enable_vr)
openxr_init();
return true;
}
@@ -2597,7 +2639,12 @@ void gr_flip(bool execute_scripting)
uniform_buffer_managers_retire_buffers();
TRACE_SCOPE(tracing::PageFlip);
gr_screen.gf_flip();
//Prevent a real page flip if OpenXR is on and claims that that wasn't the full image yet
if (!gr_openxr_flip()) {
gr_screen.gf_flip();
gr_setup_frame();
}
}
void gr_print_timestamp(int x, int y, fix timestamp, int resize_mode)
+28
View File
@@ -203,6 +203,7 @@ enum shader_type {
SDR_TYPE_VOLUMETRIC_FOG,
SDR_TYPE_ROCKET_UI,
SDR_TYPE_COPY,
SDR_TYPE_COPY_WORLD,
SDR_TYPE_MSAA_RESOLVE,
SDR_TYPE_POST_PROCESS_SMAA_EDGE,
@@ -237,6 +238,10 @@ enum shader_type {
#define SDR_FLAG_VOLUMETRICS_DO_EDGE_SMOOTHING (1<<0)
#define SDR_FLAG_VOLUMETRICS_NOISE (1<<1)
#define SDR_FLAG_COPY_FROM_ARRAY (1 << 0)
#define SDR_FLAG_TONEMAPPING_LINEAR_OUT (1 << 0)
enum class uniform_block_type {
Lights = 0,
@@ -697,6 +702,8 @@ typedef struct screen {
// switch onscreen, offscreen
std::function<void()> gf_flip;
std::function<void()> gf_setup_frame;
// sets the clipping region
std::function<void(int x, int y, int w, int h, int resize_mode)> gf_set_clip;
@@ -912,6 +919,14 @@ typedef struct screen {
std::function<void(int x, int y, int width, int height)> gf_set_viewport;
std::function<void(bool set_override)> gf_override_fog;
//OpenXR functions
std::function<SCP_vector<const char*>()> gf_openxr_get_extensions;
std::function<bool()> gf_openxr_test_capabilities;
std::function<bool()> gf_openxr_create_session;
std::function<int64_t(const SCP_vector<int64_t>&)> gf_openxr_get_swapchain_format;
std::function<bool()> gf_openxr_acquire_swapchain_buffers;
std::function<bool()> gf_openxr_flip;
} screen;
// handy macro
@@ -966,6 +981,7 @@ extern screen gr_screen;
#define GR_RESIZE_MENU 3
#define GR_RESIZE_MENU_ZOOMED 4
#define GR_RESIZE_MENU_NO_OFFSET 5
#define GR_RESIZE_REPLACE 6
void gr_set_screen_scale(int x, int y, int zoom_x = -1, int zoom_y = -1, int max_x = gr_screen.max_w, int max_y = gr_screen.max_h, int center_x = gr_screen.center_w, int center_y = gr_screen.center_h, bool force_stretch = false);
void gr_reset_screen_scale();
@@ -1011,6 +1027,10 @@ extern void gr_activate(int active);
//#define gr_flip GR_CALL(gr_screen.gf_flip)
void gr_flip(bool execute_scripting = true);
inline void gr_setup_frame() {
gr_screen.gf_setup_frame();
}
//#define gr_set_clip GR_CALL(gr_screen.gf_set_clip)
inline void gr_set_clip(int x, int y, int w, int h, int resize_mode=GR_RESIZE_FULL)
{
@@ -1272,6 +1292,14 @@ inline void gr_sync_delete(gr_sync sync)
gr_screen.gf_sync_delete(sync);
}
//OpenXR
#define gr_openxr_get_extensions GR_CALL(gr_screen.gf_openxr_get_extensions)
#define gr_openxr_test_capabilities GR_CALL(gr_screen.gf_openxr_test_capabilities)
#define gr_openxr_create_session GR_CALL(gr_screen.gf_openxr_create_session)
#define gr_openxr_get_swapchain_format GR_CALL(gr_screen.gf_openxr_get_swapchain_format)
#define gr_openxr_acquire_swapchain_buffers GR_CALL(gr_screen.gf_openxr_acquire_swapchain_buffers)
#define gr_openxr_flip GR_CALL(gr_screen.gf_openxr_flip)
// color functions
void gr_init_color(color *c, int r, int g, int b);
void gr_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type = AC_TYPE_HUD );
+2 -17
View File
@@ -734,7 +734,7 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y, bool m
}
}
void generic_anim_render_ex(generic_anim* ga, float frametime, int x, int y, int w, int h, bool menu, const generic_extras* ge)
void generic_anim_bitmap_set(generic_anim* ga, float frametime, const generic_extras* ge)
{
if ((ge != nullptr) && (ga->use_hud_color == true)) {
Warning(LOCATION, "Monochrome generic anims can't use extra info (yet)");
@@ -752,23 +752,8 @@ void generic_anim_render_ex(generic_anim* ga, float frametime, int x, int y, int
generic_anim_render_fixed_frame_delay(ga, frametime, a);
}
if (ga->num_frames > 0) {
if (ga->num_frames > 0)
ga->previous_frame = ga->current_frame;
if (ga->use_hud_color) {
gr_aabitmap_ex(x, y, w, h, 0, 0, (menu ? GR_RESIZE_MENU : GR_RESIZE_FULL));
}
else {
if (ge == nullptr) {
gr_bitmap_ex(x, y, w, h, 0, 0, (menu ? GR_RESIZE_MENU : GR_RESIZE_FULL));
}
else if (ge->draw == true) {
// currently only for lua streaminganim objects
// and don't draw them unless requested...
gr_bitmap_uv(x, y, w, h, ge->u0, ge->v0, ge->u1, ge->v1, ge->resize_mode);
}
}
}
}
/*
+1 -1
View File
@@ -91,6 +91,6 @@ int generic_anim_stream(generic_anim *ga, const bool cache = true);
int generic_bitmap_load(generic_bitmap *gb);
void generic_anim_unload(generic_anim *ga);
void generic_anim_render(generic_anim *ga, float frametime, int x, int y, bool menu = false, const generic_extras *ge = nullptr);
void generic_anim_render_ex(generic_anim* ga, float frametime, int x, int y, int w, int h, bool menu = false, const generic_extras* ge = nullptr);
void generic_anim_bitmap_set(generic_anim* ga, float frametime, const generic_extras* ge = nullptr);
void generic_anim_reset(generic_anim *ga);
#endif
+47 -2
View File
@@ -18,6 +18,11 @@
#include "bmpman/bm_internal.h"
void gr_stub_setup_frame()
{
}
uint gr_stub_lock()
{
return 1;
@@ -421,7 +426,37 @@ void gr_stub_delete_query_object(int /*obj*/)
{
}
bool gr_stub_init()
SCP_vector<const char*> gr_stub_openxr_get_extensions()
{
return {};
}
bool gr_stub_openxr_test_capabilities()
{
return false;
}
bool gr_stub_openxr_create_session()
{
return false;
}
int64_t gr_stub_openxr_get_swapchain_format(const SCP_vector<int64_t>& /*allowed*/)
{
return 0;
}
bool gr_stub_openxr_acquire_swapchain_buffers()
{
return false;
}
bool gr_stub_openxr_flip()
{
return false;
}
bool gr_stub_init()
{
if (gr_screen.res != GR_640) {
gr_screen.res = GR_640;
@@ -447,8 +482,13 @@ bool gr_stub_init()
Gr_blue.mask = 0xff;
Gr_t_blue = Gr_blue;
return true;
}
void gr_stub_init_function_pointers() {
// function pointers...
gr_screen.gf_flip = gr_stub_flip;
gr_screen.gf_setup_frame = gr_stub_setup_frame;
gr_screen.gf_set_clip = gr_stub_set_clip;
gr_screen.gf_reset_clip = gr_stub_reset_clip;
@@ -572,5 +612,10 @@ bool gr_stub_init()
gr_screen.gf_override_fog = [](bool /*b*/) {};
return true;
gr_screen.gf_openxr_get_extensions = gr_stub_openxr_get_extensions;
gr_screen.gf_openxr_test_capabilities = gr_stub_openxr_test_capabilities;
gr_screen.gf_openxr_create_session = gr_stub_openxr_create_session;
gr_screen.gf_openxr_get_swapchain_format = gr_stub_openxr_get_swapchain_format;
gr_screen.gf_openxr_acquire_swapchain_buffers = gr_stub_openxr_acquire_swapchain_buffers;
gr_screen.gf_openxr_flip = gr_stub_openxr_flip;
}
+1 -1
View File
@@ -1,3 +1,3 @@
void gr_stub_init_function_pointers();
bool gr_stub_init();
+7
View File
@@ -15,6 +15,7 @@
#include "cmdline/cmdline.h"
#include "graphics/2d.h"
#include "io/timer.h"
#include "lighting/lighting.h"
#include "lighting/lighting_profiles.h"
#include "math/bitarray.h"
@@ -43,6 +44,12 @@ struct gr_light
int type;
};
//FADEIN STUFF
shader Viewer_shader;
FadeType Fade_type = FadeType::FI_NONE;
TIMESTAMP Fade_start_timestamp = TIMESTAMP::invalid();
TIMESTAMP Fade_end_timestamp = TIMESTAMP::invalid();
// Variables
SCP_vector<gr_light> gr_lights;
graphics::model_light gr_light_uniforms[graphics::MAX_UNIFORM_LIGHTS];
+15
View File
@@ -5,6 +5,20 @@
#include "lighting/lighting.h"
#include "cmdline/cmdline.h"
//-----Fadein stuff
struct shader;
extern shader Viewer_shader;
enum class FadeType {
FI_NONE = 0,
FI_FADEIN,
FI_FADEOUT
};
extern FadeType Fade_type;
extern TIMESTAMP Fade_start_timestamp;
extern TIMESTAMP Fade_end_timestamp;
//Variables
extern int Num_active_gr_lights;
@@ -13,6 +27,7 @@ extern const float gr_light_zero[4];
extern const float gr_light_emission[4];
extern float gr_light_ambient[4];
//Functions
void gr_set_light(light *fs_light);
void gr_reset_lighting();
+70 -24
View File
@@ -6,11 +6,19 @@
#include <direct.h>
#endif
#if !defined __APPLE_CC__ && defined SCP_UNIX
#include<glad/glad_glx.h>
//Required because X defines none and always, which is used later
#undef None
#undef Always
#endif
#include "gropengl.h"
#include "ShaderProgram.h"
#include "gropenglbmpman.h"
#include "gropengldeferred.h"
#include "gropengldraw.h"
#include "gropenglopenxr.h"
#include "gropenglpostprocessing.h"
#include "gropenglquery.h"
#include "gropenglshader.h"
@@ -107,6 +115,18 @@ void gr_opengl_flip()
if (!GL_initted)
return;
if (Cmdline_window_res) {
GL_state.BindFrameBuffer(0, GL_DRAW_FRAMEBUFFER);
GL_state.BindFrameBuffer(Back_framebuffer, GL_READ_FRAMEBUFFER);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_BACK);
glBlitFramebuffer(0, 0, gr_screen.max_w, gr_screen.max_h, 0, 0, Cmdline_window_res->first, Cmdline_window_res->second, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glDrawBuffer(GL_NONE);
GL_state.PopFramebufferState();
}
if (Cmdline_gl_finish)
glFinish();
@@ -123,6 +143,17 @@ void gr_opengl_flip()
#endif
}
void gr_opengl_setup_frame() {
if (!GL_initted)
return;
if (Cmdline_window_res) {
GL_state.PushFramebufferState();
GL_state.BindFrameBuffer(Back_framebuffer);
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
}
}
void gr_opengl_set_clip(int x, int y, int w, int h, int resize_mode)
{
// check for sanity of parameters
@@ -134,7 +165,7 @@ void gr_opengl_set_clip(int x, int y, int w, int h, int resize_mode)
y = 0;
}
int to_resize = (resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)));
int to_resize = (resize_mode != GR_RESIZE_NONE && resize_mode != GR_RESIZE_REPLACE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)));
int max_w = ((to_resize) ? gr_screen.max_w_unscaled : gr_screen.max_w);
int max_h = ((to_resize) ? gr_screen.max_h_unscaled : gr_screen.max_h);
@@ -143,28 +174,30 @@ void gr_opengl_set_clip(int x, int y, int w, int h, int resize_mode)
gr_unsize_screen_pos(&max_w, &max_h);
}
if (x >= max_w) {
x = max_w - 1;
}
if (resize_mode != GR_RESIZE_REPLACE) {
if (x >= max_w) {
x = max_w - 1;
}
if (y >= max_h) {
y = max_h - 1;
}
if (y >= max_h) {
y = max_h - 1;
}
if (x + w > max_w) {
w = max_w - x;
}
if (x + w > max_w) {
w = max_w - x;
}
if (y + h > max_h) {
h = max_h - y;
}
if (y + h > max_h) {
h = max_h - y;
}
if (w > max_w) {
w = max_w;
}
if (w > max_w) {
w = max_w;
}
if (h > max_h) {
h = max_h;
if (h > max_h) {
h = max_h;
}
}
gr_screen.offset_x_unscaled = x;
@@ -901,9 +934,10 @@ int opengl_init_display_device()
return 0;
}
void opengl_setup_function_pointers()
void gr_opengl_init_function_pointers()
{
gr_screen.gf_flip = gr_opengl_flip;
gr_screen.gf_setup_frame = gr_opengl_setup_frame;
gr_screen.gf_set_clip = gr_opengl_set_clip;
gr_screen.gf_reset_clip = gr_opengl_reset_clip;
@@ -1032,6 +1066,13 @@ void opengl_setup_function_pointers()
gr_screen.gf_override_fog = gr_opengl_override_fog;
gr_screen.gf_openxr_get_extensions = gr_opengl_openxr_get_extensions;
gr_screen.gf_openxr_test_capabilities = gr_opengl_openxr_test_capabilities;
gr_screen.gf_openxr_create_session = gr_opengl_openxr_create_session;
gr_screen.gf_openxr_get_swapchain_format = gr_opengl_openxr_get_swapchain_format;
gr_screen.gf_openxr_acquire_swapchain_buffers = gr_opengl_openxr_acquire_swapchain_buffers;
gr_screen.gf_openxr_flip = gr_opengl_openxr_flip;
// NOTE: All function pointers here should have a Cmdline_nohtl check at the top
// if they shouldn't be run in non-HTL mode, Don't keep separate entries.
// *****************************************************************************
@@ -1230,6 +1271,12 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
Error(LOCATION, "Failed to load OpenGL!");
}
#if !defined __APPLE_CC__ && defined SCP_UNIX
if (!gladLoadGLXLoader(GL_context->getLoaderFunction(), nullptr, 0)) {
Error(LOCATION, "Failed to load GLX!");
}
#endif
// version check
GL_version = (GLVersion.major * 10) + GLVersion.minor;
@@ -1262,11 +1309,6 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
}
#endif
// this MUST be done before any other gr_opengl_* or
// opengl_* function calls!!
opengl_setup_function_pointers();
mprintf(( " OpenGL Vendor : %s\n", glGetString(GL_VENDOR) ));
mprintf(( " OpenGL Renderer : %s\n", glGetString(GL_RENDERER) ));
mprintf(( " OpenGL Version : %s\n", glGetString(GL_VERSION) ));
@@ -1346,11 +1388,15 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
Gr_current_green = &Gr_green;
Gr_current_alpha = &Gr_alpha;
gr_setup_frame();
gr_opengl_reset_clip();
gr_opengl_clear();
gr_opengl_flip();
gr_setup_frame();
gr_opengl_clear();
gr_opengl_flip();
gr_setup_frame();
gr_opengl_clear();
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &GL_max_elements_vertices);
+1
View File
@@ -16,6 +16,7 @@
#include "globalincs/pstypes.h"
#include "graphics/grinternal.h"
void gr_opengl_init_function_pointers();
bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps);
void gr_opengl_cleanup(bool closing, int minimize=1);
int opengl_check_for_errors(const char *err_at = NULL);
+212 -121
View File
@@ -1,6 +1,7 @@
#include "gropengldeferred.h"
#include "globalincs/vmallocator.h"
#include "ShaderProgram.h"
#include "gropengldraw.h"
@@ -170,11 +171,42 @@ void gr_opengl_deferred_lighting_end()
GL_state.ColorMask(true, true, true, false);
}
static GLuint deferred_light_cylinder_vbo = 0;
static GLuint deferred_light_cylinder_ibo = 0;
static GLushort deferred_light_cylinder_vcount = 0;
static GLuint deferred_light_cylinder_icount = 0;
static GLuint deferred_light_sphere_vbo = 0;
static GLuint deferred_light_sphere_ibo = 0;
static GLushort deferred_light_sphere_vcount = 0;
static GLuint deferred_light_sphere_icount = 0;
extern SCP_vector<light> Lights;
extern int Num_lights;
namespace ltp = lighting_profiles;
using namespace ltp;
static bool override_fog = false;
graphics::deferred_light_data*
// common conversion operations to translate a game light data structure into a render-ready light uniform.
prepare_light_uniforms(light& l, graphics::util::UniformAligner& uniformAligner)
{
graphics::deferred_light_data* light_data = uniformAligner.addTypedElement<graphics::deferred_light_data>();
light_data->lightType = static_cast<int>(l.type);
vec3d diffuse;
diffuse.xyz.x = l.r * l.intensity;
diffuse.xyz.y = l.g * l.intensity;
diffuse.xyz.z = l.b * l.intensity;
light_data->diffuseLightColor = diffuse;
// Set a default value for all lights. Only the first directional light will change this.
light_data->enable_shadows = false;
light_data->sourceRadius = l.source_radius;
return light_data;
}
void gr_opengl_deferred_lighting_finish()
{
@@ -188,8 +220,8 @@ void gr_opengl_deferred_lighting_finish()
GL_state.SetAlphaBlendMode(ALPHA_BLEND_ADDITIVE);
gr_zbuffer_set(GR_ZBUFF_NONE);
//GL_state.DepthFunc(GL_GREATER);
//GL_state.DepthMask(GL_FALSE);
// GL_state.DepthFunc(GL_GREATER);
// GL_state.DepthMask(GL_FALSE);
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_LIGHTING, 0));
@@ -214,7 +246,7 @@ void gr_opengl_deferred_lighting_finish()
if (Shadow_quality != ShadowQuality::Disabled) {
GL_state.Texture.Enable(4, GL_TEXTURE_2D_ARRAY, Shadow_map_texture);
}
// We need to use stable sorting here to make sure that the relative ordering of the same light types is the same as
// the rest of the code. Otherwise the shadow mapping would be applied while rendering the wrong light which would
// lead to flickering lights in some circumstances
@@ -225,19 +257,43 @@ void gr_opengl_deferred_lighting_finish()
size_t num_data_elements = Lights.size();
// Get a uniform buffer for our data
auto buffer = gr_get_uniform_buffer(uniform_block_type::Lights, num_data_elements);
auto& uniformAligner = buffer.aligner();
auto light_buffer = gr_get_uniform_buffer(uniform_block_type::Lights, num_data_elements);
auto& light_uniform_aligner = light_buffer.aligner();
auto matrix_buffer = gr_get_uniform_buffer(uniform_block_type::Matrices, num_data_elements);
auto& matrix_uniform_aligner = matrix_buffer.aligner();
// This is the light which is responsible for shadows and volumetric nebula lighting
const light* global_light = nullptr;
vec3d global_light_diffuse;
// To allow reduced bind calls, we sort lights into subsets based on rendering methods.
// It might seem optimal to create these subsets as lights are added, or some other method,
// but this keeps the graphics implementation methods better contained and profiling currently
// (dec 2023) shows negligable cost of doing it this way.
SCP_vector<light> full_frame_lights = SCP_vector<light>();
SCP_vector<light> sphere_lights = SCP_vector<light>();
SCP_vector<light> cylinder_lights = SCP_vector<light>();
for (auto& l : Lights) {
switch (l.type) {
case Light_Type::Directional:
full_frame_lights.push_back(l);
break;
case Light_Type::Cone:
FALLTHROUGH;
case Light_Type::Point:
sphere_lights.push_back(l);
break;
case Light_Type::Tube:
cylinder_lights.push_back(l);
break;
}
}
{
GR_DEBUG_SCOPE("Build buffer data");
auto lp = ltp::current();
auto header = uniformAligner.getHeader<deferred_global_data>();
auto header = light_uniform_aligner.getHeader<deferred_global_data>();
if (Shadow_quality != ShadowQuality::Disabled) {
// Avoid this overhead when we are not going to use these values
header->shadow_mv_matrix = Shadow_view_matrix_light;
@@ -258,133 +314,178 @@ void gr_opengl_deferred_lighting_finish()
// Only the first directional light uses shaders so we need to know when we already saw that light
bool first_directional = true;
for (auto& l : Lights) {
auto light_data = uniformAligner.addTypedElement<deferred_light_data>();
light_data->lightType = static_cast<int>(l.type);
for (auto& l : full_frame_lights) {
auto light_data = prepare_light_uniforms(l, light_uniform_aligner);
if (Shadow_quality != ShadowQuality::Disabled) {
light_data->enable_shadows = first_directional ? 1 : 0;
}
vec3d diffuse;
diffuse.xyz.x = l.r * l.intensity;
diffuse.xyz.y = l.g * l.intensity;
diffuse.xyz.z = l.b * l.intensity;
// Global light direction should match shadow light direction
if (first_directional) {
global_light = &l;
global_light_diffuse = light_data->diffuseLightColor;
}
light_data->diffuseLightColor = diffuse;
vec4 light_dir;
light_dir.xyzw.x = -l.vec.xyz.x;
light_dir.xyzw.y = -l.vec.xyz.y;
light_dir.xyzw.z = -l.vec.xyz.z;
light_dir.xyzw.w = 0.0f;
vec4 view_dir;
// Set a default value for all lights. Only the first directional light will change this.
light_data->enable_shadows = false;
light_data->sourceRadius = l.source_radius;
vm_vec_transform(&view_dir, &light_dir, &gr_view_matrix);
switch (l.type) {
case Light_Type::Directional:
if (Shadow_quality != ShadowQuality::Disabled) {
light_data->enable_shadows = first_directional ? 1 : 0;
}
light_data->lightDir.xyz.x = view_dir.xyzw.x;
light_data->lightDir.xyz.y = view_dir.xyzw.y;
light_data->lightDir.xyz.z = view_dir.xyzw.z;
// Global light direction should match shadow light direction
if (first_directional) {
global_light = &l;
global_light_diffuse = diffuse;
}
vec4 light_dir;
light_dir.xyzw.x = -l.vec.xyz.x;
light_dir.xyzw.y = -l.vec.xyz.y;
light_dir.xyzw.z = -l.vec.xyz.z;
light_dir.xyzw.w = 0.0f;
vec4 view_dir;
first_directional = false;
}
for (auto& l : sphere_lights) {
auto light_data = prepare_light_uniforms(l, light_uniform_aligner);
vm_vec_transform(&view_dir, &light_dir, &gr_view_matrix);
light_data->lightDir.xyz.x = view_dir.xyzw.x;
light_data->lightDir.xyz.y = view_dir.xyzw.y;
light_data->lightDir.xyz.z = view_dir.xyzw.z;
first_directional = false;
break;
case Light_Type::Cone:
if (l.type == Light_Type::Cone) {
light_data->dualCone = l.dual_cone ? 1.0f : 0.0f;
light_data->coneAngle = l.cone_angle;
light_data->coneInnerAngle = l.cone_inner_angle;
light_data->coneDir = l.vec2;
FALLTHROUGH;
case Light_Type::Point: {
float rad = (Lighting_mode == lighting_mode::COCKPIT) ? lp->cockpit_light_radius_modifier.handle(MAX(l.rada, l.radb)) : MAX(l.rada, l.radb);
light_data->lightRadius = rad;
//A small padding factor is added to guard against potentially clipping the edges of the light with facets of the volume mesh.
light_data->scale.xyz.x = rad * 1.05f;
light_data->scale.xyz.y = rad * 1.05f;
light_data->scale.xyz.z = rad * 1.05f;
break;
}
case Light_Type::Tube: {
float rad = (Lighting_mode == lighting_mode::COCKPIT) ? lp->cockpit_light_radius_modifier.handle(l.radb) : l.radb;
light_data->lightRadius = rad;
light_data->lightType = LT_TUBE;
vec3d a;
vm_vec_sub(&a, &l.vec, &l.vec2);
auto length = vm_vec_mag(&a);
//Tube light volumes must be extended past the length of their requested light vector
//to allow smooth fall-off from all angles. Since the light volume starts at the mesh
//origin we must extend it here. Later the position will be adjusted as well.
length += light_data->lightRadius * 2.0f;
//A small padding factor is added to guard against potentially clipping the edges of the light with facets of the volume mesh.
light_data->scale.xyz.x = rad * 1.05f;
light_data->scale.xyz.y = rad * 1.05f;
light_data->scale.xyz.z = length;
break;
}
}
float rad = (Lighting_mode == lighting_mode::COCKPIT)
? lp->cockpit_light_radius_modifier.handle(MAX(l.rada, l.radb))
: MAX(l.rada, l.radb);
light_data->lightRadius = rad;
// A small padding factor is added to guard against potentially clipping the edges of the light with facets
// of the volume mesh.
light_data->scale.xyz.x = rad * 1.05f;
light_data->scale.xyz.y = rad * 1.05f;
light_data->scale.xyz.z = rad * 1.05f;
}
for (auto& l : cylinder_lights) {
auto light_data = prepare_light_uniforms(l, light_uniform_aligner);
float rad =
(Lighting_mode == lighting_mode::COCKPIT) ? lp->cockpit_light_radius_modifier.handle(l.radb) : l.radb;
light_data->lightRadius = rad;
light_data->lightType = LT_TUBE;
vec3d a;
vm_vec_sub(&a, &l.vec, &l.vec2);
auto length = vm_vec_mag(&a);
// Tube light volumes must be extended past the length of their requested light vector
// to allow smooth fall-off from all angles. Since the light volume starts at the mesh
// origin we must extend it here. Later the position will be adjusted as well.
length += light_data->lightRadius * 2.0f;
// A small padding factor is added to guard against potentially clipping the edges of the light with facets
// of the volume mesh.
light_data->scale.xyz.x = rad * 1.05f;
light_data->scale.xyz.y = rad * 1.05f;
light_data->scale.xyz.z = length;
}
// Uniform data has been assembled, upload it to the GPU and issue the draw calls
buffer.submitData();
light_buffer.submitData();
}
{
for (size_t i = 0; i<full_frame_lights.size(); i++) {
// just keeping things aligned really.
matrix_uniform_aligner.addTypedElement<graphics::matrix_uniforms>();
}
for (auto& l : sphere_lights) {
auto matrix_data = matrix_uniform_aligner.addTypedElement<graphics::matrix_uniforms>();
g3_start_instance_matrix(&l.vec, &vmd_identity_matrix, true);
matrix_data->modelViewMatrix = gr_model_view_matrix;
matrix_data->projMatrix = gr_projection_matrix;
g3_done_instance(true);
}
for (auto& l : cylinder_lights ) {
auto matrix_data = matrix_uniform_aligner.addTypedElement<graphics::matrix_uniforms>();
vec3d dir, newPos;
matrix orient;
vm_vec_sub(&dir, &l.vec, &l.vec2);
vm_vector_2_matrix(&orient, &dir, nullptr, nullptr);
// Tube light volumes must be extended past the length of their requested light vector
// to allow smooth fall-off from all angles. Since the light volume starts at the mesh
// origin we must extend it, which has been done above, and then move it backwards one radius.
vm_vec_normalize(&dir);
vm_vec_scale_sub(&newPos, &l.vec2, &dir, l.radb);
g3_start_instance_matrix(&newPos, &orient, true);
matrix_data->modelViewMatrix = gr_model_view_matrix;
matrix_data->projMatrix = gr_projection_matrix;
g3_done_instance(true);
}
matrix_buffer.submitData();
}
{
GR_DEBUG_SCOPE("Render light geometry");
gr_bind_uniform_buffer(uniform_block_type::DeferredGlobals, buffer.getBufferOffset(0),
sizeof(graphics::deferred_global_data), buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::DeferredGlobals,
light_buffer.getBufferOffset(0),
sizeof(graphics::deferred_global_data),
light_buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::Matrices,
matrix_buffer.getBufferOffset(0),
sizeof(graphics::matrix_uniforms),
matrix_buffer.bufferHandle());
size_t element_index = 0;
for (auto& l : Lights) {
GR_DEBUG_SCOPE("Deferred apply single light");
vertex_layout vertex_declare;
vertex_declare.add_vertex_component(vertex_format_data::POSITION3, sizeof(float) * 3, 0);
switch (l.type) {
case Light_Type::Directional:
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data), buffer.bufferHandle());
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
++element_index;
break;
case Light_Type::Cone:
case Light_Type::Point:
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data), buffer.bufferHandle());
gr_opengl_draw_deferred_light_sphere(&l.vec);
++element_index;
break;
case Light_Type::Tube:
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data), buffer.bufferHandle());
for (size_t i = 0; i<full_frame_lights.size(); i++) {
GR_DEBUG_SCOPE("Deferred apply single dir light");
vec3d dir, newPos;
matrix orient;
vm_vec_sub(&dir, &l.vec, &l.vec2);
vm_vector_2_matrix(&orient, &dir, nullptr, nullptr);
//Tube light volumes must be extended past the length of their requested light vector
//to allow smooth fall-off from all angles. Since the light volume starts at the mesh
//origin we must extend it, which has been done above, and then move it backwards one radius.
vm_vec_normalize(&dir);
vm_vec_scale_sub(&newPos, &l.vec2, &dir, l.radb);
gr_opengl_draw_deferred_light_cylinder(&newPos, &orient);
++element_index;
break;
default:
continue;
}
gr_bind_uniform_buffer(uniform_block_type::Lights,
light_buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data),
light_buffer.bufferHandle());
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
++element_index;
}
if (!sphere_lights.empty()) {
opengl_bind_vertex_layout(vertex_declare, deferred_light_sphere_vbo, deferred_light_sphere_ibo);
}
for (size_t i = 0; i<sphere_lights.size(); i++) {
gr_bind_uniform_buffer(uniform_block_type::Lights,
light_buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data),
light_buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::Matrices,
matrix_buffer.getAlignerElementOffset(element_index),
sizeof(graphics::matrix_uniforms),
matrix_buffer.bufferHandle());
glDrawRangeElements(GL_TRIANGLES,
0,
deferred_light_sphere_vcount,
deferred_light_sphere_icount,
GL_UNSIGNED_SHORT,
0);
opengl_draw_sphere();
++element_index;
}
if (!cylinder_lights.empty()) {
opengl_bind_vertex_layout(vertex_declare, deferred_light_cylinder_vbo, deferred_light_cylinder_ibo);
}
for (size_t i = 0; i<cylinder_lights.size(); i++) {
gr_bind_uniform_buffer(uniform_block_type::Lights,
light_buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data),
light_buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::Matrices,
matrix_buffer.getAlignerElementOffset(element_index),
sizeof(graphics::matrix_uniforms),
matrix_buffer.bufferHandle());
glDrawRangeElements(GL_TRIANGLES,
0,
deferred_light_cylinder_vcount,
deferred_light_cylinder_icount,
GL_UNSIGNED_SHORT,
0);
++element_index;
}
}
@@ -535,11 +636,6 @@ void gr_opengl_draw_deferred_light_sphere(const vec3d *position)
}
static GLuint deferred_light_cylinder_vbo = 0;
static GLuint deferred_light_cylinder_ibo = 0;
static GLushort deferred_light_cylinder_vcount = 0;
static GLuint deferred_light_cylinder_icount = 0;
void gr_opengl_deferred_light_cylinder_init(int segments) // Generate a VBO of a cylinder of radius and height 1.0f, based on code at http://www.ogre3d.org/tikiwiki/ManualSphereMeshes
{
unsigned int nVertex = (segments + 1) * 2 * 3 + 6; // Can someone verify this?
@@ -656,11 +752,6 @@ void gr_opengl_deferred_light_cylinder_init(int segments) // Generate a VBO of a
Vertices = nullptr;
}
static GLuint deferred_light_sphere_vbo = 0;
static GLuint deferred_light_sphere_ibo = 0;
static GLushort deferred_light_sphere_vcount = 0;
static GLuint deferred_light_sphere_icount = 0;
void gr_opengl_deferred_light_sphere_init(int rings, int segments) // Generate a VBO of a sphere of radius 1.0f, based on code at http://www.ogre3d.org/tikiwiki/ManualSphereMeshes
{
unsigned int nVertex = (rings + 1) * (segments+1) * 3;
+4
View File
@@ -1,6 +1,9 @@
#pragma once
#include "globalincs/pstypes.h"
#include "graphics/util/UniformAligner.h"
#include "graphics/util/uniform_structs.h"
#include "lighting/lighting.h"
void gr_opengl_deferred_init();
@@ -9,6 +12,7 @@ void gr_opengl_deferred_lighting_begin(bool clearNonColorBufs = false);
void gr_opengl_deferred_lighting_msaa();
void gr_opengl_deferred_lighting_end();
void gr_opengl_deferred_lighting_finish();
graphics::deferred_light_data* prepare_light_uniforms(light& l, graphics::util::UniformAligner& uniformAligner);
void gr_opengl_deferred_light_sphere_init(int rings, int segments);
void gr_opengl_deferred_light_cylinder_init(int segments);
+51
View File
@@ -50,6 +50,10 @@ GLuint Scene_depth_texture_ms;
GLuint Cockpit_depth_texture;
GLuint Scene_stencil_buffer;
GLuint Back_framebuffer;
GLuint Back_texture;
GLuint Back_depth_texture;
GLuint Distortion_framebuffer = 0;
GLuint Distortion_texture[2];
int Distortion_switch = 0;
@@ -525,6 +529,53 @@ void opengl_setup_scene_textures()
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
}
if (Cmdline_window_res) {
//Gen Framebuffer
glGenFramebuffers(1, &Back_framebuffer);
GL_state.BindFrameBuffer(Back_framebuffer);
opengl_set_object_label(GL_FRAMEBUFFER, Back_framebuffer, "Backbuffer");
// setup main render texture
// setup high dynamic range color texture
glGenTextures(1, &Back_texture);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Back_texture);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, gr_screen.max_w, gr_screen.max_h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Back_texture, 0);
opengl_set_object_label(GL_TEXTURE, Back_texture, "Backbuffer texture");
glGenTextures(1, &Back_depth_texture);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Back_depth_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, gr_screen.max_w, gr_screen.max_h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
opengl_set_object_label(GL_TEXTURE, Back_depth_texture, "Backbuffer depth texture");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Back_depth_texture, 0);
gr_zbuffer_set(GR_ZBUFF_FULL);
glClear(GL_DEPTH_BUFFER_BIT);
}
//Setup thruster distortion framebuffer
if (Gr_framebuffer_effects.any_set())
{
+3
View File
@@ -38,6 +38,9 @@ extern GLuint Scene_depth_texture_ms;
extern GLuint Cockpit_depth_texture;
extern GLuint Scene_stencil_buffer;
extern GLuint Back_framebuffer;
extern GLuint Back_texture;
void gr_opengl_update_distortion();
void gr_opengl_sphere(material *material_def, float rad);
+471
View File
@@ -0,0 +1,471 @@
#include "gropenglopenxr.h"
#include "io/cursor.h"
#include "io/mouse.h"
#include "graphics/matrix.h"
#include "graphics/opengl/gropengl.h"
#include "graphics/opengl/gropengldraw.h"
#include "graphics/opengl/gropenglshader.h"
#include "graphics/opengl/gropenglstate.h"
#include "graphics/opengl/ShaderProgram.h"
#include "osapi/osapi.h"
#ifdef WIN32
#define XR_USE_PLATFORM_WIN32
#include <unknwn.h>
#elif defined __APPLE_CC__
//Not supported
#elif defined SCP_UNIX
#define XR_USE_PLATFORM_XLIB
#include<X11/Xlib.h>
#include<glad/glad_glx.h>
#endif
#define XR_USE_GRAPHICS_API_OPENGL
#include "graphics/openxr_internal.h"
#include <SDL_syswm.h>
#ifndef __APPLE_CC__
//SETUP FUNCTIONS OGL
SCP_vector<const char*> gr_opengl_openxr_get_extensions() {
return { XR_KHR_OPENGL_ENABLE_EXTENSION_NAME };
}
bool gr_opengl_openxr_test_capabilities() {
XrGraphicsRequirementsOpenGLKHR requirements{
XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR,
nullptr,
0,
0
};
if (openxr_callExtensionFunction<PFN_xrGetOpenGLGraphicsRequirementsKHR>("xrGetOpenGLGraphicsRequirementsKHR", xr_instance, xr_system, &requirements) != XR_SUCCESS) {
mprintf(("Failed to query OpenXR graphics requirements!\n"));
return false;
}
if (requirements.minApiVersionSupported > XR_MAKE_VERSION(GLVersion.major, GLVersion.minor, 0)) {
mprintf(("System doesn't meet OpenXR graphics requirements (min %" PRIu64 ", available %" PRIu64 ")!\n", requirements.minApiVersionSupported, static_cast<XrVersion>(XR_MAKE_VERSION(GLVersion.major, GLVersion.minor, 0))));
return false;
}
return true;
}
#ifdef WIN32
bool gr_opengl_openxr_create_session() {
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(os::getSDLMainWindow(), &wmInfo);
XrGraphicsBindingOpenGLWin32KHR graphicsBinding{
XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR,
nullptr,
wmInfo.info.win.hdc,
(HGLRC) SDL_GL_GetCurrentContext() //uuuuuugly, and not technically allowed by the standard, but this "opaque" SDL_GLContext type is just the hGLRC on Win32
};
XrSessionCreateInfo sessionCreateInfo{
XR_TYPE_SESSION_CREATE_INFO,
&graphicsBinding,
0,
xr_system
};
XrResult sessionInit = xrCreateSession(xr_instance, &sessionCreateInfo, &xr_session);
if (sessionInit != XR_SUCCESS) {
mprintf(("Failed to create OpenXR session with code %d\n", static_cast<int>(sessionInit)));
return false;
}
return true;
}
#elif defined SCP_UNIX
bool gr_opengl_openxr_create_session() {
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(os::getSDLMainWindow(), &wmInfo);
XWindowAttributes wa;
XGetWindowAttributes(wmInfo.info.x11.display, wmInfo.info.x11.window, &wa);
GLXContext glxcontext = (GLXContext) SDL_GL_GetCurrentContext(); //uuuuuugly, and not technically allowed by the standard, but this "opaque" SDL_GLContext type is just the GLXContext on X11
int glxfbconfigid, glxscreenid, nfbconfigs;
glXQueryContext(wmInfo.info.x11.display, glxcontext, GLX_FBCONFIG_ID, &glxfbconfigid);
glXQueryContext(wmInfo.info.x11.display, glxcontext, GLX_SCREEN, &glxscreenid);
const int fbconfigattrs[] = {GLX_FBCONFIG_ID, glxfbconfigid, None};
GLXFBConfig* fbconfigs = glXChooseFBConfig(wmInfo.info.x11.display, glxscreenid, fbconfigattrs, &nfbconfigs);
if (nfbconfigs < 1) {
mprintf(("Unable to find Linux FBConfig for OpenXR!\n"));
return false;
}
XrGraphicsBindingOpenGLXlibKHR graphicsBinding {
XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR,
nullptr,
wmInfo.info.x11.display,
static_cast<uint32_t>(XVisualIDFromVisual(wa.visual)),
fbconfigs[0],
glXGetCurrentDrawable(),
glxcontext
};
XrSessionCreateInfo sessionCreateInfo {
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO,
sessionCreateInfo.next = &graphicsBinding,
sessionCreateInfo.createFlags = 0,
sessionCreateInfo.systemId = xr_system
};
XrResult sessionInit = xrCreateSession(xr_instance, &sessionCreateInfo, &xr_session);
if (sessionInit != XR_SUCCESS) {
mprintf(("Failed to create OpenXR session with code %d\n", static_cast<int>(sessionInit)));
return false;
}
return true;
}
#endif
int64_t gr_opengl_openxr_get_swapchain_format(const SCP_vector<int64_t>& allowed) {
//We prefer whatever our backbuffer is
if (std::find(allowed.cbegin(), allowed.cend(), GL_RGBA16F) != allowed.cend())
return GL_RGBA16F;
//Otherwise, Fallback
return allowed.front();
}
//PIPELINE FUNCTIONS OGL
std::array<SCP_vector<XrSwapchainImageOpenGLKHR>, 2> swapchainImages;
GLuint xr_fbo;
GLuint xr_swap_tex;
bool gr_opengl_openxr_acquire_swapchain_buffers() {
// create framebuffer
glGenFramebuffers(1, &xr_fbo);
GL_state.BindFrameBuffer(xr_fbo);
opengl_set_object_label(GL_FRAMEBUFFER, xr_fbo, "XR Swapchain");
//While blitting from the backbuffer is fine for the 3d-scenes, when we render a flat scene, we need to bind the backbuffer as a texture.
//Since that doesn't work, we need an intermediary. Not pretty, but it doesn't need to be for the flat scenes
glGenTextures(1, &xr_swap_tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(xr_swap_tex);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, gr_screen.max_w, gr_screen.max_h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, xr_swap_tex, 0);
opengl_set_object_label(GL_TEXTURE, xr_swap_tex, "XR Swap Texture");
for (uint32_t i = 0; i < 2; i++) {
uint32_t imageCount = 0;
XrResult swapchainAcq = xrEnumerateSwapchainImages(xr_swapchains[i]->swapchain, 0, &imageCount, nullptr);
if (swapchainAcq != XR_SUCCESS) {
mprintf(("Failed to acquire OpenXR swapchain %d with code %d\n", i, static_cast<int>(swapchainAcq)));
return false;
}
swapchainImages[i] = SCP_vector<XrSwapchainImageOpenGLKHR>(imageCount, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR, nullptr, 0 });
swapchainAcq = xrEnumerateSwapchainImages(xr_swapchains[i]->swapchain, imageCount, &imageCount, (XrSwapchainImageBaseHeader*)swapchainImages[i].data());
if (swapchainAcq != XR_SUCCESS) {
mprintf(("Failed to acquire OpenXR swapchain %d with code %d\n", i, static_cast<int>(swapchainAcq)));
return false;
}
}
return true;
}
bool gr_opengl_openxr_flip() {
if (!openxr_enabled())
return false;
static bool was_multiframe = false;
//If a stereoscopic frame has started, we're good. Otherwise, this is a normal frame that still needs to be OpenXR-Initialized
//In addition, since we don't actually blit one backbuffer per eye in monoframe mode, we need to make a copy of it to a readable texture now.
if (xr_stage == OpenXRFBStage::NONE) {
openxr_start_frame();
GR_DEBUG_SCOPE("XR Blit");
GL_state.PushFramebufferState();
GL_state.BindFrameBuffer(Cmdline_window_res ? Back_framebuffer : 0, GL_READ_FRAMEBUFFER);
GL_state.BindFrameBuffer(xr_fbo, GL_DRAW_FRAMEBUFFER);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, xr_swap_tex, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glReadBuffer(Cmdline_window_res ? GL_COLOR_ATTACHMENT0 : GL_BACK);
glBlitFramebuffer(0, 0, gr_screen.max_w, gr_screen.max_h, 0, 0, gr_screen.max_w, gr_screen.max_h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glDrawBuffer(GL_NONE);
GL_state.PopFramebufferState();
if (was_multiframe) {
openxr_reset_offset();
was_multiframe = false;
}
}
else
was_multiframe = true;
uint32_t startFrame = xr_stage == OpenXRFBStage::SECOND ? 1 : 0;
uint32_t endFrame = xr_stage == OpenXRFBStage::FIRST ? 1 : 2;
for (uint32_t i = startFrame; i < endFrame; i++) {
XrSwapchain swapchain = xr_swapchains[i]->swapchain;
XrSwapchainImageAcquireInfo acquireImageInfo {
XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO,
nullptr
};
uint32_t activeIndex;
xrAcquireSwapchainImage(swapchain, &acquireImageInfo, &activeIndex);
XrSwapchainImageWaitInfo waitImageInfo{
waitImageInfo.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO,
nullptr,
waitImageInfo.timeout = std::numeric_limits<int64_t>::max()
};
xrWaitSwapchainImage(swapchain, &waitImageInfo);
const XrSwapchainImageOpenGLKHR& image = swapchainImages[i][activeIndex];
//Monoframe mode: We only have one image that FSO just tried to flip. We have it in a readable texture which we'll now render as a flat plane in a fake 3D scene directly to the swapchain
if (xr_stage == OpenXRFBStage::NONE) {
GR_DEBUG_SCOPE("XR Plane");
GL_state.PushFramebufferState();
GL_state.BindFrameBuffer(xr_fbo);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, image.image, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, xr_swap_tex);
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_COPY_WORLD, 0));
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
const auto& pos = xr_views[i].pose.position;
const auto& ori = xr_views[i].pose.orientation;
vec3d position{{ { pos.x, pos.y, -pos.z } }};
position -= xr_offset;
matrix orientation;
vm_quaternion_to_matrix(&orientation, ori.x, ori.y, -ori.z, -ori.w);
gr_set_clip(0, 0, xr_swapchains[i]->width, xr_swapchains[i]->height, GR_RESIZE_REPLACE);
gr_set_proj_matrix(asymmetric_fov {
xr_views[i].fov.angleLeft,
xr_views[i].fov.angleRight,
xr_views[i].fov.angleUp,
xr_views[i].fov.angleDown
}, i2fl(xr_swapchains[i]->width) / i2fl(xr_swapchains[i]->height), 0.01f, 1000);
gr_set_view_matrix(&position, &orientation);
glViewport(0, 0, xr_swapchains[i]->width, xr_swapchains[i]->height);
GL_state.ScissorTest(GL_FALSE);
GL_state.SetZbufferType(gr_zbuffer_type::ZBUFFER_TYPE_NONE);
GLfloat v[4][5] = {
{
-2.0f * gr_screen.clip_aspect, -2.0f, 4, 0, 0
},
{
2.0f * gr_screen.clip_aspect, -2.0f, 4, 1, 0
},
{
2.0f * gr_screen.clip_aspect, 2.0f, 4, 1, 1
},
{
-2.0f * gr_screen.clip_aspect, 2.0f, 4, 0, 1
}
};
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION3, sizeof(GLfloat) * 5, 0);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD2, sizeof(GLfloat) * 5, sizeof(GLfloat) * 3);
gr_matrix_set_uniforms();
gr_set_clear_color(20, 20, 20);
gr_clear();
gr_set_clear_color(0, 0, 0);
opengl_render_primitives_immediate(PRIM_TYPE_TRIFAN, &vert_def, 4, v, sizeof(v));
//And if we have a curser, it also needs to be put onscreen manually
if (io::mouse::CursorManager::get()->isCursorShown()) {
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_COPY_WORLD, SDR_FLAG_COPY_FROM_ARRAY));
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
float u_scale, v_scale;
uint32_t array_index;
int mouse_bm = io::mouse::CursorManager::get()->getCurrentCursor()->getBitmapHandle();
int mousex, mousey, mousew, mouseh;
bm_get_info(mouse_bm, &mousew, &mouseh);
gr_opengl_tcache_set(mouse_bm, TCACHE_TYPE_INTERFACE, &u_scale, &v_scale, &array_index);
mouse_get_pos(&mousex, &mousey);
float mouse_unscaled_x = i2fl(mousex) / i2fl(gr_screen.max_w) * 2.0f - 1.0f;
float mouse_unscaled_y = i2fl(mousey) / i2fl(gr_screen.max_h) * -2.0f + 1.0f;
float mouse_unscaled_w = i2fl(mousew) / i2fl(gr_screen.max_w);
float mouse_unscaled_h = i2fl(mouseh) / i2fl(gr_screen.max_h);
float left = 2.0f * gr_screen.clip_aspect * mouse_unscaled_x;
float right = left + 4.0f * gr_screen.clip_aspect * mouse_unscaled_w;
float top = 2.0f * mouse_unscaled_y;
float bottom = top - 4.0f * mouse_unscaled_h;
GLfloat vmouse[4][5] = {
{
left, bottom, 4, 0, 1
},
{
right, bottom, 4, 1, 1
},
{
right, top, 4, 1, 0
},
{
left, top, 4, 0, 0
}
};
opengl_render_primitives_immediate(PRIM_TYPE_TRIFAN, &vert_def, 4, vmouse, sizeof(vmouse));
}
gr_end_proj_matrix();
gr_end_view_matrix();
gr_reset_clip();
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
GL_state.Texture.Enable(0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0);
glDrawBuffer(GL_NONE);
GL_state.PopFramebufferState();
}
//If we are in stereo mode, we just need to take the current backbuffer and blit it to the proper swapchain target
else {
GR_DEBUG_SCOPE("XR Blit");
GL_state.PushFramebufferState();
GL_state.BindFrameBuffer(Cmdline_window_res ? Back_framebuffer : 0, GL_READ_FRAMEBUFFER);
GL_state.BindFrameBuffer(xr_fbo, GL_DRAW_FRAMEBUFFER);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, image.image, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glReadBuffer(Cmdline_window_res ? GL_COLOR_ATTACHMENT0 : GL_BACK);
glBlitFramebuffer(0, 0, gr_screen.max_w, gr_screen.max_h, 0, 0, xr_swapchains[i]->width, xr_swapchains[i]->height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0);
glDrawBuffer(GL_NONE);
GL_state.PopFramebufferState();
}
XrSwapchainImageReleaseInfo releaseImageInfo {
XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO,
nullptr
};
xrReleaseSwapchainImage(swapchain, &releaseImageInfo);
}
switch (xr_stage) {
case OpenXRFBStage::FIRST:
//We just rendered the first part of a stereo image. We now need to follow up with another one for the other eye
xr_stage = OpenXRFBStage::SECOND;
return true;
case OpenXRFBStage::SECOND:
case OpenXRFBStage::NONE:
//We just rendered the second part of a stereo image or a mono image. Barring further instruction, the next image may be mono again.
//Also, since that means we're done with whatever we just rendered, finish this frame
xr_stage = OpenXRFBStage::NONE;
break;
}
XrCompositionLayerProjectionView projectedViews[2];
for (uint32_t i = 0; i < 2; i++)
{
projectedViews[i].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
projectedViews[i].next = nullptr;
projectedViews[i].pose = xr_views[i].pose;
projectedViews[i].fov = xr_views[i].fov;
projectedViews[i].subImage = {
xr_swapchains[i]->swapchain,
{
{ 0, 0 },
{ (int32_t)xr_swapchains[i]->width, (int32_t)xr_swapchains[i]->height }
},
0
};
}
XrCompositionLayerProjection layer {
XR_TYPE_COMPOSITION_LAYER_PROJECTION,
nullptr,
0,
xr_space,
2,
projectedViews
};
auto pLayer = (const XrCompositionLayerBaseHeader*)&layer;
XrFrameEndInfo frameEndInfo {
XR_TYPE_FRAME_END_INFO,
nullptr,
xr_state.predictedDisplayTime,
XR_ENVIRONMENT_BLEND_MODE_OPAQUE,
0,
nullptr
};
if (xr_state.shouldRender) {
frameEndInfo.layerCount = 1;
frameEndInfo.layers = &pLayer;
}
xrEndFrame(xr_session, &frameEndInfo);
return false;
}
#else
//Stubs for Mac, as linking with OpenXR causes issues there.
SCP_vector<const char*> gr_opengl_openxr_get_extensions() { return SCP_vector<const char*>{}; }
bool gr_opengl_openxr_test_capabilities() { return false; }
bool gr_opengl_openxr_create_session() { return false; }
int64_t gr_opengl_openxr_get_swapchain_format(const SCP_vector<int64_t>& allowed) { return 0; }
bool gr_opengl_openxr_acquire_swapchain_buffers() { return false; }
bool gr_opengl_openxr_flip() { return false; }
#endif
+8
View File
@@ -0,0 +1,8 @@
#pragma once
SCP_vector<const char*> gr_opengl_openxr_get_extensions();
bool gr_opengl_openxr_test_capabilities();
bool gr_opengl_openxr_create_session();
int64_t gr_opengl_openxr_get_swapchain_format(const SCP_vector<int64_t>& allowed);
bool gr_opengl_openxr_acquire_swapchain_buffers();
bool gr_opengl_openxr_flip();
@@ -13,6 +13,7 @@
#include "cmdline/cmdline.h"
#include "def_files/def_files.h"
#include "graphics/grinternal.h"
#include "graphics/openxr.h"
#include "graphics/util/uniform_structs.h"
#include "io/timer.h"
#include "lighting/lighting.h"
@@ -66,7 +67,7 @@ void opengl_post_pass_tonemap()
GR_DEBUG_SCOPE("Tonemapping");
TRACE_SCOPE(tracing::Tonemapping);
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_TONEMAPPING, 0));
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_TONEMAPPING, openxr_enabled() ? SDR_FLAG_TONEMAPPING_LINEAR_OUT : 0));
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
+8 -1
View File
@@ -155,6 +155,9 @@ static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_COPY, "post-v.sdr", "copy-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Texture copy", false },
{ SDR_TYPE_COPY_WORLD, "passthrough-v.sdr", "copy-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Texture copy world space", false },
{ SDR_TYPE_MSAA_RESOLVE, "post-v.sdr", "msaa-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "MSAA resolve shader", false },
@@ -207,7 +210,11 @@ static opengl_shader_variant_t GL_shader_variants[] = {
{SDR_TYPE_VOLUMETRIC_FOG, false, SDR_FLAG_VOLUMETRICS_DO_EDGE_SMOOTHING, "DO_EDGE_SMOOTHING", {}, "Perform costly edge smoothing lookups"},
{SDR_TYPE_VOLUMETRIC_FOG, false, SDR_FLAG_VOLUMETRICS_NOISE, "NOISE", {}, "Add noise to volumetrics"}
{SDR_TYPE_VOLUMETRIC_FOG, false, SDR_FLAG_VOLUMETRICS_NOISE, "NOISE", {}, "Add noise to volumetrics"},
{SDR_TYPE_COPY_WORLD, false, SDR_FLAG_COPY_FROM_ARRAY, "COPY_ARRAY", {}, "Expects to copy from an array texture"},
{SDR_TYPE_POST_PROCESS_TONEMAPPING, false, SDR_FLAG_TONEMAPPING_LINEAR_OUT, "LINEAR_OUT", {}, "Will make the tonemapper output in linear color space and not in sRGB"}
};
static const int GL_num_shader_variants = sizeof(GL_shader_variants) / sizeof(opengl_shader_variant_t);
+8 -2
View File
@@ -14,6 +14,7 @@
#define BMPMAN_INTERNAL
#include "gropenglstate.h"
#include "gropengltexture.h"
#include "gropengldraw.h"
#include "bmpman/bm_internal.h"
#include "bmpman/bmpman.h"
#include "cmdline/cmdline.h"
@@ -1704,8 +1705,13 @@ int opengl_set_render_target( int slot, int face, int is_static )
}
}
GL_state.BindFrameBuffer(0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if(Cmdline_window_res) {
GL_state.BindFrameBuffer(Back_framebuffer);
}
else {
GL_state.BindFrameBuffer(0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
// done with this render target so lets move on
render_target = NULL;
+548
View File
@@ -0,0 +1,548 @@
#include "openxr_internal.h"
#include "camera/camera.h"
#include "graphics/2d.h"
#include "globalincs/version.h"
#include "mod_table/mod_table.h"
#include "render/3d.h"
#include "starfield/starfield.h"
std::unique_ptr<star[]> Stars_XRBuffer;
#ifndef __APPLE_CC__
#define XR_MAKE_VERSION_SHORT(major, minor, patch) \
((((major) & 0x3ffU) << 20) | (((minor) & 0x3ffU) << 10) | ((patch) & 0x3ffU))
bool openxr_req = false;
bool openxr_initialized = false;
bool openxr_recieve = false;
XrInstance xr_instance;
XrSystemId xr_system;
XrSession xr_session;
XrSpace xr_space;
XrTime xr_time;
XrDebugUtilsMessengerEXT xr_debugMessenger;
std::array<std::unique_ptr<XrSwapchainHandler>, 2> xr_swapchains;
std::array<XrView, 2> xr_views;
std::array<XrViewConfigurationView, 2> xr_configurationviews;
vec3d xr_offset = ZERO_VECTOR;
XrFrameState xr_state;
OpenXRFBStage xr_stage = OpenXRFBStage::NONE;
float xr_scale = 1.0f;
#if !defined(NDEBUG) && defined(FS_OPENXR_DEBUG)
static XrBool32 handleXRError(XrDebugUtilsMessageSeverityFlagsEXT severity, XrDebugUtilsMessageTypeFlagsEXT type, const XrDebugUtilsMessengerCallbackDataEXT* callbackData, void* /*userData*/) {
SCP_string message;
switch (type)
{
case XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
message = "OpenXR: general\n%s";
break;
case XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT:
message = "OpenXR: validation\n%s";
break;
case XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
message = "OpenXR: performance\n%s";
break;
case XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT:
message = "OpenXR: conformance\n%s";
break;
}
switch (severity)
{
case XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
case XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
Information(LOCATION, message.c_str(), callbackData->message);
break;
case XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
Warning(LOCATION, message.c_str(), callbackData->message);
break;
case XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
Error(LOCATION, message.c_str(), callbackData->message);
break;
}
return XR_FALSE;
}
#endif
void openxr_prepare(float hudscale) {
Hud_global_scale = hudscale;
openxr_req = true;
}
static bool openxr_init_instance() {
auto extensions = gr_openxr_get_extensions();
const gameversion::version& fso_version = gameversion::get_executable_version();
const gameversion::version& mod_version(Mod_version);
#if !defined(NDEBUG) && defined(FS_OPENXR_DEBUG)
extensions.emplace_back("XR_EXT_debug_utils");
#endif
XrInstanceCreateInfo instanceCreateInfo {
XR_TYPE_INSTANCE_CREATE_INFO,
nullptr,
0,
XrApplicationInfo {
"", //Modname
//Mod version. Should not contain negative numbers or only 0's.
XR_MAKE_VERSION_SHORT(mod_version.major < 1 ? 1U : static_cast<uint32_t>(mod_version.major),
mod_version.minor < 0 ? 0U : static_cast<uint32_t>(mod_version.minor),
mod_version.build < 0 ? 0U : static_cast<uint32_t>(mod_version.build)),
"FreeSpace Open",
XR_MAKE_VERSION_SHORT(static_cast<uint32_t>(fso_version.major), static_cast<uint32_t>(fso_version.minor), static_cast<uint32_t>(fso_version.build)),
XR_CURRENT_API_VERSION
},
0,
nullptr,
static_cast<uint32_t>(extensions.size()),
extensions.data()
};
strncpy_s(instanceCreateInfo.applicationInfo.applicationName, Mod_title.empty() ? "FreeSpace Open" : Mod_title.c_str(), XR_MAX_APPLICATION_NAME_SIZE);
XrResult create = xrCreateInstance(&instanceCreateInfo, &xr_instance);
if (create != XR_SUCCESS) {
if (create == XR_ERROR_EXTENSION_NOT_PRESENT) {
//This is to be expected to be one of THE common issue cases, since not all OpenXR runtimes, notably WMR, don't supply the OpenGL extensions
ReleaseWarning(LOCATION, "The OpenXR runtime does not support the required backend! Try to use a different OpenXR runtime.");
}
mprintf(("Failed to create OpenXR instance with code %d\n", static_cast<int>(create)));
return false;
}
#if !defined(NDEBUG) && defined(FS_OPENXR_DEBUG)
XrDebugUtilsMessengerCreateInfoEXT debugMessengerCreateInfo {
XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
nullptr,
XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT,
(PFN_xrDebugUtilsMessengerCallbackEXT)(&handleXRError),
nullptr
};
openxr_callExtensionFunction<PFN_xrCreateDebugUtilsMessengerEXT>("xrCreateDebugUtilsMessengerEXT", xr_instance, &debugMessengerCreateInfo, &xr_debugMessenger);
#endif
return true;
}
static bool openxr_init_system() {
XrSystemGetInfo systemGetInfo {
XR_TYPE_SYSTEM_GET_INFO,
nullptr,
XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY
};
XrResult systemInit = xrGetSystem(xr_instance, &systemGetInfo, &xr_system);
if (systemInit != XR_SUCCESS) {
mprintf(("Failed to create OpenXR system with code %d\n", static_cast<int>(systemInit)));
xr_system = XR_NULL_SYSTEM_ID;
return false;
}
return true;
}
static bool openxr_init_configuration_views() {
uint32_t configurationViewsCount = static_cast<uint32_t>(xr_configurationviews.size());
for (auto& configView : xr_configurationviews)
configView = { XR_TYPE_VIEW_CONFIGURATION_VIEW, nullptr, 0, 0, 0, 0, 0, 0 };
if (xrEnumerateViewConfigurationViews(xr_instance, xr_system, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, configurationViewsCount, &configurationViewsCount, xr_configurationviews.data()) != XR_SUCCESS) {
mprintf(("Failed to find OpenXR configuration views for stereo displays!\n"));
return false;
}
return true;
}
static bool openxr_init_swapchains() {
uint32_t formatCount = 0;
if (xrEnumerateSwapchainFormats(xr_session, 0, &formatCount, nullptr) != XR_SUCCESS) {
return false;
}
SCP_vector<int64_t> formats(formatCount);
if (xrEnumerateSwapchainFormats(xr_session, formatCount, &formatCount, formats.data()) != XR_SUCCESS) {
return false;
}
int64_t chosenFormat = gr_openxr_get_swapchain_format(formats);
std::array<XrSwapchain, 2> swapchains;
for (uint32_t i = 0; i < 2; i++)
{
XrSwapchainCreateInfo swapchainCreateInfo {
XR_TYPE_SWAPCHAIN_CREATE_INFO,
nullptr,
0,
XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT,
chosenFormat,
1,
xr_configurationviews[i].recommendedImageRectWidth,
xr_configurationviews[i].recommendedImageRectHeight,
1,
1,
1
};
XrResult swapchainInit = xrCreateSwapchain(xr_session, &swapchainCreateInfo, &swapchains[i]);
if (swapchainInit != XR_SUCCESS) {
mprintf(("Failed to create OpenXR swapchain %d with code %d\n", i, static_cast<int>(swapchainInit)));
return false;
}
xr_swapchains[i].reset(new XrSwapchainHandler {
swapchains[i],
chosenFormat,
xr_configurationviews[i].recommendedImageRectWidth,
xr_configurationviews[i].recommendedImageRectHeight
});
}
if (!gr_openxr_acquire_swapchain_buffers()) {
return false;
}
return true;
}
static bool openxr_init_space() {
XrReferenceSpaceCreateInfo spaceCreateInfo {
XR_TYPE_REFERENCE_SPACE_CREATE_INFO,
nullptr,
XR_REFERENCE_SPACE_TYPE_LOCAL,
XrPosef{ XrQuaternionf{ 0, 0, 0, 1 }, XrVector3f{ 0, 0, 0 } },
};
if (xrCreateReferenceSpace(xr_session, &spaceCreateInfo, &xr_space) != XR_SUCCESS) {
return false;
}
return true;
}
static void openxr_init_post() {
XrViewLocateInfo viewLocateInfo {
XR_TYPE_VIEW_LOCATE_INFO,
nullptr,
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
xr_time,
xr_space
};
XrViewState viewState {
XR_TYPE_VIEW_STATE,
nullptr,
0
};
xr_views.fill({ XR_TYPE_VIEW, nullptr, XrPosef{}, XrFovf{} });
uint32_t views;
xrLocateViews(
xr_session,
&viewLocateInfo,
&viewState,
2,
&views,
xr_views.data()
);
openxr_reset_offset();
vec3d xr_offset_debug {{ {
(xr_views[0].pose.position.x - xr_views[1].pose.position.x) * xr_scale,
(xr_views[0].pose.position.y - xr_views[1].pose.position.y) * xr_scale,
(xr_views[0].pose.position.z - xr_views[1].pose.position.z) * xr_scale} }};
mprintf(("OpenXR HMD data:\n\tLeft Res: %dx%d\n\tLeft FoV (l|r|t|b): %f, %f, %f, %f\n\tRight Res: %dx%d\n\tRight FoV (l|r|t|b): %f, %f, %f, %f\n\tIPD: %f\n",
xr_swapchains[0]->width, xr_swapchains[0]->height,
xr_views[0].fov.angleLeft, xr_views[0].fov.angleRight, xr_views[0].fov.angleUp, xr_views[0].fov.angleDown,
xr_swapchains[1]->width, xr_swapchains[1]->height,
xr_views[1].fov.angleLeft, xr_views[1].fov.angleRight, xr_views[1].fov.angleUp, xr_views[1].fov.angleDown,
vm_vec_mag(&xr_offset_debug)));
VIEWER_ZOOM_DEFAULT = COCKPIT_ZOOM_DEFAULT = asymmetric_fov {
xr_views[0].fov.angleLeft + xr_views[1].fov.angleLeft,
xr_views[0].fov.angleRight + xr_views[1].fov.angleRight,
xr_views[0].fov.angleUp + xr_views[1].fov.angleUp,
xr_views[0].fov.angleDown + xr_views[1].fov.angleDown
} * (1.0f / (2.0f * PROJ_FOV_FACTOR));
}
float openxr_preinit(float req_ar, float scale) {
xr_scale = scale;
mprintf(("Attempting to pre-initialize OpenXR...\n"));
if (!openxr_init_instance()) {
openxr_req = false;
return req_ar;
}
if (!openxr_init_system()) {
openxr_req = false;
return req_ar;
}
if (!openxr_init_configuration_views()) {
openxr_req = false;
return req_ar;
}
return i2fl(xr_configurationviews[0].recommendedImageRectWidth) / i2fl(xr_configurationviews[0].recommendedImageRectHeight);
}
void openxr_init() {
if (!openxr_req)
return;
mprintf(("Attempting to initialize OpenXR and get a session...\n"));
if (!gr_openxr_test_capabilities())
return;
//Non OpenGL backends, like vulkan, may need to query certain extensions to be enabled here as well
if (!gr_openxr_create_session())
return;
if (!openxr_init_swapchains())
return;
if (!openxr_init_space())
return;
openxr_initialized = true;
mprintf(("OpenXR initialized!\n"));
while (openxr_initialized && !openxr_recieve) {
os_poll();
}
mprintf(("OpenXR recieving!\n"));
openxr_init_post();
}
void openxr_close() {
xrDestroySpace(xr_space);
for (auto& sc : xr_swapchains)
sc.release();
xrDestroySession(xr_session);
#if !defined(NDEBUG) && defined(FS_OPENXR_DEBUG)
openxr_callExtensionFunction<PFN_xrDestroyDebugUtilsMessengerEXT>("xrDestroyDebugUtilsMessengerEXT", xr_debugMessenger);
#endif
xrDestroyInstance(xr_instance);
}
bool openxr_enabled() {
return openxr_initialized && openxr_recieve;
}
bool openxr_requested() {
return openxr_req;
}
void openxr_reset_offset() {
xr_offset = ZERO_VECTOR;
for (uint32_t i = 0; i < 2; i++) {
const auto& pos = xr_views[i].pose.position;
xr_offset += vec3d{ { {pos.x * xr_scale, pos.y * xr_scale, pos.z * -xr_scale} } };
}
xr_offset /= 2;
}
void openxr_start_mission() {
if (!openxr_initialized)
return;
openxr_reset_offset();
if (!static_cast<bool>(Stars_XRBuffer))
Stars_XRBuffer = make_unique<star[]>(MAX_STARS);
extern std::unique_ptr<star[]> Stars;
std::copy(Stars.get(), Stars.get() + MAX_STARS, Stars_XRBuffer.get());
}
void openxr_poll() {
if (!openxr_initialized)
return;
XrEventDataBuffer eventData{
XR_TYPE_EVENT_DATA_BUFFER,
nullptr,
{0}
};
XrResult result = xrPollEvent(xr_instance, &eventData);
if (result == XR_EVENT_UNAVAILABLE) {
//No event
}
else if (result != XR_SUCCESS) {
openxr_initialized = false;
openxr_close();
}
else {
switch (eventData.type)
{
case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING:
openxr_initialized = false;
openxr_close();
break;
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED:
{
auto event = (XrEventDataSessionStateChanged*)&eventData;
xr_time = event->time;
switch (event->state)
{
case XR_SESSION_STATE_IDLE:
openxr_recieve = false;
break;
case XR_SESSION_STATE_READY:
{
XrSessionBeginInfo sessionBeginInfo{
XR_TYPE_SESSION_BEGIN_INFO,
nullptr,
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO
};
if (xrBeginSession(xr_session, &sessionBeginInfo) != XR_SUCCESS) {
openxr_initialized = false;
openxr_close();
}
}
/*fallthrough*/
case XR_SESSION_STATE_SYNCHRONIZED:
case XR_SESSION_STATE_VISIBLE:
case XR_SESSION_STATE_FOCUSED:
openxr_recieve = true;
break;
case XR_SESSION_STATE_STOPPING:
xrEndSession(xr_session);
/*fallthrough*/
case XR_SESSION_STATE_LOSS_PENDING:
case XR_SESSION_STATE_EXITING:
openxr_initialized = false;
openxr_close();
break;
default:
break;
}
break;
}
default:
break;
}
}
}
OpenXRTrackingInfo openxr_start_stereo_frame() {
if (!openxr_initialized)
return OpenXRTrackingInfo{};
xr_stage = OpenXRFBStage::FIRST;
openxr_start_frame();
OpenXRTrackingInfo info{};
for (uint32_t i = 0; i < 2; i++) {
const auto& pos = xr_views[i].pose.position;
const auto& ori = xr_views[i].pose.orientation;
info.eyes[i].offset = vec3d{{ {pos.x * xr_scale, pos.y * xr_scale, pos.z * -xr_scale} }} - xr_offset;
vm_quaternion_to_matrix(&info.eyes[i].orientation, ori.x, ori.y, -ori.z, -ori.w);
info.eyes[i].zoom = asymmetric_fov{ xr_views[i].fov.angleLeft, xr_views[i].fov.angleRight, xr_views[i].fov.angleUp, xr_views[i].fov.angleDown } * (1.0f / PROJ_FOV_FACTOR);
}
return info;
}
//Internal Helper functions
void openxr_start_frame() {
XrFrameWaitInfo frameWaitInfo {
XR_TYPE_FRAME_WAIT_INFO,
nullptr
};
xr_state = XrFrameState {
XR_TYPE_FRAME_STATE,
nullptr,
0,
0,
0
};
xrWaitFrame(xr_session, &frameWaitInfo, &xr_state);
XrViewLocateInfo viewLocateInfo {
XR_TYPE_VIEW_LOCATE_INFO,
nullptr,
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
xr_state.predictedDisplayTime,
xr_space
};
xr_time = xr_state.predictedDisplayTime;
XrViewState viewState {
XR_TYPE_VIEW_STATE,
nullptr,
0
};
xr_views.fill({ XR_TYPE_VIEW, nullptr, XrPosef{}, XrFovf{} });
uint32_t views;
xrLocateViews(
xr_session,
&viewLocateInfo,
&viewState,
2,
&views,
xr_views.data()
);
XrFrameBeginInfo beginFrameInfo{ XR_TYPE_FRAME_BEGIN_INFO, nullptr };
xrBeginFrame(xr_session, &beginFrameInfo);
}
#else
//Stubs for Mac, as linking with OpenXR causes issues there.
void openxr_prepare(float hudscale) {}
float openxr_preinit(float req_ar, float scale) {
mprintf(("Cannot create OpenXR session on macOS.\n"));
return 0.0f;
}
void openxr_init() {}
void openxr_close() {}
void openxr_poll() {}
void openxr_start_mission() {}
bool openxr_enabled() { return false; }
bool openxr_requested() { return false; }
OpenXRTrackingInfo openxr_start_stereo_frame() { return OpenXRTrackingInfo{}; }
#endif
+64
View File
@@ -0,0 +1,64 @@
#pragma once
#include <array>
#include "camera/camera.h"
struct OpenXRTrackingInfo {
struct OpenXREyeInfo {
vec3d offset;
matrix orientation;
fov_t zoom; //zoom, not fov! difference of a factor of PROJ_FOV_FACTOR
};
std::array<OpenXREyeInfo, 2> eyes;
};
/**
* @brief Performs required Setup actions for OpenXR before actually trying to initialize the graphics
* @param hudscale Sets the scale at which the HUD is rendered. May need to be tweakable to make the hud visible to players with small FoV
*/
void openxr_prepare(float hudscale = 0.5f);
/**
* @brief Initializes the OpenXR API and opens the XR system
* @param req_ar The aspect ratio as specified by the user resolution
* @param scale Controls the scale of the OpenXR coordinates. This mainly affects eye distance and how far real movement translates to ingame movement
* @returns the expected aspect ratio of the swapchain
*/
float openxr_preinit(float req_ar, float scale = 1.0f);
/**
* @brief Opens an OpenXR session to the point that we can render. As this waits for OpenXR, this may take a while
*/
void openxr_init();
/**
* @brief Shuts down OpenXR and cleans up memory
*/
void openxr_close();
/**
* @brief Polls OpenXR state. Does NOT poll HMD position!
*/
void openxr_poll();
/**
* @brief Grabs the last known HMD position and sets it as the zero-state (whereever the specified eyepoint is in mission / ship), as well as initializing buffers for the mission
*/
void openxr_start_mission();
/**
* @brief Polls whether OpenXR is active and can render
*/
bool openxr_enabled();
/**
* @brief Polls whether OpenXR is requested to start. Required if you need to poll for OpenXR during some initialization where it might not yet be running
*/
bool openxr_requested();
/**
* @brief Polls HMD position and sets up the OpenXR state machine to wait for and accept two frames, one for each eye.
* You must ensure that after calling this, the next two gr_flip() calls correspond to the frames for each eye!
* @returns The HMD tracking data including position and rotation in FSO coordinates.
*/
OpenXRTrackingInfo openxr_start_stereo_frame();
+54
View File
@@ -0,0 +1,54 @@
#pragma once
//Don't include this file unless you know what you are doing and need to _directly_ interface with OpenXR
#include "openxr.h"
#include <type_traits>
#include <tl/optional.hpp>
#ifndef __APPLE_CC__
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
struct XrSwapchainHandler {
XrSwapchain swapchain;
int64_t format;
uint32_t width;
uint32_t height;
~XrSwapchainHandler() {
xrDestroySwapchain(swapchain);
}
};
extern bool openxr_initialized; //is true if initialization was successfull. Does NOT imply that we can render right now!
extern XrInstance xr_instance;
extern XrSystemId xr_system;
extern XrSession xr_session;
extern XrSpace xr_space;
extern XrTime xr_time; //The last known time something happened. May be the last state change or the (predicted) time of the last frame
extern std::array<std::unique_ptr<XrSwapchainHandler>, 2> xr_swapchains;
extern std::array<XrView, 2> xr_views;
extern XrFrameState xr_state;
extern vec3d xr_offset;
enum class OpenXRFBStage { NONE, FIRST, SECOND };
extern OpenXRFBStage xr_stage; //State machine tracker for rendering. Needed since OpenXR needs to be able to tell whether this is a stereoscopic frame or not whenever the code flips
void openxr_start_frame();
void openxr_reset_offset();
template<typename openxr_fnc, typename... arg_t>
tl::optional<typename std::result_of<openxr_fnc(arg_t...)>::type> openxr_callExtensionFunction(const char* const name, arg_t&&... args) {
openxr_fnc func;
if (xrGetInstanceProcAddr(xr_instance, name, (PFN_xrVoidFunction*)&func) != XR_SUCCESS) {
return tl::nullopt;
}
return func(std::forward<arg_t>(args)...);
}
#endif
+1 -6
View File
@@ -344,12 +344,7 @@ namespace
stuff_string(lang_name, F_NAME, LCL_LANG_NAME_LEN + 1);
// find language and set the index, or if not found move to the next one
for (auto i = 0; i < (int)Lcl_languages.size(); ++i) {
if (!strcmp(Lcl_languages[i].lang_name, lang_name)) {
lang_idx = i;
break;
}
}
lang_idx = lcl_find_lang_index_by_name(lang_name);
if (lang_idx == -1) {
Warning(LOCATION, "Ignoring invalid language (%s) specified by font (%s); not built-in or in strings.tbl",
+1 -1
View File
@@ -89,7 +89,7 @@ void convert_model_material(model_uniform_data* data_out,
if (material.is_alpha_mult_active())
data_out->flags |= MODEL_SDR_FLAG_ALPHA_MULT;
if (material.get_animated_effect() > 0) {
if (material.get_animated_effect() >= 0) {
data_out->anim_timer = material.get_animated_effect_time();
data_out->effect_num = material.get_animated_effect();
}
+4 -2
View File
@@ -15,6 +15,10 @@ namespace {
std::unique_ptr<VulkanRenderer> renderer_instance;
}
void initialize_function_pointers() {
init_stub_pointers();
}
bool initialize(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
{
renderer_instance.reset(new VulkanRenderer(std::move(graphicsOps)));
@@ -22,8 +26,6 @@ bool initialize(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
return false;
}
init_stub_pointers();
gr_screen.gf_flip = []() {
renderer_instance->flip();
};
+1
View File
@@ -7,6 +7,7 @@ namespace vulkan {
class VulkanRenderer;
void initialize_function_pointers();
bool initialize(std::unique_ptr<os::GraphicsOperations>&& graphicsOps);
VulkanRenderer* getRendererInstance();
+22
View File
@@ -15,6 +15,8 @@ gr_buffer_handle stub_create_buffer(BufferType, BufferUsageHint)
return gr_buffer_handle::invalid();
}
void stub_setup_frame() {}
void stub_delete_buffer(gr_buffer_handle /*handle*/) {}
int stub_preload(int /*bitmap_num*/, int /*is_aabitmap*/) { return 0; }
@@ -232,11 +234,24 @@ std::uint64_t stub_get_query_value(int /*obj*/) { return 0; }
void stub_delete_query_object(int /*obj*/) {}
SCP_vector<const char*> stub_openxr_get_extensions() { return {}; }
bool stub_openxr_test_capabilities() { return false; }
bool stub_openxr_create_session() { return false; }
int64_t stub_openxr_get_swapchain_format(const SCP_vector<int64_t>& /*allowed*/) { return 0; }
bool stub_openxr_acquire_swapchain_buffers() { return false; }
bool stub_openxr_flip() { return false; }
} // namespace
void init_stub_pointers()
{
// function pointers...
gr_screen.gf_setup_frame = stub_setup_frame;
gr_screen.gf_set_clip = stub_set_clip;
gr_screen.gf_reset_clip = stub_reset_clip;
@@ -353,6 +368,13 @@ void init_stub_pointers()
gr_screen.gf_sync_delete = [](gr_sync /*sync*/) {};
gr_screen.gf_set_viewport = [](int /*x*/, int /*y*/, int /*width*/, int /*height*/) {};
gr_screen.gf_openxr_get_extensions = stub_openxr_get_extensions;
gr_screen.gf_openxr_test_capabilities = stub_openxr_test_capabilities;
gr_screen.gf_openxr_create_session = stub_openxr_create_session;
gr_screen.gf_openxr_get_swapchain_format = stub_openxr_get_swapchain_format;
gr_screen.gf_openxr_acquire_swapchain_buffers = stub_openxr_acquire_swapchain_buffers;
gr_screen.gf_openxr_flip = stub_openxr_flip;
}
} // namespace vulkan
+14 -7
View File
@@ -15,6 +15,7 @@
#include "freespace.h"
#include "gamesnd/eventmusic.h"
#include "gamesnd/gamesnd.h"
#include "graphics/openxr.h"
#include "globalincs/alphacolors.h"
#include "globalincs/linklist.h"
#include "hud/hud.h"
@@ -1178,9 +1179,9 @@ bool HudGauge::canRender()
if (render_for_cockpit_toggle > 0) {
if ((Viewer_mode & VM_CHASE) && (render_for_cockpit_toggle == 2)) {
return true;
} else if (cockpitActive && (render_for_cockpit_toggle == 2)) {
} else if (Cockpit_active && (render_for_cockpit_toggle == 2)) {
return false;
} else if (!cockpitActive && (render_for_cockpit_toggle == 1)) {
} else if (!Cockpit_active && (render_for_cockpit_toggle == 1)) {
return false;
}
}
@@ -1865,6 +1866,9 @@ void hud_render_gauges(int cockpit_display_num)
}
}
//Since we render things twice in VR mode, frametime needs to be halved for HUD, as the HUD uses the frametime to advance ANI's and crucially, the missile lock...
float frametime = openxr_enabled() ? flFrametime * 0.5f : flFrametime;
// Check if this ship has its own HUD gauges.
if ( sip->hud_enabled ) {
num_gauges = sip->hud_gauges.size();
@@ -1877,7 +1881,7 @@ void hud_render_gauges(int cockpit_display_num)
sip->hud_gauges[j]->preprocess();
}
sip->hud_gauges[j]->onFrame(flFrametime);
sip->hud_gauges[j]->onFrame(frametime);
if ( !sip->hud_gauges[j]->setupRenderCanvas(render_target) ) {
continue;
@@ -1891,7 +1895,7 @@ void hud_render_gauges(int cockpit_display_num)
sip->hud_gauges[j]->resetClip();
sip->hud_gauges[j]->setFont();
sip->hud_gauges[j]->render(flFrametime);
sip->hud_gauges[j]->render(frametime);
}
} else {
num_gauges = default_hud_gauges.size();
@@ -1901,7 +1905,7 @@ void hud_render_gauges(int cockpit_display_num)
default_hud_gauges[j]->preprocess();
default_hud_gauges[j]->onFrame(flFrametime);
default_hud_gauges[j]->onFrame(frametime);
if ( !default_hud_gauges[j]->canRender() ) {
continue;
@@ -1911,7 +1915,7 @@ void hud_render_gauges(int cockpit_display_num)
default_hud_gauges[j]->resetClip();
default_hud_gauges[j]->setFont();
default_hud_gauges[j]->render(flFrametime);
default_hud_gauges[j]->render(frametime);
}
}
@@ -3775,7 +3779,7 @@ void HUD_get_nose_coordinates(int *x, int *y)
*x = 0;
*y = 0;
vm_vec_scale_add(&p0, &Player_obj->pos, &Player_obj->orient.vec.fvec, 10000.0f);
vm_vec_scale_add(&p0, &Player_obj->pos, &Player_obj->orient.vec.fvec, 1000.0f);
g3_rotate_vertex(&v0, &p0);
if (v0.codes == 0) {
@@ -3833,6 +3837,7 @@ void hud_save_restore_camera_data(int save)
{
static vec3d save_view_position;
static fov_t save_view_zoom;
static fov_t save_proj_fov;
static matrix save_view_matrix;
static matrix save_eye_matrix;
static vec3d save_eye_position;
@@ -3840,6 +3845,7 @@ void hud_save_restore_camera_data(int save)
if ( save ) {
save_view_position = View_position;
save_view_zoom = View_zoom;
save_proj_fov = Proj_fov;
save_view_matrix = View_matrix;
save_eye_matrix = Eye_matrix;
save_eye_position = Eye_position;
@@ -3848,6 +3854,7 @@ void hud_save_restore_camera_data(int save)
// restore global view variables
View_position = save_view_position;
View_zoom = save_view_zoom;
Proj_fov = save_proj_fov;
View_matrix = save_view_matrix;
Eye_matrix = save_eye_matrix;
Eye_position = save_eye_position;
-5
View File
@@ -103,11 +103,6 @@ extern int HUD_color_alpha;
extern color HUD_color_debug;
// Values used "wiggle" the HUD. In the 2D HUD case, the clip region accounts
// for these, but for the 3d-type hud stuff, you need to add these in manually.
extern float HUD_offset_x;
extern float HUD_offset_y;
// the offset of the player's view vector and the ship forward vector in pixels (Swifty)
extern int HUD_nose_x;
extern int HUD_nose_y;
+1 -1
View File
@@ -357,7 +357,7 @@ void ssm_create(object *target, vec3d *start, size_t ssm_index, ssm_firing_info
ssm.sinfo.start_pos.resize(count);
for (idx = 0; idx < count; idx++) {
ssm.sinfo.delay_stamp[idx] = _timestamp(200 + (int)frand_range(-199.0f, 1000.0f));
ssm.sinfo.delay_stamp[idx] = _timestamp(200 + Random::next(-199, 1000));
ssm_get_random_start_pos(&ssm.sinfo.start_pos[idx], start, &dir, ssm_index);
}
+1 -1
View File
@@ -672,7 +672,7 @@ void HudGaugeBrackets::renderBoundingBrackets(int x1, int y1, int x2, int y2, in
break;
case OBJ_JUMP_NODE:
for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
if(jnp->GetSCPObject() == t_objp)
if(jnp->GetSCPObjectNumber() == target_objnum)
break;
}
tinfo_name = jnp->GetDisplayName();
+1 -1
View File
@@ -616,7 +616,7 @@ void hud_config_init_ui(bool API_Access, int x, int y, int w)
// can't find a better one. Need to get the furthest right and bottom
// pixels to be rendered to calculate the percent change. That is then
// used to rescale each gauge correctly for the rendering size and position. - Mjn
for (auto gauge : HC_gauge_regions[gr_screen.res]) {
for (const auto& gauge : HC_gauge_regions[gr_screen.res]) {
if (!stricmp(gauge.filename, NOX("none"))) {
continue;
}
+14 -7
View File
@@ -125,25 +125,32 @@ void update_ets(object* objp, float fl_frametime)
// This will translate to 71% max speed at 50% engines, and 31% max speed at 10% engines
//
float engine_aggregate_strength;
float effective_engine_strength;
float actual_engine_strength;
if (ship_p->flags[Ship::Ship_Flags::Maneuver_despite_engines]) {
// Pretend our strength is 100% when this flag is active
engine_aggregate_strength = 1.0f;
effective_engine_strength = 1.0f;
actual_engine_strength = 1.0f;
} else {
engine_aggregate_strength = ship_get_subsystem_strength(ship_p, SUBSYSTEM_ENGINE);
effective_engine_strength = ship_get_subsystem_strength(ship_p, SUBSYSTEM_ENGINE);
// very annoying, but ship_get_subsystem_strength will typically cap at no lower than 15% strength reported
// causing the condition below to possibly erroneously believe the engine strength isn't changing while being
// repaired below that threshold. use the ACTUAL strength for this check
actual_engine_strength = ship_get_subsystem_strength(ship_p, SUBSYSTEM_ENGINE, false, true);
}
// only update max speed if engine_aggregate_strength has changed
// which helps minimize amount of overrides to max speed
if (engine_aggregate_strength != ship_p->prev_engine_aggregate_strength) {
if (actual_engine_strength != ship_p->prev_engine_strength) {
ets_update_max_speed(objp);
ship_p->prev_engine_aggregate_strength = engine_aggregate_strength;
ship_p->prev_engine_strength = actual_engine_strength;
// check if newly updated max speed should be reduced due to engine damage
// don't let engine strength affect max speed when playing on lowest skill level
if ((objp != Player_obj) || (Game_skill_level > 0)) {
if (engine_aggregate_strength < SHIP_MIN_ENGINES_FOR_FULL_SPEED) {
objp->phys_info.max_vel.xyz.z *= fl_sqrt(engine_aggregate_strength);
if (effective_engine_strength < SHIP_MIN_ENGINES_FOR_FULL_SPEED) {
objp->phys_info.max_vel.xyz.z *= fl_sqrt(effective_engine_strength);
}
}
}
+1 -1
View File
@@ -1583,7 +1583,7 @@ void hud_do_lock_indicators(float frametime)
lock_slot->target_in_lock_cone = false;
}
if ( !lock_slot->locked && wip->trigger_lock && !(swp->flags[Ship::Weapon_Flags::Trigger_Lock]) ) {
if ( !lock_slot->locked && wip->trigger_lock && !(swp->flags[Ship::Weapon_Flags::Secondary_trigger_down]) ) {
// only reset locks that are not locked if this is a trigger dependent weapon
// and player isn't holding down trigger
ship_clear_lock(lock_slot);
+15 -5
View File
@@ -645,7 +645,7 @@ void hud_add_msg_to_scrollback(const char *text, int source, int t)
}
// create the new node for the vector
line_node newLine = {t, source, 0, 1, w, ""};
line_node newLine = {t, The_mission.HUD_timer_padding, source, 0, 1, w, ""};
newLine.text = text;
Msg_scrollback_vec.push_back(newLine);
@@ -853,7 +853,7 @@ void hud_initialize_scrollback_lines()
char* text = c_text;
char* split = split_str_once(text, max_width);
Msg_scrollback_lines.push_back({node_msg.time, node_msg.source, node_msg.x, 1, node_msg.underline_width, text});
Msg_scrollback_lines.push_back({node_msg.time, The_mission.HUD_timer_padding, node_msg.source, node_msg.x, 1, node_msg.underline_width, text});
while (split != nullptr) {
text = split;
@@ -864,7 +864,7 @@ void hud_initialize_scrollback_lines()
if (split == nullptr)
offset = height / 3;
Msg_scrollback_lines.push_back({0, node_msg.source, node_msg.x, offset, 0, text});
Msg_scrollback_lines.push_back({0, 0, node_msg.source, node_msg.x, offset, 0, text});
}
} else {
node_msg.y = height / 3;
@@ -1214,12 +1214,22 @@ void HudGaugeTalkingHead::render(float frametime)
int hx = tablePosX + Anim_offsets[0];
int hy = tablePosY + Anim_offsets[1];
if (gr_screen.rendering_to_texture != -1)
if (gr_screen.rendering_to_texture != -1) {
gr_set_screen_scale(canvas_w, canvas_h, -1, -1, target_w, target_h, target_w, target_h, true);
hx += gr_screen.offset_x_unscaled;
hy += gr_screen.offset_y_unscaled;
}
else
gr_set_screen_scale(base_w, base_h);
generic_anim_render_ex(head_anim,frametime, hx, hy, Anim_size[0], Anim_size[1]);
generic_anim_bitmap_set(head_anim, frametime);
bitmap_rect_list brl = bitmap_rect_list(hx, hy, Anim_size[0], Anim_size[1]);
if (head_anim->use_hud_color)
gr_aabitmap_list(&brl, 1, GR_RESIZE_FULL);
else
gr_bitmap_list(&brl, 1, GR_RESIZE_FULL);
gr_reset_screen_scale();
// draw title
+1
View File
@@ -38,6 +38,7 @@ typedef struct HUD_message_data {
typedef struct line_node {
fix time; // timestamp when message was added
int timer_padding; // the mission timer padding, in seconds, at the time the message was added
int source; // who/what the source of the message was (for color coding)
int x;
int y;
+18 -6
View File
@@ -10,6 +10,7 @@
#include "cmdline/cmdline.h"
#include "graphics/font.h" //for gr_force_fit_string
#include "graphics/openxr.h"
#include "hud/hud.h"
#include "hud/hudbrackets.h"
#include "hud/hudconfig.h" // for retrieving user's hud config
@@ -41,6 +42,7 @@ extern bool Ships_inited; //Need this
float Hud_unit_multiplier = 1.0f; //Backslash
float Hud_speed_multiplier = 1.0f; //The E
float Hud_global_scale = 1.0f;
// Goober5000
int Hud_reticle_style = HUD_RETICLE_STYLE_FS2;
@@ -1212,12 +1214,12 @@ void adjust_for_multimonitor(int *base_res, bool set_position, int *coords)
float scale_w = (float)gr_screen.center_w / (float)base_res[0];
float scale_h = (float)gr_screen.center_h / (float)base_res[1];
base_res[0] = fl2ir(base_res[0] * ((float)gr_screen.max_w / (float)gr_screen.center_w));
base_res[1] = fl2ir(base_res[1] * ((float)gr_screen.max_h / (float)gr_screen.center_h));
base_res[0] = fl2ir(base_res[0] * ((float)gr_screen.max_w / (float)gr_screen.center_w / Hud_global_scale));
base_res[1] = fl2ir(base_res[1] * ((float)gr_screen.max_h / (float)gr_screen.center_h / Hud_global_scale));
if (set_position) {
coords[0] += fl2ir(gr_screen.center_offset_x / scale_w);
coords[1] += fl2ir(gr_screen.center_offset_y / scale_h);
coords[0] += fl2ir(gr_screen.center_offset_x / scale_w + ((1.0f - Hud_global_scale) * 0.5f * (float)base_res[0]));
coords[1] += fl2ir(gr_screen.center_offset_y / scale_h + ((1.0f - Hud_global_scale) * 0.5f * (float)base_res[1]));
}
}
@@ -1387,6 +1389,11 @@ std::unique_ptr<T> gauge_load_common(gauge_settings* settings, T* preAllocated =
instance->lockConfigColor(lock_color);
}
if (openxr_requested()) {
//In this case, we must always slew every hud gauge, no matter what.
instance->initSlew(true);
}
return instance;
}
@@ -1396,11 +1403,11 @@ void gauge_assign_common(const gauge_settings* settings, std::unique_ptr<T>&& hu
for (auto ship_index = settings->ship_idx->begin(); ship_index != settings->ship_idx->end(); ++ship_index) {
std::unique_ptr<T> instance(new T());
*instance = *hud_gauge;
Ship_info[*ship_index].hud_gauges.push_back(move(instance));
Ship_info[*ship_index].hud_gauges.push_back(std::move(instance));
}
// Previous instance goes out of scope here and is destructed
} else {
default_hud_gauges.push_back(move(hud_gauge));
default_hud_gauges.push_back(std::move(hud_gauge));
}
}
@@ -3708,6 +3715,7 @@ void load_gauge_directives(gauge_settings* settings)
char fname_middle[MAX_FILENAME_LEN] = "directives2";
char fname_bottom[MAX_FILENAME_LEN] = "directives3";
int bottom_bg_offset = 0;
int key_line_x_offset = 0;
settings->origin[0] = 0.0f;
settings->origin[1] = 0.5f;
@@ -3756,6 +3764,9 @@ void load_gauge_directives(gauge_settings* settings)
if ( optional_string("Max Line Width:") ) {
stuff_int(&max_line_width);
}
if (optional_string("Key Line X Offset:")) {
stuff_int(&key_line_x_offset);
}
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
hud_gauge->initMiddleFrameOffsetY(middle_frame_offset_y);
@@ -3764,6 +3775,7 @@ void load_gauge_directives(gauge_settings* settings)
hud_gauge->initTextStartOffsets(text_start_offsets[0], text_start_offsets[1]);
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
hud_gauge->initMaxLineWidth(max_line_width);
hud_gauge->initKeyLineXOffset(key_line_x_offset);
gauge_assign_common(settings, std::move(hud_gauge));
}
+1
View File
@@ -13,6 +13,7 @@
extern int Num_custom_gauges;
extern float Hud_unit_multiplier;
extern float Hud_speed_multiplier;
extern float Hud_global_scale;
#define NUM_HUD_RETICLE_STYLES 2
+2 -2
View File
@@ -232,7 +232,7 @@ void hud_squadmsg_start()
if (scripting::hooks::OnHudCommMenuOpened->isActive())
{
auto paramList = scripting::hook_param_list(scripting::hook_param("Player", 'o', Player_obj));
scripting::hooks::OnHudCommMenuOpened->run(paramList);
scripting::hooks::OnHudCommMenuOpened->run(std::move(paramList));
}
}
@@ -255,7 +255,7 @@ void hud_squadmsg_end()
if (scripting::hooks::OnHudCommMenuClosed->isActive())
{
auto paramList = scripting::hook_param_list(scripting::hook_param("Player", 'o', Player_obj));
scripting::hooks::OnHudCommMenuClosed->run(paramList);
scripting::hooks::OnHudCommMenuClosed->run(std::move(paramList));
}
}
+3 -2
View File
@@ -1754,8 +1754,9 @@ int turret_compare_func(const eval_next_turret *p1, const eval_next_turret *p2)
}
}
extern bool turret_weapon_has_flags(ship_weapon *swp, Weapon::Info_Flags flags);
extern bool turret_weapon_has_subtype(ship_weapon *swp, int subtype);
extern bool turret_weapon_has_flags(const ship_weapon *swp, Weapon::Info_Flags flags);
extern bool turret_weapon_has_subtype(const ship_weapon *swp, int subtype);
// target the next/prev live turret on the current target
// auto_advance from hud_update_closest_turret
void hud_target_live_turret(int next_flag, int auto_advance, int only_player_target)
Loaded 100 of 676 files, more files were not shown because too many files have changed in this diff. Show more