Tthis gives us the option to specify what type a file should be loaded
as, avoidng the need to case it and does some automatic checks on the
fitness of the data, while making the process simpler.
If no type is given then the type will be set to std::byte which limit
what operations can be performed on the data.
This is part of the work to allow us to eliminate buffer padding.
As this is a hotspot, we have 4 separate functions for each non-square
primitive, resulting in quite a bit of code:
1. Unclipped ("Full")
2. Vertical-only clip
3. Vertical + Left clip
4. Vertical + Right clip
FPS at 640x480: 1420 -> 1530
Rename the config entry for changing the quick messages texts
Other small improvements and simplifications
Set the quick spell hotkey text to be white with a black shadow
Add QuitGame action, unbound by default
Set the ItemInfo and QuestDebug keys to be unbound by default
This fixes a data race by deleting the sound exactly when it finishes
playing.
Previously, a data race could happen in
`CleanupFinishedDuplicateSounds`, where the sound would be destroyed
while Aulib was reading from its buffer.
`std::make_unique<T[]>(size)` always zero-initalizes the array.
C++20 has `std::make_unique_for_overwrite` to avoid that, while
older C++ versions can use the approach applied here.
No longer needed as of #1796
We could probably go further and not expose `ItemAnimWidth`,
but it'd be dangerous because sometimes `_iAnimData` is null.
The new approach only makes 2 read calls and does not do any seeks.
It is also less general and is internal to `art.cpp`, allowing us to
simplify it somewhat.
Previously, we always loaded entire videos in memory before playing them.
`libsmacker` does not provide a streaming API but it does provide a
`FILE *` file pointer API.
We now take advantage of the `FILE *` API by streaming the videos on
platforms that support `fopencookie`.
This means faster startup and less memory usage on these platforms.