Add FixedPoint::divideWithoutWidening for cases where the caller can
already show the wide intermediate isn't needed, and use it in
AnimationInfo::setNewAnimation to avoid a 64-bit division that the
original int32_t arithmetic never required.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Replaces ParseFixed6/parseFixed6/readFixed6/readDecimal's raw-int
plumbing with the new FixedPoint type, then propagates strongly-typed
fixed-point fields through everywhere that consumed them: player
_pHitPoints/_pMana (and their base/max variants), ClassAttributes'
percentage/multiplier fields, Item::_iPLHP/_iPLMana, and
Monster::hitPoints/maxHitPoints. Eliminates manual <<6/>>6 bit-shifting
at nearly every call site in favor of fromInt/fromRaw/whole() and the
new fixed-point arithmetic operators, while preserving raw() only at
genuine serialization/network wire-format boundaries.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Added option to show summoned monster (Golem) party portrait
Fixed crash when loading .trn files for monsters with missing animations
(Golem is missing standing animation)
Split several monolithic files to reduce transitive dependencies and
enable the dun_render_benchmark to link without bringing in all of
DevilutionX:
- Extract dungeon tile globals and loading functions from `gendung` into
`dun_tile_data.{hpp,cpp}`
- Extract light table data and MakeLightTable from lighting into
`engine/light_tables.{hpp,cpp}`
- Move cursor_id and SelectionRegion to cursor_defs.hpp
- Extract quest log rendering to `panels/quest_log.{hpp,cpp}`
- Extract drlg quest setpiece logic to `levels/drlg_quests.{hpp,cpp}`
- Extract quest data loading to `tables/questdat.{hpp,cpp}`
- Move `GameData` and `gbIsMultiplayer` into `game_mode.{hpp,cpp}`
- Add `parse_sfx_id.{hpp,cpp}`
- Update CMake libraries accordingly
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- `fmt::format` with literal format strings -> `std::format`.
- `fmt::format(fmt::runtime(...))` -> `FormatRuntime` in the new
`utils/format.hpp`, a std::vformat wrapper that is also safe under the
P2905 lvalue requirement of `std::make_format_args`.
- `fmt::dynamic_format_arg_store` (Lua logging) -> a small hand-rolled
per-field formatter over `std::variant`, returning `std::expected`.
- `fmt::format_int` -> `std::to_chars`.
- `fmt::join` -> manual joins at the two call sites.
- SDL_audiolib: new patch that rewrites aulib_log.h to use std::format
and drops the fmt dependency from its CMakeLists.
- The `-static-libstdc++` guard now keys off
`DEVILUTIONX_STATIC_SDL_AUDIOLIB` instead of `DEVILUTIONX_STATIC_LIBFMT`.
- libfmt removed from CMake, vcpkg, Brewfile, CI workflows,
Dockerfiles, packaging scripts, UWP project, and docs.
- macOS bumped to 13.3+, iOS to 16.3+ (required for `<format>`)
- Amiga m68k: provide `__cmpdf2`, which is missing from the hard-float
libgcc multilib but referenced via libstdc++'s long double paths.
Co-Authored-By: Claude Fable 5 <[email protected]>
Now that the project targets C++23, use the standard library's
std::expected instead of the vendored tl::expected polyfill:
- tl::expected -> std::expected, tl::unexpected/tl::make_unexpected -> std::unexpected
- .map()/.map_error() -> .transform()/.transform_error()
- #include <expected.hpp> -> #include <expected>, grouped with std headers
- Remove 3rdParty/tl/expected.hpp (the tl target remains for function_ref.hpp)
Co-Authored-By: Claude Fable 5 <[email protected]>
The loaders returned success with a null/empty buffer when a file could
not be opened in HeadlessMode, breaking every caller that probes
has_value() to pick between asset sources. With Diablo-only data the
Hellfire->Diablo town fallbacks (LoadLvlGFX / LoadMinData /
LoadLevelSOLData) never triggered: entering town dereferenced a null
town.min with uninitialized tileCount in SetDungeonMicros, a null
pMegaTiles in T_FillSector, and silently kept the previous level's
SOLData.
Files that do exist were already loaded identically in headless and
graphical builds; the special case only affected the missing-file path.
Headless code paths are a subset of the graphical ones, so reporting
the error exactly like the graphical build restores the intended
fallback behaviour with no call-site changes.
`mpqfs` API changed from bool/NULL return values and
a global `mpqfs_last_error()` to `mpqfs_error_code` return values.
`MpqArchive::Open/Clone now return `tl::expected<MpqArchive, std::string>`
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Our CMake assumed that `ANDROID` meant we're compiling for Android from
a non-Android machine.
However, these days it's entirely possible to use an Android device as a
Linux machine (e.g. via Termux).
These don't currently seem to affect performance (GCC-15).
Still, they serve as documentation and perhaps future smarter
compilers can't take more advantage of it.
Five independent improvements measured via light_render_benchmark
(RelWithDebInfo, baseline 66,322 ns):
- Replace integer division in Interpolate with a 240-byte constexpr
lookup table indexed by (lightLevel - q1, q2 - q1). Saves an idiv
per interpolated edge. (~1%)
- Make DecrementTowardZero branchless: `num - ((num >> 31) | 1)`.
Called 6x per row in the RenderTriangle inner loop, so branch
misprediction cost adds up. (~6%)
- Iterate the light-level loop from maxLight down to minLight directly
instead of scanning all LightsMax levels with continue/break. Cuts
up to 14 spurious iterations per cell. (~8%)
- Cache adjacent quad values across columns. (~3%)
- Replace memset with FillBytes in hot paths (~30% faster)
Final: ~38,000ns (~40% faster)
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
For some reason, setting the scaling on just `texture` still results
in bluriness. However, setting the default scaling mode on the renderer
fixes it.
Also, does a few more things the SDL3 way.
This doesn't implement full sound support but stubs out most of the
sound code under SDL3, so that we can implement it piecemeal.
Implemented here:
1. Sound device initialization.
2. SVid sound playback.
Does not add a dependency on `SDL_mixer`: SDL3 built-ins
are enough to play SVid audio.