dao::gui
The Flash interface: answer movies’ calls into the game, call into movies, add screens.
Declared in dao/Gui.h.
Classes
| Class | |
|---|---|
| Call | An ExternalInterface call, as a handler receives it. |
| Movie | A Flash movie the game is showing (GFx’s GFxMovieView). |
| Popup | A message box the game is showing: its text and its buttons. |
| Screen | A screen the GUI system keeps, either the game’s or a plugin’s. |
| Value | A value passed between the game and a movie (GFx’s GFxValue): the arguments and return value of an ExternalInterface call, and a Movie’s variables and arguments. |
Type aliases
ExternalInterfaceHandler
using ExternalInterfaceHandler = std::function<void(const Call &call)>
Handles an ExternalInterface call.
FSCommandHandler
using FSCommandHandler = std::function<void(void *owner, std::string_view args)>
Handles an FSCommand.
It is given the calling movie’s owner (as in Call::owner) and the command’s argument text.
MoviePatch
using MoviePatch = std::function<std::optional<std::vector<std::byte>>(std::span<const std::byte> movie)>
A patch to a movie.
It is given the movie uncompressed (dao/core/GfxMovie.h) and returns the changed movie, or nullopt to leave it unchanged.
Functions
AddScreen()
bool AddScreen(std::wstring_view name, std::wstring_view movie, std::int32_t layer, std::uint32_t flags=0)
Adds a screen of your own to the GUI system, alongside the game’s.
A screen is kept by name, and the GUI system opens its movie on a layer when the screen is shown (dev/GUI.md).
dao::gui::AddScreen(L"TurnOrder", L"turnorder", dao::gui::kLayerHud);
dao::gui::ShowScreen(L"TurnOrder");
The GUI system exists from the first frame of the main menu, so a frame callback can add a screen. HasMovie tells you whether a movie can be found.
| Parameter | |
|---|---|
name |
the screen’s name, for ShowScreen, HideScreen and CloseScreen |
movie |
the movie’s name without its extension. For “turnorder”, turnorder.gfx is looked for in the game’s resources (its override folders and archives), and then in the plugin’s own folder as daolib\plugins\<name>\turnorder.gfx or .swf |
layer |
the stacking order: one of the kLayer constants |
flags |
kScreenModal for a modal screen, 0x10 for a loading screen, or 0 |
Returns false if the GUI system is not up yet or the name is already taken
CloseScreen()
bool CloseScreen(std::wstring_view name)
Closes a screen and releases its movie. Returns false before the GUI system is up.
CurrentFullScreen()
std::optional<Screen> CurrentFullScreen()
Returns the full-screen interface that is open: the inventory, the character record, the map, the journal, the tactics screen or the level-up screen.
At most one is open at a time.
if (const auto full = dao::gui::CurrentFullScreen()) ... // full->name == L"Inventory"
Returns the screen; nullopt if none is open or the GUI system is not up yet
CurrentPopup()
std::optional<Popup> CurrentPopup()
Returns the message box the game is showing, the game’s own or one a screen’s movie shows itself.
A tool that cannot see the screen can use it, for example a test whose load has stopped at “this save requires the following content”. Call it on the game thread. The box’s input field, checkbox and picker are not read.
Returns the box; nullopt when no box is up, or before the GUI system is up
FindOwner()
void * FindOwner(std::wstring_view name)
Returns the record of the movie with a given name, such as L”inventory”.
Returns the record, or null if there is none
HasMovie()
bool HasMovie(std::wstring_view file)
Returns whether a movie file can be found in the places a screen’s movie is looked for: the game’s resources and the plugin’s own folder.
| Parameter | |
|---|---|
file |
the file’s name with its extension, such as L”turnorder.gfx” |
HideScreen()
bool HideScreen(std::wstring_view name)
Hides a screen but keeps its movie loaded. Returns false before the GUI system is up.
InterceptExternalInterface()
void InterceptExternalInterface(std::string name, std::function<bool(const Call &call)> filter)
Lets a filter take some of the ExternalInterface calls with a given name, like InterceptFSCommand.
InterceptFSCommand()
void InterceptFSCommand(std::string name, std::function<bool(void *owner, std::string_view args)> filter)
Lets a filter take some of the FSCommands with a given name.
The filter returns true to take a call. Filters for a name are asked in the order they were added. A call that no filter takes goes on to the OnFSCommand handler, or to the game’s own. For example, dao/Options.h uses this to take its checkboxes’ clicks out of the SendMessage command that every button in the game sends.
LoadInto()
bool LoadInto(Movie movie, std::string_view clip, std::wstring_view ownMovie)
Loads your plugin’s own movie into a new clip on the root of a game movie.
Use it to add an element to a game screen, drawn with the screen’s own art. The loaded movie shares the game movie’s _root, so its script can attachMovie the game movie’s exported symbols, for example the tactics screen’s “OnOffButton”, and read the screen’s values in the data tree (dao/Data.h). It talks to the plugin through fscommand and ExternalInterface (OnFSCommand, OnExternalInterface).
dao::gui::OnFullScreen([](std::wstring_view name, bool shown) {
if (name == L"Tactics" && shown)
if (auto movie = dao::gui::ScreenMovie(L"Tactics"))
dao::gui::LoadInto(*movie, "MyPluginTactics_mc", L"myplugin_tactics");
});
The movie arrives on the game movie’s next update. Closing the screen removes the clip, so call this each time the screen opens; a clip whose load never arrived is created again. In the loaded script, wait for a game element’s m_bLoaded before using it, as the screen’s own rows do.
| Parameter | |
|---|---|
movie |
the game’s movie, as ScreenMovie returns it |
clip |
the new clip’s name on the movie’s root; do not use a name the loaded script attaches inside it |
ownMovie |
your movie’s file name without its extension, from the plugin’s folder (.gfx or .swf) |
Returns true if the load was requested, or if the clip is already there with its movie loaded; false if the plugin’s folder has no such movie or the clip could not be created
MouseOverInterface()
bool MouseOverInterface()
Returns whether the mouse is over an element of one of the interface’s movies, or one of them is holding a mouse press.
Explore mode makes the same check before it works out what is under the cursor, and selects nothing when the answer is true (dao/GameModes.h). A plugin that draws at the point the cursor is over in the world can use this to tell “over the interface” from “over nothing”. A plugin’s own movie under the cursor counts, like the game’s. The answer changes with mouse events, not every frame.
Returns the engine’s answer; false before the interface is up
MovieOf()
void * MovieOf(const void *owner)
Returns a record’s movie (GFx’s GFxMovieView), ready to wrap in a Movie.
Returns the movie, or null for a null record or one without a movie
NameOf()
std::wstring_view NameOf(const void *owner)
Returns the name of a record’s movie, or an empty view for null.
The view points into the record.
OnAnyExternalInterface()
void OnAnyExternalInterface(ExternalInterfaceHandler observer)
Calls an observer for every ExternalInterface call, before any filter or handler.
OnAnyFSCommand()
void OnAnyFSCommand(std::function<void(void *owner, std::string_view name, std::string_view args)> observer)
Calls an observer for every FSCommand, before any filter or handler.
The call then goes on to its handler as usual.
OnExternalInterface()
void OnExternalInterface(std::string name, ExternalInterfaceHandler handler)
Handles every ExternalInterface call with a given name, replacing the game’s own handler for that name, like OnFSCommand.
The handler sets the return value through Call::Return.
OnFSCommand()
void OnFSCommand(std::string name, FSCommandHandler handler)
Handles every FSCommand with a given name, replacing the game’s own handler for that name if there is one.
Call it at plugin load or later. A second handler for the same name replaces the first. The handler runs on the thread that advances the movie, possibly inside a plugin’s call to Movie::Invoke, so it should return quickly.
| Parameter | |
|---|---|
name |
the command’s name; case-sensitive, like the game’s |
OnFullScreen()
void OnFullScreen(std::function<void(std::wstring_view name, bool shown)> observer)
Calls an observer when a full-screen interface opens or closes, whatever opened it.
The screens are checked every frame, so the observer runs on the first frame after the change, on the game thread, with the screen’s movie open. ScreenMovie and LoadInto work inside it. When one screen closes as another opens, the observer hears about the close first.
| Parameter | |
|---|---|
observer |
given the screen’s name as CurrentFullScreen gives it, such as “Inventory” or “Tactics”, and true when it opened or false when it closed |
OnMovieLoad()
void OnMovieLoad(std::wstring_view name, MoviePatch patch)
Patches one of the game’s movies as the game opens its file.
Use it to add to a screen whose contents are built by its script; for example, dao/Input.h adds rows to the controls screen this way.
dao::gui::OnMovieLoad(L"optionsmenu", [](std::span<const std::byte> movie) {
return dao::core::gfx::InsertAfter(movie, {"AddKeyBinding", "HideMainInterface"}, code);
});
The patch runs once, on the thread that opens the file, the first time the game opens it. The game uses the result from then on, so add patches at plugin load. Patches for one movie run in the order they were added, each on the previous one’s result. Other plugins’ patches run too, in no guaranteed order. Nothing is written to disk.
| Parameter | |
|---|---|
name |
the movie’s file name without its extension, in any case: “optionsmenu” for optionsmenu.gfx |
Owners()
std::vector<void *> Owners()
Returns the GUI manager’s movie records, one for each movie the game has open.
A movie record is the game object that owns a movie; it is the owner passed with each FSCommand or ExternalInterface call.
Returns the records; empty before the GUI manager exists
PressPopupButton()
bool PressPopupButton(std::size_t index)
Presses a button of the message box that is up, as a click does: the box closes as the popup movie closes it, then the game receives the button’s callback.
| Parameter | |
|---|---|
index |
the button’s position in CurrentPopup’s list, from 0 |
Returns false, with nothing done, when no box is up, for a button the box does not have, or for a callback the engine cannot turn into a message
ReplaceMovie()
bool ReplaceMovie(std::wstring_view name, const std::filesystem::path &file)
Replaces one of the game’s movies with a file from your plugin, for as long as the plugin is loaded.
The file is a copy of the game’s movie changed in a Flash editor such as FFDec, as SWF or GFx, compressed or not.
Use it where a change needs graphics of its own or more than a script can add. To leave room for other plugins’ changes to the same movie, add script through OnMovieLoad instead (core::gfx::AppendDoAction). A copy of the game’s movie is BioWare’s file, so a plugin that ships it is distributing that file. A patch added later for the same movie applies to this file; one added earlier is set aside.
| Parameter | |
|---|---|
name |
the movie’s name, as OnMovieLoad takes it |
file |
the replacement, read during the call |
Returns false, leaving the game’s movie alone, if the file cannot be read or is not a movie
ReturnFSCommand()
bool ReturnFSCommand(void *owner, std::span<const std::int32_t> values)
Returns values to an FSCommand the way the game’s own handlers do: sets an array of ints at the calling movie’s _root.fsc_retval, which the ActionScript reads after its fscommand() call.
| Parameter | |
|---|---|
owner |
the owner the FSCommand handler was given |
Returns false if the owner has no movie or GFx could not set the array
ScreenMovie()
std::optional<Movie> ScreenMovie(std::wstring_view screen)
Returns the movie of a shown screen, by the screen’s name.
Use it to drive the screen’s own controls through its ActionScript, as a click would, where no engine message does the job.
if (auto options = dao::gui::ScreenMovie(L"Options"))
{
const dao::gui::Value page[] = {dao::gui::Value::String("Controls")};
options->Invoke("SceneManager.PlayScene", page); // a function of optionsmenu.gfx
const dao::gui::Value bottom[] = {dao::gui::Value::Number(100)};
options->Invoke("_root.KeyBindings_mc.SetScrollPercentage", bottom);
}
Returns the movie; nullopt if the screen is not shown or has no movie
Screens()
std::vector<Screen> Screens()
Returns every screen the GUI system keeps, the game’s and plugins’, ordered by ID.
Call it on the game thread, like ShownScreens and CurrentFullScreen.
Returns the screens; empty before the GUI system is up
ShownScreens()
std::vector<Screen> ShownScreens()
Returns the screens being shown, top layer first.
A tool that cannot see the screen can use it to find out whether the inventory, a store or the map is open.
for (const dao::gui::Screen &screen : dao::gui::ShownScreens())
log(screen.name, screen.layer);
The popup layer counts as shown even with no box up; CurrentPopup tells you whether a box is up.
ShowScreen()
bool ShowScreen(std::wstring_view name)
Opens a screen’s movie, loading it if needed, and shows it.
Call it on the game thread, like HideScreen and CloseScreen.
Returns false before the GUI system is up, or for a screen the game does not have
Variables
kLayerDialog
constexpr std::int32_t kLayerDialog = 5
conversations, death, the main menu
kLayerFloaty
constexpr std::int32_t kLayerFloaty = 0
the floating combat text
kLayerHud
constexpr std::int32_t kLayerHud = 1
the HUD (GUIMain)
kLayerLoading
constexpr std::int32_t kLayerLoading = 8
loading screens
kLayerMenu
constexpr std::int32_t kLayerMenu = 3
in-game menus: the map, journal and skills
kLayerOptions
constexpr std::int32_t kLayerOptions = 6
the options screen
kLayerPopup
constexpr std::int32_t kLayerPopup = 7
message boxes
kScreenModal
constexpr std::uint32_t kScreenModal = 0x20
AddScreen’s flag for a modal screen.