dao::resources
Read a file as the game finds it, a mod’s version over the game’s.
Declared in dao/Resources.h.
Classes
| Class | |
|---|---|
| Source | One of the places the game finds its files in. |
| Texture | A Direct3D texture the engine has made from a .dds file. |
Type aliases
ReadDone
using ReadDone = std::function<void(std::optional<std::vector<std::byte>> bytes)>
What ReadAsync hands back: the file’s bytes, or nullopt as Read answers.
ResourcePatch
using ResourcePatch = std::function<std::optional<std::vector<std::byte>>(std::wstring_view name, std::span<const std::byte> bytes)>
A patch to a file as the game reads it.
It is given the file’s name, in lower case with its extension, and its bytes as the game found them, and returns the changed bytes, or nullopt to leave them.
TextureEvent
using TextureEvent = std::function<void(const Texture &texture)>
What OnTexture hands a texture to.
Enumerations
SourceKind
enum class SourceKind
What kind of place a source is.
| Value | |
|---|---|
Folder |
loose files, in a folder and its subfolders |
Rim |
an archive the game reads whole, a level’s or an area’s |
Archive |
an .erf |
Other |
Functions
AddFolder()
bool AddFolder(const std::filesystem::path &folder, bool watched=false)
Adds a folder to the places the game finds its files in, as a plugin’s override\ folder is.
The game finds any file in the folder or its subfolders by name, ahead of its own archives and patches and behind the player’s override folder. A file that two added folders both have comes from either. A watched folder is listed again every fifth frame, so keep it small. Adding a folder a second time does nothing and returns true.
Call it from DAOLib_Load, where the folder is added as the game starts and true means only that it will be, or on the game thread once the game is running. A file the game has loaded already stays as it is until the game loads it again.
| Parameter | |
|---|---|
folder |
the folder’s full path |
watched |
true to have the game find files written into the folder after it is added, as it does for the player’s override folder; false to read it once, when it is added |
Returns false if it is not a folder, the game is not a build the library knows, or the game did not take it
Exists()
bool Exists(std::wstring_view file)
Returns whether the game has a file by this name, found the same way as Read finds it.
It loads the file to find out, so call it on the game thread too.
Names()
std::vector<std::wstring> Names(std::wstring_view type)
Returns the names of the game’s files of one type, each once, in no order: every file the game has in its folders and archives as they are now, add-ins’ and a plugin’s among them.
Call it on the game thread, once the game has started. The files of an area’s own archives are among them only while the area is loaded.
| Parameter | |
|---|---|
type |
the extension, with its dot or without: L”mao”, L”.dds” |
Returns the names in lower case, each with its extension; empty if the game has none, or is not a build the library knows
OnLoad()
void OnLoad(std::wstring_view extension, ResourcePatch patch)
Patches every file of a type as the game reads it, whichever copy the game takes: a mod’s, an add-in’s, a campaign’s or the core’s.
Use it to add to the game’s files where a whole replacement would hide every other version of them.
dao::resources::OnLoad(L"mao", [](std::wstring_view name, std::span<const std::byte> bytes) {
return WithMetalness(name, bytes); // the material with lines of the plugin's own added
});
The patch runs each time the game reads such a file’s bytes: when it first uses the file, and again if it has let the file go and uses it again. It runs on the thread that reads, any of the game’s, so it must not call the game; and while it runs, other reads from the same archive wait for it. Patches for one type run in the order they were added, each on the previous one’s result; other plugins’ patches run too, in no guaranteed order. Add patches at plugin load, before the game reads anything. Textures (.dds) are not patched: the game turns their bytes into its own form within the read. Nothing is written to disk.
| Parameter | |
|---|---|
extension |
the type, with its dot or without, in any case: L”mao”, L”.gda” |
OnTexture()
void OnTexture(TextureEvent made, TextureEvent released)
Calls back when the engine makes a Direct3D texture from a .dds file, whichever copy of it, and again when it frees that texture, so that a plugin can tell what it draws with.
Both run on the thread that made or frees the texture, any of the game’s, so they must not call the game; while made runs, other reads from the file’s archive wait for it. Call it at plugin load, before the game reads anything: a texture made before is not reported.
| Parameter | |
|---|---|
made |
runs once the texture is made, with every mip the texture quality keeps; once per texture, though a file read again may be given the texture the engine already has for it |
released |
runs with the same name and pointer just before the engine releases it, after which the pointer may be another texture’s |
PathOf()
std::optional<std::filesystem::path> PathOf(std::wstring_view sourceName)
Returns the file on disk an engine source name stands for, through the engine’s alias table: L”WRITE_OVERRIDE:my mod\\x.rim” is the file under the override folder the game writes to.
The part after the ‘:’ comes back in lower case, as the engine makes it. Seen with ENV:, OVERRIDE:, WRITE_OVERRIDE:, ADDINS: and BUILD_ADDINS:. Call it on the game thread.
Returns nullopt before the table is made, for an alias the table has not, and for a name that is no path; a full path comes back as it is
Read()
std::optional<std::vector<std::byte>> Read(std::wstring_view file)
Returns a copy of a file’s bytes.
Call it on the game thread, once the game has started. A texture (.dds) is read from its archive or folder each time, since the game keeps its own form of a texture it has used and not the file; every other file is copied from what the game holds.
| Parameter | |
|---|---|
file |
the file name with its extension, such as L”rules_core.ncs” |
Returns nullopt if the game has no file by that name or cannot read it. The game may write a line about it to its own log.
ReadAsync()
void ReadAsync(std::wstring_view file, ReadDone done)
Reads a copy of a file’s bytes as Read does, but away from the game thread, and hands them to a callback on the game thread when they are read.
For a large file, a texture above all, that would hold the game thread for long enough to be seen. The reads go one at a time, in the order asked. Call it once the game has started, from any thread.
| Parameter | |
|---|---|
file |
the file name with its extension |
done |
runs once, on the game thread (dao/Frame.h), a frame or more later |
RemoveFolder()
bool RemoveFolder(const std::filesystem::path &folder)
Takes away a folder that AddFolder added, so the game finds the files it had elsewhere, or not at all.
Call it where AddFolder is called. A file the game has loaded already stays as it is until the game loads it again.
| Parameter | |
|---|---|
folder |
the path given to AddFolder |
Returns false if this plugin has not added the folder, or the game did not have it
SourceOf()
std::optional<Source> SourceOf(std::wstring_view file)
Returns the place the game takes a file from: the first of Sources() that has it.
It loads the file to find out, as Exists does, so call it on the game thread.
| Parameter | |
|---|---|
file |
the file name with its extension, such as L”rules_core.ncs” |
Returns nullopt if the game has no file by that name
Sources()
std::vector<Source> Sources()
Returns the places the game finds its files in, in the order it looks in them: a file comes from the first that has it.
Call it on the game thread, once the game has started. Loading a level or a campaign adds and takes away sources.
Returns empty if the game’s sources are not set up yet, or the game is not a build the library knows