The new algorithm is a lot less code, slightly faster, and results
in a smaller binary (-40 KiB on rg99).
The previous algorithm filled all the pixels around every solid pixel.
The new algorithm only fills pixels that will be visible.
We first collect the outline pixels into an array (which may contain a
small amount of duplicates). Then, we render the entire array in a
single loop. This turns out to be slightly faster than rendering inline,
at the cost of ~4 KiB of stack (basically free).
To collect the pixels, we go through the CLX sprite, keeping track
of the solid runs in the current row, and the filled pixels on the line
above and the line below.
To be able to quickly test the pixels above and below, we introduce a
new data structure, `StaticBitVector`. It is similar to a bitset,
except the size is determined at runtime (capacity is fixed),
and it supports quick updates of entire subspans.
We know that length is never 0.
Letting the compiler know that allows it to optimize one instruction
away.
Moreover, for Fill runs, we also know that the length is at least 2.
Inlines blit command parsing.
We previously had blit commands because we supported rendering multiple
formats (CEL, CL2, CLX) but now we only ever render CLX, so this is
no longer necessary.
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>