50 Commits
Author SHA1 Message Date
Goober5000andClaude Opus 5.5 6ce6ba8eb1 list the event editor's working messages in FRED sexp trees
The sexp tree refactor (#7301) moved the message listing behind
SexpTreeEditorInterface, whose default reads the global Messages[]
array.  FRED's event editor edits a local copy of the messages and
only commits them on save, but did not override getMessages() or
hasDefaultMessageParameter(), so newly created messages could not be
used in an event until the editor was saved and closed.  Restore the
pre-refactor behavior by overriding both, as QtFRED already does.

Also remove current_message_name() and get_message_list_item(), which
have had no callers since the refactor.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-08 19:52:44 -05:00
Goober5000andClaude Fable 5.1 acf613c13c Fix FastDebug builds linking the non-redistributable debug CRT (#7919)
* fix FastDebug QtFRED linking the debug CRT

FastDebug builds in the DLL-runtime tree (used whenever qtFRED is
enabled) compiled with /MDd and, since #7450, linked Qt's debug
libraries.  Both import ucrtbased.dll, MSVCP140D.dll and
VCRUNTIME140D.dll, which Microsoft does not license for redistribution,
so end users could not run the FastDebug qtFRED shipped in nightlies
and releases.  Static Qt is ruled out by the LGPL, so the only shippable
shape is the release CRT plus release Qt.

On MSVC, _DEBUG is the CRT's own contract: /MTd and /MDd define it
themselves, and the STL headers select msvcprtd.lib and
_ITERATOR_DEBUG_LEVEL=2 from it.  Stop force-defining it for FastDebug
on MSVC; the engine keys its debug behaviour on NDEBUG, and the few
_DEBUG guards in code/ are switched to NDEBUG so they keep working.
The static tree is unchanged: /MTd still defines _DEBUG there.

Fixes #7915

Co-Authored-By: Claude Fable 5.1 <[email protected]>

* derive the MSVC runtime choice once

The "DLL runtime or not" condition was spelled out in the toolchain and
twice in fred2 with "keep in sync" comments, and gtest_force_shared_crt
and antlr4's WITH_STATIC_CRT had already drifted: they only looked at
MSVC_USE_RUNTIME_DLL, so a qtFRED tree with tests enabled would have
asked both for the static CRT.  That is harmless today only because our
flag strings carry no literal /MD for them to rewrite.

Compute FSO_MSVC_RUNTIME_DLL once in toolchain-msvc.cmake and use it
everywhere.  InstallRequiredSystemLibraries deliberately stays keyed on
MSVC_USE_RUNTIME_DLL: the qtFRED deploy ships no compiler runtime.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

* remove FastDebug runtime leftovers

The /MD -> /MDd substitution on the FastDebug flag strings has done
nothing since the runtime moved to CMAKE_MSVC_RUNTIME_LIBRARY: the
Release flags it copies contain no runtime switch.  The commented-out
_ITERATOR_DEBUG_LEVEL=0 lines for gtest and the OpenXR loader belong to
the scheme #7450 removed from the toolchain.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

* use the release CRT for all FastDebug builds

Microsoft's documentation marks the static debug libraries (libcmtd,
libucrtd, libvcruntimed) "Not redistributable" and states that debug
versions of an application may only be copied to machines used for
testing, and the license grants distribution rights only for code on
the REDIST list, which contains no debug library in any form.  So the
statically linked FastDebug game and FRED2 are no more shippable than
the /MDd qtFRED was.

Link every FastDebug build against the release runtime.  The engine's
debug behaviour keys on NDEBUG, which FastDebug still leaves undefined,
so asserts, warnings and mprintf are unaffected; only the debug CRT's
heap checking goes, and that remains available in Debug builds.  FRED2's
static MFC library follows the CRT: the debug variant requires the debug
runtime.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

* keep the debug icon, version flag and FRED2 asserts without _DEBUG

The resource compiler only ever sees the explicit definitions, so with
_DEBUG no longer defined for FastDebug the game lost its debug icon and
both editors lost the VS_FF_DEBUG version flag.  Key those on NDEBUG,
which FastDebug still leaves undefined.

FRED2 also used MFC's ASSERT, VERIFY, ASSERT_VALID and TRACE0, which are
all compiled out without _DEBUG.  Convert them to the FSO equivalents
FRED2 already uses nearly everywhere else: Assert, Verify, a null check
in place of ASSERT_VALID (AssertValid only exists in debug MFC), and
mprintf.  The AssertValid/Dump overrides and DEBUG_NEW stay under
_DEBUG, as they must.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

---------

Co-authored-by: Claude Fable 5.1 <[email protected]>
2026-10-24 03:09:57 -04:00
Goober5000 831f3a4c92 Merge pull request #7539 from Goober5000/feature/reorder_messages_events
Add event and message reordering to the FRED event editor
2026-07-18 23:59:13 -04:00
Goober5000andClaude Fable 5 35e1686c2f const-qualify read-only sexp tree methods
Add const to query methods that the sexp_tree refactor left non-const:

- FRED2/qtFRED views: node, type, handle, and root lookups; label-edit
  eligibility; annotation key resolution and comment getters; qtFRED's
  validOperatorsForNode
- SexpTreeOPF: all instance get_listing_opf_* functions plus the
  dispatcher and get_default_value (the class holds only a reference
  to its model, so these are read-only by construction)
- SexpTreeModel: compute_context_menu_state and the two remaining
  ctx_* helpers, which write only their state out-parameter
- ISexpTreeUI: the two read-only navigation callbacks
  (ui_get_child_item, ui_has_children) in the interface and both
  frontend implementations

Also convert the four listing functions that use no editor state at all
(species, language, functional_when_eval_type, wing_formation) to
static, removing the NOLINT suppressions that had silenced clang-tidy's
convert-to-static warning since before the refactor.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-11 17:11:05 -04:00
Goober5000andClaude Opus 4.8 63b26ade93 Add event and message reordering to the FRED event editor
Add "Move to top / up / down / to bottom" controls -- vertical icon-button
strips beside both the event tree and the message list -- so events and
messages can be reordered in place.

Also add an "Insert Msg" button that inserts a message at the current
selection, mirroring the existing "Insert Event".

Tweak the message-area layout, drop the "Messages" label, and edit the
AFX_DIALOG_LAYOUT table for proper behavior when the dialog is resized.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-11 15:46:43 -04:00
Goober5000andClaude Fable 5 50de61cf74 prevent zombie annotations and restore help box root-label comments
Root-label annotations (event-name comments/colors) that lose their
node — e.g. because their event was deleted — could survive
indefinitely and surface on the wrong items:

- saveToGlobal's root-key branch kept an unresolvable annotation in
  Event_annotations with an empty path instead of marking it for
  pruning, so once a zombie was persisted in a mission file it
  survived every save/load cycle.
- getByKey(-1) matched annotations whose node_index had been reset to
  the unresolved sentinel, so such a zombie's comment could display on
  any item that has no annotation key of its own.

Guard findByKey against the -1 sentinel, and prune any annotation
whose rebuilt path is empty at save time.  (The complementary
in-session fixes — removing a root-label annotation when its event is
deleted and re-keying it when insert-operator changes the formula
node — are handled in the shared model and actions by 'Keep event
annotations attached to their node across tree mutations'.)

Also restore root-label comments in the FRED2 help box: update_help
resolved comments by model node index, which is -1 for labels.  Route
it through a get_item_comment virtual that the event editor's tree
overrides with its annotation key lookup, matching pre-refactor
behavior.  (qtFRED renders comments per-item via NoteRole, which
already covers labels; its help box does not show comments by design.)

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-11 01:17:31 -04:00
Mike Nelson 4d8538e5cc Qtfred sexp tree refactor (#7301)
* long project will be long

* add shared foundation files

* unify some shared types across both editors

* sexptreemodel framework

* move opf functions to the model

* move shared functions into the model

* move variable/container stuff to the model

* sexptreeactions and ui interface

* wire the model into the ui

* move some shared logic to the model

* move more methods to the model

* move clipboard to model

* create new right click menu model

* begin connecting the new right click menu

* wire up the new right click menu in fred

* wire up the new right click menu in qtfred

* move help text and visuals to model

* move menu option enable disable to model

* wire up sexp_tree to the model

* rename sexp_tree files to sexp_tree_ui

* fix build errors

* fix warning

* remove all opf forwarders

* remove some forwarder methods

* connect qtfred events editor directly to model

* wite plan for unifying tree types

* replace legacy m_mode with treeflags

* fix qtfred campaign dialog

* fix qtfred ship/wing dialog trees

* build error

* documentation

* more documentation

* even more documentation

* move more opf functions to opf file

* clean up context menu function

* move default argument to opf file

* build errors

* fix qtfred dialogs and annoations

* new shared annotations model

* sexp_tree_ui to sexp_tree_view

* documentation pass

* document annotations model

* delete the plan

* move event annotations to the new model

* generic cleanup

* remove some old defines

* cleanup includes

* more cleanup

* parenthesis

* more parenthesis

* variable collisions

* too many parenthesis this time

* clang modernization

* variable names again

* more clang and assertions

* static cast

* clang again

* fix some bugs and issues

* Refactor sexp tree action duplication into SexpTreeActions

* fix a few more minor issues

* avoid clang false positive

* rebase tweaks

* fix annotations issue

* fix typo and two small bugs claude found

* fix event editor tree widget loading

* fix ship and wing sexp tree editors in qtfred

* fix qtfred briefing and debriefing trees

* fix a regression Claude found

* address feedback

* fix annotations for root items in qtfred by copying fred's method

* address feedback

* rescope variables

* clang
2026-07-04 02:12:34 +02:00
Goober5000andClaude Opus 4.8 1c079a79c1 Fix FRED play/media button transparency and disabled state (#7524)
CButton::SetBitmap blits a bitmap verbatim and does not perform the
magic-color substitution MFC applies when loading toolbar bitmaps. So a
button bitmap's background -- the legacy C0C0C0 gray baked into play.bmp
et al., or a magenta transparency key -- was drawn literally, reading as
a dark/colored rectangle instead of matching the real button face
(~F0F0F0 on modern Windows), and a disabled bitmap button embossed its
whole opaque rectangle into a solid gray square.

Add load_button_icon() to management.{cpp,h}, which builds an icon from
a button bitmap by keying out a background color into a transparency
mask. Driven through BS_ICON/SetIcon, the OS blends it with the button
face and grays it correctly when disabled. Route every play/media button
through it (event editor, briefing, debriefing, command brief, music
player, sound environment). Also add load_btnface_mapped() -- a
toolbar-style color remap -- kept as a lighter alternative for
always-enabled buttons.

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-15 22:33:37 -04:00
Goober5000andClaude Fable 5 9be8c62f82 add move semantics for message media references (#7517)
MMessage's avi_info/wave_info unions hold strdup'd filenames in FRED
(indices in the game), but moves copied the pointers without nulling
the source, so every vector shift on Messages left moved-from elements
aliasing live allocations -- one careless edit away from a double-free.

Wrap each union in a MessageMediaRef struct whose moves null the source
and whose copies stay shallow (the event editor's backup pattern copies
then re-strdups).  MMessage keeps its implicit copy and gains a correct
implicit move; access syntax at all use sites is unchanged.

Add a message_free_media_names() helper and use it at the FRED
delete/wipe sites.  Two fixes ride along: messages_init() now frees
mission messages' media names before discarding them, closing a leak
that fired on every mission load in FRED; and the message editor's
OnDelete now uses the move-based array_remove_slot instead of a
copy-shift that left a stale aliasing tail.

No destructor: the active union member depends on Fred_running, and
shallow copies alias, so freeing remains explicit.

Co-authored-by: Claude Fable 5 <[email protected]>
2026-06-15 22:33:30 -04:00
Goober5000andClaude Opus 4.7 e4c7c730cc null out editor-dialog globals on DestroyWindow (#7512)
Several dialogs already null their global at the top of DestroyWindow, but a few do not: briefing, debriefing, event, background, message, cutscene, goal, and Fred_view_wnd.  OnClose nulls in those five cover the user-initiated close path, but any teardown that bypasses OnClose leaves a dangling pointer that could be dereferenced.

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-06-12 07:45:21 -04:00
Goober5000 0b7ded2407 fix copy-paste error
Due to a copy-paste error, the event editor would always be marked modified.  Fix the comparison.

This bug originally appeared in QtFRED also, but no longer does.

Follow-up to #6529.
2026-06-12 01:43:41 -04:00
Goober5000 b970e22410 add additional double quote conversion to FRED and qtFRED
Any place in FRED that uses XSTR is susceptible to double quotes interfering with the standard XSTR format, not just the expected briefing, debriefing, messages, etc.  This PR adds `lcl_fred_replace_stuff()` - which handles not only quotes but semicolons and slashes as well - to the other places where XSTR is used.

(Note that quotes are handled just fine in non-XSTR fields.  Semicolons will still truncate non-XSTR fields, but addressing that is beyond the scope of this PR as it would require editing every text field in FRED.  Fortunately, errant semicolons merely modify the text as opposed to corrupting the mission file.)

Fixes #7005 in both FRED and qtFRED; tested in both.  Caveat aedificator: the briefing editor is not yet implemented in qtFRED, so the relevant fixes to briefing icon labels and closeup labels cannot yet be ported over.
2025-08-28 01:02:06 -04:00
Goober5000 133b033ea0 some upgrades to vmallocator.h
Make `SCP_vector`, `SCP_list`, `SCP_set`, and `SCP_multiset` subclasses of their STL counterparts.  This allows helper functions to be added to each, including the `contains()` function which is not available until C++20.  (This has minor effects on other parts of the codebase that treated `SCP_` and `std::` as synonyms.)  Since there is now a nontrivial amount of code that needs to be in a .cpp file, create vmallocator.cpp.

Note that `SCP_string` truncation has been refactored to use length rather than C-string size to be consistent with other `std::basic_string` functions.

Also, remove some enum class hashing code which is no longer necessary now that the codebase is at C++17.
2025-02-02 14:54:26 -05:00
Goober5000 af11d1c8c6 fix event editor modification check
The `query_modified()` function in FRED did not correctly check whether messages were modified, although interestingly, it did so in qtFRED.  Even in qtFRED, there were a few minor omissions.  Overall, this fixes FRED and syncs up the FRED and qtFRED versions.

Fixes #6528.
2025-01-16 21:27:30 -05:00
Goober5000 4026d30bdc fix DDV_ validation in FRED, especially DDV_MaxChars
Any DDV (Dialog Data Validation) routine must appear immediately after the field it validates in order for the enforcement to work in real-time.  If the DDV_ routine is not linked to the field, it will perform validation after-the-fact by displaying a dialog box and returning an error.  This is an alternate way of handling validation, but in order for the dialog box not to generate an endless loop, it would be necessary to check the return value of every `UpdateData(TRUE)` call in the FRED codebase (or at least the first `UpdateData(TRUE)` in a pair of them) and then, if the return value is `FALSE`, doing an early return from the enclosing function.

Fixes #6427 as well as all similar cases in FRED.
2024-11-18 23:01:21 -05: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
Mike Nelson eeaf894b15 Message notes feature (#5541)
* Add stage notes feature for mission messages

* don't keep notes outside the mission editor

* use F_MULTITEXT and do lcl_replacements

* this should be multitext too
2023-10-23 07:38:33 -04:00
Goober5000 720d938a3a address feedback 2023-06-02 16:26:25 -04:00
Goober5000 ff2ec6a2ab preliminary sexp operator popup 2023-05-28 22:42:22 -04:00
Goober5000 3e0c7f0721 add lcase_equal and lcase_lessthan
The `SCP_string_lcase_equal_to()()` and `SCP_string_lcase_less_than()()` functors are rather unwieldy to use in non-functor situations, so this adds conventional function equivalents.
2023-05-20 18:21:37 -04:00
Goober5000 587d5af8ca some FRED cleanup
1. Disambiguate dialog IDs for the music player and the volumetric nebula dialogs
2. Fix compilation of qtFRED
3. Small refactor of Personas access to use STL functions where appropriate
2023-04-21 23:16:51 -04:00
Mike Nelson 3c30257816 Modular messages table (#5285)
* modular messages table

* clarify warning
2023-04-16 08:40:25 +09:00
Goober5000 23c5355bc7 make multiline comments display properly without length restriction 2023-02-18 15:45:28 -05:00
MjnMixael 5694e5c810 Allow negative number in event editor (#5106)
* allow negative number in event editor

* handle qtFRED ui also
2023-01-20 18:06:08 +01:00
Goober5000 226e956fcc dynamic events and goals
Make events and goals dynamic in missions and campaigns.  When parsing, initialize all fields to their defaults.
2022-12-09 13:10:39 -05:00
Goober5000 cb7c760255 make sexp_tree dragging more user-friendly
FREDders expect events (and goals and campaign links) to land where you drag them.  So when dragging items earlier in the list, insert them before the item they are dropped on.
2022-11-24 20:55:18 -05:00
Goober5000 bd50aadf5c fix swapping of things in FRED
This properly updates event and goal signatures when events are moved around.  Fixes Mantis bugs 1005, 1961, and 2998.
2022-11-10 15:47:20 -05:00
MjnMixael 291f4f68ea Allow adding custom head anis to the list in FRED (#4818) 2022-10-27 16:22:49 +09:00
Goober5000 495010275b add helpful dialog box 2022-07-06 12:08:38 -04:00
Goober5000 47d5582a31 address highlighting for events with background colors
Events with background colors had their highlighting behavior disabled, because since an event has to be selected to add a color, users thought the color adding didn't work.  However it was pointed out in #4129 that users still would like to know which event is selected.  So this PR attempts to solve the problem by drawing a border over a selected event if that event has a background color.
2022-04-03 00:14:31 -04:00
Goober5000 ae5d458dde fix a bunch of FRED dialog problems (#4102)
1) Fixes the ship and wing dialog resizing for both sexp help and arrival/departure cues
2) Restores the sexp help in the Mission Goals dialog, which had been broken since the mini-help-box was added
2022-03-26 20:39:04 -05:00
Goober5000 e41077e07f fix message list crash
PR #3342 meant that occasionally FRED would try to save a message that didn't exist.  Make sure the old saved index doesn't point past the end of the valid message list.

Fixes #3996.
2022-03-15 20:32:53 -04:00
Joshua Glatt 40b47ed8a8 tpo fix 2021-12-28 14:56:46 -08:00
Joshua Glatt be89d88313 revert change and add comment on why event_editor::OnCancel() is blank 2021-12-28 13:49:24 -08:00
Joshua Glatt 9d79c8f947 check for unsaved changes in Events Editor before closing with Esc key 2021-12-28 11:55:35 -08:00
Goober5000 af8422cf7b confirm cancel in Event Editor
This syncs up the Close and Cancel behavior.  In both cases, if there are any changes, FRED will display a prompt.
2021-08-26 16:32:18 -04:00
Goober5000 35094851f2 modify saving of edited messages
Instead of saving based on the m_cur_msg index, which may have been reset to -1, save on the most recent positive index.  This should keep track of modified text and dropdowns even when m_cur_msg is set to -1 when the message list loses focus.

Fixes #3308.
2021-03-30 17:32:02 -04:00
Goober5000 03dbdf7f09 don't display unmodified annotations 2021-03-02 15:09:28 -05:00
Goober5000 41f9dbb003 fix event editor closing on key press
Restores the MFC functions that were taken out in #3073.  These functions appeared redundant, but they were actually necessary to intercept the MFC handling of Enter and Escape.  In addition to fixing that behavior, this PR also adds some clarifying comments and renames some functions to prevent confusion.
2021-02-14 01:32:03 -05:00
Goober5000 47543ac7d4 implement keyboard shortcuts, implement mission saving for bg color 2021-02-01 00:46:17 -05:00
Goober5000 c0446cd03c color stuff works pretty well 2021-02-01 00:46:17 -05:00
Goober5000 bc37fda89e reorganize event annotations a bit
preliminary work for background color and changing indent
implement a sort-of-working background color change
2021-02-01 00:46:17 -05:00
Goober5000 9bebdbb575 rename event_comment to event_annotation 2021-01-28 18:56:15 -05:00
Goober5000 04cf220f2d comment capability for FRED
Add FRED comments. These aren't the typical source-code style comments that are embedded in mission or table files; these are regular strings that are stored as mission data. You might think of them as annotations. Right-click on any node in the event tree and click on Edit Comment to add one. The tree node will then show a different icon and the comment will be visible as a tooltip when you mouse over the node text.
2021-01-28 18:25:19 -05:00
Goober5000 1a928632e0 fix sexp auto-complete for manually-entered text
The old way of finding the closest match of sexp text to entered text didn't work very well.  This method uses Levenstein distance.
2020-07-03 16:00:43 -04:00
Goober5000 1c8f07b012 allow intervals and chain delays to use milliseconds
This adds the titular feature, as well as FRED support.  There are also some associated minor UI fixes in FRED and some cleanup in missiongoals.cpp.  And "Event Flags" are now a thing in case we want to add any other flags in the future.
2020-04-14 16:28:57 -04:00
TRBlount e7a8adb367 Make APNG default file for head ani selection 2018-03-09 16:11:57 -07:00
MageKing17 011d74bb4d Resize Messages vector before storing messages into it in FRED.
Not resizing the Messages vector here was leading to a debug error about an out-of-range vector subscript, and who knows what other problems were being caused by overwriting whatever memory was after the Messages vector. There's no equivalent problem when parsing, because as each message is parsed, it gets pushed onto the back of the vector instead of assigned directly to an index.
2016-12-31 21:10:17 -08:00
asarium 1e534cfc9f Fix 64-bit warnings in FRED2 2016-08-25 14:50:46 +02:00
asarium 1bcd5400d3 Move build system to CMake 2016-07-22 12:07:19 +02:00