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