For monsters with the same sprite, load the sprite from the file system only once.
Example:
```
VERBOSE: Loaded monster graphics: falspear\phall 452 KiB x1
VERBOSE: Loaded monster graphics: skelbow\sklbw 618 KiB x1
VERBOSE: Loaded monster graphics: skelsd\sklsr 610 KiB x1
VERBOSE: Loaded monster graphics: goatbow\goatb 832 KiB x1
VERBOSE: Loaded monster graphics: bat\bat 282 KiB x2 <-- here we only load the sprite once
VERBOSE: Loaded monster graphics: rhino\rhino 1306 KiB x1
VERBOSE: Loaded monster graphics: golem\golem 298 KiB x1
VERBOSE: Total monster graphics: 4401 KiB 4684 KiB
```
Here, the bat sprite will be loaded from the MPQ only once.
For the second sprite, we simply clone the first sprite before applying TRNs.
This also reduces the size of `MonsterData` from 88 bytes to 80.
When we migrate monster data to a TSV, the sprite IDs can be generated automatically at load time.
Enabled only in Debug mode.
Runs Lua similar to the `lua` CLI.
Supports multiline input with Shift+Enter.
Missing features:
1. Scrollback.
2. Input history on up/down.
Open with backtick, close with Esc.
```lua
local render = devilutionx.render
local function drawGreet ()
render.string("Hello from " .. _VERSION, 10, 40)
end
Events.OnGameDrawComplete.Add(drawGreet)
```
This version of NDK finally comes with updated libc++.
The last update to libc++ in NDK was in early 2020.
This update brings lots of improvements and bugfixes from upstream
libc++.
NDK 26 only support SDK 21+, so we bump `minSdkVersion` as well.
Reduces noisy logging in stderr.txt.
On Windows9x there is no such thing as PrefPath, so there
is no point in trying to get/create one.
Also fixes `SDL_GetBasePath()` to return the directory path rather than
the exe path.
Replaces `NXDK` ifdefs that relate to the lack of wchar APIs
with the more general `DEVILUTIONX_WINDOWS_NO_WCHAR` ifdefs.
This should make it much easier to port to Windows 98.
Usually we call fread in a loop until reaching EOF.
Reaching EOF is not an error, so we should not log it as such.
The error message was previously seen when loading demo files.
We also add a direct string move-assignment (`operator=(std::string &&)`),
which results in better codegen.
As a consequence, we have to replace `= {}` assignments with `= StringOrView {}`
because `= {}` is now ambiguous.
Adds a `ParseInt` function which uses `std::from_chars`.
From `std::from_chars` documentation:
> Unlike other parsing functions in C++ and C libraries,
> std::from_chars is locale-independent, non-allocating, and non-throwing.
Co-authored-by: Andrew James <ephphatha@thelettereph.com>
Adds handy helpers for performing algorithms on the entire container.
They're prefixed with `c_` for container.
This naming convention is identical to some popular C++ libraries, such
as Abseil.
Original Blizzard encoder is slightly less optimal than our encoder.
While size in RAM in less of a concern for the non-`UNPACKED_MPQS`
build, smaller files are faster to render.
Savings for unpacked and minified MPQs:
* diabdat.mpq: 918,311 bytes.
* hellfire.mpq: 313,882 bytes.
Example player graphics (note that only a few are loaded at any given time for single player):
* diabdat/plrgfx/warrior/: 366,564 bytes.
Example monster graphics savings:
* diabdat/monsters/skelbow: 5,391 bytes.
Based on the implementation from https://github.com/diasurgical/devilutionx-graphics-tools/pull/6